01 Maintain: Build and Deploy Site #3
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
| name: "01 Maintain: Build and Deploy Site" | |
| on: | |
| push: | |
| branches: | |
| - main | |
| schedule: | |
| - cron: '0 0 * * 2' | |
| workflow_dispatch: | |
| inputs: | |
| name: | |
| description: 'Who triggered this build?' | |
| required: true | |
| default: 'Maintainer (via GitHub)' | |
| CACHE_VERSION: | |
| description: 'Optional renv cache version override' | |
| required: false | |
| default: '' | |
| reset: | |
| description: 'Reset cached markdown files' | |
| required: false | |
| default: false | |
| type: boolean | |
| sandpaper-version: | |
| description: 'The version of sandpaper to use. You can use the remotes syntax to specify a version to use. Defaults to latest on the r-universe.' | |
| default: 'latest' | |
| pegboard-version: | |
| description: 'The version of pegboard to use. You can use the remotes syntax to specify a version to use. Defaults to latest on the r-universe.' | |
| default: 'latest' | |
| varnish-version: | |
| description: 'The version of varnish to use. You can use the remotes syntax to specify a version to use. Defaults to latest on the r-universe.' | |
| default: 'latest' | |
| workflow_run: | |
| workflows: ["03 Maintain: Apply Package Cache"] | |
| types: | |
| - completed | |
| jobs: | |
| preflight: | |
| name: "Preflight: Schedule, Push, or PR?" | |
| runs-on: ubuntu-latest | |
| outputs: | |
| do-build: ${{ steps.check.outputs.push_or_pr }} | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| steps: | |
| - name: "Should we run build and deploy?" | |
| id: check | |
| run: | | |
| if [[ "${{ github.event_name }}" == "schedule" || | |
| "${{ github.event_name }}" == "workflow_dispatch" || | |
| "${{ github.event_name }}" == "workflow_run" ]]; then | |
| echo "✅ Schedule, manual, or auto trigger. Build will run." | |
| echo "push_or_pr=true" >> $GITHUB_OUTPUT | |
| elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == "refs/heads/main" ]]; then | |
| PRE_PR=$(gh pr list --repo "${{ github.repository }}" --state merged --search "${{ github.sha }}" --json number -q ".[0].number") >> $GITHUB_ENV | |
| if [[ -n "$PRE_PR" ]]; then | |
| LABELS=$(gh pr view "$PRE_PR" --repo "${{ github.repository }}" --json labels -q ".labels[].name") | |
| if echo "$LABELS" | grep -q "type: package cache"; then | |
| echo "❗Package Cache PR merged. Please run '03 Maintain: Apply Package Cache' if not already running!" | |
| echo "push_or_pr=false" >> $GITHUB_OUTPUT | |
| exit 1 | |
| else | |
| echo "✅ Valid PR merged. Build will run." | |
| echo "push_or_pr=true" >> $GITHUB_OUTPUT | |
| fi | |
| else | |
| echo "✅ Direct push to main. Build will run." | |
| echo "push_or_pr=true" >> $GITHUB_OUTPUT | |
| fi | |
| else | |
| echo "❗This was not a schedule or valid trigger. No build will run." | |
| echo "push_or_pr=false" >> $GITHUB_OUTPUT | |
| exit 1 | |
| fi | |
| check-renv: | |
| name: "Check if We Need {renv}" | |
| runs-on: ubuntu-latest | |
| needs: preflight | |
| if: ${{ needs.preflight.outputs.do-build == 'true' }} | |
| outputs: | |
| renv-needed: ${{ steps.check-for-renv.outputs.exists }} | |
| steps: | |
| - name: "Checkout Lesson" | |
| uses: actions/checkout@v4 | |
| - name: "Check for renv" | |
| id: check-for-renv | |
| run: | | |
| if [[ -d renv ]]; then | |
| echo "exists=true" >> $GITHUB_OUTPUT | |
| fi | |
| prepare-renv: | |
| name: "Grab renv.lock hash" | |
| runs-on: ubuntu-latest | |
| needs: check-renv | |
| if: ${{ needs.check-renv.outputs.renv-needed == 'true' }} | |
| outputs: | |
| renv-cache-hashsum: ${{ steps.set-hash.outputs.renv-cache-hashsum }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Calculate renv hash | |
| id: set-hash | |
| run: | | |
| CACHE_VERSION_INPUT="${{ github.event.inputs.CACHE_VERSION || vars.CACHE_VERSION }}" | |
| if [ -z "$CACHE_VERSION_INPUT" ]; then | |
| echo "renv-cache-hashsum=${{ hashFiles('renv/profiles/lesson-requirements/renv.lock') }}" >> $GITHUB_OUTPUT | |
| else | |
| echo "renv-cache-hashsum=$CACHE_VERSION_INPUT" >> $GITHUB_OUTPUT | |
| fi | |
| prepare-wb-package-override: | |
| name: "Any Workbench package version inputs?" | |
| runs-on: ubuntu-latest | |
| outputs: | |
| varnish-version: ${{ steps.input-wb-vers.outputs.varnish-version-override }} | |
| sandpaper-version: ${{ steps.input-wb-vers.outputs.sandpaper-version-override }} | |
| pegboard-version: ${{ steps.input-wb-vers.outputs.pegboard-version-override }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: "Get var/input Workbench package versions" | |
| id: input-wb-vers | |
| run: | | |
| VARNISH_VERSION_INPUT="${{ github.event.inputs.varnish-version || 'latest' }}" | |
| if [ ! -z "$VARNISH_VERSION_INPUT" ]; then | |
| echo "varnish-version-override=$VARNISH_VERSION_INPUT" >> $GITHUB_OUTPUT | |
| fi | |
| SANDPAPER_VERSION_INPUT="${{ github.event.inputs.sandpaper-version || 'latest' }}" | |
| if [ ! -z "$SANDPAPER_VERSION_INPUT" ]; then | |
| echo "sandpaper-version-override=$SANDPAPER_VERSION_INPUT" >> $GITHUB_OUTPUT | |
| fi | |
| PEGBOARD_VERSION_INPUT="${{ github.event.inputs.pegboard-version || 'latest' }}" | |
| if [ ! -z "$PEGBOARD_VERSION_INPUT" ]; then | |
| echo "pegboard-version-override=$PEGBOARD_VERSION_INPUT" >> $GITHUB_OUTPUT | |
| fi | |
| full-build: | |
| name: "Build Full Site" | |
| runs-on: ubuntu-latest | |
| needs: [preflight, check-renv, prepare-renv, prepare-wb-package-override] | |
| if: ${{ needs.preflight.outputs.do-build == 'true' }} | |
| env: | |
| VARNISH_VER: ${{ needs.prepare-wb-package-override.outputs.varnish-version }} | |
| SANDPAPER_VER: ${{ needs.prepare-wb-package-override.outputs.sandpaper-version }} | |
| PEGBOARD_VER: ${{ needs.prepare-wb-package-override.outputs.pegboard-version }} | |
| permissions: | |
| checks: write | |
| contents: write | |
| pages: write | |
| container: | |
| image: 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_CONFIG_EXTERNAL_LIBRARIES: "/usr/local/lib/R/site-library" | |
| RENV_VERSION: ${{ needs.prepare-renv.outputs.renv-cache-hashsum }} | |
| VARNISH_VER: ${{ needs.prepare-wb-package-override.outputs.varnish-version }} | |
| SANDPAPER_VER: ${{ needs.prepare-wb-package-override.outputs.sandpaper-version }} | |
| PEGBOARD_VER: ${{ needs.prepare-wb-package-override.outputs.pegboard-version }} | |
| volumes: | |
| - ${{ github.workspace }}:/home/rstudio/lesson | |
| options: --cpus 1 | |
| steps: | |
| - name: "Checkout Lesson" | |
| uses: actions/checkout@v4 | |
| - name: Check if renv Exists | |
| id: check-renv | |
| run: | | |
| if [ -d "/home/rstudio/lesson/renv" ]; then | |
| echo "RENV_EXISTS=true" >> $GITHUB_ENV | |
| else | |
| echo "RENV_EXISTS=false" >> $GITHUB_ENV | |
| fi | |
| - name: "Grabbed renv.lock hash" | |
| if: env.RENV_EXISTS == 'true' | |
| run: echo "RENV_VERSION is $RENV_VERSION" | |
| - name: Current env | |
| run: env | sort | |
| - name: Debugging Info | |
| run: | | |
| cd /home/rstudio/lesson | |
| echo "Current Directory: $(pwd)" | |
| ls -lah /home/rstudio/.workbench | |
| ls -lah $(pwd) | |
| Rscript -e 'sessionInfo()' | |
| - name: Mark Repository as Safe | |
| run: | | |
| git config --global --add safe.directory $(pwd) | |
| - name: Setup Lesson Dependencies | |
| run: | | |
| Rscript /home/rstudio/.workbench/setup_lesson_deps.R | |
| - name: Restore renv from cache | |
| id: restore-renv-cache | |
| uses: actions/cache@v4 | |
| if: env.RENV_EXISTS == 'true' | |
| with: | |
| path: /home/rstudio/lesson/renv | |
| key: ${{ runner.os }}-${{ inputs.cache-version }}-renv-${{ needs.prepare-renv.outputs.renv-cache-hashsum }} | |
| restore-keys: | |
| ${{ runner.os }}-${{ inputs.cache-version }}-renv- | |
| - name: Restore renv Dependencies | |
| if: env.RENV_EXISTS == 'true' && steps.restore-renv-cache.outputs.cache-hit == 'true' | |
| run: | | |
| lsn_path <- fs::path("/home/rstudio/lesson") | |
| renv::load(project = lsn_path) | |
| renv_lib <- renv::paths$library(project = lsn_path) | |
| renv_lock <- renv::paths$lockfile(project = lsn_path) | |
| renv::restore(project = lsn_path, library = renv_lib, lockfile = renv_lock, prompt = FALSE) | |
| shell: Rscript {0} | |
| - name: Fail on renv cache miss | |
| if: env.RENV_EXISTS == 'true' && steps.restore-renv-cache.outputs.cache-hit != 'true' | |
| run: | | |
| echo "❌ renv cache required but none available. Please run the "02 Maintain: Check for Updated Packages" then the "03 Maintain: Apply Package Cache" workflows." | |
| exit 1 | |
| - name: Override any Workbench packages | |
| if: env.VARNISH_VER != 'latest' || env.SANDPAPER_VER != 'latest' || env.PEGBOARD_VER != 'latest' | |
| run: | | |
| varnish_version <- '${{ env.VARNISH_VER }}' | |
| sandpaper_version <- '${{ env.SANDPAPER_VER }}' | |
| pegboard_version <- '${{ env.PEGBOARD_VER }}' | |
| cfg_file <- '/home/rstudio/lesson/config.yaml' | |
| library("remotes") | |
| cfg <- if (file.exists(cfg_file)) readLines(cfg_file) else character(0) | |
| get_version <- function(x, key = "varnish") { | |
| res <- x[grepl(paste0("^", key, "\\s?:"), x)] | |
| if (length(res)) { | |
| res <- trimws(strsplit(res, ":")[[1]][2]) | |
| # trim quotes | |
| res <- gsub("[\"']", "", res) | |
| if (grepl("^[0-9]", res)) { | |
| res <- paste0("carpentries/", key, "@", res) | |
| } | |
| } else { | |
| res <- "latest" | |
| } | |
| res | |
| } | |
| varnish_version <- get_version(cfg, key = "varnish") | |
| sandpaper_version <- get_version(cfg, key = "sandpaper") | |
| pegboard_version <- get_version(cfg, key = "pegboard") | |
| if (varnish_version != "latest") { | |
| cat("::group::Installing", varnish_version, "\n") | |
| remotes::install_github(varnish_version) | |
| cat("::endgroup::\n") | |
| } | |
| if (sandpaper_version != "latest") { | |
| cat("::group::Installing", sandpaper_version, "\n") | |
| remotes::install_github(sandpaper_version) | |
| cat("::endgroup::\n") | |
| } | |
| if (pegboard_version != "latest") { | |
| cat("::group::Installing", pegboard_version, "\n") | |
| remotes::install_github(pegboard_version) | |
| cat("::endgroup::\n") | |
| } | |
| shell: Rscript {0} | |
| - name: Run Container and Build Site | |
| run: | | |
| library(sandpaper) | |
| sandpaper::package_cache_trigger(TRUE) | |
| sandpaper:::ci_deploy(reset = TRUE) | |
| shell: Rscript {0} |