Skip to content

Commit 6eb9aee

Browse files
vdusekclaude
andauthored
ci: Extract docs versioning and release into reusable workflows (#728)
## Summary **Docs versioning** (`manual_version_docs.yaml`): - Extract the inline `version_docs` job from `manual_release_stable.yaml` into a standalone reusable workflow - Can be triggered manually from the GitHub UI (with an optional ref input) or called from the release pipeline - Fix `api:version` ENOENT bug by running docusaurus commands through `uv run` - Clean up all existing versions for the same major version, not just exact major.minor match - Remove non-docs artifacts (pyproject.toml, .gitignore, caches) from versioned doc snapshots - Align `doc_release` ref to use `version_docs_commitish` instead of `default_branch` **Docs release** (`manual_release_docs.yaml`): - Rename `_release_docs.yaml` to `manual_release_docs.yaml` to match the naming convention - Add optional `ref` input to `workflow_dispatch` so it can be triggered from the GitHub UI with a specific ref (falling back to the default branch) - Replace `CHECKOUT_REF` env var approach with a `Determine checkout ref` step, consistent with `manual_version_docs.yaml` - Update all references in `manual_release_stable.yaml` and `on_master.yaml` --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0a668f2 commit 6eb9aee

6 files changed

Lines changed: 166 additions & 66 deletions

File tree

.github/workflows/manual_regenerate_models.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ jobs:
4646
steps:
4747
- name: Validate inputs
4848
if: inputs.docs_pr_number || inputs.docs_workflow_run_id
49+
env:
50+
DOCS_WORKFLOW_RUN_ID: ${{ inputs.docs_workflow_run_id }}
4951
run: |
5052
if [[ -n "$DOCS_PR_NUMBER" ]] && ! [[ "$DOCS_PR_NUMBER" =~ ^[1-9][0-9]*$ ]]; then
5153
echo "::error::docs_pr_number must be a positive integer, got: $DOCS_PR_NUMBER"
5254
exit 1
5355
fi
54-
if [[ -n "${{ inputs.docs_workflow_run_id }}" ]] && ! [[ "${{ inputs.docs_workflow_run_id }}" =~ ^[0-9]+$ ]]; then
55-
echo "::error::docs_workflow_run_id must be a numeric run ID, got: ${{ inputs.docs_workflow_run_id }}"
56+
if [[ -n "$DOCS_WORKFLOW_RUN_ID" ]] && ! [[ "$DOCS_WORKFLOW_RUN_ID" =~ ^[0-9]+$ ]]; then
57+
echo "::error::docs_workflow_run_id must be a numeric run ID, got: $DOCS_WORKFLOW_RUN_ID"
5658
exit 1
5759
fi
5860
@@ -173,5 +175,5 @@ jobs:
173175
run: |
174176
gh pr comment "$DOCS_PR_NUMBER" \
175177
--repo apify/apify-docs \
176-
--body "Python client model regeneration failed. [See workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})." \
178+
--body "Python client model regeneration failed. [See workflow run](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})." \
177179
|| echo "Warning: Failed to post failure comment to apify/apify-docs PR #$DOCS_PR_NUMBER."

.github/workflows/_release_docs.yaml renamed to .github/workflows/manual_release_docs.yaml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
1-
name: Doc release
1+
name: Release docs
22

33
on:
44
# Runs when manually triggered from the GitHub UI.
55
workflow_dispatch:
6+
inputs:
7+
ref:
8+
description: Git ref to checkout (branch, tag, or SHA). Defaults to the default branch.
9+
required: false
10+
type: string
11+
default: ""
612

713
# Runs when invoked by another workflow.
814
workflow_call:
915
inputs:
1016
ref:
17+
description: Git ref to checkout (branch, tag, or SHA)
1118
required: true
1219
type: string
1320

1421
env:
1522
NODE_VERSION: 22
1623
PYTHON_VERSION: 3.14
17-
CHECKOUT_REF: ${{ github.event_name == 'workflow_call' && inputs.ref || github.ref }}
1824

1925
jobs:
2026
release_docs:
21-
name: Doc release
27+
name: Release docs
2228
environment:
2329
name: github-pages
2430
permissions:
@@ -28,11 +34,20 @@ jobs:
2834
runs-on: ubuntu-latest
2935

3036
steps:
37+
- name: Determine checkout ref
38+
id: resolve_ref
39+
env:
40+
INPUT_REF: ${{ inputs.ref }}
41+
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
42+
run: |
43+
REF="${INPUT_REF:-$DEFAULT_BRANCH}"
44+
echo "ref=$REF" >> "$GITHUB_OUTPUT"
45+
3146
- name: Checkout repository
3247
uses: actions/checkout@v6
3348
with:
3449
token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
35-
ref: ${{ env.CHECKOUT_REF }}
50+
ref: ${{ steps.resolve_ref.outputs.ref }}
3651

3752
- name: Set up Node
3853
uses: actions/setup-node@v6

.github/workflows/manual_release_stable.yaml

Lines changed: 7 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -105,62 +105,12 @@ jobs:
105105
version_docs:
106106
name: Version docs
107107
needs: [release_prepare, changelog_update, pypi_publish]
108-
runs-on: ubuntu-latest
109108
permissions:
110109
contents: write
111-
env:
112-
NODE_VERSION: 22
113-
PYTHON_VERSION: 3.14
114-
115-
steps:
116-
- name: Checkout repository
117-
uses: actions/checkout@v6
118-
with:
119-
ref: ${{ github.event.repository.default_branch }}
120-
token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
121-
122-
- name: Set up Node
123-
uses: actions/setup-node@v6
124-
with:
125-
node-version: ${{ env.NODE_VERSION }}
126-
127-
- name: Set up Python
128-
uses: actions/setup-python@v6
129-
with:
130-
python-version: ${{ env.PYTHON_VERSION }}
131-
132-
- name: Set up uv package manager
133-
uses: astral-sh/setup-uv@v7
134-
with:
135-
python-version: ${{ env.PYTHON_VERSION }}
136-
137-
- name: Install Python dependencies
138-
run: uv run poe install-dev
139-
140-
- name: Install website dependencies
141-
run: |
142-
cd website
143-
yarn install
144-
145-
- name: Snapshot the current version
146-
run: |
147-
cd website
148-
VERSION="$(python -c "import tomllib, pathlib; print(tomllib.loads(pathlib.Path('../pyproject.toml').read_text())['project']['version'])")"
149-
MAJOR_MINOR="$(echo "$VERSION" | cut -d. -f1-2)"
150-
export MAJOR_MINOR
151-
rm -rf "versioned_docs/version-${MAJOR_MINOR}"
152-
rm -rf "versioned_sidebars/version-${MAJOR_MINOR}-sidebars.json"
153-
jq 'map(select(. != env.MAJOR_MINOR))' versions.json > tmp.json && mv tmp.json versions.json
154-
bash build_api_reference.sh
155-
npx docusaurus docs:version "$MAJOR_MINOR"
156-
npx docusaurus api:version "$MAJOR_MINOR"
157-
158-
- name: Commit and push the version snapshot
159-
uses: EndBug/add-and-commit@v10
160-
with:
161-
author_name: Apify Release Bot
162-
author_email: noreply@apify.com
163-
message: "docs: update versioned docs for ${{ needs.release_prepare.outputs.version_number }}"
110+
uses: ./.github/workflows/manual_version_docs.yaml
111+
with:
112+
ref: ${{ needs.changelog_update.outputs.changelog_commitish }}
113+
secrets: inherit
164114

165115
doc_release:
166116
name: Doc release
@@ -169,8 +119,8 @@ jobs:
169119
contents: write
170120
pages: write
171121
id-token: write
172-
uses: ./.github/workflows/_release_docs.yaml
122+
uses: ./.github/workflows/manual_release_docs.yaml
173123
with:
174-
# Use the default branch to include both the changelog update and the versioned docs snapshot.
175-
ref: ${{ github.event.repository.default_branch }}
124+
# Use the version_docs commit to include both changelog and versioned docs.
125+
ref: ${{ needs.version_docs.outputs.version_docs_commitish }}
176126
secrets: inherit
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
name: Version docs
2+
3+
on:
4+
# Runs when manually triggered from the GitHub UI.
5+
workflow_dispatch:
6+
inputs:
7+
ref:
8+
description: Git ref to checkout (branch, tag, or SHA). Defaults to the default branch.
9+
required: false
10+
type: string
11+
default: ""
12+
13+
# Runs when invoked by another workflow.
14+
workflow_call:
15+
inputs:
16+
ref:
17+
description: Git ref to checkout (branch, tag, or SHA)
18+
required: true
19+
type: string
20+
outputs:
21+
version_docs_commitish:
22+
description: The commit SHA of the versioned docs commit
23+
value: ${{ jobs.version_docs.outputs.version_docs_commitish }}
24+
25+
concurrency:
26+
group: version-docs
27+
cancel-in-progress: false
28+
29+
permissions:
30+
contents: read
31+
32+
env:
33+
NODE_VERSION: "22"
34+
PYTHON_VERSION: "3.14"
35+
36+
jobs:
37+
version_docs:
38+
name: Version docs
39+
runs-on: ubuntu-latest
40+
outputs:
41+
version_docs_commitish: ${{ steps.resolve_commitish.outputs.commitish }}
42+
permissions:
43+
contents: write
44+
45+
steps:
46+
- name: Determine checkout ref
47+
id: resolve_ref
48+
env:
49+
INPUT_REF: ${{ inputs.ref }}
50+
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
51+
run: |
52+
REF="${INPUT_REF:-$DEFAULT_BRANCH}"
53+
echo "ref=$REF" >> "$GITHUB_OUTPUT"
54+
55+
- name: Checkout repository
56+
uses: actions/checkout@v6
57+
with:
58+
token: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }}
59+
ref: ${{ steps.resolve_ref.outputs.ref }}
60+
61+
- name: Set up Node
62+
uses: actions/setup-node@v6
63+
with:
64+
node-version: ${{ env.NODE_VERSION }}
65+
66+
- name: Set up Python
67+
uses: actions/setup-python@v6
68+
with:
69+
python-version: ${{ env.PYTHON_VERSION }}
70+
71+
- name: Set up uv package manager
72+
uses: astral-sh/setup-uv@v7
73+
with:
74+
python-version: ${{ env.PYTHON_VERSION }}
75+
76+
- name: Install Python dependencies
77+
run: uv run poe install-dev
78+
79+
- name: Snapshot the current version
80+
id: snapshot
81+
run: |
82+
cd website
83+
corepack enable
84+
yarn install
85+
86+
# Extract version from pyproject.toml.
87+
FULL_VERSION="$(uv version --short)"
88+
MAJOR_MINOR_VERSION="$(echo "$FULL_VERSION" | cut -d. -f1-2)"
89+
MAJOR_VERSION="$(echo "$FULL_VERSION" | cut -d. -f1)"
90+
echo "version=$FULL_VERSION" >> "$GITHUB_OUTPUT"
91+
echo "Version: $FULL_VERSION, Major.Minor: $MAJOR_MINOR_VERSION, Major: $MAJOR_VERSION"
92+
93+
# Find the existing versions for this major in versions.json (if any).
94+
if [[ -f versions.json ]]; then
95+
OLD_VERSIONS="$(jq -r --arg major "$MAJOR_VERSION" '.[] | select(startswith($major + "."))' versions.json)"
96+
else
97+
OLD_VERSIONS=""
98+
echo "[]" > versions.json
99+
fi
100+
101+
# Remove all old versions for this major (if found).
102+
if [[ -n "$OLD_VERSIONS" ]]; then
103+
while IFS= read -r OLD_VERSION; do
104+
[[ -z "$OLD_VERSION" ]] && continue
105+
echo "Removing old version $OLD_VERSION for major $MAJOR_VERSION"
106+
rm -rf "versioned_docs/version-${OLD_VERSION}"
107+
rm -f "versioned_sidebars/version-${OLD_VERSION}-sidebars.json"
108+
done <<< "$OLD_VERSIONS"
109+
jq --arg major "$MAJOR_VERSION" 'map(select(startswith($major + ".") | not))' versions.json > tmp.json && mv tmp.json versions.json
110+
else
111+
echo "No existing versions found for major $MAJOR_VERSION, nothing to remove"
112+
fi
113+
114+
# Build API reference and create Docusaurus version snapshots.
115+
bash build_api_reference.sh
116+
uv run npx docusaurus docs:version "$MAJOR_MINOR_VERSION"
117+
uv run npx docusaurus api:version "$MAJOR_MINOR_VERSION"
118+
119+
- name: Commit and push versioned docs
120+
id: commit_versioned_docs
121+
uses: EndBug/add-and-commit@v10
122+
with:
123+
add: website/versioned_docs website/versioned_sidebars website/versions.json
124+
message: "docs: Version docs for v${{ steps.snapshot.outputs.version }} [skip ci]"
125+
default_author: github_actions
126+
127+
- name: Resolve output commitish
128+
id: resolve_commitish
129+
env:
130+
COMMIT_SHA: ${{ steps.commit_versioned_docs.outputs.commit_long_sha }}
131+
run: |
132+
echo "commitish=${COMMIT_SHA:-$(git rev-parse HEAD)}" >> "$GITHUB_OUTPUT"

.github/workflows/on_master.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
contents: write
2929
pages: write
3030
id-token: write
31-
uses: ./.github/workflows/_release_docs.yaml
31+
uses: ./.github/workflows/manual_release_docs.yaml
3232
with:
3333
# Use the same ref as the one that triggered the workflow.
3434
ref: ${{ github.ref }}
@@ -112,7 +112,7 @@ jobs:
112112
contents: write
113113
pages: write
114114
id-token: write
115-
uses: ./.github/workflows/_release_docs.yaml
115+
uses: ./.github/workflows/manual_release_docs.yaml
116116
with:
117117
# Use the ref from the changelog update to include the updated changelog.
118118
ref: ${{ needs.changelog_update.outputs.changelog_commitish }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Session.vim
6464
# Docs
6565
docs/changelog.md
6666
website/versioned_docs/*/changelog.md
67+
website/versioned_docs/*/pyproject.toml
6768

6869
# Website build artifacts, node dependencies
6970
website/build

0 commit comments

Comments
 (0)