From da56d969e93e8e98fdf6d0e5b661c2fb9455f27b Mon Sep 17 00:00:00 2001 From: Denis Anikiev Date: Mon, 12 Oct 2026 22:40:06 +0300 Subject: [PATCH] fix: update workflows to enhance documentation deployment and version checking --- .github/workflows/docs.yml | 42 ++++++++++++++++++++++++++------- .github/workflows/push-tag.yml | 22 ++++++++++------- CHANGELOG.md | 6 ++--- RELEASE.md | 43 ++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 20 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 056a9d0..2b0362b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -3,15 +3,10 @@ name: Docs on: push: branches: ["main", "dev"] - workflow_call: - inputs: - ref: - required: false - type: string workflow_dispatch: inputs: ref: - description: "Optional branch, tag, or SHA to build" + description: "Optional branch, tag, or SHA to build, such as refs/tags/vX.Y.Z. Runs on main deploy it" required: false type: string @@ -23,6 +18,8 @@ permissions: jobs: build-docs: runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.version }} # A newer push to the same branch supersedes a build that is still running. Builds of # different refs never cancel each other, so a dev push cannot cancel a main or tag build concurrency: @@ -33,8 +30,8 @@ jobs: - name: Checkout uses: actions/checkout@v6 with: - # Only override the ref when one is supplied by workflow_call or - # workflow_dispatch; leaving it empty lets actions/checkout resolve the event. + # Only override the ref when one is supplied by workflow_dispatch; leaving it + # empty lets actions/checkout resolve the event. ref: ${{ inputs.ref }} fetch-depth: 0 fetch-tags: true @@ -66,6 +63,10 @@ jobs: python -m pip install --upgrade pip pip install -e .[docs] + - name: Record docs version + id: version + run: echo "version=$(python -c "from importlib.metadata import version; print(version('pynetdesign'))")" >> "$GITHUB_OUTPUT" + - name: Verify release version if: >- startsWith(github.ref, 'refs/tags/v') || @@ -105,7 +106,10 @@ jobs: path: docs/build/html deploy-pages: - if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') + # Only runs on main deploy. GitHub Pages ignores a deployment made from a tag when main + # has already deployed the same commit (actions/deploy-pages#383), so push-tag.yml + # starts a run on main to publish a release + if: github.ref == 'refs/heads/main' needs: build-docs runs-on: ubuntu-latest # Deployments run one at a time, and one that has started always completes @@ -120,3 +124,23 @@ jobs: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v5 + + - name: Check the deployed version + shell: bash + env: + PAGE_URL: ${{ steps.deployment.outputs.page_url }} + EXPECTED: ${{ needs.build-docs.outputs.version }} + run: | + # Pages can report success and keep serving the previous upload, so read the version + # back from the live site. A new query string on each request bypasses the CDN cache + url="${PAGE_URL%/}/_static/documentation_options.js" + for attempt in $(seq 1 10); do + live="$(curl -fsS "$url?check=$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT-$attempt" || true)" + if [[ "$live" == *"VERSION: '$EXPECTED'"* ]]; then + echo "The live docs show version $EXPECTED" + exit 0 + fi + sleep 30 + done + echo "::error::The live docs do not show version $EXPECTED. See 'Deploying the docs manually' in RELEASE.md" + exit 1 diff --git a/.github/workflows/push-tag.yml b/.github/workflows/push-tag.yml index 9e2f61c..81bcaec 100644 --- a/.github/workflows/push-tag.yml +++ b/.github/workflows/push-tag.yml @@ -7,8 +7,6 @@ on: permissions: contents: read - pages: write - id-token: write jobs: validate-tag: @@ -18,12 +16,20 @@ jobs: permissions: contents: read + # GitHub Pages ignores a deployment made from a tag when main has already deployed the same + # commit (actions/deploy-pages#383), and main deploys each merge before it is tagged. A Docs + # run on main therefore builds the tag and deploys it docs: needs: validate-tag - uses: ./.github/workflows/docs.yml - with: - ref: ${{ needs.validate-tag.outputs.ref }} + runs-on: ubuntu-latest permissions: - contents: read - pages: write - id-token: write + actions: write + steps: + - name: Start the Docs workflow on main for the tag + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + TAG_REF: ${{ needs.validate-tag.outputs.ref }} + run: | + gh workflow run docs.yml --ref main -f ref="$TAG_REF" + echo "Started a Docs run on main for $TAG_REF: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/workflows/docs.yml" >> "$GITHUB_STEP_SUMMARY" diff --git a/CHANGELOG.md b/CHANGELOG.md index 47148e4..abf5abc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to PyNetDesign will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [v1.1.0] - 2026-10-05 +## [v1.1.0] - 2026-10-12 Feature release: phase-resolved wave modes, per-receiver free surface and receiver projection, synthetic geometry builders, a documentation site in HTML and PDF, and @@ -31,8 +31,8 @@ branding. - `methodology.rst` documenting the theory actually implemented: spectral conventions, the attenuation operator, the peak frequency, the detection threshold and its conversion coefficients, the free surface correction, receiver projection and DAS directionality, the radiation pattern with the full root-mean-square derivation, the homogeneous seismic moment relation with a standalone derivation from the far-field point source, and the network detectability criterion - `docs/source/references.bib` with the seven works cited from the docstrings and the methodology, so the `:cite:` roles added earlier now resolve - `citing`, `contributing` and `credits` documentation pages, plus a changelog page that is generated from `CHANGELOG.md` when the documentation is built, so the changelog has a single source and the generated page is not committed. On that page each version links to its changes on GitHub. These pages follow the main chapters in the order Citing, Contributing, Changelog, Credits -- `docs.yml` workflow building the documentation on every push and deploying it to GitHub Pages from `main` and from release tags, including a check that the built version matches the tag -- `push-tag.yml` workflow, so that pushing a `vX.Y.Z` tag validates it and publishes versioned documentation +- `docs.yml` workflow building the documentation on every push and deploying it to GitHub Pages from `main`, including a check that the built version matches the tag and, after each deployment, a check that the live site shows the deployed version +- `push-tag.yml` workflow, so that pushing a `vX.Y.Z` tag validates it and starts a `docs.yml` run on `main` that publishes the documentation of that tag. The run is on `main` because GitHub Pages ignores a deployment made from a tag when `main` has already deployed the same commit ([actions/deploy-pages#383](https://github.com/actions/deploy-pages/issues/383)) - `build-docs.bat` and `build-docs.sh` for building the documentation, and `serve-docs.bat` and `serve-docs.sh` for viewing it locally. `serve-docs` rebuilds incrementally before serving, so only the pages that changed are regenerated, and accepts `--port` and `--no-build`. Both accept `SPHINXOPTS`, and neither needs `make`: they call `python -m sphinx -M` directly. Both also take `--pdf`, which builds the PDF edition and places it where the documentation links to it - a PDF edition of the documentation, produced from the same sources through lualatex and linked from the site header and the front page, so the whole manual can be read offline as one file. Each web page keeps its own reference list, while the PDF lists the cited works once, in a bibliography at its end that its citations link to. `docs.yml` builds it on every run, publishes it with the site and keeps a copy as a workflow artifact - `install.sh` and `uninstall.sh`, the Linux and macOS counterparts of the existing Windows scripts. `install.sh` takes `--dev` or `--no-dev` to answer the development-tools question in advance, and `uninstall.sh` takes `--yes` diff --git a/RELEASE.md b/RELEASE.md index d0cac1d..959ff7c 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -31,6 +31,9 @@ version such as `1.0.1.dev3+g1a2b3c4`. git push origin vX.Y.Z ``` + Pushing the tag also publishes the documentation of the release; see + [Documentation](#documentation). + 6. Verify the version resolves correctly before publishing: ```bash @@ -51,6 +54,8 @@ version such as `1.0.1.dev3+g1a2b3c4`. | `validate-zenodo.yml` | push / PR on `main`, `dev`; reusable | Validates `.zenodo.json` against the Zenodo schema | | `validate-tag.yml` | reusable only | Enforces strict semver and that the tag is contained in `main` | | `release-on-published.yml` | GitHub Release `published` | Validates the tag, validates the Zenodo metadata, then builds and checks the distributions | +| `docs.yml` | push on `main`, `dev`; `workflow_dispatch` | Builds the HTML and PDF documentation; runs on `main` deploy it to GitHub Pages and check the version the live site serves | +| `push-tag.yml` | push of a `v*` tag | Validates the tag, then starts a `docs.yml` run on `main` that builds and deploys the documentation of the tag | `release-on-published.yml` also accepts a `workflow_dispatch` with a `tag` input, so a release can be re-validated without republishing it. @@ -62,6 +67,44 @@ Notes: workflow that acts on a tag. - PyNetDesign is not published to PyPI. Installation is from source; see `README.md`. +## Documentation + +The documentation is published to GitHub Pages at . +Only `docs.yml` runs on `main` deploy it: a push to `main` publishes a development version, +and pushing a release tag starts a run on `main` that builds the tag and publishes it. Every +deployment ends by reading the version back from the live site, and fails if it differs. + +A release is deployed by a run on `main`, not by a run on the tag, because GitHub Pages +ignores a deployment made from a tag when `main` has already deployed the same commit, and +still reports it as successful +([actions/deploy-pages#383](https://github.com/actions/deploy-pages/issues/383)). The +release tag always sits on a merge commit that `main` deployed when it was merged. + +### Deploying the docs manually + +Use this when the live site shows the wrong version, for example when the +`Check the deployed version` step of a `Docs` run failed, or to republish a release: + +1. On GitHub, open **Actions → Docs → Run workflow**. +2. Keep **Use workflow from** at `main`. Runs on any other branch or on a tag build the + documentation but do not deploy it. +3. Set **ref** to the release tag, for example `refs/tags/v1.1.0`, or leave it empty to + publish the current `main`. +4. Click **Run workflow**. The run builds the documentation from **ref**, checks that the + documentation of a tag carries its version, deploys it and checks the live site. + +The same from a terminal, with the GitHub CLI: + +```bash +gh workflow run docs.yml --ref main -f ref=refs/tags/v1.1.0 +``` + +To see which version the live site serves (the query string bypasses the CDN cache): + +```bash +curl -s "https://danikiev.github.io/PyNetDesign/_static/documentation_options.js?$(date +%s)" | grep VERSION +``` + ## Zenodo The repository is archived on Zenodo through the GitHub integration.