Skip to content

ci: add RTD release workflow - #204

Open
jahn-junior wants to merge 5 commits into
mainfrom
work/rtd-release-automation/CRAFT-5278
Open

jahn-junior wants to merge 5 commits into
mainfrom
work/rtd-release-automation/CRAFT-5278

Conversation

@jahn-junior

Copy link
Copy Markdown
Contributor

Adds a callable workflow to automate the creation of hotfix branches, RTD versions, and redirects:

Behavior

  • Major versions:
    • creates a hotfix branch
    • activates the branch's RTD version with slug <major>
    • sets new version as the project default
    • redirects <major>.0 and <major>.0.0 to <major>
  • Minor versions:
    • creates a hotfix branch
    • deactivates the previous minor version after changing its slug to <major>.<minor> (to free up the <major> slug)
    • activates the new hotfix branch's RTD version with slug <major>
    • sets new version as the project default
    • redirects <major>.<minor> and <major>.<minor>.0 to <major>
  • Patch versions:
    • redirects <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 ;)


  • I've followed the contribution guidelines.
  • I've signed the CLA.
  • I've successfully run make lint && make test.
  • I've added or updated any relevant documentation.
  • In documents I changed, I added a meta description if one was missing.
  • I've updated the relevant release notes.

@jahn-junior
jahn-junior requested a review from lengau as a code owner October 22, 2026 23:15
Copilot AI lite review requested due to automatic review settings October 22, 2026 23:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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

Comment thread .github/workflows/release-docs.yaml
Comment thread .github/workflows/release-docs.yaml
Comment thread .github/workflows/release-docs.yaml
@jahn-junior
jahn-junior force-pushed the work/rtd-release-automation/CRAFT-5278 branch from 94461b9 to 8a4e269 Compare October 22, 2026 23:24
@jahn-junior
jahn-junior requested a review from mr-cal October 22, 2026 23:29

@mr-cal mr-cal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!


jobs:
rtd:
runs-on: [self-hosted, amd64, medium, linux]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine to do on ubuntu-latest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah agreed. Given the contents, ubuntu-slim would probably be fine too.

Comment on lines +43 to +52
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like something we could do with the gh command (since it's preinstalled on the runners):

Suggested change
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 lengau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with two suggestions.

@lengau lengau left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

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.

4 participants