Skip to content

Release job#97

Merged
ejfine merged 17 commits into
mainfrom
release-job
Jul 15, 2026
Merged

Release job#97
ejfine merged 17 commits into
mainfrom
release-job

Conversation

@ejfine

@ejfine ejfine commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Why is this change necessary?

The template had no Release workflow. The existing Publish / Publish to Staging workflows re-run lint/test/build themselves, duplicating everything CI already does for the commit. We want a release path that instead relies on a passing CI run — modeled on the copier-nuxt-python-intranet-app release.yaml — while publishing to PyPI (using the existing publish.yaml as the PyPI reference).

While wiring this up we also found that instantiated repos hit pylint R0801 duplicate-code between git_tag.py and extract_project_version.py, because this repo carried a pre-refactor fork of git_tag.py (symlinked from copier_template_resources/) that parsed pyproject.toml itself.

How does this change address the issue?

  • CI builds the distribution. Added a build job to ci.yaml.jinja that runs uv build --no-sources and uploads a python-package-distributions artifact (if-no-files-found: error), wired into workflow-summary (needs + fail-check).
  • New release.yaml.jinja. Manual workflow_dispatch with a dry_run input, generated for both libraries and executables. A guard job requires the ci.yaml run for the current commit to be completed/success (including the workflow-summary job), extracts the version via extract_project_version.py, and confirms the tag is absent — real releases must run from main. The flow then branches on deploy_as_executable:
    • Library: download the CI-built dist (never rebuilds), publish to Test PyPI and verify a fresh install, push the v<version> tag, publish to PyPI and verify again, then create a GitHub Release with generated notes.
    • Executable: push the v<version> tag, download every exe-{os}-{python} artifact the CI executable job built, package each (tar on Linux / zip on Windows), and attach them all to a GitHub Release. No PyPI publish.
      All tag/publish/release jobs are skipped on dry_run.
  • Aligned git_tag.py with base/nuxt. Replaced the local fork with the base version (--version required, no pyproject.toml parsing), and collapsed the copier_template_resources/ symlink into a real file at template/.github/workflows/git_tag.py (matching its sibling extract_project_version.py). Updated all call sites in publish.yaml and release.yaml to source the version from extract_project_version.py and pass --version.
  • Docs. Documented the Release workflow in the generated README, plus a TODO to eventually merge Publish / Publish to Staging into Release.

What side effects does this change have?

  • CI now has an extra build job on every run (gated {% if not is_frozen_executable %} to match publish.yaml).
  • git_tag.py's CLI changed: --version is now required and it no longer prints/parses the version. Any external caller relying on the old no-arg print behavior must switch to extract_project_version.py.
  • create-tag gained a needs dependency (guard in release.yaml, get-values in publish.yaml) to obtain the version.
  • template/.github/workflows/git_tag.py changed from a symlink to a regular file; copier_template_resources/git_tag.py was deleted.

How is this change tested?

Rendered the template with copier (data1 / PyPI) and verified:

  • ci.yaml, release.yaml, publish.yaml all parse as YAML; job graph, needs, and dry_run guards asserted correct.
  • All git_tag.py call sites pass --version; version sourced from extract_project_version.py.
  • pylint on the rendered scripts: 10.00/10 (previously exit 8 / R0801). ruff and pyright pass on the source git_tag.py.
  • CodeArtifact conditional branches render structurally (kept for parity so existing CodeArtifact users aren't broken).

Final enforcement happens in the lint-matrix CI job, which generates across data1/2/3 and runs pre-commit on the output.

Other

  • Fixed a pre-existing template bug: is_frozen_executable (used to gate entrypoint.py, main.py, publish.yaml, publish_to_staging.yaml) is undefined and evaluates falsy — so executable projects shipped with no entrypoint.py/main.py yet still got PyPI publish workflows. Renamed all guards (plus the CI build job) to the real deploy_as_executable question. release.yaml is intentionally ungated — it serves both cases and branches internally; publish.yaml / publish_to_staging.yaml stay library-only. Verified renders: executables now get entrypoint.py/main.py, no publish, and a release.yaml that attaches the CI-built executables; libraries get publish/release + the CI build job and no entrypoint/main.
  • Test-data coverage gap (follow-up): after the fix, no tests/copier_data file is PyPI + library (data1/data3 = PyPI + executable, data2 = CodeArtifact + library), so lint-matrix no longer exercises the PyPI-library publish/release path. Consider a data file with python_package_registry: PyPI and deploy_as_executable: no.
  • release.yaml's create-tag pushes the tag before publish-to-primary; the GitHub Release step then attaches to that existing tag (softprops/action-gh-release handles a pre-existing tag gracefully — no conflict).

Summary by CodeRabbit

  • New Features
    • Added a gated Release workflow with dry-run support, version extraction, and safe Git tag checks.
    • Generated templates now support publishing releases.
    • Optional packaging and uploading of platform executables during release.
    • Added staging publishing and install/verification prior to production release.
  • Improvements
    • CI now conditionally builds/uploads distribution artifacts for release and updates the Codecov action reference.
    • Templates now automate version extraction and tag management for the release pipeline.
  • Documentation
    • Updated release guidance to reflect the new Release workflow and deployment options.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The template adds CI package builds, staging and primary release workflows, version and tag helper scripts, release documentation, and executable entrypoint generation. Copier configuration enables release publishing and tracks the new version-extraction script.

Changes

Release pipeline

Layer / File(s) Summary
CI distribution artifacts
extensions/context.py, template/.github/workflows/ci.yaml.jinja, .devcontainer/devcontainer.json
Configures the Codecov action reference, adds conditional distribution builds and artifacts, and updates workflow-summary validation.
Version and tag helpers
template/.github/workflows/extract_project_version.py, template/.github/workflows/git_tag.py, template/.github/workflows/{% if not deploy_as_executable %}publish.yaml{% endif %}.jinja, .config/.copier-managed-files.json
Adds version extraction and tag-management CLIs, registers the managed script, and passes the extracted version into publishing tag steps.
Staging publication workflow
template/.github/workflows/{% if not deploy_as_executable %}publish_to_staging.yaml{% endif %}.jinja
Adds lint, matrix testing, package building, and publishing to TestPyPI or AWS CodeArtifact.
Release orchestration
template/.github/workflows/release.yaml.jinja, .config/.copier-answers.yml, template/README.md.jinja
Adds guarded dry-run and release jobs for staging publication, installation checks, tagging, primary publication, GitHub Releases, and release documentation.
Executable entrypoint support
template/src/{{ package_name.replace('-', '_') }}/{% if deploy_as_executable %}main.py{% endif %}.jinja, template/src/{% if deploy_as_executable %}entrypoint.py{% endif %}.jinja
Adds the generated entrypoint function and CLI wrapper for executable deployments.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseWorkflow
  participant CI
  participant StagingRegistry
  participant GitTag
  participant PrimaryRegistry
  participant GitHubRelease
  ReleaseWorkflow->>CI: verify successful workflow-summary
  ReleaseWorkflow->>StagingRegistry: publish and verify distributions
  ReleaseWorkflow->>GitTag: confirm and push version tag
  ReleaseWorkflow->>PrimaryRegistry: publish and verify distributions
  ReleaseWorkflow->>GitHubRelease: create release and upload assets
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is related to the change but too vague to clearly describe the CI-backed release workflow. Rename it to mention the new release workflow or CI-backed publishing, e.g. "Add CI-backed release workflow".
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description covers the required sections and includes rationale, implementation, side effects, testing, and extras.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

@ejfine

ejfine commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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 `@template/.github/workflows/`{% if not deploy_as_executable
%}publish_to_staging.yaml{% endif %}.jinja:
- Around line 24-25: Set explicit timeout-minutes values for both the test job
and the publishing job in the workflow, including the corresponding publishing
block noted in the comment. Choose bounded durations appropriate for each job
and preserve their existing dependencies and steps.

In `@template/.github/workflows/ci.yaml.jinja`:
- Around line 133-145: Remove the duplicate OIDC authentication step before
“Build package” in the CodeArtifact branch, since install_deps already
authenticates when a CodeArtifact role is configured. Preserve the existing
code-artifact-auth.sh invocation only if it performs setup beyond
authentication; otherwise remove that invocation as well.

In `@template/.github/workflows/release.yaml.jinja`:
- Around line 167-223: Update both verification jobs around the dependency
display and import-check steps to add a CodeArtifact-specific authentication
step and install the exact released package version before importing it.
Preserve the existing PyPI installation flow, and ensure CodeArtifact renderings
configure registry credentials and install the requested package before each
import verification.
- Around line 226-246: Make the release workflow retryable by moving the
create-tag job after the final irreversible publication and GitHub Release
stages, or update the guard and git_tag.py checks to allow an existing tag only
when it points to github.sha. Ensure downstream publication and release steps
safely reuse that matching tag during reruns while still rejecting tags that
point elsewhere.
- Around line 117-126: Update the release workflow’s OIDC role and publish index
in the “Publish distribution to Code Artifact” step to target staging: use the
staging IAM role naming convention instead of GHA-CA-Primary-* and invoke the
staging CodeArtifact index instead of code-artifact-primary. Keep the existing
authentication script and publish command flow unchanged.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 72977867-9410-4f43-a82c-c0c43bbd914b

📥 Commits

Reviewing files that changed from the base of the PR and between 14aa2a6 and 0988527.

📒 Files selected for processing (13)
  • .config/.copier-answers.yml
  • .config/.copier-managed-files.json
  • copier_template_resources/git_tag.py
  • template/.github/workflows/ci.yaml.jinja
  • template/.github/workflows/extract_project_version.py
  • template/.github/workflows/git_tag.py
  • template/.github/workflows/git_tag.py
  • template/.github/workflows/release.yaml.jinja
  • template/.github/workflows/{% if not deploy_as_executable %}publish.yaml{% endif %}.jinja
  • template/.github/workflows/{% if not deploy_as_executable %}publish_to_staging.yaml{% endif %}.jinja
  • template/README.md.jinja
  • template/src/{% if deploy_as_executable %}entrypoint.py{% endif %}.jinja
  • template/src/{{ package_name.replace('-', '_') }}/{% if deploy_as_executable %}main.py{% endif %}.jinja
💤 Files with no reviewable changes (1)
  • copier_template_resources/git_tag.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 5

🤖 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 `@template/.github/workflows/`{% if not deploy_as_executable
%}publish_to_staging.yaml{% endif %}.jinja:
- Around line 24-25: Set explicit timeout-minutes values for both the test job
and the publishing job in the workflow, including the corresponding publishing
block noted in the comment. Choose bounded durations appropriate for each job
and preserve their existing dependencies and steps.

In `@template/.github/workflows/ci.yaml.jinja`:
- Around line 133-145: Remove the duplicate OIDC authentication step before
“Build package” in the CodeArtifact branch, since install_deps already
authenticates when a CodeArtifact role is configured. Preserve the existing
code-artifact-auth.sh invocation only if it performs setup beyond
authentication; otherwise remove that invocation as well.

In `@template/.github/workflows/release.yaml.jinja`:
- Around line 167-223: Update both verification jobs around the dependency
display and import-check steps to add a CodeArtifact-specific authentication
step and install the exact released package version before importing it.
Preserve the existing PyPI installation flow, and ensure CodeArtifact renderings
configure registry credentials and install the requested package before each
import verification.
- Around line 226-246: Make the release workflow retryable by moving the
create-tag job after the final irreversible publication and GitHub Release
stages, or update the guard and git_tag.py checks to allow an existing tag only
when it points to github.sha. Ensure downstream publication and release steps
safely reuse that matching tag during reruns while still rejecting tags that
point elsewhere.
- Around line 117-126: Update the release workflow’s OIDC role and publish index
in the “Publish distribution to Code Artifact” step to target staging: use the
staging IAM role naming convention instead of GHA-CA-Primary-* and invoke the
staging CodeArtifact index instead of code-artifact-primary. Keep the existing
authentication script and publish command flow unchanged.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 72977867-9410-4f43-a82c-c0c43bbd914b

📥 Commits

Reviewing files that changed from the base of the PR and between 14aa2a6 and 0988527.

📒 Files selected for processing (13)
  • .config/.copier-answers.yml
  • .config/.copier-managed-files.json
  • copier_template_resources/git_tag.py
  • template/.github/workflows/ci.yaml.jinja
  • template/.github/workflows/extract_project_version.py
  • template/.github/workflows/git_tag.py
  • template/.github/workflows/git_tag.py
  • template/.github/workflows/release.yaml.jinja
  • template/.github/workflows/{% if not deploy_as_executable %}publish.yaml{% endif %}.jinja
  • template/.github/workflows/{% if not deploy_as_executable %}publish_to_staging.yaml{% endif %}.jinja
  • template/README.md.jinja
  • template/src/{% if deploy_as_executable %}entrypoint.py{% endif %}.jinja
  • template/src/{{ package_name.replace('-', '_') }}/{% if deploy_as_executable %}main.py{% endif %}.jinja
💤 Files with no reviewable changes (1)
  • copier_template_resources/git_tag.py
🛑 Comments failed to post (5)
template/.github/workflows/{% if not deploy_as_executable %}publish_to_staging.yaml{% endif %}.jinja (1)

24-25: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Bound the test and publishing jobs with timeouts.

Both jobs can otherwise remain active for hours when tests, authentication, or registry uploads stall.

Proposed fix
   test:
     needs: [ lint ]
+    timeout-minutes: {% endraw %}{{ gha_medium_timeout_minutes }}{% raw %}

   build:
     needs: [ test ]
+    timeout-minutes: {% endraw %}{{ gha_medium_timeout_minutes }}{% raw %}

Also applies to: 59-61

🤖 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 `@template/.github/workflows/`{% if not deploy_as_executable
%}publish_to_staging.yaml{% endif %}.jinja around lines 24 - 25, Set explicit
timeout-minutes values for both the test job and the publishing job in the
workflow, including the corresponding publishing block noted in the comment.
Choose bounded durations appropriate for each job and preserve their existing
dependencies and steps.
template/.github/workflows/ci.yaml.jinja (1)

133-145: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if install_deps configures CodeArtifact globally in the job environment.
cat template/.github/actions/install_deps/action.yml || cat template/.github/actions/install_deps/action.yaml || echo "Action file not found"

Repository: LabAutomationAndScreening/copier-python-package-template

Length of output: 4436


Consider removing the duplicate CodeArtifact auth here. install_deps already performs OIDC auth when a CodeArtifact role is provided, so this configure-aws-credentials step is redundant unless code-artifact-auth.sh is doing extra setup.

🤖 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 `@template/.github/workflows/ci.yaml.jinja` around lines 133 - 145, Remove the
duplicate OIDC authentication step before “Build package” in the CodeArtifact
branch, since install_deps already authenticates when a CodeArtifact role is
configured. Preserve the existing code-artifact-auth.sh invocation only if it
performs setup beyond authentication; otherwise remove that invocation as well.
template/.github/workflows/release.yaml.jinja (3)

117-126: 🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win

Publish the staging build to the staging CodeArtifact repository.

This job currently assumes GHA-CA-Primary-* and invokes code-artifact-primary, so the staging phase writes to production before tagging and primary publication.

Proposed fix
-          role-to-assume: arn:aws:iam::{% endraw %}{{ aws_central_infrastructure_account_id }}{% raw %}:role/GHA-CA-Primary-{% endraw %}{{ repo_name }}{% raw %}
+          role-to-assume: arn:aws:iam::{% endraw %}{{ aws_central_infrastructure_account_id }}{% raw %}:role/GHA-CA-Staging-{% endraw %}{{ repo_name }}{% raw %}

-          uv publish --verbose --index code-artifact-primary --username aws --password "$TWINE_PASSWORD"
+          uv publish --verbose --index code-artifact-staging --username aws --password "$TWINE_PASSWORD"
📝 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.

      - name: OIDC Auth for Publishing to CodeArtifact
        uses: aws-actions/configure-aws-credentials@{% endraw %}{{ gha_configure_aws_credentials }}{% raw %}
        with:
          role-to-assume: arn:aws:iam::{% endraw %}{{ aws_central_infrastructure_account_id }}{% raw %}:role/GHA-CA-Staging-{% endraw %}{{ repo_name }}{% raw %}
          aws-region: {% endraw %}{{ aws_org_home_region }}{% raw %}

      - name: Publish distribution to Code Artifact
        run: |
          . .devcontainer/code-artifact-auth.sh
          uv publish --verbose --index code-artifact-staging --username aws --password "$TWINE_PASSWORD"
🤖 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 `@template/.github/workflows/release.yaml.jinja` around lines 117 - 126, Update
the release workflow’s OIDC role and publish index in the “Publish distribution
to Code Artifact” step to target staging: use the staging IAM role naming
convention instead of GHA-CA-Primary-* and invoke the staging CodeArtifact index
instead of code-artifact-primary. Keep the existing authentication script and
publish command flow unchanged.

167-223: 🎯 Functional Correctness | 🔴 Critical | 🏗️ Heavy lift

Add CodeArtifact installation paths to both verification jobs.

For CodeArtifact renderings, the only installation blocks disappear. The jobs proceed from checkout/setup directly to import verification without authentication or installing the requested version, so the AWS release path cannot complete.

Add CodeArtifact authentication and an exact-version registry install before each import check.

Also applies to: 322-378

🤖 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 `@template/.github/workflows/release.yaml.jinja` around lines 167 - 223, Update
both verification jobs around the dependency display and import-check steps to
add a CodeArtifact-specific authentication step and install the exact released
package version before importing it. Preserve the existing PyPI installation
flow, and ensure CodeArtifact renderings configure registry credentials and
install the requested package before each import verification.

226-246: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Make post-tag release retries recoverable.

The tag is pushed before primary publication, installation verification, and GitHub Release creation. Any later transient failure leaves the tag present, while reruns are rejected by the guard and tag helper.

Delay tagging until the last irreversible stage, or accept an existing tag only when it already points to ${{ github.sha }} and make downstream publication retry-safe.

🤖 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 `@template/.github/workflows/release.yaml.jinja` around lines 226 - 246, Make
the release workflow retryable by moving the create-tag job after the final
irreversible publication and GitHub Release stages, or update the guard and
git_tag.py checks to allow an existing tag only when it points to github.sha.
Ensure downstream publication and release steps safely reuse that matching tag
during reruns while still rejecting tags that point elsewhere.

# only upload coverage from fastest job
if: ${{ matrix.JOB_MATCHING_DEV_ENV && github.actor != 'dependabot[bot]' }} # dependabot by default doesn't have access to the necessary secret...and dependabot should never be changing coverage anyway so it's fine not uploading it
uses: codecov/codecov-action@v5.1.1
uses: codecov/codecov-action@v7.0.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

NIT: Should we pull this into context.py so its with all the other versions of things?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call — moved the version pin into extensions/context.py as gha_codecov alongside the other GHA action versions, and referenced it via {{ gha_codecov }} in the workflow.

1f0c209

Reply drafted by AI (Claude), reviewed and approved by the author before posting.

Comment on lines +101 to +103
environment:
name: testpypi
url: https://test.pypi.org/p/{% endraw %}{{ package_name | replace('_', '-') }}{% raw %}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should this be wrapped in an if check

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep — wrapped the environment: block in {% if python_package_registry == "PyPI" %} so it's only emitted for PyPI deployments. For AWS CodeArtifact the testpypi environment name and Test PyPI URL don't apply.

9b8f341

Reply drafted by AI (Claude), reviewed and approved by the author before posting.

DOWNLOAD_DIR="$(mktemp -d)"
for i in $(seq 1 12); do
if pip download --no-deps --index-url https://test.pypi.org/simple/ "${PKG}==${VER}" --dest "${DOWNLOAD_DIR}" --no-cache-dir --quiet; then
if pip install --index-url https://www.pypi.org/simple --find-links "${DOWNLOAD_DIR}" "${PKG}==${VER}" --no-cache-dir --quiet; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is this the wrong url?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The --index-url pointing at real PyPI is intentional: the package itself is installed from --find-links (downloaded from Test PyPI just above), while its dependencies resolve from PyPI. But www.pypi.org was non-canonical and inconsistent with the primary-install step, which uses pypi.org/simple. Dropped the www..

cac4b87

Reply drafted by AI (Claude), reviewed and approved by the author before posting.

Comment on lines +258 to +260
environment:
name: pypi
url: https://pypi.org/p/{% endraw %}{{ package_name | replace('_', '-') }}{% raw %}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same question as above. should we wrap this in an if check?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same fix as the staging job — wrapped the environment: block in {% if python_package_registry == "PyPI" %} so the pypi environment name and PyPI URL are only emitted for PyPI deployments, not for AWS CodeArtifact.

4723d2d

Reply drafted by AI (Claude), reviewed and approved by the author before posting.

ejfine and others added 4 commits July 15, 2026 15:41
Reference the codecov-action version via the gha_codecov context var
instead of hardcoding it inline, matching every other GHA action pin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The publish-to-staging environment name/URL only apply to PyPI
deployments; emit the block only when python_package_registry is PyPI
so AWS CodeArtifact deployments don't get a misleading testpypi
environment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Use the canonical https://pypi.org/simple for dependency resolution in
the staging install step, matching the primary install step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Same fix as publish-to-staging: emit the publish-to-primary environment
name/URL only when python_package_registry is PyPI, so AWS CodeArtifact
deployments don't get a misleading pypi environment.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
template/.github/workflows/release.yaml.jinja (2)

118-126: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Staging publishes to the primary CodeArtifact registry.

The AWS CodeArtifact configuration for publish-to-staging uses the GHA-CA-Primary-{% endraw %}{{ repo_name }}{% raw %} role and the code-artifact-primary index. This identical configuration is used again in publish-to-primary (lines 277, 283). Publishing to the primary registry during the staging phase bypasses staging isolation and will likely cause the primary publish step to fail due to version conflicts (e.g., HTTP 409).

Please ensure the staging step uses a dedicated staging role and index, or conditionally omit the staging publish step if your CodeArtifact setup does not use a staging registry.

🤖 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 `@template/.github/workflows/release.yaml.jinja` around lines 118 - 126, Update
the publish-to-staging workflow configuration to avoid the primary CodeArtifact
registry: use the dedicated staging IAM role and CodeArtifact index for its
credentials and uv publish command. If no staging registry configuration exists,
omit the staging publish step instead; keep publish-to-primary using
GHA-CA-Primary-{{ repo_name }} and code-artifact-primary.

167-203: 🎯 Functional Correctness | 🔴 Critical | 🏗️ Heavy lift

Missing installation steps for AWS CodeArtifact.

The pip install logic is entirely nested inside {% if python_package_registry == "PyPI" %} with no fallback for AWS CodeArtifact. Consequently, the runner will never have the package installed, causing the subsequent "Confirm library can be imported successfully" script to fail (either failing to import entirely, or importing local source code and failing the site-packages/dist-packages path assertion).

  • template/.github/workflows/release.yaml.jinja#L167-L203: add an {% else %} block to authenticate and run pip install for the staging CodeArtifact registry.
  • template/.github/workflows/release.yaml.jinja#L323-L356: add an {% else %} block to authenticate and run pip install for the primary CodeArtifact registry.
🤖 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 `@template/.github/workflows/release.yaml.jinja` around lines 167 - 203, Add an
{% else %} branch to the release workflow’s staging installation block at
template/.github/workflows/release.yaml.jinja lines 167-203 that authenticates
with the staging AWS CodeArtifact registry and installs the package with pip;
add the corresponding {% else %} branch at lines 323-356 for the primary AWS
CodeArtifact registry. Keep the existing PyPI paths unchanged and ensure both
CodeArtifact paths install the built version before the import verification
step.
template/.github/workflows/ci.yaml.jinja (1)

120-145: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Don't run uv build with AWS/CodeArtifact creds in scope

This pull_request job assumes CoreInfraBaseAccess and sources .devcontainer/code-artifact-auth.sh before uv build; because this project has no [build-system], uv build falls back to legacy setuptools, so build backend/hook code can read those env vars. Split auth into a trusted job or clear credentials before building, and set persist-credentials: false on checkout.

🤖 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 `@template/.github/workflows/ci.yaml.jinja` around lines 120 - 145, The Build
package step must not run while AWS/CodeArtifact credentials are available. In
the python_package_registry == "AWS CodeArtifact" path, separate dependency
authentication from the build or clear all credential-related environment
variables before uv build, and set persist-credentials: false on the
actions/checkout step. Preserve dependency installation authentication while
ensuring legacy build backend hooks cannot access those credentials.
🤖 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 `@template/.github/workflows/release.yaml.jinja`:
- Around line 228-234: The create-tag job is currently excluded from executable
releases and the release job does not wait for it. In
template/.github/workflows/release.yaml.jinja lines 228-234, close the
deploy_as_executable condition before create-tag and make its
install-from-staging dependency conditional; in lines 250-256, reopen the
condition before publish-to-primary; and in lines 387-389, add create-tag to the
release job’s needs so both release types validate and push the tag before
creating the GitHub Release.

---

Outside diff comments:
In `@template/.github/workflows/ci.yaml.jinja`:
- Around line 120-145: The Build package step must not run while
AWS/CodeArtifact credentials are available. In the python_package_registry ==
"AWS CodeArtifact" path, separate dependency authentication from the build or
clear all credential-related environment variables before uv build, and set
persist-credentials: false on the actions/checkout step. Preserve dependency
installation authentication while ensuring legacy build backend hooks cannot
access those credentials.

In `@template/.github/workflows/release.yaml.jinja`:
- Around line 118-126: Update the publish-to-staging workflow configuration to
avoid the primary CodeArtifact registry: use the dedicated staging IAM role and
CodeArtifact index for its credentials and uv publish command. If no staging
registry configuration exists, omit the staging publish step instead; keep
publish-to-primary using GHA-CA-Primary-{{ repo_name }} and
code-artifact-primary.
- Around line 167-203: Add an {% else %} branch to the release workflow’s
staging installation block at template/.github/workflows/release.yaml.jinja
lines 167-203 that authenticates with the staging AWS CodeArtifact registry and
installs the package with pip; add the corresponding {% else %} branch at lines
323-356 for the primary AWS CodeArtifact registry. Keep the existing PyPI paths
unchanged and ensure both CodeArtifact paths install the built version before
the import verification step.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 452bb4de-efa1-4f02-984a-bbd70ca0952c

📥 Commits

Reviewing files that changed from the base of the PR and between 0988527 and 4723d2d.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • .devcontainer/devcontainer.json
  • extensions/context.py
  • template/.github/workflows/ci.yaml.jinja
  • template/.github/workflows/release.yaml.jinja

Comment thread template/.github/workflows/release.yaml.jinja
@ejfine
ejfine marked this pull request as ready for review July 15, 2026 17:04
On the executable path there is no create-tag job, so
action-gh-release auto-creates the tag when the release job runs.
Set target_commitish to github.sha so the tag points at the commit
that passed CI in guard, not whatever is main HEAD at release time.
No-op on the library path where the tag already exists.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
template/.github/workflows/release.yaml.jinja (2)

228-256: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Create the tag only after primary publication and validation.

create-tag currently completes before publish-to-primary and install-from-primary. If either downstream job fails, the tag remains pushed while the next run is rejected by the guard because the tag already exists, requiring manual recovery or a version change. Move tag creation after primary validation, or make the full release path explicitly retry-safe.

🤖 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 `@template/.github/workflows/release.yaml.jinja` around lines 228 - 256, The
create-tag job currently runs before primary publication and validation, leaving
pushed tags when downstream jobs fail. Update the workflow dependencies so
create-tag executes only after publish-to-primary and install-from-primary
complete successfully, while preserving its existing guard, dry-run condition,
tag confirmation, and push steps.

136-203: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Both CodeArtifact validation jobs skip installation.

The backend condition only implements installation for PyPI. Add CodeArtifact authentication and install the exact guarded version before validation in both locations:

  • template/.github/workflows/release.yaml.jinja#L136-L203: install from the staging CodeArtifact registry.
  • template/.github/workflows/release.yaml.jinja#L291-L356: install from the primary CodeArtifact registry.
🤖 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 `@template/.github/workflows/release.yaml.jinja` around lines 136 - 203, The
CodeArtifact validation paths skip installation because the workflow only
handles PyPI. In template/.github/workflows/release.yaml.jinja lines 136-203,
add CodeArtifact authentication and install the exact
needs.guard.outputs.version from the staging registry before validation; apply
the corresponding authentication and exact-version installation from the primary
CodeArtifact registry in lines 291-356. Preserve the existing PyPI behavior and
validation flow.
🤖 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.

Outside diff comments:
In `@template/.github/workflows/release.yaml.jinja`:
- Around line 228-256: The create-tag job currently runs before primary
publication and validation, leaving pushed tags when downstream jobs fail.
Update the workflow dependencies so create-tag executes only after
publish-to-primary and install-from-primary complete successfully, while
preserving its existing guard, dry-run condition, tag confirmation, and push
steps.
- Around line 136-203: The CodeArtifact validation paths skip installation
because the workflow only handles PyPI. In
template/.github/workflows/release.yaml.jinja lines 136-203, add CodeArtifact
authentication and install the exact needs.guard.outputs.version from the
staging registry before validation; apply the corresponding authentication and
exact-version installation from the primary CodeArtifact registry in lines
291-356. Preserve the existing PyPI behavior and validation flow.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a163b84a-acb3-48fe-8974-0a478b886080

📥 Commits

Reviewing files that changed from the base of the PR and between 4723d2d and 82d8846.

📒 Files selected for processing (1)
  • template/.github/workflows/release.yaml.jinja

@ejfine
ejfine merged commit 25437f2 into main Jul 15, 2026
21 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.

2 participants