Skip to content

ci: adopt blueprint release pipeline#11

Merged
FBumann merged 9 commits intomainfrom
ci/blueprint
Mar 24, 2026
Merged

ci: adopt blueprint release pipeline#11
FBumann merged 9 commits intomainfrom
ci/blueprint

Conversation

@FBumann
Copy link
Owner

@FBumann FBumann commented Mar 23, 2026

Summary

Adopt the python-project-blueprint release pipeline:

  • release.yaml: release-please on push to main, calls publish on release creation
  • publish.yaml: triggered by tag push (v*) or workflow_call — publishes to PyPI, creates GitHub Release for manual tag pushes (auto-detects prerelease from - in tag name)

Release flows

Flow How
Automated release Push to main → release-please PR → merge → tag + publish
Manual release git tag v0.1.0 && git push origin v0.1.0 → publish
Manual pre-release git tag v0.1.0-rc.1 && git push origin v0.1.0-rc.1 → publish (marked as prerelease)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Documentation is now built and validated as part of the CI pipeline.
  • Chores

    • Added automated package publishing to PyPI and GitHub release creation.
    • Updated dependency auto-merge configuration to focus on patch-level updates.
    • Simplified PR validation workflow.
    • Configured Read the Docs for documentation builds.

- release.yaml: release-please on push to main, calls publish on release
- publish.yaml: tag push + workflow_call, creates GitHub Release for manual tags

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 23, 2026

Warning

Rate limit exceeded

@FBumann has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 29 minutes and 51 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c8123ba7-0854-49e4-98de-309c7c03e598

📥 Commits

Reviewing files that changed from the base of the PR and between d11c60f and 12b3b97.

📒 Files selected for processing (2)
  • .github/workflows/publish.yaml
  • .github/workflows/release.yaml
📝 Walkthrough

Walkthrough

These changes implement a new documentation pipeline in CI, create a reusable publish workflow for PyPI and GitHub releases, refactor the release workflow to delegate publishing to it, and add ReadTheDocs configuration—while simplifying PR validation and updating dependabot automation.

Changes

Cohort / File(s) Summary
CI/CD Documentation Pipeline
.github/workflows/ci.yaml, .readthedocs.yaml
Added docs job to CI pipeline that runs mkdocs build --strict. Introduced ReadTheDocs config (v2) using uv to install dependencies via uv sync --group docs on ubuntu-24.04 with Python 3.13.
Release and Publishing Workflows
.github/workflows/publish.yaml, .github/workflows/release.yaml
Created new publish.yaml workflow for PyPI publishing and GitHub release creation, triggered on version tags or via manual call. Refactored release.yaml to invoke publish.yaml as a reusable workflow instead of handling publishing inline, removing build/publish steps and dispatch inputs.
PR and Dependency Management
.github/workflows/pr-title.yaml, .github/workflows/dependabot-auto-merge.yaml
Simplified PR title validation to run only on pull_request events, removing push-event handling. Restructured dependabot auto-merge logic with explicit GitHub App token generation for version-update:semver-patch updates only; removed minor-version auto-merge path.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Docs now build in CI's bright light,
Publish workflows hop through the night,
With tokens and releases done just right,
uv speeds the builds with all its might,
The pipeline takes its perfect flight! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'ci: adopt blueprint release pipeline' directly and concisely summarizes the main change—adopting a release pipeline from python-project-blueprint.
Description check ✅ Passed The description provides a clear summary of changes, documents three release flows with a helpful table, but does not follow the repository's template structure with Type of Change, Testing, and Checklist sections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/blueprint

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

FBumann and others added 7 commits March 23, 2026 14:11
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without synchronize, the check doesn't re-trigger on new commits.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GITHUB_TOKEN can't approve its own PRs when reviews are required.
Only auto-merge patch updates, not minor.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/ci.yaml:
- Around line 100-101: In the "Install dependencies" step replace the incorrect
uv command flag so it selects the dependency group declared under
dependency-groups: change the command string used in the Install dependencies
job from using "--extra docs" to "--group docs" (so the job runs uv sync --group
docs) to match .readthedocs.yaml and ensure the docs dependency group is synced.

In @.github/workflows/dependabot-auto-merge.yaml:
- Around line 19-25: Add a fast-fail check before the "Generate app token" step
(id: app-token) to verify that secrets.APP_ID and secrets.APP_PRIVATE_KEY are
present in the Dependabot secrets context and exit early if not; create a new
step (e.g., "Check Dependabot secrets") that runs a simple shell test using the
same expressions (e.g., test -n "${{ secrets.APP_ID }}" && test -n "${{
secrets.APP_PRIVATE_KEY }}" || { echo 'Missing APP_ID or APP_PRIVATE_KEY in
Dependabot secrets'; exit 1; }) so the workflow fails fast with a clear message
instead of attempting to run actions/create-github-app-token@v2 when those
secrets are absent.

In @.github/workflows/publish.yaml:
- Around line 6-10: The reusable workflow currently exposes workflow_call and
invokes pypa/gh-action-pypi-publish which doesn't support OIDC/trusted
publishing in reusable workflows; fix by either (A) moving the PyPI upload out
of the reusable workflow into a top-level job in the caller workflow (so the
publish step runs in the top-level workflow with OIDC), or (B) convert the
reusable path to token-based auth: add a workflow input for a PyPI token (e.g.,
input name pypi_token), update the caller to pass secrets.PYPI_API_TOKEN into
that input, and change the pypa/gh-action-pypi-publish invocation to use the
token auth instead of relying on OIDC; ensure references to workflow_call and
input tag remain unchanged except for the added token input if you choose option
B.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ced9be92-a369-4639-8ae8-03afe582dabc

📥 Commits

Reviewing files that changed from the base of the PR and between bc33dad and d11c60f.

📒 Files selected for processing (6)
  • .github/workflows/ci.yaml
  • .github/workflows/dependabot-auto-merge.yaml
  • .github/workflows/pr-title.yaml
  • .github/workflows/publish.yaml
  • .github/workflows/release.yaml
  • .readthedocs.yaml

Comment on lines +100 to +101
- name: Install dependencies
run: uv sync --extra docs
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In uv, does uv sync --extra docsinstall packages from[dependency-groups].docs, or do dependency groups require uv sync --group docs?

💡 Result:

In uv, uv sync --extra docs does NOT install packages from [dependency-groups].docs. The --extra flag is for including optional dependencies (extras) from [project.optional-dependencies], while dependency groups from [dependency-groups] require uv sync --group docs. Dependency groups are read from the [dependency-groups] table (PEP 735). The dev group is synced by default, but other groups like docs need explicit --group docs. Options include --group, --only-group, --all-groups, --no-group, etc. --extra and --group serve distinct purposes: extras for published optional deps, groups for local dev deps.

Citations:


🏁 Script executed:

# Check if .github/workflows/ci.yaml exists and examine lines 100-101
if [ -f ".github/workflows/ci.yaml" ]; then
  echo "=== .github/workflows/ci.yaml lines 100-101 ==="
  sed -n '100,101p' ".github/workflows/ci.yaml"
else
  echo ".github/workflows/ci.yaml not found"
fi

# Check pyproject.toml for [dependency-groups] section
if [ -f "pyproject.toml" ]; then
  echo -e "\n=== pyproject.toml [dependency-groups] section ==="
  grep -A 10 "\[dependency-groups\]" pyproject.toml
else
  echo "pyproject.toml not found"
fi

# Check .readthedocs.yaml for docs sync command
if [ -f ".readthedocs.yaml" ]; then
  echo -e "\n=== .readthedocs.yaml lines 17-18 ==="
  sed -n '17,18p' ".readthedocs.yaml"
else
  echo ".readthedocs.yaml not found"
fi

Repository: FBumann/fluxopt_plot

Length of output: 559


Use --group docs here, not --extra docs.

uv sync --extra ... reads from [project.optional-dependencies], while dependency groups are selected with --group. This repo declares docs under [dependency-groups], and .readthedocs.yaml already uses the correct uv sync --group docs form, so this command is syncing the wrong dependency set.

♻️ Proposed fix
       - name: Install dependencies
-        run: uv sync --extra docs
+        run: uv sync --group docs
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yaml around lines 100 - 101, In the "Install
dependencies" step replace the incorrect uv command flag so it selects the
dependency group declared under dependency-groups: change the command string
used in the Install dependencies job from using "--extra docs" to "--group docs"
(so the job runs uv sync --group docs) to match .readthedocs.yaml and ensure the
docs dependency group is synced.

Comment on lines +19 to +25
- name: Generate app token
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
id: app-token
uses: actions/create-github-app-token@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

When a GitHub Actions workflow is triggered by Dependabot on the pull_request event, are repository Actions secrets available, or only Dependabot secrets?

💡 Result:

When a GitHub Actions workflow is triggered by Dependabot on the pull_request event, only Dependabot secrets are available. Repository Actions secrets are not available.

Citations:


Ensure APP_ID and APP_PRIVATE_KEY are configured in Dependabot secrets.

On Dependabot-triggered pull_request runs, the secrets context is populated exclusively from Dependabot secrets; regular Actions secrets are unavailable. Since this workflow accesses ${{ secrets.APP_ID }} and ${{ secrets.APP_PRIVATE_KEY }}, these credentials must be configured in Dependabot secrets or the token generation will fail. If they only exist in the Actions secret store, the workflow cannot proceed.

Add a fast-fail check to catch missing secrets early:

Recommended fail-fast guard
+      - name: Verify Dependabot app secrets
+        if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
+        env:
+          APP_ID: ${{ secrets.APP_ID }}
+          APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
+        run: |
+          test -n "$APP_ID" || { echo "::error::APP_ID must be configured as a Dependabot secret"; exit 1; }
+          test -n "$APP_PRIVATE_KEY" || { echo "::error::APP_PRIVATE_KEY must be configured as a Dependabot secret"; exit 1; }
+
       - name: Generate app token
         if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
         id: app-token
         uses: actions/create-github-app-token@v2
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Generate app token
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
id: app-token
uses: actions/create-github-app-token@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Verify Dependabot app secrets
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
env:
APP_ID: ${{ secrets.APP_ID }}
APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
run: |
test -n "$APP_ID" || { echo "::error::APP_ID must be configured as a Dependabot secret"; exit 1; }
test -n "$APP_PRIVATE_KEY" || { echo "::error::APP_PRIVATE_KEY must be configured as a Dependabot secret"; exit 1; }
- name: Generate app token
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/dependabot-auto-merge.yaml around lines 19 - 25, Add a
fast-fail check before the "Generate app token" step (id: app-token) to verify
that secrets.APP_ID and secrets.APP_PRIVATE_KEY are present in the Dependabot
secrets context and exit early if not; create a new step (e.g., "Check
Dependabot secrets") that runs a simple shell test using the same expressions
(e.g., test -n "${{ secrets.APP_ID }}" && test -n "${{ secrets.APP_PRIVATE_KEY
}}" || { echo 'Missing APP_ID or APP_PRIVATE_KEY in Dependabot secrets'; exit 1;
}) so the workflow fails fast with a clear message instead of attempting to run
actions/create-github-app-token@v2 when those secrets are absent.

PyPI trusted publishing doesn't work with reusable workflow calls.
Tag push from release-please (via app token) triggers publish directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@FBumann FBumann merged commit 52d21a7 into main Mar 24, 2026
8 of 10 checks passed
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