From ee5551ec33714203ca751a30df854ab03a38cbe5 Mon Sep 17 00:00:00 2001 From: Bill Stumbo Date: Mon, 10 Aug 2026 23:52:07 -0400 Subject: [PATCH 1/6] Update gh-pages GitHub Action to use shared version in .github repo This commit points to the development branch and not the master branch. --- .github/workflows/gh-pages.yml | 109 +++++++++------------------------ 1 file changed, 28 insertions(+), 81 deletions(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 3f266b1c..fce3ee67 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -1,20 +1,26 @@ #******************************************************************************* # gh-pages.yml # -# Github Workflow to deploy Interlisp.org. +# Github Workflow to deploy Interlisp.org. # -# 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/). +# 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 two jobs, one to ensure that we have the latest -# version of the Zotero bibliography and a second job to deploy the website. +# This workflow consists of several jobs: # -# 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 verifty the the current -# bibliography is loaded and deploy a new version of the website. +# check - ensure the Zotero bibliography is up to date +# validate-docs - ensure README.md references the correct Hugo version +# test - run the bibliography JSON-LD test suite +# build - build the website using the org-level reusable workflow +# (Interlisp/.github/.github/workflows/build-site.yml) +# deploy - deploy the built site to GitHub Pages # -# 2023-10-20 Bill Stumbo +# 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. +# +# 2023-10-20 Bill Stumbo # # Copyright 2023 by Interlisp.org # @@ -49,9 +55,6 @@ defaults: shell: bash env: - # ---------------------------------------------------------------------------- - # Specify the deployment environment: staging or production - HUGO_ENVIRONMENT: ${{ vars.HUGO_ENVIRONMENT || 'staging' }} HUGO_VERSION: 0.155.3 jobs: @@ -140,7 +143,7 @@ jobs: - name: Cache Zotero Bibliography id: cache-bib - uses: actions/cache@v5 + uses: actions/cache@v5q with: path: | static/data/bibliography.json @@ -187,76 +190,21 @@ jobs: run: pytest tests/test_bibliography_jsonld.py -v # ---------------------------------------------------------------------------- - # Build the website. 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 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: needs: [check, validate-docs, test] if: always() && (github.event_name == 'push' || github.event_name == 'pull_request' || needs.check.outputs.cacheHit != 'true') && (needs.validate-docs.result == 'success' || needs.validate-docs.result == 'skipped') && (needs.check.result == 'success' || needs.check.result == 'skipped') && (needs.test.result == 'success') - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - fetch-depth: 0 - - - name: Cache Zotero Bibliography - id: cache-bib - uses: actions/cache@v5 - with: - path: | - static/data/bibliography.json - static/data/bibItems - content/en/history/bibliography - key: bib-${{ needs.check.outputs.zoteroVersion }} - - - name: Install Bibliography - if: steps.cache-bib.outputs.cache-hit != 'true' - run: | - echo "Retrieve bibliography" - cd scripts - chmod +x ./update_bibliography.sh - chmod +x ./bibSplit.pl - ./update_bibliography.sh - - # Install Hugo Extended - # - - name: Install Hugo CLI - run: | - wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ - && sudo dpkg -i ${{ runner.temp }}/hugo.deb - - - name: Setup Pages - id: pages - uses: actions/configure-pages@v6.0.0 - - - name: Setup Node - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: 'npm' - - - name: Install dependencies - run: | - npm ci - - - name: Build - env: - HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache - TZ: America/New_York - run: hugo --cleanDestinationDir -e $HUGO_ENVIRONMENT - - - name: Install pytest - run: pip install pytest pytest-cov - - - name: Run build-integrity tests - run: pytest tests/test_hugo_build.py -v - - - name: Upload artifact - uses: actions/upload-pages-artifact@v5.0.0 - with: - path: ./public + uses: Interlisp/.github/.github/workflows/build-site.yml@bs1_staging_prep + with: + hugo-environment: ${{ vars.HUGO_ENVIRONMENT || 'production' }} + # ---------------------------------------------------------------------------- + # Deploy the built site to GitHub Pages. + # Only runs on push or scheduled runs, never on pull requests. + # deploy: if: github.event_name != 'pull_request' environment: @@ -269,4 +217,3 @@ jobs: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v5 - From 51fb3db1dd5b9d2fb06ee51963f20baec1225775 Mon Sep 17 00:00:00 2001 From: Bill Stumbo Date: Mon, 10 Aug 2026 23:58:03 -0400 Subject: [PATCH 2/6] Fix typo. --- .github/workflows/gh-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index fce3ee67..49b03dba 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -143,7 +143,7 @@ jobs: - name: Cache Zotero Bibliography id: cache-bib - uses: actions/cache@v5q + uses: actions/cache@v5 with: path: | static/data/bibliography.json From 258be543fd391ff8650ec208a93b348b82049c5b Mon Sep 17 00:00:00 2001 From: Bill Stumbo Date: Tue, 11 Aug 2026 22:55:03 -0400 Subject: [PATCH 3/6] Test passing HUGO_VERSION as an output of check job. Environment variables are not available as parameters for a shared workflow - how about as a parameter availabe from a previously run job? --- .github/workflows/gh-pages.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 49b03dba..f643619d 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -66,6 +66,7 @@ jobs: outputs: zoteroVersion: ${{ steps.zoteroVersion.outputs.version }} cacheHit: ${{ steps.cache-zotero.outputs.cache-hit }} + hugoVersion: ${{ env.HUGO_VERSION }} runs-on: ubuntu-latest steps: @@ -162,7 +163,7 @@ jobs: - name: Install Hugo CLI run: | - wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ + wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${{ needs.check.outputs.hugoVersion }}/hugo_extended_${{ needs.check.outputs.hugoVersion }}_linux-amd64.deb \ && sudo dpkg -i ${{ runner.temp }}/hugo.deb - name: Setup Node @@ -199,6 +200,7 @@ jobs: if: always() && (github.event_name == 'push' || github.event_name == 'pull_request' || needs.check.outputs.cacheHit != 'true') && (needs.validate-docs.result == 'success' || needs.validate-docs.result == 'skipped') && (needs.check.result == 'success' || needs.check.result == 'skipped') && (needs.test.result == 'success') uses: Interlisp/.github/.github/workflows/build-site.yml@bs1_staging_prep with: + hugo-version: ${{ needs.check.outputs.hugoVersion }} hugo-environment: ${{ vars.HUGO_ENVIRONMENT || 'production' }} # ---------------------------------------------------------------------------- From 3bbd2610bd3e6fab3023b79d02c6250bb178f380 Mon Sep 17 00:00:00 2001 From: Bill Stumbo Date: Wed, 12 Aug 2026 06:59:17 -0400 Subject: [PATCH 4/6] Move Zotero interactions into shared build-site workflow. Update README.md to reflect current design. --- .github/workflows/gh-pages.yml | 127 +++++++-------------------------- README.md | 118 +++++++++++++++--------------- 2 files changed, 84 insertions(+), 161 deletions(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f643619d..c770224b 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -8,10 +8,12 @@ # # This workflow consists of several jobs: # -# check - ensure the Zotero bibliography is up to date # validate-docs - ensure README.md references the correct Hugo version -# test - run the bibliography JSON-LD test suite -# build - build the website using the org-level reusable workflow +# 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) # (Interlisp/.github/.github/workflows/build-site.yml) # deploy - deploy the built site to GitHub Pages # @@ -58,42 +60,6 @@ env: HUGO_VERSION: 0.155.3 jobs: - # ---------------------------------------------------------------------------- - # Use the Zotero REST API to get the current version of the Zotero Bibliography - # Compare against a cached version of the bibliography. - # - check: - outputs: - zoteroVersion: ${{ steps.zoteroVersion.outputs.version }} - cacheHit: ${{ steps.cache-zotero.outputs.cache-hit }} - hugoVersion: ${{ env.HUGO_VERSION }} - - runs-on: ubuntu-latest - steps: - - - name: Get Zotero Version Information - id: zoteroVersion - run: | - set -euo pipefail - VERSION=$(curl -fsSLI "https://api.zotero.org/groups/2914042/items?format=versions" \ - | { grep -i "last-modified-version" \ - | cut -d: -f2 \ - | tr -d $'\r ' || true; }) - if [[ -z "${VERSION:-}" ]]; then - echo "Error: Failed to determine Zotero Last-Modified-Version from API response." >&2 - exit 1 - fi - echo "version=$VERSION" >> "$GITHUB_OUTPUT" - - - name: Cache Zotero Bibliography - id: cache-zotero - uses: actions/cache/restore@v5 - with: - lookup-only: true - path: | - content/en/history/bibliography - key: bib-${{ steps.zoteroVersion.outputs.version }} - # ---------------------------------------------------------------------------- # Validate that README.md references the correct Hugo version. # Only runs on push/pull_request, not scheduled runs. @@ -128,67 +94,22 @@ jobs: echo "README.md Hugo version references are consistent" # ---------------------------------------------------------------------------- - # Run the bibliography JSON-LD test suite against a test-environment Hugo - # build that mounts tests/fixtures/bibliography/ alongside the real content. - # This job must pass before changes can be merged or deployed. + # Expose the Hugo version from the workflow environment as a job output. + # The env context is not available in a reusable workflow's `with:` block, + # so the version is surfaced here instead. Keeping it in the workflow `env` + # means version bumps are ordinary, reviewed pull requests. # - test: - needs: [check, validate-docs] - if: always() && (github.event_name == 'push' || github.event_name == 'pull_request' || needs.check.outputs.cacheHit != 'true') && (needs.validate-docs.result == 'success' || needs.validate-docs.result == 'skipped') && (needs.check.result == 'success' || needs.check.result == 'skipped') + hugo-version: runs-on: ubuntu-latest + outputs: + version: ${{ env.HUGO_VERSION }} steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - fetch-depth: 0 - - - name: Cache Zotero Bibliography - id: cache-bib - uses: actions/cache@v5 - with: - path: | - static/data/bibliography.json - static/data/bibItems - content/en/history/bibliography - key: bib-${{ needs.check.outputs.zoteroVersion }} - - - name: Install Bibliography - if: steps.cache-bib.outputs.cache-hit != 'true' - run: | - echo "Retrieve bibliography" - cd scripts - chmod +x ./update_bibliography.sh - chmod +x ./bibSplit.pl - ./update_bibliography.sh - - - name: Install Hugo CLI - run: | - wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${{ needs.check.outputs.hugoVersion }}/hugo_extended_${{ needs.check.outputs.hugoVersion }}_linux-amd64.deb \ - && sudo dpkg -i ${{ runner.temp }}/hugo.deb - - - name: Setup Node - uses: actions/setup-node@v6 - with: - node-version: 24 - cache: 'npm' - - - name: Install Node dependencies - run: npm ci - - - name: Build test site + - name: Verify Hugo version is set env: - HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache - TZ: America/New_York - run: hugo --environment testing --destination tests/public_test - - - name: Install pytest - run: pip install pytest pyyaml pytest-cov - - - name: Run content-integrity tests - run: pytest tests/test_content_integrity.py -v --cov-report=term-missing - - - name: Run JSON-LD tests - run: pytest tests/test_bibliography_jsonld.py -v + VERSION: ${{ env.HUGO_VERSION }} + run: | + [[ -n "$VERSION" ]] || { echo "::error::HUGO_VERSION is empty"; exit 1; } + echo "Hugo version: $VERSION" # ---------------------------------------------------------------------------- # Build the website using the org-level reusable workflow. This job is @@ -196,24 +117,26 @@ jobs: # cache was determined to be out of date. # build: - needs: [check, validate-docs, test] - if: always() && (github.event_name == 'push' || github.event_name == 'pull_request' || needs.check.outputs.cacheHit != 'true') && (needs.validate-docs.result == 'success' || needs.validate-docs.result == 'skipped') && (needs.check.result == 'success' || needs.check.result == 'skipped') && (needs.test.result == 'success') + needs: [validate-docs, hugo-version] + if: always() && (needs.validate-docs.result == 'success' || needs.validate-docs.result == 'skipped') && (needs.hugo-version.result == 'success') uses: Interlisp/.github/.github/workflows/build-site.yml@bs1_staging_prep with: - hugo-version: ${{ needs.check.outputs.hugoVersion }} + hugo-version: ${{ needs.hugo-version.outputs.version }} hugo-environment: ${{ vars.HUGO_ENVIRONMENT || 'production' }} + skip-if-fresh: ${{ github.event_name == 'schedule' }} # ---------------------------------------------------------------------------- # Deploy the built site to GitHub Pages. - # Only runs on push or scheduled runs, never on pull requests. + # Only runs on push or scheduled runs, never on pull requests, and never + # when the build was skipped because the bibliography was already current. # deploy: - if: github.event_name != 'pull_request' + if: github.event_name != 'pull_request' && needs.build.outputs.skipped != 'true' environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest - needs: [build, test] + needs: [build] steps: - name: Deploy to GitHub Pages diff --git a/README.md b/README.md index ddb01006..facadcba 100644 --- a/README.md +++ b/README.md @@ -241,17 +241,7 @@ Building the website is driven by a GitHub workflow (`.github/workflows/gh-pages The workflow consists of four jobs: -**1. `check` — Verify Bibliography is Current** - -Uses Zotero's REST interface to query for the latest version of the group bibliography. A `GET` call is made to: - -``` -https://api.zotero.org/groups/2914042/items -``` - -This returns metadata including the `Last-Modified-Version` header, which is incremented every time the Zotero Interlisp catalog is updated. This value is used as a cache key for the bibliography. If the cache key matches one in the current GitHub Action cache, we reuse the saved bibliography and skip rebuilding. - -**2. `validate-docs` — Verify Documentation Consistency** +**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: - The Hugo badge displays the version defined in `HUGO_VERSION` @@ -259,32 +249,49 @@ Runs on `push` and `pull_request` events to ensure that README.md references the This job prevents documentation drift from the actual build configuration. -**3. `build` — Build the Website** - -- Determines if a build is needed: - - On `push` or `pull_request`: Always builds - - On schedule: Skips build if Zotero cache is current -- Checks out the repository -- If the Zotero cache is valid, copies its contents into the `content/en/history/bibliography` directory -- If the cache is invalid, runs `update_bibliography.sh` to download and process a new copy -- Runs Hugo Extended (version defined by `HUGO_VERSION` environment variable) with flags: - - `-e $HUGO_ENVIRONMENT` — specifies production or staging build - - `--cleanDestinationDir` — clears `./public` directory to avoid stale artifacts +**2. `hugo-version` — Expose the Hugo Version** + +Reads the `HUGO_VERSION` environment variable and exposes it as a job +output. The `env` context is not available in a reusable workflow's +`with:` block, so the version is surfaced here instead. Keeping it in +the workflow `env` means version bumps are ordinary, reviewed pull +requests. + +**3. `build` — Build the Website and Run the Tests** + +Delegates to the org-level reusable workflow +(`Interlisp/.github/.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) +- On scheduled runs, skips the build when the bibliography is unchanged + (exposed via the workflow's `skipped` output) +- Runs Hugo Extended with the build environment passed as an input + (`-e production` for this repository) +- Runs the full test suite: + - Content-integrity and bibliography JSON-LD suites against a + `testing`-environment build (which mounts bibliography test fixtures) + - Build-integrity tests (`test_hugo_build.py`) against the production + output - Uses the GitHub `upload-pages-artifact` action to package and store the `./public` directory contents for deployment **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. +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. ### Environment Variables -The following environment variables control the build and deployment process: +The following repository variables control the build and deployment process: | Variable | Description | Values | Default | |----------|-------------|--------|---------| -| `HUGO_ENVIRONMENT` | Specifies the build environment | `development`, `staging`, `production` | `staging` | +| `HUGO_ENVIRONMENT` | Build environment used by the production workflow | `development`, `staging`, `production` | `production` | | `HUGO_VERSION` | Hugo version used in CI/CD | Semantic version (e.g., `0.155.3`) | Set in workflow | +`HUGO_ENVIRONMENT` is resolved in `.github/workflows/gh-pages.yml` and passed +as the `hugo-environment` input to the shared build workflow. The staging +repository always builds with the `staging` environment. + **Environment-specific behavior:** | Environment | Analytics | Crawlers | Use Case | @@ -293,42 +300,35 @@ The following environment variables control the build and deployment process: | `staging` | Disabled | Blocked | PR previews and testing | | `development` | Disabled | N/A | Local development | -These variables are set in `.github/workflows/gh-pages.yml` and can be overridden via GitHub repository variables. - ### Deploying a Staging Site -To deploy a personal staging site for testing: - -**1. Initial Setup:** - -1. Fork/clone the Interlisp.github.io repository to your GitHub account -2. In your repository, go to **Settings → Pages** -3. Under **Build and deployment**, set Source to **Deploy from GitHub Actions** - -**2. Configure Your Fork:** - -Create a branch and make these required changes: - -1. Update `baseURL` in `config/staging/hugo.yaml` to match your repository: - -```yaml -baseURL: https://YOUR_USERNAME.github.io/YOUR_REPO_NAME/ - -languageCode: en-us -title: 'Staging Environment' -``` - -> **Important:** The `baseURL` must reflect the complete path of your repository. Incorrect URLs will cause deployment failures or broken links. - -**3. Deploy:** - -1. Commit and push your branch -2. Create a Pull Request to merge into your repository's main branch -3. Merge the PR — GitHub Actions will build and deploy your staging site - -**4. Develop Features:** - -Create feature branches for new work. Once tested on your staging site, create a PR to merge content into the main Interlisp repository. +Every pull request to `main` is automatically deployed to a per-PR staging +preview. A dedicated repository, `Interlisp/interlisp.staging`, acts as the +deployment target. Each PR is served from a unique subdirectory of that +repository's GitHub Pages site: + +| Deployment | URL | +|------------|-----| +| Staging root | `https://interlisp.github.io/interlisp.staging/` | +| PR #123 preview | `https://interlisp.github.io/interlisp.staging/pr-123/` | + +When a PR is opened or updated, the production workflow (`gh-pages.yml`) +triggers the `deploy-preview` workflow in the staging repository, which: + +1. Checks out the PR's head commit +2. Builds the site using the shared org-level workflow + (`Interlisp/.github/.github/workflows/build-site.yml`) +3. Deploys the result to the `pr-/` subdirectory +4. Posts the preview URL as a comment on the PR + +When a PR is closed or merged, `preview-cleanup.yml` triggers the +`remove-preview` workflow in the staging repository to delete the +subdirectory. + +Because the build logic lives in the org-level reusable workflow, production +and staging are always built the same way. The staging environment uses +`config/staging/hugo.yaml`, which sets a `baseURL` for the staging site and +disables production-only behavior such as search-engine crawling. --- From 54048ac62bc3e57dc13a49cf9add74985ad215f5 Mon Sep 17 00:00:00 2001 From: Bill Stumbo Date: Fri, 14 Aug 2026 07:38:37 -0400 Subject: [PATCH 5/6] Re-add per-PR staging preview phase and flip shared workflow pin to @main - gh-pages.yml: add preview job triggering deploy-preview.yml in Interlisp.staging for every PR (guarded to skip fork PRs and when STAGING_APP_ID is unset); pin build-site.yml@main - preview-cleanup.yml: on PR close, dispatch remove-preview.yml in Interlisp.staging to delete the /pr-/ subdirectory - .gitignore: ignore .coverage, tests/__pycache__/, and _vendor/ --- .github/workflows/gh-pages.yml | 44 +++++++++++++++++++++++-- .github/workflows/preview-cleanup.yml | 46 +++++++++++++++++++++++++++ .gitignore | 3 ++ 3 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/preview-cleanup.yml diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index c770224b..44444276 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -14,7 +14,10 @@ # org-level reusable workflow; also checks the Zotero # bibliography version (skipping the build on scheduled # runs when it is unchanged) -# (Interlisp/.github/.github/workflows/build-site.yml) +# (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 +# the STAGING_APP_ID secret is unset) # deploy - deploy the built site to GitHub Pages # # The workflow is executed either on a push or via scheduled run times. When @@ -119,12 +122,49 @@ jobs: build: needs: [validate-docs, hugo-version] if: always() && (needs.validate-docs.result == 'success' || needs.validate-docs.result == 'skipped') && (needs.hugo-version.result == 'success') - uses: Interlisp/.github/.github/workflows/build-site.yml@bs1_staging_prep + uses: Interlisp/shared-workflows/.github/workflows/build-site.yml@main with: hugo-version: ${{ needs.hugo-version.outputs.version }} hugo-environment: ${{ vars.HUGO_ENVIRONMENT || 'production' }} skip-if-fresh: ${{ github.event_name == 'schedule' }} + # ---------------------------------------------------------------------------- + # Trigger a per-PR staging preview in Interlisp/Interlisp.staging. Skips on + # fork pull requests and when the GitHub App credentials are not configured, + # so the workflow remains green during rollout. The Hugo version is passed + # as a dispatch input (a step can read the env context, unlike a reusable + # 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 && + secrets.STAGING_APP_ID != '' + runs-on: ubuntu-latest + needs: [build] + steps: + - name: Mint GitHub App token + id: app-token + uses: actions/create-github-app-token@v3 + with: + client-id: ${{ secrets.STAGING_APP_ID }} + private-key: ${{ secrets.STAGING_APP_PRIVATE_KEY }} + owner: Interlisp + repositories: | + Interlisp.staging + + - name: Trigger staging preview + uses: benc-uk/workflow-dispatch@v1 + with: + workflow: deploy-preview.yml + 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 }}" + }' + # ---------------------------------------------------------------------------- # Deploy the built site to GitHub Pages. # Only runs on push or scheduled runs, never on pull requests, and never diff --git a/.github/workflows/preview-cleanup.yml b/.github/workflows/preview-cleanup.yml new file mode 100644 index 00000000..529f23cc --- /dev/null +++ b/.github/workflows/preview-cleanup.yml @@ -0,0 +1,46 @@ +#******************************************************************************* +# preview-cleanup.yml +# +# GitHub Workflow that removes the staging preview for a pull request once +# the pull request is closed or merged. +# +# Triggers the remove-preview workflow in the Interlisp/Interlisp.staging +# repository, which deletes the pr-/ subdirectory from the staging +# Pages site. +# +# Copyright 2026 by Interlisp.org +# +# ****************************************************************************** +name: Preview Cleanup + +on: + pull_request: + branches: + - main + types: [closed] + +jobs: + remove-preview: + if: secrets.STAGING_APP_ID != '' + runs-on: ubuntu-latest + steps: + - name: Mint GitHub App token + id: app-token + uses: actions/create-github-app-token@v3 + with: + client-id: ${{ secrets.STAGING_APP_ID }} + private-key: ${{ secrets.STAGING_APP_PRIVATE_KEY }} + owner: Interlisp + repositories: | + Interlisp.staging + + - name: Trigger staging preview removal + uses: benc-uk/workflow-dispatch@v1 + with: + workflow: remove-preview.yml + repo: Interlisp/Interlisp.staging + ref: main + token: ${{ steps.app-token.outputs.token }} + inputs: '{ + "pr_number": "${{ github.event.pull_request.number }}" + }' diff --git a/.gitignore b/.gitignore index 2a1a5fd2..651b401b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,9 @@ tests/public_test/ node_modules/ _gen/ .hugo_build.lock +.coverage +tests/__pycache__/ +_vendor/ .idea data/bibliography.json static/data/bibliography.json From bcb22b0af9f0725f4d4e6b6c95d632c33a9ca44f Mon Sep 17 00:00:00 2001 From: Bill Stumbo Date: Sat, 15 Aug 2026 07:59:56 -0400 Subject: [PATCH 6/6] Updates to move staging site to Interlisp.staging Automates creation of staging site per PR allowing preview of changes. Upon merge or close of PR, staging site is torn down. --- .github/workflows/gh-pages.yml | 6 +++--- .github/workflows/preview-cleanup.yml | 4 ++-- README.md | 10 +++++----- config/staging/hugo.yaml | 2 +- tests/test_hugo_build.py | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 44444276..adcc23c7 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -17,7 +17,7 @@ # (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 -# the STAGING_APP_ID secret is unset) +# 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 @@ -138,7 +138,7 @@ jobs: preview: if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && - secrets.STAGING_APP_ID != '' + vars.STAGING_APP_ID != '' runs-on: ubuntu-latest needs: [build] steps: @@ -146,7 +146,7 @@ jobs: id: app-token uses: actions/create-github-app-token@v3 with: - client-id: ${{ secrets.STAGING_APP_ID }} + client-id: ${{ vars.STAGING_APP_ID }} private-key: ${{ secrets.STAGING_APP_PRIVATE_KEY }} owner: Interlisp repositories: | diff --git a/.github/workflows/preview-cleanup.yml b/.github/workflows/preview-cleanup.yml index 529f23cc..fac87f73 100644 --- a/.github/workflows/preview-cleanup.yml +++ b/.github/workflows/preview-cleanup.yml @@ -21,14 +21,14 @@ on: jobs: remove-preview: - if: secrets.STAGING_APP_ID != '' + if: vars.STAGING_APP_ID != '' runs-on: ubuntu-latest steps: - name: Mint GitHub App token id: app-token uses: actions/create-github-app-token@v3 with: - client-id: ${{ secrets.STAGING_APP_ID }} + client-id: ${{ vars.STAGING_APP_ID }} private-key: ${{ secrets.STAGING_APP_PRIVATE_KEY }} owner: Interlisp repositories: | diff --git a/README.md b/README.md index facadcba..24ef364a 100644 --- a/README.md +++ b/README.md @@ -260,7 +260,7 @@ requests. **3. `build` — Build the Website and Run the Tests** Delegates to the org-level reusable workflow -(`Interlisp/.github/.github/workflows/build-site.yml`), which: +(`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) @@ -303,21 +303,21 @@ repository always builds with the `staging` environment. ### Deploying a Staging Site Every pull request to `main` is automatically deployed to a per-PR staging -preview. A dedicated repository, `Interlisp/interlisp.staging`, acts as the +preview. A dedicated repository, `Interlisp/Interlisp.staging`, acts as the deployment target. Each PR is served from a unique subdirectory of that repository's GitHub Pages site: | Deployment | URL | |------------|-----| -| Staging root | `https://interlisp.github.io/interlisp.staging/` | -| PR #123 preview | `https://interlisp.github.io/interlisp.staging/pr-123/` | +| Staging root | `https://interlisp.github.io/Interlisp.staging/` | +| PR #123 preview | `https://interlisp.github.io/Interlisp.staging/pr-123/` | When a PR is opened or updated, the production workflow (`gh-pages.yml`) triggers the `deploy-preview` workflow in the staging repository, which: 1. Checks out the PR's head commit 2. Builds the site using the shared org-level workflow - (`Interlisp/.github/.github/workflows/build-site.yml`) + (`Interlisp/shared-workflows/.github/workflows/build-site.yml`) 3. Deploys the result to the `pr-/` subdirectory 4. Posts the preview URL as a comment on the PR diff --git a/config/staging/hugo.yaml b/config/staging/hugo.yaml index 904e9b61..d6576ecb 100644 --- a/config/staging/hugo.yaml +++ b/config/staging/hugo.yaml @@ -1,4 +1,4 @@ -baseURL: https://stumbo.github.io/InterlispDraft.github.io/ +baseURL: https://interlisp.github.io/Interlisp.staging/ languageCode: en-us diff --git a/tests/test_hugo_build.py b/tests/test_hugo_build.py index a69049cc..24596afc 100644 --- a/tests/test_hugo_build.py +++ b/tests/test_hugo_build.py @@ -36,8 +36,8 @@ def _get_baseurl_path() -> str: """Return the path component of the Hugo baseURL for the active environment. When ``baseURL`` contains a path prefix (e.g. - ``https://stumbo.github.io/InterlispDraft.github.io/``), Hugo prepends - that path (``/InterlispDraft.github.io``) to every site-root-relative + ``https://interlisp.github.io/interlisp-staging/``), Hugo prepends + that path (``/interlisp-staging``) to every site-root-relative ``href``. This helper extracts just the path component so link checks can strip it before resolving to the filesystem. """ @@ -174,7 +174,7 @@ def test_no_broken_internal_links(self) -> None: content = html_file.read_text(encoding="utf-8", errors="ignore") # Match href values that start with / (site-root-relative) for href in re.findall(r'href="(/[^"#?]*?)"', content): - # If baseURL has a path component (e.g., /InterlispDraft.github.io), + # If baseURL has a path component (e.g., /interlisp-staging), # Hugo prepends it to site-root-relative links. Strip it before # resolving to the filesystem. resolved = href