Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: audit.connect
Title: Posit Connect Health Check
Version: 0.8.8
Version: 0.8.9
Authors@R:
person("Jumping", "Rivers", , "info@jumpingrivers.com", role = c("aut", "cre"))
Description: Posit Connect Health Check. Deploys various content types to
Expand All @@ -21,11 +21,13 @@ Imports:
pins (>= 1.1.0),
processx,
purrr,
R6,
quarto (>= 1.3),
rlang,
rsconnect (>= 1.10.0),
stringr,
tibble,
utils,
withr
Suggests:
glue,
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ export(get_quarto_old_users)
export(get_quarto_user_roles)
export(sanitise)
import(audit.base)
importFrom(R6,R6Class)
importFrom(rlang,.data)
importFrom(rlang,.env)
11 changes: 11 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# audit.connect 0.8.9

## Bug fixes and minor improvements

* Any exported class whose name starts with `check_` is run as a check, as the README says. Before, only `check_deploy*` classes were (#72).
* `check()` prints the user summary once (#72).
* The Git-backed check deploys with its own title, so its content is deleted afterwards (#72).
* Python clean-up deletes only content owned by the auditor (#72).
* The report's old-users table lists users who have never logged in. Users inactive for exactly 6 or 12 months are no longer left out (#72).
* The README's renv advice uses a temporary cache, instead of deleting the user's whole renv cache (#72).

# audit.connect 0.8.8

## Bug fixes and minor improvements
Expand Down
19 changes: 1 addition & 18 deletions R/check.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#' * 1: clean-up all files, but display build steps
#' * 2: No clean-up (on connect and on disk) and display build steps
#' @importFrom rlang .data .env
#' @importFrom R6 R6Class
#' @import audit.base
#' @export
check = function(server = NULL, token = NULL, dir = ".", debug_level = 0:2) {
Expand All @@ -33,7 +34,6 @@ check = function(server = NULL, token = NULL, dir = ".", debug_level = 0:2) {
check_list$versions = summarise_versions(get_server(), get_token())

# check_list$feature_usage = summarise_feature_usage(get_server(), get_token()) #nolint
check_list$audit_details = audit_details(get_server(), get_token())
check_list$users_details = summarise_users(
server = get_server(),
token = get_token(),
Expand All @@ -45,20 +45,3 @@ check = function(server = NULL, token = NULL, dir = ".", debug_level = 0:2) {
cli::cli_h1("All checks complete")
invisible(check_list)
}

init_r6_checks = function(dir, file) {
exports = getNamespaceExports("audit.connect")
check_exports = sort(exports[stringr::str_starts(exports, "check_deploy")])
r6_inits = lapply(check_exports, init_r6_check, dir = dir, file = file)
r6_inits
}

init_r6_check = function(export, dir, file) {
obj = eval(parse(text = export))
if (inherits(obj, "R6ClassGenerator")) {
obj = obj$new(dir, file)
} else {
obj = NULL
}
obj
}
6 changes: 5 additions & 1 deletion R/check_deployments.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
check_deployments = function(dir, debug_level) {
cli::cli_h2("Document Deployment Checks")
r6_inits = init_r6_checks(dir = dir, file = "config-uat-rsc.yml")
r6_inits = audit.base::init_r6_checks(
dir = dir,
file = "config-uat-rsc.yml",
pkg_name = "audit.connect"
)
lapply(r6_inits, function(r6) r6$check(debug_level = debug_level))
deployments = purrr::map_dfr(r6_inits, ~ .x$get_log())
deployments = dplyr::arrange(deployments, .data$group, .data$short)
Expand Down
2 changes: 1 addition & 1 deletion R/deploy_flask-r6.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ check_deploy_python_flask = R6::R6Class(
"check_deploy_python_flask",
inherit = audit.base::base_check,
public = list(
#' @description Checks deployment of Quarto document with HTML output
#' @description Checks deployment of a Python Flask API
#' @param debug_level See check() for details
check = function(debug_level) {
if (skip_without_rsconnect_python(self)) {
Expand Down
2 changes: 1 addition & 1 deletion R/deploy_git.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ deploy_git = function(repository, debug_level, title) {
repository,
branch = "main",
subdirectory = ".",
title = "UAT"
title = title
))

# If deploy not successful, content not created
Expand Down
2 changes: 1 addition & 1 deletion R/deploy_plumber-r6.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#' Check classes
#' @export
check_deploy_plumber_api = R6::R6Class(
"check_deploy_pluumber_api",
"check_deploy_plumber_api",
inherit = audit.base::base_check,
public = list(
#' @description Checks deployment of a Plumber API
Expand Down
5 changes: 3 additions & 2 deletions R/deploy_python.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ deploy_python = function(
python_dir,
python_files = c("app.py", "index.qmd", "hash.ipynb"),
rsconnect_type = c("api", "streamlit", "quarto", "voila"),
debug_level = debug_level
debug_level
) {
suppress = get_suppress(debug_level)
rsconnect_type = match.arg(rsconnect_type)
Expand Down Expand Up @@ -69,7 +69,8 @@ cleanup_python = function(tmp_dir, debug_level, title) {
api_key = get_token()
)
)
content = suppress(connectapi::get_content(con))
# Only the auditor's content, so nobody else's item with the same title is deleted
content = suppress(connectapi::get_content(con, owner_guid = con$me()$guid))
guid = content$guid[content$title %in% title]
purrr::map(
guid,
Expand Down
2 changes: 1 addition & 1 deletion R/deploy_quarto.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
deploy_quarto = function(
quarto_dir,
account = NULL,
debug_level = debug_level
debug_level
) {
suppress = get_suppress(debug_level)

Expand Down
2 changes: 1 addition & 1 deletion R/deploy_shiny-r6.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ check_deploy_shiny = R6::R6Class(
"check_deploy_shiny",
inherit = audit.base::base_check,
public = list(
#' @description Checks deployment of an R Markdown document with Word Docx output
#' @description Checks deployment of a Shiny app
#' @param debug_level See check() for details
check = function(debug_level) {
shiny_dir = system.file(
Expand Down
9 changes: 5 additions & 4 deletions R/quarto-helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,21 @@ get_quarto_old_users = function(out) {
) /
months(1), #nolint
last_log_in = dplyr::case_when(
is.na(last_log_on_diff) ~ "Never logged in",
last_log_on_diff > 12 ~ "12 months+",
last_log_on_diff > 6 & last_log_on_diff < 12 ~ "6 months+",
last_log_on_diff > 3 & last_log_on_diff < 6 ~ "3 months+",
last_log_on_diff > 6 ~ "6 months+",
last_log_on_diff > 3 ~ "3 months+",
.default = NA
)
) |>
dplyr::filter(.data$last_log_on_diff > 3) |>
dplyr::filter(!is.na(.data$last_log_in)) |>

dplyr::group_by(.data$last_log_in) |>
dplyr::reframe(email = paste(.data$email, collapse = ", ")) |>
dplyr::mutate(
last_log_in = factor(
.data$last_log_in,
c("12 months+", "6 months+", "3 months+"),
c("Never logged in", "12 months+", "6 months+", "3 months+"),
ordered = TRUE
)
) |>
Expand Down
2 changes: 1 addition & 1 deletion R/summarise_setup.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Note: storing variables in .connect as in the (near) future, we'll want to pass
# keys / servers as variables
summarise_setup = function(server, token) {
cli::cli_h2("Summary audit.connect v{packageVersion('audit.connect')}")
cli::cli_h2("Summary audit.connect v{utils::packageVersion('audit.connect')}")
setup = list()
setup$server = check_server(server)
setup$api_key = check_api_key(token)
Expand Down
4 changes: 2 additions & 2 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ If you aren't using binaries or the OS is the same, then you won't have any issu
If you want to be sure, we can use {renv}

```{r, eval = FALSE}
# Ensure we don't use the existing renv cache
fs::dir_delete(renv::paths$cache())
# Use a new, empty cache for this project, leaving your own renv cache alone
Sys.setenv(RENV_PATHS_CACHE = tempfile("renv-cache-"))
# Use the slow installation method
renv::init(repo = "https://cloud.r-project.org/")
renv::install("remotes")
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ If you aren’t using binaries or the OS is the same, then you won’t have
any issue. If you want to be sure, we can use {renv}

``` r
# Ensure we don't use the existing renv cache
fs::dir_delete(renv::paths$cache())
# Use a new, empty cache for this project, leaving your own renv cache alone
Sys.setenv(RENV_PATHS_CACHE = tempfile("renv-cache-"))
# Use the slow installation method
renv::init(repo = "https://cloud.r-project.org/")
renv::install("remotes")
Expand Down
14 changes: 7 additions & 7 deletions man/check_deploy_plumber_api.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/check_deploy_python_flask.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/check_deploy_shiny.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/deploy_python.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions tests/testthat/test-quarto-helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,20 @@ test_that("get_quarto_locked_user_apps() counts content owned by locked users",
# An evaluation licence skips the user audit
expect_identical(get_quarto_locked_user_apps(list(users_details = list(locked_apps = NULL))), 0L)
})

test_that("get_quarto_old_users lists users who have never logged in", {
now = lubridate::now()
users = tibble::tibble(
email = c("a@x.com", "b@x.com", "c@x.com", "d@x.com"),
locked = FALSE,
active_time = c(now - lubridate::days(400), now - lubridate::days(200), now, NA)
)
out = list(users_details = list(user_list = list(users = users)))

old_users = get_quarto_old_users(out)
expect_equal(
as.character(old_users$last_log_in),
c("Never logged in", "12 months+", "6 months+")
)
expect_equal(old_users$email, c("d@x.com", "a@x.com", "b@x.com"))
})
Loading