mirror of
https://github.com/paperclipai/paperclip-docs.git
synced 2026-11-07 06:16:07 -10:00
ci: tag docs releases automatically on merge to main (#133)
Tags every docs release automatically, so the `docs/vX.Y.Z` tag stops depending on someone remembering to create it after the merge. So far, 11 of 16 releases were never tagged. ## What changes - **New workflow, `.github/workflows/tag-docs-release.yml`.** It runs on every push to `main`. For each new commit titled `Release docs for paperclip vYYYY.MDD.P`, it tags that commit `docs/vYYYY.MDD.P`. - Anything after a space in the title, such as `(#132)`, is ignored. - Pre-release versions like `-beta.1` are skipped. - Tags that already exist are left alone. - **`skills/sync-docs/SKILL.md` (Phase 9) and `maintenance/runbook.md`.** The after-merge step now checks that the tag exists instead of creating it by hand. It also tells you to keep the release PR title format, because the workflow reads the version from it. ## Tested I ran the version matching against all 16 release squash-commit titles on `main` and it matched every one, including `(content + screenshot overhaul) (#95)` and titles with no PR number. It rejects `-beta.1`. The workflow itself hasn't run on GitHub yet; the next release merge will be its first run. ## Needs The workflow needs permission to push tags: `permissions: contents: write`. If the repo's Actions permissions are read-only and that can't be changed per workflow, the first run will fail with a clear error. Fix it in Settings → Actions → Workflow permissions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
a3368fb06b
commit
478d24ce5d
3 files changed
+64
-7
No files matched your search
@@ -0,0 +1,50 @@
|
||||
name: Tag docs release
|
||||
|
||||
# Tags every release squash commit on `main` as `docs/vYYYY.MDD.P`.
|
||||
#
|
||||
# The tag used to be a manual post-merge step, and 11 of the first 16 releases
|
||||
# never got one. Release PRs are always titled
|
||||
# `Release docs for paperclip vYYYY.MDD.P`, and a squash merge keeps that title
|
||||
# as the commit subject, so the version can be read straight from the commit.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
tag:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Tag release commits
|
||||
env:
|
||||
BEFORE: ${{ github.event.before }}
|
||||
AFTER: ${{ github.sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# A branch-creating push has an all-zero `before`; look at the tip only.
|
||||
if [ -z "${BEFORE//0/}" ] || ! git cat-file -e "$BEFORE^{commit}" 2>/dev/null; then
|
||||
range="$AFTER -1"
|
||||
else
|
||||
range="$BEFORE..$AFTER"
|
||||
fi
|
||||
|
||||
git log --format='%H %s' $range | while read -r sha subject; do
|
||||
version=$(printf '%s\n' "$subject" \
|
||||
| sed -nE 's/^Release docs for paperclip (v[0-9]{4}\.[0-9]{1,4}\.[0-9]+)( .*)?$/\1/p')
|
||||
[ -n "$version" ] || continue
|
||||
tag="docs/$version"
|
||||
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null; then
|
||||
echo "$tag already exists at $(git rev-parse --short "$tag^{commit}") — leaving it."
|
||||
continue
|
||||
fi
|
||||
git tag "$tag" "$sha"
|
||||
git push origin "refs/tags/$tag"
|
||||
echo "Tagged $tag at ${sha:0:7}."
|
||||
done
|
||||
@@ -126,12 +126,12 @@ When a new parent release tag drops (`v2026.X.Y`):
|
||||
- Frontmatter `paperclip_version` correctly stamped on changed pages.
|
||||
4. Merge to `main` when satisfied.
|
||||
5. **After merge — four follow-ups:**
|
||||
- Tag the merge commit:
|
||||
- Confirm the merge commit was tagged. The `Tag docs release` workflow does this automatically on the push to `main`, reading the version from the squash commit's subject — so keep the PR title `Release docs for paperclip v2026.X.Y`:
|
||||
```sh
|
||||
git checkout main && git pull
|
||||
git tag docs/v2026.X.Y
|
||||
git push --tags
|
||||
git checkout main && git pull --tags
|
||||
git rev-parse --short docs/v2026.X.Y # should print the squash commit
|
||||
```
|
||||
If it's missing, check the workflow run, then tag by hand: `git tag docs/v2026.X.Y <squash-sha> && git push origin docs/v2026.X.Y`.
|
||||
- Verify `.sync-state.json` on `main` now shows `base_release_tag: v2026.X.Y` and `base_release_sha` matches.
|
||||
- **Confirm the site actually rebuilt — don't assume.** Cloudflare Pages is supposed to auto-deploy on push to `main`, but that hook has silently no-opped (v2026.824.0 merged with a correct changelog entry and production served the previous build for hours). Check the live site, not the Pages dashboard:
|
||||
|
||||
|
||||
@@ -457,11 +457,18 @@ Skip in nightly mode (Cloudflare branch previews are best-effort, not reader-fac
|
||||
skipped at least once; none are optional.
|
||||
|
||||
```sh
|
||||
git checkout main && git pull
|
||||
git tag docs/v2026.X.Y && git push --tags
|
||||
git checkout main && git pull --tags
|
||||
git rev-parse --short docs/v2026.X.Y # must print the release squash commit
|
||||
node scripts/sync/realign-nightly.mjs release/v2026.X.Y --push # see Phase 7
|
||||
```
|
||||
|
||||
The `docs/v2026.X.Y` tag is created by `.github/workflows/tag-docs-release.yml`
|
||||
on the push to `main`. It reads the version from the squash commit's subject,
|
||||
so the release PR **must** keep the title `Release docs for paperclip vYYYY.MDD.P`
|
||||
(anything after a space, like `(#132)`, is fine). If the tag is missing a minute
|
||||
after the merge, check that workflow's run and tag by hand:
|
||||
`git tag docs/v2026.X.Y <squash-sha> && git push origin docs/v2026.X.Y`.
|
||||
|
||||
Then flip `nightly`'s `.sync-state.json` back to `"branch_mode": "nightly"` and
|
||||
commit it. The merge-down inherits `"release"` from `main` and nothing else
|
||||
corrects it, so the next nightly run starts from a state file that lies about
|
||||
@@ -497,7 +504,7 @@ Skip in nightly mode (Cloudflare branch previews are best-effort, not reader-fac
|
||||
4. **Show the evidence in the run summary** — the URLs you checked, the status
|
||||
codes, and the changelog version you read back. "Merged" is not evidence.
|
||||
|
||||
> The "never push without asking" rule still holds here. Steps 1 and 3 push tags
|
||||
> The "never push without asking" rule still holds here. Steps 1 and 3 push the nightly realign
|
||||
> and publish to production — ask before each, and if the answer is no, hand off
|
||||
> with the exact commands so the human can run them. What is **not** optional is
|
||||
> step 2: always check the live site and always report what you found, even when
|
||||
|
||||
Reference in new issue
Block a user