Skip to content

ci: auto-sync docs/vX.Y branch when a release tag is pushed#510

Closed
marc0olo wants to merge 3 commits intomainfrom
marco.walz/sync-docs-branch-automation
Closed

ci: auto-sync docs/vX.Y branch when a release tag is pushed#510
marc0olo wants to merge 3 commits intomainfrom
marco.walz/sync-docs-branch-automation

Conversation

@marc0olo
Copy link
Copy Markdown
Member

@marc0olo marc0olo commented Apr 17, 2026

Summary

Adds automation to keep `docs/vX.Y` branches in sync with release tags, and prevents a redundant docs re-deployment after the sync.

Files changed:

  • `.github/workflows/sync-docs-branch.yml` — new workflow that force-resets `docs/vX.Y` on every release tag
  • `.github/workflows/docs.yml` — skips `publish-versioned-docs` when `github-actions[bot]` pushes (avoids redundant re-deploy)
  • `.claude/skills/release/task6-docs.md` — updated release playbook to document the automation

The problem

Both `v*` tags and `docs/v*` branches trigger the same `publish-versioned-docs` job and deploy to the same `/X.Y/` folder on the live site. Without sync automation, `docs/vX.Y` silently drifts behind the tag — and any future push to it (e.g. a docs hotfix) would overwrite the live docs with older content. This happened: `docs/v0.2` was sitting at its March 30 state while the live `/0.2/` docs were correctly deployed from the April 8 `v0.2.3` tag.

How it works

sync-docs-branch.yml

Triggers on every `v*` release tag push (pre-release tags excluded via `!v*-*`).

Tag v0.2.3 pushed
  └─ Extract minor version: 0.2 → DOCS_BRANCH=docs/v0.2
  └─ docs/v0.2 exists remotely?
       YES → git checkout -b docs/v0.2 v0.2.3 && git push --force
       NO  → git checkout -b docs/v0.2 v0.2.3 && git push

The force-push is an atomic reset — no merge commits, no conflict resolution, no manual steps. The branch ends up pointing exactly at the tag commit.

Skip guard in docs.yml

The force-push to `docs/vX.Y` triggers `docs.yml` again (because docs files changed). Without a guard, `publish-versioned-docs` would re-deploy content that is identical to what was just deployed from the tag — wasting CI minutes.

The added condition:

if: github.event_name == 'push' && github.actor != 'github-actions[bot]' && (...)

skips `publish-versioned-docs` only when `github-actions[bot]` pushes to `docs/v*`. It does not affect:

  • Tag pushes (always done by humans or release tooling, not the bot)
  • Human pushes to `docs/v*` (docs hotfixes still deploy normally)
  • `workflow_dispatch` (condition requires `event_name == 'push'`)

Sequence for a release tag push

v0.2.3 tag pushed
  ├─ docs.yml triggered (actor: human)
  │    └─ publish-versioned-docs: RUNS → deploys /0.2/ from v0.2.3 ✓
  │
  └─ sync-docs-branch.yml triggered
       └─ force-pushes docs/v0.2 to v0.2.3 state
            └─ docs.yml triggered again (actor: github-actions[bot])
                 └─ publish-versioned-docs: SKIPPED (actor guard) ✓

⚠️ Required: branch protection configuration

This workflow will fail until configured:

GitHub → Settings → Branches → protection rule for `docs/v*`:

Allow force pushes → Specify who can force push → add `github-actions[bot]`

Without this, the `git push --force` step exits with "Cannot force-push to this branch".

Behavior table

Scenario Result
First release of a new minor (e.g. `v0.3.0`, no `docs/v0.3` yet) Branch created from tag (normal push)
Patch release (`v0.2.4`, `docs/v0.2` exists) Branch force-reset to tag
Docs-only improvements on `main` to backport Cherry-pick manually onto `docs/vX.Y` after the reset
Human pushes a docs hotfix to `docs/v0.2` `publish-versioned-docs` runs normally (actor check doesn't apply)

Test plan

  • Configure branch protection bypass for `github-actions[bot]` on `docs/v*`
  • On next release tag push, verify `sync-docs-branch.yml` runs and force-resets `docs/vX.Y`
  • Verify the second `docs.yml` run (triggered by the bot's push) skips `publish-versioned-docs`
  • Push a manual docs hotfix to `docs/vX.Y` and verify `publish-versioned-docs` still runs normally

Adds sync-docs-branch.yml workflow that opens a PR to reset docs/vX.Y
to the new tag whenever a v* release is tagged. Prevents the branch from
drifting behind the latest patch and avoids silently overwriting live
docs if someone pushes a hotfix to a stale branch.

Updates the release playbook (task6-docs.md) to document the new
automated PR and when to merge it.
@marc0olo marc0olo requested a review from a team as a code owner April 17, 2026 20:25
@marc0olo
Copy link
Copy Markdown
Member Author

Closing in favor of a cleaner approach: replacing docs/v* branches with docs/v* tags. Branches can drift silently; tags are immutable by convention and moving one requires explicit intent — eliminating the whole drift problem without needing sync automation or branch protection bypass config. A new PR will implement Option B (tag-based deployment).

@marc0olo marc0olo closed this Apr 17, 2026
@marc0olo marc0olo deleted the marco.walz/sync-docs-branch-automation branch April 17, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant