Skip to content

feat: tag-triggered release workflow for wheel, sdist and Windows bundle - #159

Merged
wpak-ai merged 7 commits into
masterfrom
feat/tag-triggered-release-workflow
Jul 30, 2026
Merged

feat: tag-triggered release workflow for wheel, sdist and Windows bundle#159
wpak-ai merged 7 commits into
masterfrom
feat/tag-triggered-release-workflow

Conversation

@clean6378-max-it

@clean6378-max-it clean6378-max-it commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Closes #155

Adds a release workflow that runs when you push a version tag. It builds the Python packages and the Windows zip, checks that all three files are there, then attaches them to the GitHub Release. You can also trigger the build jobs manually without publishing. CI now installs pywebview for the Windows PyInstaller step so it matches what the release job ships.

I dry-ran the build locally on 0.2.0: wheel about 154 KiB, sdist about 225 KiB, Windows zip about 36 MiB. The exe passed a --help smoke test. A test tag on a fork is still the way to confirm publish end-to-end before we cut 0.2.1.

Summary by CodeRabbit

  • New Features

    • Release workflow can be triggered manually for build verification; publishing is still limited to v* tag pushes.
    • Added a check to ensure the expected release artifacts (wheel, sdist, and Windows bundle) are present before publishing.
  • Bug Fixes

    • Improved Windows desktop packaging by ensuring the required webview dependency is installed during the PyInstaller build.
  • Documentation

    • Refined “GitHub Releases” instructions for matching pyproject.toml version with the pushed tag, and updated related wording.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The release workflow supports manual builds while publishing only on tag pushes, validates exactly three expected release assets, and documents version matching. Windows packaging now installs pywebview and retains webview as a hidden import.

Changes

Release automation

Layer / File(s) Summary
Build artifact prerequisites
.github/workflows/tests.yml, cursor-browser.spec
The Windows/Python 3.12 packaging job installs pywebview, and the PyInstaller configuration retains webview as a hidden import.
Controlled release publication
.github/workflows/release.yml, README.md
Manual dispatch is supported, publishing remains restricted to tag pushes, the downloaded assets must contain exactly one versioned wheel, one versioned source archive, and the Windows zip, and release documentation explains version matching and artifact naming.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Trigger
  participant ReleaseWorkflow
  participant AssetVerification
  participant GitHubRelease
  Trigger->>ReleaseWorkflow: Push v* tag or manually dispatch workflow
  ReleaseWorkflow->>ReleaseWorkflow: Build Python and Windows artifacts
  ReleaseWorkflow->>AssetVerification: Verify exactly three expected assets
  AssetVerification->>GitHubRelease: Publish assets for tag push
Loading

Suggested reviewers: wpak-ai

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR fully implements all acceptance criteria from issue #155: new release.yml workflow triggered on v* tags, builds wheel/sdist via python -m build, builds Windows bundle from spec, uploads all three assets, pins Actions to SHAs, and includes dry-run evidence.
Out of Scope Changes check ✅ Passed All changes are within scope: release.yml workflow addition, README documentation updates, cursor-browser.spec comment clarification, and tests.yml pywebview installation for Windows PyInstaller parity.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: a tag-triggered release workflow that builds and publishes the wheel, sdist, and Windows bundle.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/tag-triggered-release-workflow

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

@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: 2

🤖 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 @.github/workflows/release.yml:
- Line 3: Update the release documentation to describe tags without implying
annotation requirements: in .github/workflows/release.yml lines 3-3 and 12-12,
replace “annotated version tag” and “annotated test tag” with “version tag” and
“test tag”; in README.md line 268, replace “annotated tag” with “tag”.
- Around line 20-21: Change the workflow-level permissions to grant contents:
read by default, then add job-level contents: write permissions only to the
publish job. Ensure the build jobs retain read access and do not inherit write
access.
🪄 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

Run ID: a6671609-70f2-4c47-9aab-56b31585baca

📥 Commits

Reviewing files that changed from the base of the PR and between b2a4d0d and 94aa46b.

📒 Files selected for processing (3)
  • .github/workflows/release.yml
  • README.md
  • cursor-browser.spec

Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml Outdated
@clean6378-max-it clean6378-max-it self-assigned this Jul 30, 2026

@bradjin8 bradjin8 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Should fix] Issue #155 acceptance criteria and Verification section ask for a fork tag push or dry run with the resulting artifact names and sizes recorded in the PR body.

The workflow header (release.yml:7–10) and README table document expected names and local 0.2.0 wheel/sdist sizes, but this PR body only has local sanity-check commands - no fork Actions run link or actual uploaded asset sizes (especially CursorChatBrowser-windows.zip).

Please add a short "Release workflow verification" section here with either:

  • a fork tag push (e.g. v0.0.0-test) + link to the Actions run and the three asset filenames/sizes from the Release, or
  • a dry-run summary from a local python -m build + pyinstaller run including the Windows zip size at the locked dependency tree.

Without that, we won't know the publish job works end-to-end before is-10.

[Nice to have] .github/workflows/tests.yml:123

cursor-browser.spec now lists webview as a hiddenimport (see spec line 20), and the release workflow correctly installs pywebview before PyInstaller. The unittest matrix Windows PyInstaller steps (123–129) still build without pywebview, so CI only smoke-tests --help and does not exercise the same bundle graph as the published Release asset.

Consider adding python -m pip install 'pywebview>=5.0,<7' to the Windows 3.12 PyInstaller block (matching release.yml:68–74) so CI validates the desktop bundle we actually ship.

Comment thread cursor-browser.spec Outdated
Comment thread .github/workflows/release.yml
Comment thread .github/workflows/release.yml
Comment thread README.md Outdated
@clean6378-max-it

clean6378-max-it commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

[Should fix] Issue #155 acceptance criteria and Verification section ask for a fork tag push or dry run with the resulting artifact names and sizes recorded in the PR body.

The workflow header (release.yml:7–10) and README table document expected names and local 0.2.0 wheel/sdist sizes, but this PR body only has local sanity-check commands — no fork Actions run link or actual uploaded asset sizes (especially CursorChatBrowser-windows.zip).

Please add a short "Release workflow verification" section here with either:

  • a fork tag push (e.g. v0.0.0-test) + link to the Actions run and the three asset filenames/sizes from the Release, or
  • a dry-run summary from a local python -m build + pyinstaller run including the Windows zip size at the locked dependency tree.

Without that, we won't know the publish job works end-to-end before is-10.

[Nice to have] .github/workflows/tests.yml:123

cursor-browser.spec now lists webview as a hiddenimport (see spec line 20), and the release workflow correctly installs pywebview before PyInstaller. The unittest matrix Windows PyInstaller steps (123–129) still build without pywebview, so CI only smoke-tests --help and does not exercise the same bundle graph as the published Release asset.

Consider adding python -m pip install 'pywebview>=5.0,<7' to the Windows 3.12 PyInstaller block (matching release.yml:68–74) so CI validates the desktop bundle we actually ship.

Added a dry-run table above with local wheel, sdist, and Windows zip sizes from the locked tree.
Also added workflow_dispatch so we can run the build jobs without tagging; publish still requires a v* tag.

Windows 3.12 PyInstaller step now installs pywebview>=5.0,<7 before the build, same as release.yml.

@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: 2

🤖 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 @.github/workflows/release.yml:
- Around line 122-130: The “Verify release asset set” step must validate
artifact filenames against the intended release version, not only extensions and
counts. Derive the release version from the workflow’s existing tag/version
symbol, then assert the single .whl and .tar.gz names contain that version while
preserving the existing three-file and Windows ZIP checks.
- Line 105: Update the release publish condition to require both github.ref_type
== 'tag' and github.event_name == 'push', keeping manually dispatched tag runs
build-only. In the asset validation step, verify the expected
cppa_cursor_browser-<version>-py3-none-any.whl and
cppa_cursor_browser-<version>.tar.gz filenames in addition to the existing wheel
and sdist count checks.
🪄 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

Run ID: ef89cd26-b892-4c4d-91fe-0d097023c75f

📥 Commits

Reviewing files that changed from the base of the PR and between 0571377 and 8b8eca2.

📒 Files selected for processing (4)
  • .github/workflows/release.yml
  • .github/workflows/tests.yml
  • README.md
  • cursor-browser.spec
🚧 Files skipped from review as they are similar to previous changes (2)
  • cursor-browser.spec
  • README.md

Comment thread .github/workflows/release.yml Outdated
Comment thread .github/workflows/release.yml
@clean6378-max-it
clean6378-max-it requested a review from wpak-ai July 30, 2026 18:41

@wpak-ai wpak-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.

  1. .github/workflows/release.yml:80-81, .github/workflows/tests.yml:136-138: replace both --help smoke tests with an assertion that the pywebview payload actually landed, e.g. fail when dist\CursorChatBrowser\_internal\webview\lib is absent, and add an explicit shell: pwsh to the release step (the step gating the Windows binary cannot fail for two independent reasons, launcher.py:24 exits on --help before import webview at line 27 while PyInstaller logs an unresolved hidden import and exits 0, and console=False at cursor-browser.spec:58 makes the exe GUI-subsystem so the default pwsh never waits or sets $LASTEXITCODE, so this PR's own fix has no test that can observe it and a windowless exe would publish silently)

  2. .github/workflows/release.yml:11: replace the v0.0.0-test fork rehearsal with v0.2.0, which matches pyproject today and exercises the full path including publish (the documented recipe can never produce a Release, because the verify step derives the expected wheel name from the tag while hatchling names it from pyproject's 0.2.0, and Version("0.0.0-test") raises InvalidVersion so retagging pyproject to match is impossible, this is the recipe for issue #155's Part E acceptance criterion)

  3. pyproject.toml, .github/workflows/release.yml:123, README.md:268, CHANGELOG.md:113: add a preflight step at the top of build-python comparing ${GITHUB_REF_NAME#v} against [project].version and failing with a message naming both values (the tag-equals-pyproject invariant is instructed in the README, stored in pyproject, mirrored by the CHANGELOG headings and compare links, and enforced only by a bare test -f in the final job, so editing one surface without the others costs both builds and surfaces as an unexplained non-zero exit)

  4. .github/workflows/release.yml:72, .github/workflows/tests.yml:126, pyproject.toml:29: add a check that the pywebview range in both workflows matches [project.optional-dependencies].desktop, since installing the extra directly would bypass requirements-lock.txt and is not a clean substitute (pywebview>=5.0,<7 is written out three times character-identically and the comment at tests.yml:123 asserts the copies match, but nothing enforces it, so a bump in pyproject would silently leave the shipped Windows bundle built against the old range)

@clean6378-max-it

Copy link
Copy Markdown
Collaborator Author
  1. .github/workflows/release.yml:80-81, .github/workflows/tests.yml:136-138: replace both --help smoke tests with an assertion that the pywebview payload actually landed, e.g. fail when dist\CursorChatBrowser\_internal\webview\lib is absent, and add an explicit shell: pwsh to the release step (the step gating the Windows binary cannot fail for two independent reasons, launcher.py:24 exits on --help before import webview at line 27 while PyInstaller logs an unresolved hidden import and exits 0, and console=False at cursor-browser.spec:58 makes the exe GUI-subsystem so the default pwsh never waits or sets $LASTEXITCODE, so this PR's own fix has no test that can observe it and a windowless exe would publish silently)
  2. .github/workflows/release.yml:11: replace the v0.0.0-test fork rehearsal with v0.2.0, which matches pyproject today and exercises the full path including publish (the documented recipe can never produce a Release, because the verify step derives the expected wheel name from the tag while hatchling names it from pyproject's 0.2.0, and Version("0.0.0-test") raises InvalidVersion so retagging pyproject to match is impossible, this is the recipe for issue cppa-cursor-browser: tag-triggered release workflow that builds and attaches artifacts #155's Part E acceptance criterion)
  3. pyproject.toml, .github/workflows/release.yml:123, README.md:268, CHANGELOG.md:113: add a preflight step at the top of build-python comparing ${GITHUB_REF_NAME#v} against [project].version and failing with a message naming both values (the tag-equals-pyproject invariant is instructed in the README, stored in pyproject, mirrored by the CHANGELOG headings and compare links, and enforced only by a bare test -f in the final job, so editing one surface without the others costs both builds and surfaces as an unexplained non-zero exit)
  4. .github/workflows/release.yml:72, .github/workflows/tests.yml:126, pyproject.toml:29: add a check that the pywebview range in both workflows matches [project.optional-dependencies].desktop, since installing the extra directly would bypass requirements-lock.txt and is not a clean substitute (pywebview>=5.0,<7 is written out three times character-identically and the comment at tests.yml:123 asserts the copies match, but nothing enforces it, so a bump in pyproject would silently leave the shipped Windows bundle built against the old range)

Pushed fixes for all four.
Dropped the --help smoke test on both workflows; we now check that webview/lib exists after the PyInstaller build, and the release Windows steps run under pwsh.
The fork rehearsal note says v0.2.0 instead of v0.0.0-test. build-python compares the tag to pyproject before building. Pywebview installs read the [desktop] pin through read_desktop_pywebview_spec.py, and lockfile runs check_pywebview_workflow_pin.py so the version range does not get pasted into the YAML.

That last bit had to move out of tests.yml because the inline guard was matching its own file and failing CI.

@clean6378-max-it
clean6378-max-it requested a review from wpak-ai July 30, 2026 20:43
@wpak-ai
wpak-ai merged commit afc21e4 into master Jul 30, 2026
18 checks passed
@wpak-ai
wpak-ai deleted the feat/tag-triggered-release-workflow branch July 30, 2026 21:08
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.

cppa-cursor-browser: tag-triggered release workflow that builds and attaches artifacts

3 participants