Skip to content

Commit 0e2cb7a

Browse files
authored
Merge pull request #3081 from superdoc-dev/caio/promote-stable-docs-dispatch-stable
feat(ci): add workflow_dispatch to promote-stable-docs (cherry-pick to stable)
2 parents 0caff9c + 4e0e649 commit 0e2cb7a

2 files changed

Lines changed: 69 additions & 16 deletions

File tree

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
# Advances docs-stable when SuperDoc itself ships a stable release.
1+
# Advances docs-stable to the current stable HEAD (or a chosen SHA).
22
#
3-
# Scope is intentionally narrow: only release-superdoc.yml. The CLI/SDK/MCP
4-
# bundle and the React/esign/template-builder/vscode-ext wrappers do not
5-
# advance docs-stable, even when they release successfully — docs-stable
6-
# represents the documentation for the stable SuperDoc release, not every
7-
# stable package release.
3+
# Auto path (workflow_run): only release-superdoc.yml triggers a promotion,
4+
# and only when a real v* tag actually appeared on stable. The CLI/SDK/MCP
5+
# tooling bundle and the React/esign/template-builder/vscode-ext wrappers do
6+
# not advance docs-stable - docs-stable represents the documentation for
7+
# the stable SuperDoc release.
88
#
9-
# A successful release-superdoc.yml run is not enough on its own: the run
10-
# could have been a semantic-release no-op (no qualifying commits). Check
11-
# that a v* tag actually appeared between the run's head_sha and
12-
# origin/stable before pushing.
9+
# Manual path (workflow_dispatch): for cases the auto path cannot cover,
10+
# e.g. the first stable bundle run that ships CLI/SDK/MCP without a SuperDoc
11+
# release, or a docs-only refresh between SuperDoc versions. Defaults to
12+
# pushing the current origin/stable head; an optional `sha` input promotes
13+
# a specific commit instead.
1314
name: 🚀 Promote stable docs
1415

1516
on:
@@ -18,6 +19,12 @@ on:
1819
- "📦 Release superdoc"
1920
types:
2021
- completed
22+
workflow_dispatch:
23+
inputs:
24+
sha:
25+
description: 'Commit SHA to promote to docs-stable. Leave empty to promote the current origin/stable head.'
26+
required: false
27+
type: string
2128

2229
permissions:
2330
contents: write
@@ -28,7 +35,9 @@ concurrency:
2835

2936
jobs:
3037
promote:
31-
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'stable'
38+
if: |
39+
github.event_name == 'workflow_dispatch' ||
40+
(github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'stable')
3241
runs-on: ubuntu-24.04
3342
steps:
3443
- name: Generate token
@@ -43,17 +52,18 @@ jobs:
4352
fetch-depth: 0
4453
token: ${{ steps.generate_token.outputs.token }}
4554

55+
# Auto path: gate on a real SuperDoc release between the triggering
56+
# run's head_sha and origin/stable. A no-op semantic-release run must
57+
# not advance docs-stable.
4658
- name: Detect SuperDoc release
59+
if: github.event_name == 'workflow_run'
4760
id: detect
4861
env:
4962
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
5063
run: |
5164
set -euo pipefail
5265
git fetch origin stable --tags --force
5366
54-
# v* tags reachable from origin/stable that were NOT reachable from
55-
# the run's head_sha. If empty, the release-superdoc.yml run was a
56-
# semantic-release no-op and docs-stable must not advance.
5767
tags_at_stable=$(git tag --merged origin/stable --list 'v[0-9]*' | sort -u)
5868
tags_at_head=$(git tag --merged "${HEAD_SHA}" --list 'v[0-9]*' | sort -u)
5969
new_tags=$(comm -23 <(echo "${tags_at_stable}") <(echo "${tags_at_head}"))
@@ -66,6 +76,27 @@ jobs:
6676
echo "New SuperDoc tag(s) detected: $(echo "${new_tags}" | tr '\n' ' ')"
6777
fi
6878
69-
- name: Push docs-stable
70-
if: steps.detect.outputs.released == 'true'
79+
- name: Push docs-stable (auto)
80+
if: github.event_name == 'workflow_run' && steps.detect.outputs.released == 'true'
7181
run: git push origin "refs/remotes/origin/stable:refs/heads/docs-stable"
82+
83+
# Manual path: trust the operator. Promote either the requested SHA
84+
# or the current origin/stable head. The push is rejected by GitHub
85+
# if it isn't a fast-forward, so this stays safe even on operator
86+
# error - no `--force`.
87+
- name: Push docs-stable (manual)
88+
if: github.event_name == 'workflow_dispatch'
89+
env:
90+
REQUESTED_SHA: ${{ inputs.sha }}
91+
run: |
92+
set -euo pipefail
93+
git fetch origin stable --tags --force
94+
95+
if [ -n "${REQUESTED_SHA}" ]; then
96+
target="${REQUESTED_SHA}"
97+
else
98+
target=$(git rev-parse origin/stable)
99+
fi
100+
101+
echo "Promoting ${target} to docs-stable."
102+
git push origin "${target}:refs/heads/docs-stable"

scripts/__tests__/release-local.test.mjs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,28 @@ test('docs promotion is keyed to SuperDoc only', async () => {
353353
);
354354
});
355355

356+
test('docs promotion supports manual workflow_dispatch with optional sha input', async () => {
357+
const promoteWorkflow = await readRepoFile('.github/workflows/promote-stable-docs.yml');
358+
assert.ok(
359+
promoteWorkflow.includes('workflow_dispatch:'),
360+
'.github/workflows/promote-stable-docs.yml: must expose workflow_dispatch for manual promotion',
361+
);
362+
assert.ok(
363+
/sha:\s*\n\s*description:/.test(promoteWorkflow),
364+
'.github/workflows/promote-stable-docs.yml: must accept an optional sha input',
365+
);
366+
assert.ok(
367+
promoteWorkflow.includes("github.event_name == 'workflow_dispatch'"),
368+
'.github/workflows/promote-stable-docs.yml: job must allow workflow_dispatch in addition to workflow_run',
369+
);
370+
// Manual path must NOT depend on the auto-path detect step output, otherwise
371+
// a manual run would skip the push (detect only runs on workflow_run).
372+
assert.ok(
373+
/Push docs-stable \(manual\)[\s\S]*if:\s*github\.event_name == 'workflow_dispatch'/.test(promoteWorkflow),
374+
'.github/workflows/promote-stable-docs.yml: manual push step must gate on workflow_dispatch only, not on detect.outputs',
375+
);
376+
});
377+
356378
test('stable release workflows and commit filters include shared workspace coverage', async () => {
357379
const workflowFiles = [
358380
'.github/workflows/release-superdoc.yml',

0 commit comments

Comments
 (0)