chore: Auto-update from GitHub Actions #2305
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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 | |
| # | |
| # NOTE: This workflow is overkill for most R packages and | |
| # check-standard.yaml is likely a better choice. | |
| # usethis::use_github_action("check-standard") will install it. | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - master | |
| - release | |
| - next | |
| - cran-* | |
| pull_request: | |
| branches: | |
| - main | |
| - master | |
| workflow_dispatch: | |
| inputs: | |
| ref: | |
| description: "Branch, tag, or commit to check out" | |
| required: false | |
| default: "main" | |
| versions-matrix: | |
| description: "Create a matrix of R versions" | |
| type: boolean | |
| default: false | |
| dep-suggests-matrix: | |
| description: "Create a matrix of suggested dependencies" | |
| type: boolean | |
| default: false | |
| run-rcc-full: | |
| description: "Run rcc-full job" | |
| type: boolean | |
| default: false | |
| run-rcc-suggests: | |
| description: "Run rcc-suggests job" | |
| type: boolean | |
| default: false | |
| # SECURITY: a merge-queue run executes the queued pull request's code with | |
| # the base repository's token and secrets, unlike `pull_request`, where a | |
| # fork only ever gets a read-only token and no secrets. Adding a fork's pull | |
| # request to the queue is therefore as much of a trust decision as merging | |
| # it; keep "Require merge queue" paired with a branch rule that only lets | |
| # maintainers enqueue. | |
| merge_group: | |
| types: | |
| - checks_requested | |
| schedule: | |
| - cron: "10 1 * * *" | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.ref || github.head_ref || github.sha }}-${{ github.base_ref || '' }} | |
| cancel-in-progress: true | |
| name: rcc | |
| # Read-only by default; every job opts back into what it actually needs. | |
| # Note that for a pull request from a fork GitHub caps the token at read-only | |
| # regardless of what is requested here. | |
| permissions: | |
| contents: read | |
| jobs: | |
| rcc-smoke: | |
| # Deliberately amd64. The smoke test is the gate that also styles, | |
| # roxygenizes, updates snapshots, commits back and deploys pkgdown, so it | |
| # must run on the most stable and available runner. The ubuntu-26.04-arm | |
| # image is still in public preview (actions/runner-images#14226 -- possible | |
| # instability and queueing), so arm64 is exercised in the full version matrix | |
| # (rcc-full) instead, where fail-fast: false isolates failures and jobs don't | |
| # mutate the repo. Revisit once the arm image is generally available. | |
| runs-on: ubuntu-26.04 | |
| outputs: | |
| sha: ${{ steps.commit.outputs.sha }} | |
| versions-matrix: ${{ steps.versions-matrix.outputs.matrix }} | |
| dep-suggests-matrix: ${{ steps.dep-suggests-matrix.outputs.matrix }} | |
| name: "Smoke test: stock R" | |
| permissions: | |
| contents: write | |
| statuses: write | |
| pull-requests: write | |
| actions: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ inputs.ref }} | |
| - name: Update status for rcc (pending) | |
| if: github.actor != 'Copilot' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) | |
| uses: ./.github/workflows/commit-status | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| state: pending | |
| sha: ${{ inputs.ref }} | |
| - name: Report the GitHub API rate limit | |
| uses: ./.github/workflows/rate-limit | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Configure the Git identity | |
| uses: ./.github/workflows/git-identity | |
| - name: Run the repository-specific before-install steps | |
| uses: ./.github/workflows/custom/before-install | |
| if: hashFiles('.github/workflows/custom/before-install/action.yml') != '' | |
| - name: Install R and the package dependencies | |
| uses: ./.github/workflows/install | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| cache-version: rcc-smoke-2 | |
| needs: build, check, website, roxygen2 | |
| # Beware of using dev pkgdown here, has brought in dev dependencies in the past | |
| extra-packages: any::rcmdcheck r-lib/roxygen2 any::decor r-lib/pkgdown deps::. | |
| - name: Run the repository-specific after-install steps | |
| uses: ./.github/workflows/custom/after-install | |
| if: hashFiles('.github/workflows/custom/after-install/action.yml') != '' | |
| # Must come after the custom after-install workflow | |
| - name: Install package | |
| run: | | |
| _R_SHLIB_STRIP_=true R CMD INSTALL . | |
| shell: bash | |
| # From here on, every step is marked `continue-on-error: true` so that a | |
| # failing check doesn't hide the results of all the checks that follow. | |
| # The "Summarize checks" step at the end fails the job if any of them | |
| # did not succeed. | |
| - name: Collect the R versions into a matrix | |
| id: versions-matrix | |
| continue-on-error: true | |
| # Only run for: | |
| # - pull requests if the base repo is different from the head repo | |
| # - pull requests if the branch name starts with "cran-" | |
| # Do not run for: | |
| # - workflow_dispatch if not requested | |
| # Always run for other events. | |
| if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository || startsWith(github.head_ref, 'cran-')) && (github.event_name != 'workflow_dispatch' || inputs.versions-matrix) | |
| uses: ./.github/workflows/versions-matrix | |
| - name: Collect the suggested dependencies into a matrix | |
| id: dep-suggests-matrix | |
| continue-on-error: true | |
| # Not for workflow_dispatch if not requested, always run for other events | |
| if: github.event_name != 'workflow_dispatch' || inputs.dep-suggests-matrix | |
| uses: ./.github/workflows/dep-suggests-matrix | |
| - name: Determine repository state | |
| id: repo-state | |
| uses: ./.github/workflows/repo-state | |
| # Styling on foreign PRs works through the format-suggest workflow | |
| - name: Style the R sources | |
| id: style | |
| continue-on-error: true | |
| uses: ./.github/workflows/style | |
| if: steps.repo-state.outputs.foreign != 'true' || steps.repo-state.outputs.is_pr != 'true' | |
| # Snapshot tests can't work in a way similar to format-suggests | |
| # because it requires running code which is a security risk on pull_request_target workflows | |
| - name: Update the testthat snapshots | |
| id: snapshots | |
| continue-on-error: true | |
| uses: ./.github/workflows/update-snapshots | |
| with: | |
| base: ${{ inputs.ref || github.head_ref }} | |
| - name: Roxygenize the documentation | |
| id: roxygenize | |
| continue-on-error: true | |
| uses: ./.github/workflows/roxygenize | |
| - name: Remove config files from previous iteration | |
| run: | | |
| rm -f .github/dep-suggests-matrix.json .github/versions-matrix.json | |
| shell: bash | |
| - name: Commit and push the generated changes | |
| id: commit | |
| continue-on-error: true | |
| uses: ./.github/workflows/commit | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Run R CMD check | |
| id: check | |
| continue-on-error: true | |
| uses: ./.github/workflows/check | |
| with: | |
| results: ${{ runner.os }}-smoke-test | |
| - name: Build the pkgdown website | |
| id: pkgdown-build | |
| continue-on-error: true | |
| uses: ./.github/workflows/pkgdown-build | |
| if: github.event_name != 'push' | |
| # Deliberately deploy only on push | |
| # Deployment on schedule adds too much noise. | |
| # Deployment on pull_request is not possible because it requires a token with write permissions, which is not available in pull_request workflows for security reasons. | |
| # Deployment on workflow_dispatch is available via the pkgdown workflow | |
| # Deploying a broken package's website is worse than not deploying at all, | |
| # hence this is the one step that is still gated on a check. | |
| - name: Build and deploy the pkgdown website | |
| id: pkgdown-deploy | |
| continue-on-error: true | |
| uses: ./.github/workflows/pkgdown-deploy | |
| if: github.event_name == 'push' && steps.check.outcome == 'success' | |
| # Upload sha as artifact | |
| - name: Record the commit SHA reached by the smoke test | |
| run: | | |
| echo -n "${{ steps.commit.outputs.sha }}" > rcc-smoke-sha.txt | |
| shell: bash | |
| - name: Upload the commit SHA reached by the smoke test | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: rcc-smoke-sha | |
| path: rcc-smoke-sha.txt | |
| # This is the step that fails the job if any of the checks above failed | |
| - name: Summarize checks | |
| if: always() | |
| run: | | |
| ## -- Summarize checks -- | |
| status=0 | |
| report() { | |
| outcome="${2:-skipped}" | |
| case "${outcome}" in | |
| success) icon="✅" ;; | |
| skipped) icon="⏭️" ;; | |
| *) icon="❌" ; status=1 ;; | |
| esac | |
| echo "| ${1} | ${icon} ${outcome} |" >> "${GITHUB_STEP_SUMMARY}" | |
| } | |
| { | |
| echo "## Smoke test summary" | |
| echo | |
| echo "| Check | Result |" | |
| echo "| --- | --- |" | |
| } >> "${GITHUB_STEP_SUMMARY}" | |
| report "R versions matrix" "${{ steps.versions-matrix.outcome }}" | |
| report "Suggested dependencies matrix" "${{ steps.dep-suggests-matrix.outcome }}" | |
| report "Style" "${{ steps.style.outcome }}" | |
| report "Snapshots" "${{ steps.snapshots.outcome }}" | |
| report "Roxygenize" "${{ steps.roxygenize.outcome }}" | |
| report "Commit" "${{ steps.commit.outcome }}" | |
| report "R CMD check" "${{ steps.check.outcome }}" | |
| report "pkgdown build" "${{ steps.pkgdown-build.outcome }}" | |
| report "pkgdown deploy" "${{ steps.pkgdown-deploy.outcome }}" | |
| if [ "${status}" -ne 0 ]; then | |
| printf '\nAt least one check failed, see the log for details.\n' >> "${GITHUB_STEP_SUMMARY}" | |
| fi | |
| exit "${status}" | |
| shell: bash | |
| - name: Update status for rcc (final) | |
| if: always() && (github.actor != 'Copilot') && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) | |
| uses: ./.github/workflows/commit-status | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| state: ${{ job.status }} | |
| # The commit that the commit-back step created, if there was one | |
| sha: ${{ steps.commit.outputs.sha || inputs.ref }} | |
| - name: Update status for rcc (Copilot) | |
| # Update status directly when triggered by Copilot or bots, since they can't dispatch workflows | |
| if: always() && (github.actor == 'Copilot') | |
| uses: ./.github/workflows/commit-status | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| state: ${{ job.status }} | |
| sha: ${{ inputs.ref }} | |
| rcc-smoke-check-matrix: | |
| runs-on: ubuntu-26.04 | |
| name: "Check matrix" | |
| needs: | |
| - rcc-smoke | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ needs.rcc-smoke.outputs.sha }} | |
| - name: Show the R versions matrix | |
| uses: ./.github/workflows/matrix-check | |
| with: | |
| matrix: ${{ needs.rcc-smoke.outputs.versions-matrix }} | |
| - name: Show the suggested dependencies matrix | |
| uses: ./.github/workflows/matrix-check | |
| with: | |
| matrix: ${{ needs.rcc-smoke.outputs.dep-suggests-matrix }} | |
| rcc-full: | |
| needs: | |
| - rcc-smoke | |
| runs-on: ${{ matrix.os }} | |
| if: ${{ needs.rcc-smoke.outputs.versions-matrix != '' }} | |
| name: 'rcc: ${{ matrix.os }} (${{ matrix.r }}) ${{ matrix.desc }}' | |
| permissions: | |
| # Both required by the update-snapshots action, which opens a pull | |
| # request with refreshed snapshots. It is skipped for forks, where the | |
| # token is read-only anyway. | |
| contents: write | |
| pull-requests: write | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{fromJson(needs.rcc-smoke.outputs.versions-matrix)}} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ needs.rcc-smoke.outputs.sha }} | |
| - name: Apply environment variables from the test matrix | |
| # Generic: matrix entries defined in .github/versions-matrix.R can | |
| # carry an "env" field (one KEY=VALUE per line). | |
| # Write it to $GITHUB_ENV here, in the workflow, | |
| # because composite actions cannot read the matrix context. | |
| # The variables then reach every subsequent step, | |
| # including the custom before-install and after-install actions, | |
| # without requiring repos to implement any plumbing of their own. | |
| if: matrix.env != '' | |
| env: | |
| MATRIX_ENV: ${{ matrix.env }} | |
| run: | | |
| printf '%s\n' "$MATRIX_ENV" | tee -a "$GITHUB_ENV" | |
| shell: bash | |
| - name: Run the repository-specific before-install steps | |
| uses: ./.github/workflows/custom/before-install | |
| if: hashFiles('.github/workflows/custom/before-install/action.yml') != '' | |
| - name: Install R and the package dependencies | |
| uses: ./.github/workflows/install | |
| with: | |
| r-version: ${{ matrix.r }} | |
| cache-version: rcc-full-1 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| needs: build, check | |
| - name: Run the repository-specific after-install steps | |
| uses: ./.github/workflows/custom/after-install | |
| if: hashFiles('.github/workflows/custom/after-install/action.yml') != '' | |
| - name: Must allow NOTEs if packages are missing, even with _R_CHECK_FORCE_SUGGESTS_ | |
| run: | | |
| if (Sys.getenv("RCMDCHECK_ERROR_ON") %in% c("", "note")) { | |
| pkgs <- setdiff(desc::desc_get_deps()$package, "R") | |
| installable <- vapply(pkgs, FUN.VALUE = logical(1), requireNamespace, quietly = TRUE) | |
| if (any(!installable)) { | |
| message("Missing packages: ", paste(pkgs[!installable], collapse = ", ")) | |
| cat('RCMDCHECK_ERROR_ON="warning"\n', file = Sys.getenv("GITHUB_ENV"), append = TRUE) | |
| } | |
| } | |
| shell: Rscript {0} | |
| - name: Update the testthat snapshots | |
| uses: ./.github/workflows/update-snapshots | |
| # Generic escape hatch: a custom action may set SKIP_UPDATE_SNAPSHOTS | |
| # to opt out of running the snapshot updater, | |
| # which runs tests directly via testthat::test_local() | |
| # and is difficult to disable otherwise. | |
| if: (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && env.SKIP_UPDATE_SNAPSHOTS != 'true' | |
| with: | |
| base: ${{ github.head_ref }} | |
| - name: Run R CMD check | |
| uses: ./.github/workflows/check | |
| if: ${{ ! matrix.covr }} | |
| with: | |
| # Include the architecture: the matrix pairs each arm64 runner with an | |
| # amd64 one on the same OS and the same R version (ubuntu-26.04-arm / | |
| # ubuntu-26.04, windows-11-arm / windows-latest), so `runner.os` alone | |
| # yields duplicate artifact names, which upload-artifact rejects. | |
| results: ${{ runner.os }}-${{ runner.arch }}-r${{ matrix.r }} | |
| - name: Compute and upload the test coverage | |
| uses: ./.github/workflows/covr | |
| if: ${{ matrix.covr }} | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| # The status update is taken care of by R-CMD-check-status.yaml | |
| rcc-suggests: | |
| needs: | |
| - rcc-smoke | |
| runs-on: ubuntu-26.04 | |
| if: ${{ needs.rcc-smoke.outputs.dep-suggests-matrix != '' && (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.run-rcc-suggests)) }} | |
| name: Without ${{ matrix.package }} | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{fromJson(needs.rcc-smoke.outputs.dep-suggests-matrix)}} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Run the repository-specific before-install steps | |
| uses: ./.github/workflows/custom/before-install | |
| if: hashFiles('.github/workflows/custom/before-install/action.yml') != '' | |
| - name: Install R and the package dependencies | |
| uses: ./.github/workflows/install | |
| with: | |
| cache-version: rcc-dev-${{ matrix.package }}-1 | |
| needs: build, check | |
| extra-packages: "any::rcmdcheck any::remotes ." | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Remove ${{ matrix.package }} and all strong dependencies | |
| run: | | |
| pkg <- "${{ matrix.package }}" | |
| pkgs <- tools::package_dependencies(pkg, reverse = TRUE)[[1]] | |
| installed <- rownames(utils::installed.packages()) | |
| to_remove <- c(pkg, intersect(pkgs, installed)) | |
| print(to_remove) | |
| remove.packages(to_remove) | |
| shell: Rscript {0} | |
| - name: Session info | |
| run: | | |
| options(width = 100) | |
| if (!requireNamespace("sessioninfo", quietly = TRUE)) install.packages("sessioninfo") | |
| pkgs <- installed.packages()[, "Package"] | |
| sessioninfo::session_info(pkgs, include_base = TRUE) | |
| shell: Rscript {0} | |
| - name: Run the repository-specific after-install steps | |
| uses: ./.github/workflows/custom/after-install | |
| if: hashFiles('.github/workflows/custom/after-install/action.yml') != '' | |
| - name: Must allow NOTEs, even with _R_CHECK_FORCE_SUGGESTS_ | |
| run: | | |
| if (Sys.getenv("RCMDCHECK_ERROR_ON") %in% c("", "note")) { | |
| cat('RCMDCHECK_ERROR_ON="warning"\n', file = Sys.getenv("GITHUB_ENV"), append = TRUE) | |
| } | |
| shell: Rscript {0} | |
| - name: Check env vars | |
| run: | | |
| print(Sys.getenv('_R_CHECK_FORCE_SUGGESTS_')) | |
| print(Sys.getenv('RCMDCHECK_ERROR_ON')) | |
| shell: Rscript {0} | |
| - name: Run R CMD check | |
| uses: ./.github/workflows/check | |
| with: | |
| results: ${{ matrix.package }} | |
| # The status update is taken care of by R-CMD-check-status.yaml |