Repository navigation
ci: add RTD release workflow - #204
jahn-junior wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The workflow has a critical skipped-minor-release bug plus moderate validation, reliability, portability, idempotency, and documentation issues.
3 open issues
What changed in this PR
Adds a reusable GitHub Actions workflow that automates Read the Docs releases for semantic-versioned tags, including hotfix branch creation, RTD version management, default-version updates, and redirects.
Changes:
- Parses major, minor, and patch release versions.
- Creates and manages corresponding GitHub hotfix branches and RTD versions.
- Adds redirects from version-specific documentation paths to the current major version.
| File | Description | Review findings |
|---|---|---|
.github/workflows/release-docs.yaml |
Defines the callable documentation-release workflow and GitHub/RTD API operations. | Critical (1 vote): Consecutive-minor assumption can mislabel versions and fabricate redirects; derive the outgoing slug from RTD metadata or reject skipped minors. Moderate (1 vote): Reject non-semver caller refs to prevent malformed redirects. Moderate (1 vote): Distinguish RTD 404s from transient, authentication, or rate-limit failures and retry appropriately. Moderate (1 vote): Avoid hard-coding a generic self-hosted runner, and constrain Bash-only steps to supported Linux runners. Moderate (2 votes): Make redirect creation idempotent to prevent duplicate rules on reruns. Nit (2 votes): Document invocation requirements, including rtd-project, RTD_TOKEN, contents: write, and tag-triggered usage. |
Review effort: Lite
94461b9 to
8a4e269
Compare
|
|
||
| jobs: | ||
| rtd: | ||
| runs-on: [self-hosted, amd64, medium, linux] |
There was a problem hiding this comment.
I think this is fine to do on ubuntu-latest
There was a problem hiding this comment.
Yeah agreed. Given the contents, ubuntu-slim would probably be fine too.
| run: | | ||
| BRANCH="hotfix/$MAJOR.$MINOR" | ||
| API="https://api.github.com/repos/$REPOSITORY" | ||
|
|
||
| if ! curl -sf -H "Authorization: Token $GH_TOKEN" "$API/git/refs/heads/$BRANCH" >/dev/null; then | ||
| curl -fX POST -H "Authorization: Token $GH_TOKEN" -H "Content-Type: application/json" \ | ||
| -d "{\"ref\":\"refs/heads/$BRANCH\",\"sha\":\"$SHA\"}" \ | ||
| "$API/git/refs" | ||
| fi | ||
|
|
There was a problem hiding this comment.
This feels like something we could do with the gh command (since it's preinstalled on the runners):
| run: | | |
| BRANCH="hotfix/$MAJOR.$MINOR" | |
| API="https://api.github.com/repos/$REPOSITORY" | |
| if ! curl -sf -H "Authorization: Token $GH_TOKEN" "$API/git/refs/heads/$BRANCH" >/dev/null; then | |
| curl -fX POST -H "Authorization: Token $GH_TOKEN" -H "Content-Type: application/json" \ | |
| -d "{\"ref\":\"refs/heads/$BRANCH\",\"sha\":\"$SHA\"}" \ | |
| "$API/git/refs" | |
| fi | |
| run: | | |
| BRANCH="hotfix/$MAJOR.$MINOR" | |
| STATUS=$(gh api "repos/$REPOSITORY/git/refs" \ | |
| -f ref="refs/heads/$BRANCH" -f sha="$SHA" --silent \ | |
| --include 2>/dev/null | awk '/^HTTP/{print $2}') | |
| if [ "$STATUS" != "201" ] && [ "$STATUS" != "422" ]; then | |
| echo "Failed with HTTP $STATUS" >&2 | |
| exit 1 | |
| fi | |
That attempts to create the branch regardless. If it fails with a 422 Reference already exists or succeeds (201 Created), then this is considered a success. Otherwise it fails.
lengau
left a comment
There was a problem hiding this comment.
LGTM with two suggestions.
There was a problem hiding this comment.
Oh actually, sorry — one other request. Can you create a self-test workflow for this that actually runs it in Starflow with a fake ref name? (You'll need to make it so an input can override the ref name). We can limit it to pull requests that touch this file or that self-test file, but I'd like to see the workflow in action here just in case we missed anything.
(I ask this because this workflow is fairly complex and I've royally messed up much simpler workflows in ways that nobody else noticed until after merge too)



Adds a callable workflow to automate the creation of hotfix branches, RTD versions, and redirects:
Behavior
<major><major>.0and<major>.0.0to<major><major>.<minor>(to free up the<major>slug)<major><major>.<minor>and<major>.<minor>.0to<major><major>.<minor>.<patch>to<major>Validation
I tested every case manually on my fork of Snapcraft. These tags, pushed one by one, resulted in this RTD project's active versions and redirects without any manual intervention.
AI disclosure
A good chunk of this workflow was implemented by Claude Sonnet 5, with lots of guidance on how the steps and API calls should look.
I wrote this PR description myself though ;)
make lint && make test.