Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial infrastructure for the dual repo approach #25

Merged
merged 17 commits into from
Jun 6, 2024
1 change: 0 additions & 1 deletion .github/workflows/check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ jobs:
- {os: windows-latest, r: 'release'}
- {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
- {os: ubuntu-latest, r: 'release'}
- {os: ubuntu-latest, r: 'oldrel-1'}

env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
Expand Down
50 changes: 50 additions & 0 deletions .github/workflows/pkgdown.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
push:
branches: [main]
pull_request:
branches: [main]
release:
types: [published]
workflow_dispatch:

name: pkgdown

jobs:
pkgdown:
runs-on: ubuntu-latest
concurrency:
group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v3

- uses: r-lib/actions/setup-pandoc@v2

- name: system dependencies
if: runner.os == 'Linux'
run: sudo apt-get install -y libmbedtls-dev

- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::pkgdown, local::.
needs: website
cache-version: 2

- name: Build site
run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
shell: Rscript {0}

- name: Deploy to GitHub pages
if: github.event_name != 'pull_request'
uses: JamesIves/github-pages-deploy-action@v4.6.1
with:
clean: false
branch: gh-pages
folder: docs
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Package: multiverse.internals
Title: Internal Infrastructure for R-multiverse
Description: R-multiverse requires this internal internal infrastructure
package to automate contribution reviews and populate universes.
Version: 0.1.4
Version: 0.2.0
License: MIT + file LICENSE
URL: https://github.com/r-multiverse/multiverse.internals
BugReports: https://github.com/r-multiverse/multiverse.internals/issues
Expand Down
5 changes: 5 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ export(assert_cran_url)
export(assert_package)
export(assert_release_exists)
export(get_current_versions)
export(issues_checks)
export(issues_descriptions)
export(issues_versions)
export(meta_checks)
export(meta_packages)
export(record_issues)
export(record_versions)
export(review_pull_request)
Expand Down
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# multiverse.internals 0.2.0

* Add more checks to `record_issues()`: results from the R-universe check API, plus specific results from package `DESCRIPTION` files.
* Refactor and document specific checks in `check_checks()`, `check_descriptions()`, and `check_versions()`.
* Add a `pkgdown` website.

# multiverse.internals 0.1.4

* Do not write `version_issues.json` from `record_versions()`.
Expand Down
41 changes: 41 additions & 0 deletions R/issues_checks.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#' @title Report issues from R-universe package check results.
#' @export
#' @family issues
#' @description Check R-universe package check results.
#' @details [issues_checks()] reads output from
#' the R-universe check API
#' to scan all R-multiverse packages for issues that may have
#' happened during building and testing.
#' @inheritSection record_issues Package issues
#' @return A named list of information about packages which do not comply
#' with `DESCRPTION` checks. Each name is a package name,
#' and each element contains specific information about
#' non-compliance.
#' @param meta A data frame with R-universe package check results
#' returned by [meta_checks()].
#' @examples
#' meta <- meta_checks(repo = "https://wlandau.r-universe.dev")
#' issues <- issues_checks(meta = meta)
#' str(issues)
issues_checks <- function(meta) {
fields_check <- c(
"_linuxdevel",
"_macbinary",
"_wasmbinary",
"_winbinary",
"_status"
)
fields_info <- c(
"_buildurl"
)
fields <- c(fields_check, fields_info)
for (field in fields) {
meta[[field]][is.na(meta[[field]])] <- "src-failure"
}
success <- rep(TRUE, nrow(meta))
for (field in fields_check) {
success <- success & (meta[[field]] %in% c("success", "skipped"))
}
meta <- meta[!success,, drop = FALSE] # nolint
issues_list(meta[, c("package", fields)])
}
31 changes: 31 additions & 0 deletions R/issues_descriptions.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#' @title Report `DESCRIPTION` file issues.
#' @export
#' @family issues
#' @description Report issues with the `DESCRIPTION` files of packages.
#' @details [issues_descriptions()] scans downloaded metadata from the
#' `PACKAGES.json` file of an R universe and reports issues with a
#' package's description file, such as the presence of a
#' `"Remotes"` field.
#' @inheritSection record_issues Package issues
#' @return A named list of information about packages which do not comply
#' with `DESCRPTION` checks. Each name is a package name,
#' and each element contains specific information about
#' non-compliance.
#' @param meta A data frame with R-universe package check results
#' returned by [meta_checks()].
#' @examples
#' meta <- meta_packages(repo = "https://wlandau.r-universe.dev")
#' issues <- issues_descriptions(meta = meta)
#' str(issues)
issues_descriptions <- function(meta) {
meta <- issues_descriptions_remotes(meta)
fields <- "remotes"
meta <- meta[, c("package", fields)]
issues_list(meta)
}

issues_descriptions_remotes <- function(meta) {
meta[["remotes"]] <- meta[["remotes"]] %||% replicate(nrow(meta), NULL)
meta$remotes <- lapply(meta$remotes, function(x) x[nzchar(x)])
meta[vapply(meta$remotes, length, integer(1L)) > 0L, ]
}
63 changes: 63 additions & 0 deletions R/issues_versions.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#' @title Check package versions.
#' @export
#' @family issues
#' @description Check package version number history for compliance.
#' @details This function checks the version number history of packages
#' in R-multiverse and reports any packages with issues. The current
#' released version of a given package must be unique, and it must be
#' greater than all the versions of all the previous package releases.
#' @inheritSection record_issues Package issues
#' @return A named list of information about packages which do not comply
#' with version number history checks. Each name is a package name,
#' and each element contains specific information about version
#' non-compliance: the current version number, the current version hash,
#' and the analogous versions and hashes of the highest-versioned
#' release recorded.
#' @inheritParams record_versions
#' @examples
#' # See https://github.com/r-multiverse/checks/blob/main/versions.json
#' # for the official versions JSON for R-multiverse.
#' lines <- c(
#' "[",
#' " {",
#' " \"package\": \"package_unmodified\",",
#' " \"version_current\": \"1.0.0\",",
#' " \"hash_current\": \"hash_1.0.0\",",
#' " \"version_highest\": \"1.0.0\",",
#' " \"hash_highest\": \"hash_1.0.0\"",
#' " },",
#' " {",
#' " \"package\": \"version_decremented\",",
#' " \"version_current\": \"0.0.1\",",
#' " \"hash_current\": \"hash_0.0.1\",",
#' " \"version_highest\": \"1.0.0\",",
#' " \"hash_highest\": \"hash_1.0.0\"",
#' " },",
#' " {",
#' " \"package\": \"version_incremented\",",
#' " \"version_current\": \"2.0.0\",",
#' " \"hash_current\": \"hash_2.0.0\",",
#' " \"version_highest\": \"2.0.0\",",
#' " \"hash_highest\": \"hash_2.0.0\"",
#' " },",
#' " {",
#' " \"package\": \"version_unmodified\",",
#' " \"version_current\": \"1.0.0\",",
#' " \"hash_current\": \"hash_1.0.0-modified\",",
#' " \"version_highest\": \"1.0.0\",",
#' " \"hash_highest\": \"hash_1.0.0\"",
#' " }",
#' "]"
#' )
#' versions <- tempfile()
#' writeLines(lines, versions)
#' out <- issues_versions(versions)
#' str(out)
issues_versions <- function(versions) {
history <- jsonlite::read_json(path = versions, simplifyVector = TRUE)
aligned <- (history$version_current == history$version_highest) &
(history$hash_current == history$hash_highest)
aligned[is.na(aligned)] <- TRUE
out <- history[!aligned,, drop = FALSE] # nolint
issues_list(out)
}
35 changes: 35 additions & 0 deletions R/meta_checks.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#' @title List metadata about R-universe package checks
#' @export
#' @family list
#' @description List package checks results reported by the
#' R-universe package API.
#' @return A data frame with one row per package and columns with
#' package check results.
#' @param repo Character of length 1, URL of the package repository.
#' R-multiverse uses `"https://multiverse.r-multiverse.org"`.
#' @examples
#' meta_checks(repo = "https://wlandau.r-universe.dev")
meta_checks <- function(repo = "https://multiverse.r-multiverse.org") {
fields <- c(
"_buildurl",
"_linuxdevel",
"_macbinary",
"_wasmbinary",
"_winbinary",
"_status"
)
listing <- file.path(
repo,
"api",
paste0("packages?stream=true&fields=", paste(fields, collapse = ","))
)
out <- jsonlite::stream_in(
con = gzcon(url(listing)),
verbose = FALSE,
simplifyVector = TRUE,
simplifyDataFrame = TRUE,
simplifyMatrix = TRUE
)
colnames(out) <- tolower(colnames(out))
out
}
25 changes: 25 additions & 0 deletions R/meta_packages.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#' @title List package metadata
#' @export
#' @family meta
#' @description List package metadata in an R universe.
#' @return A data frame with one row per package and columns with package
#' metadata.
#' @inheritParams meta_checks
#' @examples
#' meta_packages(repo = "https://wlandau.r-universe.dev")
meta_packages <- function(repo = "https://multiverse.r-multiverse.org") {
fields <- c("Version", "Remotes", "RemoteSha")
listing <- file.path(
contrib.url(repos = repo, type = "source"),
paste0("PACKAGES.json?fields=", paste(fields, collapse = ","))
)
out <- jsonlite::stream_in(
con = gzcon(url(listing)),
verbose = FALSE,
simplifyVector = TRUE,
simplifyDataFrame = TRUE,
simplifyMatrix = TRUE
)
colnames(out) <- tolower(colnames(out))
out
}
4 changes: 0 additions & 4 deletions R/package.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
#' multiverse.internals: Internal Infrastructure for R-multiverse.
#' @description Internal Infrastructure for R-multiverse.
#' @name multiverse.internals-package
#' @family help
#' @importFrom gh gh
#' @importFrom jsonlite parse_json read_json stream_in write_json
#' @importFrom nanonext ncurl parse_url status_code
Expand Down
Loading
Loading