ci(website): allow explicitly requested Pages-only publication (#1205)

ci(website): allow explicitly requested Pages-only publication
This commit is contained in:
Ysopwnable
2026-10-09 13:00:26 +08:00
committed by GitHub
4 changed files with 57 additions and 13 deletions
+34 -4
View File
@@ -2,6 +2,15 @@ name: Publish REA website
on:
workflow_dispatch:
inputs:
target:
description: Publish both hosts, or Pages while configuring Cloudflare
type: choice
required: true
default: both
options:
- both
- pages
permissions:
contents: read
@@ -19,7 +28,16 @@ jobs:
contents: read
pages: read
steps:
- name: Validate the publication target
env:
PUBLISH_TARGET: ${{ inputs.target }}
run: |
case "$PUBLISH_TARGET" in
both|pages) ;;
*) echo "::error::Unknown publication target: $PUBLISH_TARGET"; exit 1 ;;
esac
- name: Require Cloudflare publishing credentials
if: inputs.target == 'both'
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
@@ -67,21 +85,26 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Check out publishing configuration
if: inputs.target == 'both'
uses: actions/checkout@v4
- name: Set up Node.js for Wrangler
if: inputs.target == 'both'
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
- name: Download the verified website
if: inputs.target == 'both'
uses: actions/download-artifact@v4
with:
name: github-pages
path: ${{ runner.temp }}/website-archive
- name: Extract the shared publishing artifact
if: inputs.target == 'both'
run: |
mkdir -p "$RUNNER_TEMP/rea-website-public"
tar -xf "$RUNNER_TEMP/website-archive/artifact.tar" -C "$RUNNER_TEMP/rea-website-public"
- name: Publish the website to Cloudflare
if: inputs.target == 'both'
uses: cloudflare/wrangler-action@v4
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
@@ -92,9 +115,10 @@ jobs:
- name: Publish to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
- name: Verify both published revisions
- name: Verify the selected published revisions
env:
PAGES_URL: ${{ steps.deployment.outputs.page_url }}
PUBLISH_TARGET: ${{ inputs.target }}
run: |
python3 - <<'PY'
import json
@@ -109,7 +133,13 @@ jobs:
pages_url = os.environ["PAGES_URL"]
if not pages_url:
sys.exit("GitHub Pages returned no published URL.")
pending = {"Cloudflare": "https://rea.tools/", "GitHub Pages": pages_url}
target = os.environ["PUBLISH_TARGET"]
if target not in ("both", "pages"):
sys.exit("Unknown publication target: " + target)
hosts = {"GitHub Pages": pages_url}
if target == "both":
hosts["Cloudflare"] = "https://rea.tools/"
pending = dict(hosts)
for attempt in range(24):
for name, base in list(pending.items()):
url = urljoin(base, "deployment.json") + "?commit=" + expected
@@ -131,6 +161,6 @@ jobs:
if pending:
sys.exit("Published revision did not match on: " + ", ".join(pending))
with open(os.environ["GITHUB_STEP_SUMMARY"], "a", encoding="utf-8") as summary:
summary.write(f"Published commit `{expected}` to [rea.tools](https://rea.tools/) "
f"and [GitHub Pages]({pages_url}).\n")
links = " and ".join(f"[{name}]({url})" for name, url in hosts.items())
summary.write(f"Published commit `{expected}` to {links}.\n")
PY
+4 -2
View File
@@ -20,5 +20,7 @@ for asset notes and the source of case-study claims.
copying and downloads. Run `scripts/prepare-website.py` followed by
`scripts/verify-website.py`.
- Keep `website-pages.yml` as the sole, manual production publisher for
Cloudflare and Pages. Both hosts must receive the same verified artifact and
pass the published-commit check. Follow the website README.
Cloudflare and Pages. Default to `both`: both hosts receive the same verified
artifact and pass the published-commit check. Use `pages` only when explicitly
requested while Cloudflare credentials are being configured. Follow the
website README.
+15 -5
View File
@@ -261,14 +261,14 @@ Configure these repository **Actions secrets** before publishing:
- `CLOUDFLARE_ACCOUNT_ID`: that Cloudflare account's ID.
See Cloudflare's [GitHub Actions authentication instructions](https://developers.cloudflare.com/workers/ci-cd/external-cicd/github-actions/).
The workflow checks that both secrets are present before preparing a release.
Cloudflare deploys first; GitHub Pages deploys after that step succeeds.
The default `both` target checks that both secrets are present before preparing
a release. Cloudflare deploys first; GitHub Pages deploys after that step succeeds.
Preparation adds `deployment.json` with the workflow's commit SHA. Cloudflare
receives the extracted Pages artifact through Wrangler's explicit assets path;
the local custom-build output is not the uploaded directory. The workflow then
checks both public version markers and reports success only when they match
that commit. A failed publication remains failed; fix its cause and rerun the
checks the selected public version markers and reports success only when they
match that commit. A failed publication remains failed; fix its cause and rerun the
workflow to complete both deployments. The two hosts can update at different
times while a run is in progress.
@@ -294,12 +294,22 @@ website** from the Actions tab on `main`. This publishes both production hosts.
The workflow uses the `github-pages` environment, the official Pages actions and
Cloudflare's Wrangler action.
The equivalent CLI command is:
The equivalent CLI command publishes both hosts:
```sh
gh workflow run website-pages.yml --repo morluto/rea --ref main
```
While Cloudflare credentials are being configured, an explicitly requested
Pages-only publication uses the same workflow with `target=pages`:
```sh
gh workflow run website-pages.yml --repo morluto/rea --ref main -f target=pages
```
This mode verifies the Pages commit marker. The default remains `both` for
synchronized production releases.
Local development does not change Pages settings or run the deployment workflow.
Any environment protection rules are configured separately when publication is
approved.
+4 -2
View File
@@ -233,8 +233,10 @@ New analysis or behavior claims need the real evidence that supports them; a moc
or a page-loading check cannot establish those claims.
Follow the PR review and CI process, then publish using the existing manual
`website-pages.yml` workflow on `main`. It publishes the same verified artifact
to Cloudflare and GitHub Pages and checks both published commit markers.
`website-pages.yml` workflow on `main`. Its default `both` target publishes the
same verified artifact to Cloudflare and GitHub Pages and checks both published
commit markers. Use `pages` only for an explicitly requested publication while
Cloudflare credentials are being configured.
Ordinary commits should not publish the site. After deployment, check both live
pages and confirm they match the reviewed version. The legacy VitePress build
remains separate from the Pages publisher.