From bc64c3062d8072273864348fa9d8bf556832477d Mon Sep 17 00:00:00 2001 From: Bill Stumbo Date: Sun, 20 Sep 2026 11:50:55 -0400 Subject: [PATCH 1/3] Update GitHub Action to work correctly on manual deploy. This change resolves an issue that occurred after a failed deploy. An subsequent attempt to do a manual deploy failed due to the conditions around deploy. This PR fixes that issue. --- .github/workflows/gh-pages.yml | 36 ++++++++++++++++++++++------------ README.md | 4 ++-- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index adcc23c7..f714e104 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -20,10 +20,11 @@ # the STAGING_APP_ID variable is unset) # deploy - deploy the built site to GitHub Pages # -# The workflow is executed either on a push or via scheduled run times. When -# started at a scheduled run time we only do a deploy if the cached bibliography -# is no longer current. On a push, we always verify the the current -# bibliography is loaded and deploy a new version of the website. +# The workflow is executed on a push, on pull requests (build only, never +# deployed), via scheduled runs, or via manual workflow_dispatch. On a +# scheduled run we only deploy if the cached bibliography is no longer +# current. On a push or manual dispatch from main, we always verify the +# current bibliography is loaded and deploy a new version of the website. # # 2023-10-20 Bill Stumbo # @@ -65,10 +66,10 @@ env: jobs: # ---------------------------------------------------------------------------- # Validate that README.md references the correct Hugo version. - # Only runs on push/pull_request, not scheduled runs. + # Runs on push/pull_request/workflow_dispatch, not scheduled runs. # validate-docs: - if: github.event_name == 'push' || github.event_name == 'pull_request' + if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -115,9 +116,9 @@ jobs: echo "Hugo version: $VERSION" # ---------------------------------------------------------------------------- - # Build the website using the org-level reusable workflow. This job is - # conditional, we will always run it on a push or if on a scheduled run the - # cache was determined to be out of date. + # Build the website using the org-level reusable workflow. This job runs on + # push, pull_request, and workflow_dispatch (always a full build), and on + # scheduled runs (skipping the build when the bibliography cache is fresh). # build: needs: [validate-docs, hugo-version] @@ -167,11 +168,22 @@ jobs: # ---------------------------------------------------------------------------- # Deploy the built site to GitHub Pages. - # Only runs on push or scheduled runs, never on pull requests, and never - # when the build was skipped because the bibliography was already current. + # Only runs on push/workflow_dispatch from main, or on scheduled runs when + # the build was not skipped; never on pull requests. The `skipped` output + # is only consulted for scheduled runs (manual dispatches always do a full + # rebuild with `skip-if-fresh: false`, so a fresh Pages artifact is + # guaranteed when the build succeeds), and deploys are restricted to the + # main branch so a dispatch from any other ref cannot publish to production. # deploy: - if: github.event_name != 'pull_request' && needs.build.outputs.skipped != 'true' + if: >- + needs.build.result == 'success' && + github.ref == 'refs/heads/main' && + ( + github.event_name == 'push' || + github.event_name == 'workflow_dispatch' || + (github.event_name == 'schedule' && needs.build.outputs.skipped != 'true') + ) environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} diff --git a/README.md b/README.md index 24ef364a..0ee39aa1 100644 --- a/README.md +++ b/README.md @@ -243,7 +243,7 @@ The workflow consists of four jobs: **1. `validate-docs` — Verify Documentation Consistency** -Runs on `push` and `pull_request` events to ensure that README.md references the correct Hugo version. Checks that: +Runs on `push`, `pull_request`, and `workflow_dispatch` events to ensure that README.md references the correct Hugo version. Checks that: - The Hugo badge displays the version defined in `HUGO_VERSION` - The README.md installation instructions use the correct version @@ -277,7 +277,7 @@ Delegates to the org-level reusable workflow **4. `deploy` — Deploy to GitHub Pages** -Takes the output of the build step and deploys it to GitHub Pages using the GitHub `deploy-pages` action. Skipped on pull requests and when the build was skipped because the bibliography was already current. +Takes the output of the build step and deploys it to GitHub Pages using the GitHub `deploy-pages` action. Runs on `push` and manual `workflow_dispatch` from `main`, and on scheduled runs only when the build was not skipped because the bibliography was already current. Never runs on pull requests. ### Environment Variables From 25986dec2d6ae7df580c110a522a1f13b7fcbedc Mon Sep 17 00:00:00 2001 From: Bill Stumbo Date: Tue, 22 Sep 2026 23:45:45 -0400 Subject: [PATCH 2/3] Keep skipped check for dispatch, clean whitespace, document deploy matrix Gate deploy on build success, main ref, and skipped != true for all events including workflow_dispatch. Document expected deploy matrix in workflow comments and README, fix job count, strip trailing whitespace. --- .github/workflows/gh-pages.yml | 82 ++++++++++++++++++++++------------ README.md | 20 ++++++++- 2 files changed, 71 insertions(+), 31 deletions(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f714e104..914905b4 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -3,7 +3,7 @@ # # Github Workflow to deploy Interlisp.org. # -# Interlisp.org is a Hugo based static website that contains a +# Interlisp.org is a Hugo based static website that contains a # detailed bibliography maintained using Zotero (https://www.zotero.org/groups/2914042/interlispwww.zotero.org/). # # This workflow consists of several jobs: @@ -21,10 +21,13 @@ # deploy - deploy the built site to GitHub Pages # # The workflow is executed on a push, on pull requests (build only, never -# deployed), via scheduled runs, or via manual workflow_dispatch. On a -# scheduled run we only deploy if the cached bibliography is no longer -# current. On a push or manual dispatch from main, we always verify the -# current bibliography is loaded and deploy a new version of the website. +# deployed), via scheduled runs, or via manual workflow_dispatch. Deploys +# run only from main when the build succeeded and was not skipped +# (`needs.build.outputs.skipped != 'true'`). On a scheduled run the build +# is skipped when the cached bibliography is fresh, so those runs usually +# do not deploy. Push and manual dispatch pass `skip-if-fresh: false` and +# therefore rebuild every time; the `skipped` check is kept for dispatch as +# a safety net so deploy-pages never runs without a fresh Pages artifact. # # 2023-10-20 Bill Stumbo # @@ -77,24 +80,24 @@ jobs: - name: Check Hugo version consistency run: | echo "Checking README.md for Hugo version $HUGO_VERSION" - + # Check badge if ! grep -q "badge/Hugo-${HUGO_VERSION}" README.md; then echo "::error::README.md badge does not reference Hugo version $HUGO_VERSION" FAILED=1 fi - + # Check download URL if ! grep -q "hugo_extended_${HUGO_VERSION}_linux-amd64.deb" README.md; then echo "::error::README.md download URL does not reference Hugo version $HUGO_VERSION" FAILED=1 fi - + if [ "$FAILED" = "1" ]; then echo "Update README.md to use Hugo version $HUGO_VERSION" exit 1 fi - + echo "README.md Hugo version references are consistent" # ---------------------------------------------------------------------------- @@ -122,7 +125,14 @@ jobs: # build: needs: [validate-docs, hugo-version] - if: always() && (needs.validate-docs.result == 'success' || needs.validate-docs.result == 'skipped') && (needs.hugo-version.result == 'success') + if: >- + always() && + ( + needs.validate-docs.result == 'success' || + needs.validate-docs.result == 'skipped' + ) && + needs.hugo-version.result == 'success' + uses: Interlisp/shared-workflows/.github/workflows/build-site.yml@main with: hugo-version: ${{ needs.hugo-version.outputs.version }} @@ -137,9 +147,10 @@ jobs: # workflow call), keeping gh-pages.yml's env the single source of truth. # preview: - if: github.event_name == 'pull_request' && - github.event.pull_request.head.repo.full_name == github.repository && - vars.STAGING_APP_ID != '' + if: >- + github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository && + vars.STAGING_APP_ID != '' runs-on: ubuntu-latest needs: [build] steps: @@ -160,29 +171,42 @@ jobs: repo: Interlisp/Interlisp.staging ref: main token: ${{ steps.app-token.outputs.token }} - inputs: '{ - "pr_number": "${{ github.event.pull_request.number }}", - "pr_sha": "${{ github.event.pull_request.head.sha }}", - "hugo_version": "${{ env.HUGO_VERSION }}" - }' + inputs: >- + { + "pr_number": "${{ github.event.pull_request.number }}", + "pr_sha": "${{ github.event.pull_request.head.sha }}", + "hugo_version": "${{ env.HUGO_VERSION }}" + } # ---------------------------------------------------------------------------- # Deploy the built site to GitHub Pages. - # Only runs on push/workflow_dispatch from main, or on scheduled runs when - # the build was not skipped; never on pull requests. The `skipped` output - # is only consulted for scheduled runs (manual dispatches always do a full - # rebuild with `skip-if-fresh: false`, so a fresh Pages artifact is - # guaranteed when the build succeeds), and deploys are restricted to the - # main branch so a dispatch from any other ref cannot publish to production. + # Only runs from the main branch on push/workflow_dispatch/schedule, never + # on pull requests, and never when the build was skipped because the + # bibliography was already current. The `skipped` output is checked for + # all events: manual dispatches pass `skip-if-fresh: false`, so a healthy + # dispatch rebuilds and `skipped` is 'false'; keeping the check guarantees + # deploy-pages always has a fresh Pages artifact. Deploys are restricted + # to `main` so a dispatch from any other ref cannot publish to production. + # + # Expected matrix (all rows also require build == success, ref == main): + # push @ main, skipped=false -> deploy + # workflow_dispatch @ main, skipped=false -> deploy + # workflow_dispatch @ main, skipped=true -> skip (no artifact; signals + # a reusable-workflow bug instead of publishing stale output) + # schedule, skipped=false (bib changed) -> deploy + # schedule, skipped=true (bib fresh) -> skip + # pull_request (any ref) -> skip + # any event, ref != main -> skip # deploy: if: >- - needs.build.result == 'success' && - github.ref == 'refs/heads/main' && + needs.build.result == 'success' && + github.ref == 'refs/heads/main' && + needs.build.outputs.skipped != 'true' && ( - github.event_name == 'push' || - github.event_name == 'workflow_dispatch' || - (github.event_name == 'schedule' && needs.build.outputs.skipped != 'true') + github.event_name == 'push' || + github.event_name == 'workflow_dispatch' || + github.event_name == 'schedule' ) environment: name: github-pages diff --git a/README.md b/README.md index 0ee39aa1..38dc31b7 100644 --- a/README.md +++ b/README.md @@ -239,11 +239,12 @@ Building the website is driven by a GitHub workflow (`.github/workflows/gh-pages **Workflow Jobs:** -The workflow consists of four jobs: +The workflow consists of five jobs: **1. `validate-docs` — Verify Documentation Consistency** Runs on `push`, `pull_request`, and `workflow_dispatch` events to ensure that README.md references the correct Hugo version. Checks that: + - The Hugo badge displays the version defined in `HUGO_VERSION` - The README.md installation instructions use the correct version @@ -261,6 +262,7 @@ requests. Delegates to the org-level reusable workflow (`Interlisp/shared-workflows/.github/workflows/build-site.yml`), which: + - Queries the Zotero REST API for the bibliography version and caches the bibliography, running `update_bibliography.sh` to download and process a new copy whenever the version has changed (a cache miss) @@ -277,7 +279,21 @@ Delegates to the org-level reusable workflow **4. `deploy` — Deploy to GitHub Pages** -Takes the output of the build step and deploys it to GitHub Pages using the GitHub `deploy-pages` action. Runs on `push` and manual `workflow_dispatch` from `main`, and on scheduled runs only when the build was not skipped because the bibliography was already current. Never runs on pull requests. +Takes the output of the build step and deploys it to GitHub Pages using the GitHub `deploy-pages` action. Runs only from the `main` branch when the build succeeded and was not skipped (`skipped != 'true'`, checked for every event including manual dispatch as a safety net so `deploy-pages` always has a fresh artifact). Never runs on pull requests or from non-`main` refs. + +**Deploy test matrix** (every row also requires `build` result `success`): + +| Event | Ref | `skipped` | Result | +|-------|-----|-----------|--------| +| `push` | `main` | `false` | deploy | +| `workflow_dispatch` | `main` | `false` | deploy | +| `workflow_dispatch` | `main` | `true` | skip — no artifact; signals a reusable-workflow bug | +| `schedule` | `main` | `false` (bib changed) | deploy | +| `schedule` | `main` | `true` (bib fresh) | skip | +| `pull_request` | any | any | skip | +| any | not `main` | any | skip | + +Verify with: `gh run view --json jobs -q '.jobs[].conclusion'` — `deploy` should be `success` only for the deploy rows above, `skipped` otherwise; and confirm no line in `gh-pages.yml` ends with trailing whitespace. ### Environment Variables From c447304fe2b208278c12021ab826b662886966a1 Mon Sep 17 00:00:00 2001 From: Bill Stumbo Date: Tue, 22 Sep 2026 23:54:24 -0400 Subject: [PATCH 3/3] Clarify cache-hit wording in deploy docs Disambiguate cache-freshness (cached bibliography matches Zotero) from newly built Pages artifact. --- .github/workflows/gh-pages.yml | 19 +++++++++++-------- README.md | 4 ++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 914905b4..9ba9ecbd 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -12,8 +12,9 @@ # hugo-version - expose the Hugo version as a job output # build - build the website and run the full test suite using the # org-level reusable workflow; also checks the Zotero -# bibliography version (skipping the build on scheduled -# runs when it is unchanged) + # bibliography version (skipping the build on scheduled + # runs on a cache hit, i.e. the cached bibliography + # already matches Zotero's current version) # (Interlisp/shared-workflows/.github/workflows/build-site.yml) # preview - trigger a per-PR staging preview in # Interlisp/Interlisp.staging (skips on fork PRs or when @@ -24,10 +25,11 @@ # deployed), via scheduled runs, or via manual workflow_dispatch. Deploys # run only from main when the build succeeded and was not skipped # (`needs.build.outputs.skipped != 'true'`). On a scheduled run the build -# is skipped when the cached bibliography is fresh, so those runs usually -# do not deploy. Push and manual dispatch pass `skip-if-fresh: false` and +# is skipped when the cached bibliography is already current (cache hit: +# it matches Zotero's current version), so those runs usually do not +# deploy. Push and manual dispatch pass `skip-if-fresh: false` and # therefore rebuild every time; the `skipped` check is kept for dispatch as -# a safety net so deploy-pages never runs without a fresh Pages artifact. +# a safety net so deploy-pages never runs without a newly built Pages artifact. # # 2023-10-20 Bill Stumbo # @@ -182,10 +184,11 @@ jobs: # Deploy the built site to GitHub Pages. # Only runs from the main branch on push/workflow_dispatch/schedule, never # on pull requests, and never when the build was skipped because the - # bibliography was already current. The `skipped` output is checked for + # cached bibliography was already current (cache hit). The `skipped` + # output is checked for # all events: manual dispatches pass `skip-if-fresh: false`, so a healthy # dispatch rebuilds and `skipped` is 'false'; keeping the check guarantees - # deploy-pages always has a fresh Pages artifact. Deploys are restricted + # deploy-pages always has a newly built Pages artifact. Deploys are restricted # to `main` so a dispatch from any other ref cannot publish to production. # # Expected matrix (all rows also require build == success, ref == main): @@ -194,7 +197,7 @@ jobs: # workflow_dispatch @ main, skipped=true -> skip (no artifact; signals # a reusable-workflow bug instead of publishing stale output) # schedule, skipped=false (bib changed) -> deploy - # schedule, skipped=true (bib fresh) -> skip + # schedule, skipped=true (cache hit) -> skip # pull_request (any ref) -> skip # any event, ref != main -> skip # diff --git a/README.md b/README.md index 38dc31b7..b26860fa 100644 --- a/README.md +++ b/README.md @@ -279,7 +279,7 @@ Delegates to the org-level reusable workflow **4. `deploy` — Deploy to GitHub Pages** -Takes the output of the build step and deploys it to GitHub Pages using the GitHub `deploy-pages` action. Runs only from the `main` branch when the build succeeded and was not skipped (`skipped != 'true'`, checked for every event including manual dispatch as a safety net so `deploy-pages` always has a fresh artifact). Never runs on pull requests or from non-`main` refs. +Takes the output of the build step and deploys it to GitHub Pages using the GitHub `deploy-pages` action. Runs only from the `main` branch when the build succeeded and was not skipped (`skipped != 'true'`, checked for every event including manual dispatch as a safety net so `deploy-pages` always has a newly built artifact). Never runs on pull requests or from non-`main` refs. **Deploy test matrix** (every row also requires `build` result `success`): @@ -289,7 +289,7 @@ Takes the output of the build step and deploys it to GitHub Pages using the GitH | `workflow_dispatch` | `main` | `false` | deploy | | `workflow_dispatch` | `main` | `true` | skip — no artifact; signals a reusable-workflow bug | | `schedule` | `main` | `false` (bib changed) | deploy | -| `schedule` | `main` | `true` (bib fresh) | skip | +| `schedule` | `main` | `true` (cache hit — cached bibliography matches Zotero) | skip | | `pull_request` | any | any | skip | | any | not `main` | any | skip |