From 4ef75657d3246d4b9580bcf03ae4a5099e6d56cf Mon Sep 17 00:00:00 2001 From: zkamvar <3639446+zkamvar@users.noreply.github.com> Date: Tue, 1 Sep 2026 00:45:10 +0000 Subject: [PATCH] [actions] update sandpaper workflow to version v1.0.2 --- .github/workflows/README.md | 108 ++++++--- .github/workflows/docker_apply_cache.yaml | 224 ++++++++----------- .github/workflows/docker_build_deploy.yaml | 25 +-- .github/workflows/docker_pr_receive.yaml | 72 +----- .github/workflows/pr-comment.yaml | 16 +- .github/workflows/pr-post-remove-branch.yaml | 4 +- .github/workflows/pr-preflight.yaml | 4 +- .github/workflows/update-cache.yaml | 8 +- .github/workflows/update-workflows.yaml | 7 +- .github/workflows/workflows-version.txt | 2 +- 10 files changed, 202 insertions(+), 268 deletions(-) diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 59a48610..4516bb10 100755 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -1,4 +1,7 @@ -# Workflow Documentation +# Workbench Workflows Documentation + +These GitHub Actions workflows manage and maintain the build processes for lessons using the Carpentries Workbench on GitHub. + ## Managing Workflow Updates @@ -9,7 +12,11 @@ You can do this locally using your own R and Workbench installation, or via the ### Updating locally -In a terminal/git bash, navigate to the lesson folder where you want to update the workflows. +In a terminal/git bash, navigate to the lesson folder where you want to update the workflows, e.g.: + +```bash +cd ~/lessons/shell-novice +``` Then, start an R session and: @@ -39,7 +46,22 @@ $ git push origin main > - Cancel any "01 Maintain: Build and Deploy Site" workflow currently running > - Run the "02 Maintain: Check for Updated Packages" workflow and merge any PR opened to update the renv lockfile > - This should automatically run the "03 Maintain: Apply Package Cache" workflow to install packages and build the cache -> - A successful cache buid should then trigger the "01 Maintain: Build and Deploy Site" workflow +> - A successful cache build should then trigger the "01 Maintain: Build and Deploy Site" workflow + +#### Updating to a specific workflow release or branch + +To test new Workbench workflow features or branches, or to pin to a specific release, the `branch` option can be supplied to `update_github_workflows()`. + +For a given branch: + +```r +sandpaper::update_github_workflows(branch="develop") +``` + +Or for a given release version: +```r +sandpaper::update_github_workflows(branch="1.0.1") +``` ### Updating using GitHub @@ -71,40 +93,49 @@ This will raise a PR with any changes to the workflows that are needed. If you are happy with the changes made, you can merge the PR into your lesson repository. -## Package Caches for RMarkdown Lessons +## Dependency Images for RMarkdown Lessons + +Lessons that use R packages and RMarkdown are built on GitHub using Docker images within these workflows. +These images are based on the [workbench-docker](https://github.com/carpentries/workbench-docker) image. +This base image only contains the Workbench packages to build lessons and not any extra R packages your lesson might need. -In summary, generating a reusable package cache is achieved by running the "02 Maintain: Check for Updated Packages" workflow, and then the "03 Maintain: Apply Package Cache" workflow. +Therefore, there are two steps to perform to resolve the required R packages in a lesson, and then generate a Docker image layer comprising those packages. + +The "02 Maintain: Check for Updated Packages" workflow checks for any used R packages and their versions, and if successful, opens a Pull Request to update your lesson's renv lockfile (`renv.lock`). +Once the PR is merged, the "03 Maintain: Apply Package Cache" workflow builds the dependency image layer with `docker build` and publishes it in your user or organisation account Packages area. > [!NOTE] > Caching is only relevant for lessons that use Rmd files and renv to manage R packages. > If you are building basic markdown documents, caching will not apply to you, and the only > workflow that needs to be run is "01 Maintain: Build and Deploy Site". -### Caching +### Publishing dependency images -The two cache management workflows are separated to ensure that once you have a successful build with a working renv cache, this cache is stored and will be reused by the Workbench Docker container. -This means that lesson builds will be faster once an renv cache is created and reused by the Docker container. +The two dependency workflows are separated to ensure that once you have a successful build with a working renv environment, the resulting dependency image is stored and will be reused by the Workbench Docker container. +This means that lesson builds will be faster and more consistent once a dependency image is created and reused. This is doubly important if you need very specific versions of R packages, i.e. "pinning". -Another major bonus of this setup is that you can keep using this cache indefinitely to build your lesson. -This is important if you need very specific versions of R packages ("pinning"). +This setup means that this dependency image layer is available indefinitely: +- to build your lesson, improving robustness and reproducibility +- for others to use as a complete environment in their local builds, teaching environments, or Codespaces -If and when you want to perform an update to the cache, you can re-run the "02 Maintain: Check for Updated Packages" and verify that your lesson still builds with the new packages. -If all looks good, re-run the "03 Maintain: Apply Package Cache" workflow, and this will write a new renv cache file to GitHub. +If and when you want to perform an update to the dependency image, you can re-run the "02 Maintain: Check for Updated Packages" workflow and verify that your lesson still builds with any new packages or changes. +The "03 Maintain: Apply Package Cache" workflow will publish a new repository- or organisation-local GHCR image for the lesson. -In any case, the renv cache is invalidated by new versions of the `renv.lock` file. +As such, the dependency image is invalidated by new versions of the `renv.lock` file. This happens: - - if you update your lockfile locally by using the `sandpaper::update_cache()` function, and then push it to the lesson repository + - if you update your lockfile locally by using the `sandpaper::update_cache()` and `sandpaper::manage_deps()` functions, and then push it to the lesson repository - when you run the "02 Maintain: Check for Updated Packages" and there are new packages to install -More information on managing local renv caches for lessons can be found in the [Sandpaper packages vignettes](https://carpentries.github.io/sandpaper/articles/building-with-renv.html). +More information on managing local renv-based lesson dependencies can be found in the [Sandpaper packages vignettes](https://carpentries.github.io/sandpaper/articles/building-with-renv.html). -#### Using different package cache versions +#### Using different dependency image versions -There are times when you may want to go back to a previous renv package cache file: +There are times when you may want to go back to a previous dependency image: - if you run "02 Maintain: Check for Updated Packages" and "03 Maintain: Apply Package Cache" and the cache generation fails for some reason - if there is a new R package that produces incorrect or broken lesson output + - a new R version is released and downstream packages fail to build and install, and need updating by the package maintainer(s) -Cache files will have the following name format, where IMAGE is the workbench-docker image version, and HASHSUM is the `renv.lock` lockfile MD5 hash: +Dependency images will have the following name format, where IMAGE is the workbench-docker image version, and HASHSUM is the `renv.lock` lockfile hash: ``` IMAGE HASHSUM @@ -112,22 +143,40 @@ IMAGE HASHSUM v0.2.4_renv-2e499eb706112971b2cffceb49b55a6efe49f3ed75cd6579b10ff224489daca4 ``` -Copy the hashsum part of the desired cache file you want to use, e.g. `2e499eb706112971b2cffceb49b55a6efe49f3ed75cd6579b10ff224489daca4`. +Copy the hashsum part of the desired image tag you want to use, e.g. `2e499eb706112971b2cffceb49b55a6efe49f3ed75cd6579b10ff224489daca4`. Then either: 1. Add a repository variable called CACHE_VERSION, and paste in the hash - - Go to ... - 2. Run the "01 Maintain: Build and Deploy Site" manually, supplying the CACHE_VERSION input - - Go to ... + 2. Run the "01 Maintain: Build and Deploy Site" manually, supplying the `Optional renv cache version override` input -If you have no caches listed, make sure to run the "02 Maintain: Check for Updated Packages" and "03 Maintain: Apply Package Cache" to create a new renv cache file. +If you have no images listed, make sure to run the "02 Maintain: Check for Updated Packages" and "03 Maintain: Apply Package Cache" workflows to publish a new dependency image. > [!NOTE] -> If you are maintaining an official lesson, caches are saved in an AWS S3 bucket owned by the Carpentries. -> Once a successful cache has been saved, these will be listed in the outputs of the "01 Maintain: Build and Deploy Site" workflow. +> If you are maintaining an official lesson, dependency images are saved to the Carpentries lesson program organisation, e.g. `datacarpentry`, GHCR package namespace. +> Once a successful dependency image has been published, the build workflows will use it automatically when the matching Docker version tag exists, e.g. 'latest' or a specific version. > -> If you are developing a lesson in your own repository, caches are saved on GitHub. -> You can see available caches by going to the Actions tab, and clicking Caches on the left hand side. +> If you are developing a lesson in your own repository, the dependency images are stored in your repository's GHCR package namespace. +> You can see available images by going to your user or organisation's Packages tab, e.g. `https://github.com/?tab=packages`. + +#### Pruning dependency image layers + +Through the lifetime of a lesson, an increasing number of dependency images will be generated. +As the images are public, GitHub currently charges no storage, or network ingress or egress fees to upload or download them. + +The "03 Maintain: Apply Package Cache" workflow will automatically check the number of published dependency images and keep each version published plus one underlying untagged digest (if any) for each version. +This means it is possible to roll back easily to a previous version or digest, but not end up with a huge number of dependency images to manage. + +In any case, you can manually delete any versions you wish by: +- going to your user or organisation's Packages tab, e.g. `https://github.com/?tab=packages`. +- selecting the dependency image you want to manage, e.g. `-deps` +- selecting `Package settings` on the right hand side +- deleting any images + +> [!NOTE] +> Deleting these images manually may break your builds. +> Only perform this action if you are sure you want to delete the generated dependency images. +> +> If you mistakenly delete an image, you can rebuild it by rerunning the "03 Maintain: Apply Package Cache" workflow. ## User Settings @@ -186,7 +235,6 @@ Repository-level variables for this workflow are: - This can be set to a specific version number to force all builds to use a given container version - Default is unset or `latest` - ### 04 Maintain: Update Workflow Files (update-workflows.yaml) There are no repository variables for this workflow. @@ -194,7 +242,7 @@ There are no repository variables for this workflow. ## Pull Request and Review Management -Because our lessons execute code, pull requests are a security risk for any lesson and thus have security measures associted with them. +Because our lessons execute code, pull requests are a security risk for any lesson and thus have security measures associated with them. **Do not merge any pull requests that do not pass checks and do not have bots commented on them.** This series of workflows all go together and are described in the following diagram and the below sections: @@ -256,5 +304,5 @@ This emits an artifact that is the pull request number for the next action. ### Remove Pull Request Branch (pr-post-remove-branch.yaml) -Tiggered by `pr-close-signal.yaml`. +Triggered by `pr-close-signal.yaml`. This removes the temporary branch associated with the pull request (if it was created). diff --git a/.github/workflows/docker_apply_cache.yaml b/.github/workflows/docker_apply_cache.yaml index 0f3a1abb..dcebb3b3 100644 --- a/.github/workflows/docker_apply_cache.yaml +++ b/.github/workflows/docker_apply_cache.yaml @@ -1,5 +1,5 @@ name: "03 Maintain: Apply Package Cache" -description: "Generate the package cache for the lesson after a pull request has been merged or via manual trigger, and cache in S3 or GitHub" +description: "Build and publish the lesson dependency image after a pull request has been merged or via manual trigger" on: workflow_dispatch: inputs: @@ -7,6 +7,16 @@ on: description: 'Who triggered this build?' required: true default: 'Maintainer (via GitHub)' + force-dependency-image-rebuild: + description: 'Rebuild the dependency image layer even if one already exists?' + required: false + default: false + type: boolean + prune-keep-count: + description: 'How many existing dependency image layers to keep?' + required: false + default: 1 + type: number pull_request: types: - closed @@ -42,171 +52,120 @@ jobs: runs-on: ubuntu-latest needs: preflight if: needs.preflight.outputs.do-apply == 'true' - permissions: - id-token: write outputs: renv-needed: ${{ steps.check-for-renv.outputs.renv-needed }} renv-cache-hashsum: ${{ steps.check-for-renv.outputs.renv-cache-hashsum }} - renv-cache-available: ${{ steps.check-for-renv.outputs.renv-cache-available }} steps: - name: "Check for renv" id: check-for-renv - uses: carpentries/actions/renv-checks@main + uses: carpentries/actions/renv-checks@v1 with: - role-to-assume: ${{ secrets.AWS_GH_OIDC_ARN }} - aws-region: ${{ secrets.AWS_GH_OIDC_REGION }} WORKBENCH_TAG: ${{ vars.WORKBENCH_TAG || 'latest' }} - token: ${{ secrets.GITHUB_TOKEN }} + skip-cache-check: true no-renv-cache-used: - name: "No renv cache used" + name: "No renv package dependency image needed" runs-on: ubuntu-latest needs: check-renv if: needs.check-renv.outputs.renv-needed != 'true' steps: - - name: "No renv cache needed" - run: echo "No renv cache needed for this lesson" - - renv-cache-available: - name: "renv cache available" - runs-on: ubuntu-latest - needs: check-renv - if: needs.check-renv.outputs.renv-cache-available == 'true' - steps: - - name: "renv cache available" - run: echo "renv cache available for this lesson" + - name: "No dependency image needed" + run: echo "No renv dependency image needed for this lesson" update-renv-cache: - name: "Update renv Cache" + name: "Publish renv package dependency image" runs-on: ubuntu-latest needs: check-renv - if: | - needs.check-renv.outputs.renv-needed == 'true' && - needs.check-renv.outputs.renv-cache-available != 'true' && - ( - github.event_name == 'workflow_dispatch' || - ( - github.event.pull_request.merged == true && - ( - ( - contains( - join(github.event.pull_request.labels.*.name, ','), - 'type: package cache' - ) && - github.event.pull_request.head.ref == 'update/packages' - ) - || - ( - contains( - join(github.event.pull_request.labels.*.name, ','), - 'type: workflows' - ) && - github.event.pull_request.head.ref == 'update/workflows' - ) - || - ( - contains( - join(github.event.pull_request.labels.*.name, ','), - 'type: docker version' - ) && - github.event.pull_request.head.ref == 'update/workbench-docker-version' - ) - ) - ) - ) + if: needs.check-renv.outputs.renv-needed == 'true' permissions: - checks: write - contents: write - pages: write - id-token: write - container: - image: ghcr.io/carpentries/workbench-docker:${{ vars.WORKBENCH_TAG || 'latest' }} - env: - WORKBENCH_PROFILE: "ci" - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - RENV_PATHS_ROOT: /home/rstudio/lesson/renv - RENV_PROFILE: "lesson-requirements" - RENV_VERSION: ${{ needs.check-renv.outputs.renv-cache-hashsum }} - RENV_CONFIG_EXTERNAL_LIBRARIES: "/usr/local/lib/R/site-library" - volumes: - - ${{ github.workspace }}:/home/rstudio/lesson - options: --cpus 2 + contents: read + packages: write steps: - uses: actions/checkout@v6 - - name: "Debugging Info" - run: | - echo "Current Directory: $(pwd)" - ls -lah /home/rstudio/.workbench - ls -lah $(pwd) - Rscript -e 'sessionInfo()' - shell: bash - - - name: "Mark Repository as Safe" - run: | - git config --global --add safe.directory $(pwd) - shell: bash - - - name: "Ensure sandpaper is loadable" - run: | - .libPaths() - library(sandpaper) - shell: Rscript {0} - - - name: "Setup Lesson Dependencies" - run: | - Rscript /home/rstudio/.workbench/setup_lesson_deps.R - shell: bash - - - name: "Fortify renv Cache" - run: | - Rscript /home/rstudio/.workbench/fortify_renv_cache.R - shell: bash - - name: "Get Container Version Used" id: wb-vers - uses: carpentries/actions/container-version@main + uses: carpentries/actions/container-version@v1 with: WORKBENCH_TAG: ${{ vars.WORKBENCH_TAG }} renv-needed: ${{ needs.check-renv.outputs.renv-needed }} token: ${{ secrets.GITHUB_TOKEN }} - - name: "Validate Current Org and Workflow" - id: validate-org-workflow - uses: carpentries/actions/validate-org-workflow@main + - name: Log in to GHCR + uses: docker/login-action@v4 with: - repo: ${{ github.repository }} - workflow: ${{ github.workflow }} + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set dependency image tags + id: image + env: + IMAGE_OWNER: ${{ github.repository_owner }} + IMAGE_NAME: ${{ github.event.repository.name }} + WB_VERSION: ${{ steps.wb-vers.outputs.container-version }} + RENV_HASH: ${{ needs.check-renv.outputs.renv-cache-hashsum }} + run: | + set -euo pipefail + exact_image="ghcr.io/${IMAGE_OWNER}/${IMAGE_NAME}-deps:${WB_VERSION}_renv-${RENV_HASH}" + latest_image="ghcr.io/${IMAGE_OWNER}/${IMAGE_NAME}-deps:latest" - - name: "Configure AWS credentials via OIDC" - id: aws-creds + # lowercaseify + echo "exact_image=${exact_image,,}" >> "$GITHUB_OUTPUT" + echo "latest_image=${latest_image,,}" >> "$GITHUB_OUTPUT" + shell: bash + + - name: Check for existing dependency image tag + id: image-exists env: - role-to-assume: ${{ secrets.AWS_GH_OIDC_ARN }} - aws-region: ${{ secrets.AWS_GH_OIDC_REGION }} + EXACT_IMAGE: ${{ steps.image.outputs.exact_image }} + run: | + set -euo pipefail + if docker manifest inspect "${EXACT_IMAGE}" >/dev/null 2>&1; then + echo "exists=true" >> "$GITHUB_OUTPUT" + echo "## ⚠️ Dependency image already exists" >> $GITHUB_STEP_SUMMARY + echo "Dependency image already exists for this renv hash: ${EXACT_IMAGE}" >> $GITHUB_STEP_SUMMARY + echo "Dependency image already exists for this renv hash: ${EXACT_IMAGE}" + else + echo "exists=false" >> "$GITHUB_OUTPUT" + echo "No existing dependency image found for this renv hash: ${EXACT_IMAGE}" + fi + shell: bash + + - name: Build and push dependency image layer + id: build-push-deps-layer if: | - steps.validate-org-workflow.outputs.is_valid == 'true' && - env.role-to-assume != '' && - env.aws-region != '' - uses: aws-actions/configure-aws-credentials@v6 + steps.image-exists.outputs.exists != 'true' || + ( + github.event_name == 'workflow_dispatch' && + github.event.inputs.force-dependency-image-rebuild == 'true' + ) + uses: carpentries/actions/build-dependency-image@v1 with: - role-to-assume: ${{ env.role-to-assume }} - aws-region: ${{ env.aws-region }} - output-credentials: true - - - name: "Upload cache object to S3" - id: upload-cache - uses: tespkg/actions-cache@v1.10.0 + workbench-tag: ${{ vars.WORKBENCH_TAG || 'latest' }} + github-token: ${{ secrets.GITHUB_TOKEN }} + github-repository: ${{ github.repository }} + github-sha: ${{ github.sha }} + exact-image: ${{ steps.image.outputs.exact_image }} + latest-image: ${{ steps.image.outputs.latest_image }} + build-context: ${{ github.workspace }} + + prune-dependency-images: + name: "Prune Dependency Images" + runs-on: ubuntu-latest + needs: check-renv + steps: + - name: Prune any old dependency image layers + uses: carpentries/actions/prune-dependency-images@v1 + if: needs.check-renv.outputs.renv-needed == 'true' with: - accessKey: ${{ steps.aws-creds.outputs.aws-access-key-id }} - secretKey: ${{ steps.aws-creds.outputs.aws-secret-access-key }} - sessionToken: ${{ steps.aws-creds.outputs.aws-session-token }} - bucket: workbench-docker-caches - path: | - /home/rstudio/lesson/renv - /usr/local/lib/R/site-library - key: ${{ github.repository }}/${{ steps.wb-vers.outputs.container-version }}_renv-${{ needs.check-renv.outputs.renv-cache-hashsum }} - restore-keys: - ${{ github.repository }}/${{ steps.wb-vers.outputs.container-version }}_renv- + github-token: ${{ secrets.GITHUB_TOKEN }} + owner: ${{ github.repository_owner }} + owner-type: ${{ github.event.repository.owner.type }} + repository: ${{ github.event.repository.name }} + package-name: ${{ github.event.repository.name }}-deps + keep-count: ${{ github.event.inputs.prune-keep-count }} + continue-on-error: true record-cache-result: name: "Record Caching Status" @@ -217,9 +176,8 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: "Record cache result" - run: | - echo "${{ needs.update-renv-cache.result == 'success' || needs.check-renv.outputs.renv-cache-available == 'true' || 'false' }}" > ${{ github.workspace }}/apply-cache-result + echo "${{ needs.check-renv.outputs.renv-needed != 'true' || needs.update-renv-cache.result == 'success' }}" > ${{ github.workspace }}/apply-cache-result shell: bash - name: "Upload cache result" diff --git a/.github/workflows/docker_build_deploy.yaml b/.github/workflows/docker_build_deploy.yaml index 4baf306f..bb0d0fd6 100644 --- a/.github/workflows/docker_build_deploy.yaml +++ b/.github/workflows/docker_build_deploy.yaml @@ -48,6 +48,7 @@ jobs: do-build: ${{ steps.build-check.outputs.do-build }} renv-needed: ${{ steps.build-check.outputs.renv-needed }} renv-cache-hashsum: ${{ steps.build-check.outputs.renv-cache-hashsum }} + dependency-image-ref: ${{ steps.build-check.outputs.dependency-image-ref }} workbench-container-file-exists: ${{ steps.wb-vers.outputs.workbench-container-file-exists }} wb-vers: ${{ steps.wb-vers.outputs.container-version }} last-wb-vers: ${{ steps.wb-vers.outputs.last-container-version }} @@ -57,7 +58,7 @@ jobs: steps: - name: "Should we run build and deploy?" id: build-check - uses: carpentries/actions/build-preflight@main + uses: carpentries/actions/build-preflight@v1 - name: "Checkout Lesson" if: steps.build-check.outputs.do-build == 'true' @@ -66,7 +67,7 @@ jobs: - name: "Get container version info" id: wb-vers if: steps.build-check.outputs.do-build == 'true' - uses: carpentries/actions/container-version@main + uses: carpentries/actions/container-version@v1 with: WORKBENCH_TAG: ${{ vars.WORKBENCH_TAG }} renv-needed: ${{ steps.build-check.outputs.renv-needed }} @@ -86,9 +87,8 @@ jobs: checks: write contents: write pages: write - id-token: write container: - image: ghcr.io/carpentries/workbench-docker:${{ vars.WORKBENCH_TAG || 'latest' }} + image: ${{ needs.preflight.outputs.dependency-image-ref }} env: WORKBENCH_PROFILE: "ci" GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} @@ -116,23 +116,12 @@ jobs: git config --global --add safe.directory $(pwd) shell: bash - - name: "Setup Lesson Dependencies" - id: build-container-deps - uses: carpentries/actions/build-container-deps@main - with: - CACHE_VERSION: ${{ vars.CACHE_VERSION || github.event.inputs.CACHE_VERSION || '' }} - WORKBENCH_TAG: ${{ vars.WORKBENCH_TAG || 'latest' }} - LESSON_PATH: ${{ vars.LESSON_PATH || '/home/rstudio/lesson' }} - role-to-assume: ${{ secrets.AWS_GH_OIDC_ARN }} - aws-region: ${{ secrets.AWS_GH_OIDC_REGION }} - token: ${{ secrets.GITHUB_TOKEN }} - - name: "Run Container and Build Site" id: build-and-deploy - uses: carpentries/actions/build-and-deploy@main + uses: carpentries/actions/build-and-deploy@v1 with: reset: ${{ vars.BUILD_RESET || github.event.inputs.reset || 'false' }} - skip-manage-deps: ${{ github.event.inputs.force-skip-manage-deps == 'true' || steps.build-container-deps.outputs.renv-cache-available || steps.build-container-deps.outputs.backup-cache-used || 'false' }} + skip-manage-deps: ${{ github.event.inputs.force-skip-manage-deps == 'true' || contains(needs.preflight.outputs.dependency-image-ref, '-deps:') }} lang-code: ${{ vars.LANG_CODE || '' }} update-container-version: @@ -152,7 +141,7 @@ jobs: ) steps: - name: "Record container version used" - uses: carpentries/actions/record-container-version@main + uses: carpentries/actions/record-container-version@v1 with: CONTAINER_VER: ${{ needs.preflight.outputs.wb-vers }} AUTO_MERGE: ${{ vars.AUTO_MERGE_CONTAINER_VERSION_UPDATE || 'true' }} diff --git a/.github/workflows/docker_pr_receive.yaml b/.github/workflows/docker_pr_receive.yaml index 486b4b4f..9ed11c95 100644 --- a/.github/workflows/docker_pr_receive.yaml +++ b/.github/workflows/docker_pr_receive.yaml @@ -96,7 +96,7 @@ jobs: - name: "Check PR" id: check-pr - uses: carpentries/actions/check-valid-pr@main + uses: carpentries/actions/check-valid-pr@v1 with: pr: ${{ env.NR }} invalid: ${{ fromJSON(steps.hash.outputs.json)[github.repository] }} @@ -107,13 +107,14 @@ jobs: outputs: renv-needed: ${{ steps.renv-check.outputs.renv-needed }} renv-cache-hashsum: ${{ steps.renv-check.outputs.renv-cache-hashsum }} + dependency-image-ref: ${{ steps.renv-check.outputs.dependency-image-ref }} steps: - name: "Checkout Lesson" uses: actions/checkout@v6 - name: "Is renv required?" id: renv-check - uses: carpentries/actions/renv-checks@main + uses: carpentries/actions/renv-checks@v1 with: CACHE_VERSION: ${{ inputs.CACHE_VERSION || '' }} skip-cache-check: true @@ -131,14 +132,10 @@ jobs: GHWMD: ${{ github.workspace }}/site/built PR_BRANCH: ${{ needs.test-pr.outputs.pr_branch }} PR_NUMBER: ${{ needs.test-pr.outputs.pr_number }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} permissions: - checks: write - contents: write - pages: write - id-token: write + contents: read container: - image: ghcr.io/carpentries/workbench-docker:${{ vars.WORKBENCH_TAG || 'latest' }} + image: ${{ needs.check-renv.outputs.dependency-image-ref }} env: WORKBENCH_PROFILE: "ci" GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} @@ -150,7 +147,6 @@ jobs: - ${{ github.workspace }}:/home/rstudio/lesson options: --cpus 2 outputs: - workbench-update: ${{ steps.wb-vers.outputs.workbench-update }} build-site: ${{ steps.build-site.outcome }} steps: - uses: actions/checkout@v6 @@ -178,64 +174,6 @@ jobs: Rscript /home/rstudio/.workbench/setup_lesson_deps.R shell: bash - - name: Get Container Version Used - id: wb-vers - if: needs.check-renv.outputs.renv-needed == 'true' - uses: carpentries/actions/container-version@main - with: - WORKBENCH_TAG: ${{ vars.WORKBENCH_TAG }} - renv-needed: ${{ needs.check-renv.outputs.renv-needed }} - token: ${{ secrets.GITHUB_TOKEN }} - - - name: "Validate Current Org and Workflow" - id: validate-org-workflow - if: needs.check-renv.outputs.renv-needed == 'true' - uses: carpentries/actions/validate-org-workflow@main - with: - repo: ${{ github.repository }} - workflow: ${{ github.workflow }} - - - name: Configure AWS credentials via OIDC - id: aws-creds - env: - role-to-assume: ${{ secrets.AWS_GH_OIDC_ARN }} - aws-region: ${{ secrets.AWS_GH_OIDC_REGION }} - if: | - steps.validate-org-workflow.outputs.is_valid == 'true' && - needs.check-renv.outputs.renv-needed == 'true' && - env.role-to-assume != '' && - env.aws-region != '' - uses: aws-actions/configure-aws-credentials@v6 - with: - role-to-assume: ${{ env.role-to-assume }} - aws-region: ${{ env.aws-region }} - output-credentials: true - - - name: Get cache object from S3 - id: s3-cache - uses: tespkg/actions-cache/restore@v1.10.0 - if: needs.check-renv.outputs.renv-needed == 'true' - with: - # insecure: false # optional, use http instead of https. default false - accessKey: ${{ steps.aws-creds.outputs.aws-access-key-id }} - secretKey: ${{ steps.aws-creds.outputs.aws-secret-access-key }} - sessionToken: ${{ steps.aws-creds.outputs.aws-session-token }} - bucket: workbench-docker-caches - path: | - /home/rstudio/lesson/renv - /usr/local/lib/R/site-library - key: ${{ github.repository }}/${{ steps.wb-vers.outputs.container-version }}_renv-${{ needs.check-renv.outputs.renv-cache-hashsum }} - restore-keys: - ${{ github.repository }}/${{ steps.wb-vers.outputs.container-version }}_renv- - - - name: "Fortify renv Cache" - if: | - needs.check-renv.outputs.renv-needed == 'true' && - steps.s3-cache.outputs.cache-hit != 'true' - run: | - Rscript /home/rstudio/.workbench/fortify_renv_cache.R - shell: bash - - name: "Validate and Build Markdown" id: build-site run: | diff --git a/.github/workflows/pr-comment.yaml b/.github/workflows/pr-comment.yaml index 9ec78c6c..c2928514 100644 --- a/.github/workflows/pr-comment.yaml +++ b/.github/workflows/pr-comment.yaml @@ -22,7 +22,7 @@ jobs: steps: - name: "Download PR artifact" id: dl - uses: carpentries/actions/download-workflow-artifact@main + uses: carpentries/actions/download-workflow-artifact@v1 with: run: ${{ github.event.workflow_run.id }} name: 'pr' @@ -81,7 +81,7 @@ jobs: - name: "Check PR" id: check-pr if: ${{ steps.dl.outputs.success == 'true' }} - uses: carpentries/actions/check-valid-pr@main + uses: carpentries/actions/check-valid-pr@v1 with: pr: ${{ steps.get-pr.outputs.NUM }} sha: ${{ github.event.workflow_run.head_sha }} @@ -92,7 +92,7 @@ jobs: - name: "Comment result of validation" id: comment-diff if: always() - uses: carpentries/actions/comment-diff@main + uses: carpentries/actions/comment-diff@v1 with: pr: ${{ steps.get-pr.outputs.NUM }} body: ${{ steps.check-pr.outputs.MSG }} @@ -120,7 +120,7 @@ jobs: - name: "Download built markdown" id: dl - uses: carpentries/actions/download-workflow-artifact@main + uses: carpentries/actions/download-workflow-artifact@v1 with: run: ${{ github.event.workflow_run.id }} name: 'built' @@ -159,7 +159,7 @@ jobs: steps: - name: "Download comment artifact" id: dl - uses: carpentries/actions/download-workflow-artifact@main + uses: carpentries/actions/download-workflow-artifact@v1 with: run: ${{ github.event.workflow_run.id }} name: 'diff' @@ -170,7 +170,7 @@ jobs: - name: "Comment on PR" id: comment-diff if: steps.dl.outputs.success == 'true' - uses: carpentries/actions/comment-diff@main + uses: carpentries/actions/comment-diff@v1 with: pr: ${{ env.NR }} path: ${{ github.workspace }}/diff.md @@ -192,7 +192,7 @@ jobs: steps: - name: "Check for spoofing" id: dl - uses: carpentries/actions/download-workflow-artifact@main + uses: carpentries/actions/download-workflow-artifact@v1 with: run: ${{ github.event.workflow_run.id }} name: 'built' @@ -210,7 +210,7 @@ jobs: - name: "Comment on PR" id: comment-diff - uses: carpentries/actions/comment-diff@main + uses: carpentries/actions/comment-diff@v1 with: pr: ${{ env.NR }} body: ${{ env.body }} diff --git a/.github/workflows/pr-post-remove-branch.yaml b/.github/workflows/pr-post-remove-branch.yaml index 9419e2be..ebbe22df 100644 --- a/.github/workflows/pr-post-remove-branch.yaml +++ b/.github/workflows/pr-post-remove-branch.yaml @@ -17,7 +17,7 @@ jobs: contents: write steps: - name: 'Download artifact' - uses: carpentries/actions/download-workflow-artifact@main + uses: carpentries/actions/download-workflow-artifact@v1 with: run: ${{ github.event.workflow_run.id }} name: pr @@ -27,6 +27,6 @@ jobs: unzip pr.zip echo "NUM=$(<./NUM)" >> $GITHUB_OUTPUT - name: 'Remove branch' - uses: carpentries/actions/remove-branch@main + uses: carpentries/actions/remove-branch@v1 with: pr: ${{ steps.get-pr.outputs.NUM }} diff --git a/.github/workflows/pr-preflight.yaml b/.github/workflows/pr-preflight.yaml index d0d7420d..d292d91f 100644 --- a/.github/workflows/pr-preflight.yaml +++ b/.github/workflows/pr-preflight.yaml @@ -25,7 +25,7 @@ jobs: EOF" >> $GITHUB_OUTPUT - name: "Check PR" id: check-pr - uses: carpentries/actions/check-valid-pr@main + uses: carpentries/actions/check-valid-pr@v1 with: pr: ${{ github.event.number }} invalid: ${{ fromJSON(steps.hash.outputs.json)[github.repository] }} @@ -33,7 +33,7 @@ jobs: - name: "Comment result of validation" id: comment-diff if: ${{ always() }} - uses: carpentries/actions/comment-diff@main + uses: carpentries/actions/comment-diff@v1 with: pr: ${{ github.event.number }} body: ${{ steps.check-pr.outputs.MSG }} diff --git a/.github/workflows/update-cache.yaml b/.github/workflows/update-cache.yaml index d182ac7a..b711f2d8 100644 --- a/.github/workflows/update-cache.yaml +++ b/.github/workflows/update-cache.yaml @@ -2,7 +2,7 @@ name: "02 Maintain: Check for Updated Packages" description: "Check for updated R packages and create a pull request to update the lesson's renv lockfile and package cache" on: schedule: - - cron: '0 0 * * 2' + - cron: '0 0 * * 2' # every Tuesday at midnight UTC workflow_dispatch: inputs: name: @@ -67,7 +67,7 @@ jobs: - name: "Is renv required?" id: renv-check - uses: carpentries/actions/renv-checks@main + uses: carpentries/actions/renv-checks@v1 with: CACHE_VERSION: ${{ inputs.CACHE_VERSION || '' }} skip-cache-check: true @@ -99,7 +99,7 @@ jobs: - name: "Update {renv} deps and determine if a PR is needed" id: update - uses: carpentries/actions/update-lockfile@main + uses: carpentries/actions/update-lockfile@v1 with: update: ${{ env.UPDATE_PACKAGES }} force-renv-init: ${{ env.FORCE_RENV_INIT }} @@ -108,7 +108,7 @@ jobs: - name: "Validate Current Org and Workflow" id: validate-org-workflow - uses: carpentries/actions/validate-org-workflow@main + uses: carpentries/actions/validate-org-workflow@v1 with: repo: ${{ github.repository }} workflow: ${{ github.workflow }} diff --git a/.github/workflows/update-workflows.yaml b/.github/workflows/update-workflows.yaml index 35106872..6d63a32c 100644 --- a/.github/workflows/update-workflows.yaml +++ b/.github/workflows/update-workflows.yaml @@ -33,7 +33,7 @@ jobs: - name: "Validate Current Org and Workflow" id: validate-org-workflow - uses: carpentries/actions/validate-org-workflow@main + uses: carpentries/actions/validate-org-workflow@v1 with: repo: ${{ github.repository }} workflow: ${{ github.workflow }} @@ -71,7 +71,7 @@ jobs: - name: "Validate token" id: validate-token - uses: carpentries/actions/check-valid-credentials@main + uses: carpentries/actions/check-valid-credentials@v1 with: token: ${{ steps.set-pat.outputs.pat || secrets.SANDPAPER_WORKFLOW }} @@ -87,10 +87,11 @@ jobs: - name: Update Workflows id: update if: ${{ steps.validate-token.outputs.wf == 'true' }} - uses: carpentries/actions/update-workflows@main + uses: carpentries/actions/update-workflows@v1 with: version: ${{ github.event.inputs.version || 'latest' }} clean: ${{ github.event.inputs.clean || '.yaml' }} + token: ${{ steps.set-pat.outputs.pat || secrets.SANDPAPER_WORKFLOW }} - name: Create Pull Request id: cpr diff --git a/.github/workflows/workflows-version.txt b/.github/workflows/workflows-version.txt index 7dea76ed..570c7965 100644 --- a/.github/workflows/workflows-version.txt +++ b/.github/workflows/workflows-version.txt @@ -1 +1 @@ -1.0.1 +v1.0.2