Repository navigation
ci: release-please + publish + contributors automation - #1
Conversation
📝 WalkthroughWalkthroughThis PR establishes the complete CI/CD and release infrastructure for the mockcast project, including conventional commit enforcement, automated release versioning via release-please, multi-stage PyPI publishing with trusted publishing, and contributor list management. ChangesRelease Infrastructure and CI/CD
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Tools execution failed with the following error: Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error) Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
release-please-config.json (1)
18-27: ⚡ Quick winAlign changelog sections with allowed commit types.
build,style, andrevertare allowed bycommitlint.config.mjsbut not explicitly mapped here. Add them (or explicitly hide them) to keep release notes deterministic.Suggested alignment diff
"changelog-sections": [ { "type": "feat", "section": "Features" }, { "type": "fix", "section": "Bug Fixes" }, { "type": "perf", "section": "Performance" }, { "type": "refactor", "section": "Refactoring" }, { "type": "docs", "section": "Documentation" }, { "type": "ci", "section": "CI/CD" }, { "type": "test", "section": "Testing" }, + { "type": "build", "section": "Build System", "hidden": true }, + { "type": "style", "section": "Style", "hidden": true }, + { "type": "revert", "section": "Reverts" }, { "type": "chore", "section": "Miscellaneous", "hidden": true } ]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@release-please-config.json` around lines 18 - 27, The changelog-sections array is missing mappings for commit types allowed by commitlint (build, style, revert); update the "changelog-sections" configuration to include entries for { "type": "build" }, { "type": "style" }, and { "type": "revert" } — either map them to explicit section names (e.g., "Build", "Style", "Reverts") or add them with "hidden": true so release-please produces deterministic release notes; ensure you modify the existing "changelog-sections" array in release-please-config.json accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.contributors.yml:
- Around line 40-43: The identity_map entry currently contains a personal email
for login "smorin"; remove or replace the plaintext PII by updating the
identity_map mapping (the "login: smorin" and its "emails" list) to use the
GitHub no-reply address (e.g., `@users.noreply.github.com`) or move the mapping
out of the repo into a private/secret config; ensure the commit removes the
personal email from .contributors.yml and preserves the login mapping if needed
with the no-reply address.
In @.github/workflows/commitlint.yml:
- Around line 19-24: The workflow currently references mutable action tags
"actions/checkout@v4" and "wagoid/commitlint-github-action@v6"; replace those
with the corresponding immutable commit SHAs to harden CI supply-chain integrity
(locate the two uses of actions/checkout and wagoid/commitlint-github-action in
the file and substitute the tag suffixes with the full commit SHA values for the
exact versions you intend to pin, keeping the existing with: configFile:
commitlint.config.mjs and fetch-depth: 0 settings intact).
In @.github/workflows/publish.yml:
- Around line 38-46: The workflow step "Verify tag matches pyproject version"
relies on tomllib (Python 3.11+) but doesn't pin Python; update the job to run
actions/setup-python@v5 (or later) and set python-version to "3.11" (or
">=3.11") before the step that defines TAG_VERSION and PKG_VERSION so tomllib is
available; ensure the setup-python action precedes the shell run that computes
PKG_VERSION.
In @.github/workflows/release-please.yml:
- Around line 35-73: The sync-uv-lock job runs after release-please has already
created the release tag, meaning any uv.lock updates happen after the tag points
to a commit with an out-of-sync lockfile. Move the uv.lock synchronization to
occur before the release tag is created by either removing the post-release
sync-uv-lock job and configuring release-please to ensure uv.lock is in sync as
part of its PR validation (using a pre-commit hook or additional CI check), or
by adding a validation step that fails the release if uv.lock is out of sync
rather than fixing it after the fact.
In @.github/workflows/update-contributors.yml:
- Around line 11-15: Remove the unnecessary permissions entry by deleting the
"issues: write" permission under the permissions block so the workflow token
only has the required "contents: write" and "pull-requests: write" entries;
update the permissions block (permissions, contents, pull-requests) accordingly
and verify the workflow still operates when creating/updating PRs.
---
Nitpick comments:
In `@release-please-config.json`:
- Around line 18-27: The changelog-sections array is missing mappings for commit
types allowed by commitlint (build, style, revert); update the
"changelog-sections" configuration to include entries for { "type": "build" }, {
"type": "style" }, and { "type": "revert" } — either map them to explicit
section names (e.g., "Build", "Style", "Reverts") or add them with "hidden":
true so release-please produces deterministic release notes; ensure you modify
the existing "changelog-sections" array in release-please-config.json
accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b50d3fc6-0a54-4599-a366-4cf7217fbd24
📒 Files selected for processing (10)
.contributors.yml.github/workflows/commitlint.yml.github/workflows/publish.yml.github/workflows/release-please.yml.github/workflows/update-contributors.yml.release-please-manifest.jsonCHANGELOG.mdCONTRIBUTORS.mdcommitlint.config.mjsrelease-please-config.json
| identity_map: | ||
| - login: smorin | ||
| emails: | ||
| - steve.morin@gmail.com |
There was a problem hiding this comment.
Avoid committing personal email addresses in repo config.
identity_map currently contains a personal email in plaintext. Prefer GitHub @users.noreply.github.com (or move mapping to a secret/private config) to avoid unnecessary PII exposure in-repo.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.contributors.yml around lines 40 - 43, The identity_map entry currently
contains a personal email for login "smorin"; remove or replace the plaintext
PII by updating the identity_map mapping (the "login: smorin" and its "emails"
list) to use the GitHub no-reply address (e.g., `@users.noreply.github.com`) or
move the mapping out of the repo into a private/secret config; ensure the commit
removes the personal email from .contributors.yml and preserves the login
mapping if needed with the no-reply address.
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - uses: wagoid/commitlint-github-action@v6 | ||
| with: | ||
| configFile: commitlint.config.mjs |
There was a problem hiding this comment.
Pin GitHub Actions to immutable SHAs.
Line 19 and Line 22 use mutable tags (@v4, @v6), which weakens CI supply-chain integrity. Pin to full commit SHAs.
Suggested hardening diff
- - uses: actions/checkout@v4
+ - uses: actions/checkout@<full-length-commit-sha>
with:
fetch-depth: 0
- - uses: wagoid/commitlint-github-action@v6
+ - uses: wagoid/commitlint-github-action@<full-length-commit-sha>
with:
configFile: commitlint.config.mjs🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/commitlint.yml around lines 19 - 24, The workflow
currently references mutable action tags "actions/checkout@v4" and
"wagoid/commitlint-github-action@v6"; replace those with the corresponding
immutable commit SHAs to harden CI supply-chain integrity (locate the two uses
of actions/checkout and wagoid/commitlint-github-action in the file and
substitute the tag suffixes with the full commit SHA values for the exact
versions you intend to pin, keeping the existing with: configFile:
commitlint.config.mjs and fetch-depth: 0 settings intact).
| - name: Verify tag matches pyproject version | ||
| run: | | ||
| TAG_VERSION="${GITHUB_REF_NAME#v}" | ||
| PKG_VERSION="$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")" | ||
| if [ "${TAG_VERSION}" != "${PKG_VERSION}" ]; then | ||
| echo "::error::tag ${TAG_VERSION} != pyproject ${PKG_VERSION}" | ||
| exit 1 | ||
| fi | ||
| echo "Tag matches pyproject version (${TAG_VERSION})." |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Check the default Python version on ubuntu-latest runner
# Query GitHub Actions documentation or test in the runner
echo "Checking ubuntu-latest default Python version..."
echo "Note: As of June 2026, ubuntu-latest is Ubuntu 24.04 with Python 3.12"
echo "Verify at: https://github.com/actions/runner-images"Repository: smorinlabs/mockcast
Length of output: 1941
🌐 Web query:
GitHub Actions runner-images ubuntu-latest default Python version 3.11 3.12
💡 Result:
On GitHub Actions, the ubuntu-latest runner image (currently Ubuntu 24.04) does not have a single fixed "default" Python version that remains static; instead, it includes multiple pre-cached versions of Python [1][2]. As of June 2026, the Ubuntu 24.04 image includes various versions such as 3.10, 3.11, 3.12, and 3.13 [1]. It is important to note that relying on the pre-installed default Python version found in the system PATH is discouraged, as this version can change unexpectedly when GitHub updates the runner images [3][4][5]. GitHub officially recommends explicitly specifying the desired Python version in your workflow using the actions/setup-python action to ensure consistency and reliability [3][4][5]. For example, you can set the Python version as follows: - uses: actions/setup-python@v6 with: python-version: '3.12' By using actions/setup-python, the action will check the local tool cache for the specified version or download it on-the-fly if it is not already available, ensuring your workflow uses the exact version you require regardless of the underlying runner image's default [3][5].
Citations:
- 1: https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md
- 2: Ubuntu-latest workflows will use Ubuntu-24.04 image actions/runner-images#10636
- 3: https://github.com/actions/setup-python/blob/main/README.md
- 4: https://docs.github.com/actions/guides/building-and-testing-python
- 5: https://github.com/actions/setup-python
🌐 Web query:
tomllib available Python 3.11 documentation github actions setup-python recommended
💡 Result:
The tomllib module is included in the Python standard library starting with Python 3.11 [1][2]. It provides functionality for parsing TOML files [1][3]. Regarding GitHub Actions, it is recommended to use the actions/setup-python action to explicitly define the Python version in your workflows [4][5]. This ensures consistency across different runners, as the default version of Python available on runners can vary and change unexpectedly [4][5][6]. To set up your environment, you can use the following configuration in your workflow file: steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.11' - run: python -c "import tomllib; print('tomllib is available')" By explicitly specifying python-version: '3.11' (or later), you ensure that the environment has access to the tomllib module [4][5][7]. The setup-python action is the official and recommended method for configuring Python versions in GitHub Actions [5][6].
Citations:
- 1: https://docs.python.org/3.11/library/tomllib.html
- 2: https://docs.python.org/3.11/whatsnew/3.11.html
- 3: https://github.com/python/cpython/blob/3.11/Doc/library/tomllib.rst
- 4: https://github.com/actions/setup-python?tab=readme-ov-file
- 5: https://docs.github.com/actions/guides/building-and-testing-python
- 6: https://github.com/actions/setup-python
- 7: https://github.com/actions/setup-python/blob/main/docs/advanced-usage.md
Pin Python for tomllib to avoid runner-image drift
The workflow uses tomllib, which is available only in Python 3.11+. Since ubuntu-latest ships multiple Python versions and the “default” Python on PATH can change when runner images update, the step should not rely on an implicit Python version. GitHub recommends explicitly selecting the Python version with actions/setup-python.
Recommendation: Use actions/setup-python@v5 (or later) to install Python >= 3.11 before running the tag/version check.
Option 2: Explicit Python setup
+ - uses: actions/setup-python@v5
+ with:
+ python-version: '3.11'
+
- name: Verify tag matches pyproject version🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/publish.yml around lines 38 - 46, The workflow step
"Verify tag matches pyproject version" relies on tomllib (Python 3.11+) but
doesn't pin Python; update the job to run actions/setup-python@v5 (or later) and
set python-version to "3.11" (or ">=3.11") before the step that defines
TAG_VERSION and PKG_VERSION so tomllib is available; ensure the setup-python
action precedes the shell run that computes PKG_VERSION.
| sync-uv-lock: | ||
| needs: release-please | ||
| if: needs.release-please.outputs.release_created == 'true' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - uses: actions/create-github-app-token@v3 | ||
| id: app-token | ||
| with: | ||
| app-id: ${{ secrets.RELEASE_PLEASE_APP_ID }} | ||
| private-key: ${{ secrets.RELEASE_PLEASE_PRIVATE_KEY }} | ||
|
|
||
| - uses: actions/checkout@v4 | ||
| with: | ||
| token: ${{ steps.app-token.outputs.token }} | ||
| ref: main | ||
|
|
||
| - uses: astral-sh/setup-uv@v6 | ||
| with: | ||
| enable-cache: true | ||
|
|
||
| - name: Regenerate uv.lock from pyproject | ||
| run: uv lock | ||
|
|
||
| - name: Commit uv.lock if changed | ||
| env: | ||
| TAG_NAME: ${{ needs.release-please.outputs.tag_name }} | ||
| APP_SLUG: ${{ steps.app-token.outputs.app-slug }} | ||
| run: | | ||
| if git diff --quiet uv.lock; then | ||
| echo "uv.lock already in sync; nothing to commit." | ||
| exit 0 | ||
| fi | ||
| git config user.email "${APP_SLUG}[bot]@users.noreply.github.com" | ||
| git config user.name "${APP_SLUG}[bot]" | ||
| git add uv.lock | ||
| git commit -m "chore(release): sync uv.lock for ${TAG_NAME}" | ||
| git push origin main |
There was a problem hiding this comment.
Race condition: sync-uv-lock runs after the release tag is created.
The sync-uv-lock job runs when release_created == 'true', which means release-please has already created the git tag. If uv.lock needs updating, this workflow will:
- Create release tag pointing to commit A (with out-of-sync uv.lock)
- Commit updated uv.lock as commit B on main
- Leave the release tag pointing to the old state
Impact: Users checking out the release tag will get an inconsistent lockfile. The tagged release doesn't include the synchronized uv.lock.
Recommended fix: Ensure uv.lock is synchronized in the release-please PR itself (e.g., via a pre-commit hook or CI check on the PR) rather than fixing it post-release. Alternatively, consider failing the release if uv.lock is out of sync, rather than silently fixing it afterward.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release-please.yml around lines 35 - 73, The sync-uv-lock
job runs after release-please has already created the release tag, meaning any
uv.lock updates happen after the tag points to a commit with an out-of-sync
lockfile. Move the uv.lock synchronization to occur before the release tag is
created by either removing the post-release sync-uv-lock job and configuring
release-please to ensure uv.lock is in sync as part of its PR validation (using
a pre-commit hook or additional CI check), or by adding a validation step that
fails the release if uv.lock is out of sync rather than fixing it after the
fact.
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| issues: write | ||
|
|
There was a problem hiding this comment.
Drop unnecessary issues: write permission from the workflow token.
This job appears to only open/update PR content. Keeping issues: write broadens token capabilities without clear need; remove it unless the action explicitly requires issue mutations.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/update-contributors.yml around lines 11 - 15, Remove the
unnecessary permissions entry by deleting the "issues: write" permission under
the permissions block so the workflow token only has the required "contents:
write" and "pull-requests: write" entries; update the permissions block
(permissions, contents, pull-requests) accordingly and verify the workflow still
operates when creating/updating PRs.
There was a problem hiding this comment.
Pull request overview
This PR adds CI automation to standardize releases and maintenance tasks for the Python package: release PR/tag creation via release-please, OIDC-based publishing to TestPyPI then PyPI, Conventional Commits enforcement, and automated contributor list updates.
Changes:
- Introduces release-please configuration + manifest, and seeds
CHANGELOG.md. - Adds GitHub Actions workflows for release-please tagging, publishing to TestPyPI→PyPI, and commitlint gating on PRs.
- Adds contributors-please automation configuration and a seeded
CONTRIBUTORS.md.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| release-please-config.json | Configures release-please (python strategy, changelog sections, extra files). |
| .release-please-manifest.json | Seeds manifest-mode version tracking for release-please. |
| CHANGELOG.md | Seeds a release-please-managed changelog. |
| .github/workflows/release-please.yml | Runs release-please on main and optionally syncs uv.lock post-release. |
| .github/workflows/publish.yml | Builds and publishes tagged releases to TestPyPI then PyPI via OIDC. |
| .github/workflows/commitlint.yml | Enforces Conventional Commits on PRs using commitlint. |
| commitlint.config.mjs | Self-contained commitlint rule set (no external extends). |
| .github/workflows/update-contributors.yml | Automates contributor list updates via PRs on pushes to main. |
| .contributors.yml | Configures contributors-please behavior (classification, ignore list, identity map). |
| CONTRIBUTORS.md | Seeds contributors file with markers for automation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "extra-files": [ | ||
| { "type": "toml", "path": "pyproject.toml", "jsonpath": "$.project.version" } | ||
| ] |
| - uses: astral-sh/setup-uv@v6 | ||
| with: | ||
| enable-cache: true |
| TAG_VERSION="${GITHUB_REF_NAME#v}" | ||
| PKG_VERSION="$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")" | ||
| if [ "${TAG_VERSION}" != "${PKG_VERSION}" ]; then |
| - uses: astral-sh/setup-uv@v6 | ||
| with: | ||
| enable-cache: true | ||
|
|
…it types Follow-ups from PR #1.
Adds release automation (release-please → tag → OIDC publish to TestPyPI then PyPI), a commitlint Conventional-Commits gate, and contributors-please automation.
Design: docs/superpowers/specs/2026-06-07-ci-release-contributors-design.md
Plan: docs/superpowers/plans/2026-06-07-ci-release-contributors.md
Note: GitHub environments testpypi/pypi created; PyPI/TestPyPI trusted publishers point at publish.yml.
Summary by CodeRabbit
Documentation
Chores