Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,24 @@ jobs:
- name: Run hooks on all files
run: npx prek run --all-files --show-diff-on-failure

# Workflow EXPRESSIONS are validated only by GitHub, and a bad one rejects the
# whole workflow before any job starts — no logs, no annotations, no failing step.
# That is how `|| "manual dispatch"` (expressions take single-quoted literals only)
# took the site's deploy down after it had passed YAML parsing, `bash -n`, and the
# workflow harness. actionlint catches exactly that class.
#
# Two errors are suppressed: actionlint's `job` context schema is stale and does not
# know `job.workflow_repository` / `job.workflow_sha`, both of which are real and
# documented, and which publish-gh-pages.yml depends on to version-match assemble.mjs.
- name: Lint workflow files
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
ver=$(gh api repos/rhysd/actionlint/releases/latest --jq .tag_name | tr -d v)
gh release download "v$ver" --repo rhysd/actionlint \
-p "actionlint_${ver}_linux_amd64.tar.gz" -O "$RUNNER_TEMP/al.tgz"
tar xzf "$RUNNER_TEMP/al.tgz" --no-same-owner -C "$RUNNER_TEMP" actionlint
"$RUNNER_TEMP/actionlint" -color \
-ignore 'property "workflow_(repository|sha)" is not defined'

26 changes: 20 additions & 6 deletions .github/workflows/publish-gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,27 @@ jobs:

# BUILT_BRANCH vs github.ref is the one thing a post-mortem here always trips over,
# so state both up front rather than leaving someone to infer it from a cache miss.
#
# Every context value comes through `env:`, never interpolated into the script.
# That keeps arbitrary values out of the shell, and it avoids nesting quotes: an
# expression's string literals must be SINGLE-quoted, which cannot be written
# inside a single-quoted shell word.
- name: Create staging dirs
env:
EVENT: ${{ github.event_name }}
GH_REF: ${{ github.ref }}
GH_SHA: ${{ github.sha }}
TRIGGER_URL: ${{ github.event.workflow_run.html_url }}
run: |
set -euo pipefail
mkdir -p "$RUNNER_TEMP/site" "$RUNNER_TEMP/gather"
printf '%-16s %s\n' \
'event' '${{ github.event_name }}' \
'event' "$EVENT" \
'built branch' "$BUILT_BRANCH" \
'default' "$DEFAULT" \
'github.ref' '${{ github.ref }} (always the default branch under workflow_run)' \
'github.sha' '${{ github.sha }} (→ pages_build_version)' \
'triggered by' '${{ github.event.workflow_run.html_url || "manual dispatch" }}'
'github.ref' "$GH_REF (always the default branch under workflow_run)" \
'github.sha' "$GH_SHA (→ pages_build_version)" \
'triggered by' "${TRIGGER_URL:-manual dispatch}"

# The live Pages base URL, from the Pages API — respects a custom domain
# (CNAME); falls back to the conventional github.io URL if the API call
Expand Down Expand Up @@ -252,7 +262,7 @@ jobs:
while IFS=$'\t' read -r tag dest created size assetid decision; do
[ "$dest" = "-" ] && continue
if [ -f "$failed/$assetid" ]; then
echo "::warning::release $tag: docs.zip download failed — skipping. $(cat "$failed/$assetid.err" 2>/dev/null | head -1)"
echo "::warning::release $tag: docs.zip download failed — skipping. $(head -1 "$failed/$assetid.err" 2>/dev/null)"
elif [ -s "$relcache/$assetid.zip" ]; then
cp "$relcache/$assetid.zip" "$RUNNER_TEMP/gather/$dest.zip"
else
Expand Down Expand Up @@ -523,7 +533,11 @@ jobs:
set -euo pipefail
stable_src=$(node "$GITHUB_WORKSPACE/.mvs/assemble/assemble.mjs" generate \
--site-dir "$RUNNER_TEMP/site" --base-url "$PAGES_URL" --required "$DEFAULT")
[ -n "$stable_src" ] && ln -s "$stable_src" "$RUNNER_TEMP/site/stable" || true
# An `&& ln … || true` one-liner here would also swallow a FAILED symlink, not
# just the empty-stable_src case — and a missing stable/ alias is silent damage.
if [ -n "$stable_src" ]; then
ln -s "$stable_src" "$RUNNER_TEMP/site/stable"
fi

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v5
Expand Down
5 changes: 3 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ consumer's repo stays checked out at the root so `assemble.mjs`'s `git tag` list
so a composite action could only be pinned to a literal tag — the `job` context is
the only way to self-reference at the running ref.) Note: actionlint's `job`-context
schema is stale and false-flags `job.workflow_sha`/`job.workflow_repository`; the
GitHub docs confirm both. This repo lints with biome, not actionlint.
GitHub docs confirm both, so `_lint.yml` runs actionlint with exactly those two
suppressed (`-ignore 'property "workflow_(repository|sha)" is not defined'`).

### BASE_URL must be set before `myst build`
```yaml
Expand Down Expand Up @@ -256,7 +257,7 @@ PRs always, fork PRs only when the SHA carries that status.

```bash
npm test # run the unit tests
npm run test:workflows # run publish.yml's gather steps against a mock gh (needs uv)
npm run test:workflows # gather steps against a mock gh + workflow shape asserts (needs uv)
npm run docs # build docs (same command CI uses)
npm run docs-dev # live-preview docs with the plugin loaded from local plugins/
```
Expand Down