Skip to content

chore: release-process v2#2761

Merged
tempusfrangit merged 2 commits intomainfrom
chore/release-process-v2
Feb 23, 2026
Merged

chore: release-process v2#2761
tempusfrangit merged 2 commits intomainfrom
chore/release-process-v2

Conversation

@tempusfrangit
Copy link
Contributor

@tempusfrangit tempusfrangit commented Feb 23, 2026

Summary

Overhauls the release process and adds Homebrew cask support for macOS installs.

supersedes: #2755
closes: #2738

Release process

Three release types, all from a single workflow pair:

Type Example Branch Draft? PyPI/crates.io
Stable v0.17.0 main only Yes Yes
Pre-release v0.17.0-alpha3 main only Yes Yes
Dev v0.17.0-dev1 any branch No (immediate GH pre-release) No
  • release-build.yaml: builds CLI (goreleaser), SDK wheel, coglet wheels (3 platforms), creates GH release. Draft for stable/pre-release, published pre-release for dev.
  • release-publish.yaml: triggered on publish. Pushes to PyPI, crates.io, and updates Homebrew tap (stable only). Skips entirely for dev releases.
  • Deleted version-bump.yaml — just edit crates/Cargo.toml directly.

Homebrew cask

  • Adds update-homebrew-tap job that generates a macOS cask (Intel + ARM) from goreleaser checksums and pushes to replicate/homebrew-tap via the cog-homebrew-tapbot GitHub App
  • Runs only for stable releases, after PyPI and crates.io publishing completes
  • Cask includes postflight xattr clearing so users never hit the Gatekeeper warning (fix: add xattr workaround for macOS Gatekeeper warning #2754)
  • Updates README, getting-started docs, install script to recommend brew install replicate/tap/cog

Other improvements

  • Replaced third-party robinraju/release-downloader with gh release download
  • Removed unused attestations: write permission
  • Explicit is_dev guard on publish-pypi-sdk (defense in depth)
  • PEP 440 version conversion handles dotted prerelease identifiers (e.g. beta.1)
  • Switched crates.io to OIDC trusted publishing
  • Moved goreleaser (CLI build) from publish to build step so binaries are on the draft

Setup required

  1. Create GH environments: pypi, crates-io, homebrew (with v* tag restriction)
  2. Install cog-homebrew-tapbot app (ID: 1232932405) with write access to replicate/homebrew-tap
  3. Add secret COG_HOMEBREW_TAP_PRIVATE_KEY to the homebrew environment

Co-authored-by: Mark Phelps (@markphelps)

tempusfrangit and others added 2 commits February 23, 2026 10:34
…ases from anywhere

- Stable and pre-release tags (v0.17.0, v0.17.0-alpha3) must be on main,
  create draft releases, publish to PyPI and crates.io
- Dev tags (v0.17.0-dev1) can be from any branch, publish immediately
  as GH pre-releases with full artifacts, skip PyPI/crates.io
- Move goreleaser (CLI build) from publish to build step so CLI binaries
  are available on draft releases before publishing
- Switch crates.io to OIDC trusted publishing
- Delete version-bump.yaml (just edit Cargo.toml directly)
- Add PEP 440 version conversion and SETUPTOOLS_SCM_PRETEND_VERSION
- Update README with new three-tier release documentation
Add update-homebrew-tap job to release-publish.yaml that generates a
Homebrew cask for macOS (Intel + ARM) from goreleaser checksums, pushed
to replicate/homebrew-tap via the cog-homebrew-tapbot GitHub App. Runs
only for stable releases, after PyPI and crates.io publishing completes.

Update README, getting-started docs, install script, and llms.txt to
recommend brew install replicate/tap/cog as the primary macOS install.

Also:
- Add explicit is_dev guard to publish-pypi-sdk (defense in depth)
- Fix PEP 440 sed to handle dotted prerelease (e.g. beta.1)
- Replace robinraju/release-downloader with gh release download
- Remove unused attestations:write permission

Co-authored-by: Mark Phelps <mphelps@cloudflare.com>
@tempusfrangit
Copy link
Contributor Author

The secret has been already added.

Copy link
Contributor

@meatballhat-cf meatballhat-cf left a comment

Choose a reason for hiding this comment

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

One seemingly-weird bit is that (IIUC) we're duplicating some of goreleaser's capabilities because we want to do something slightly different, which is why all goreleaser releases are "draft".

@tempusfrangit
Copy link
Contributor Author

One seemingly-weird bit is that (IIUC) we're duplicating some of goreleaser's capabilities because we want to do something slightly different, which is why all goreleaser releases are "draft".

The reason for this change was to provide ourselves a clear draft -> release process without rebuilding the artifacts. The draft feels cleaner than "boom" we have a release. However, I'm 100% open to going with goreleaser on it's own if you'd prefer. I defer to the desires of the team if you'd like me to move us back to the more immediate "release" process.

@tempusfrangit
Copy link
Contributor Author

Chatted with @meatballhat-cf - we can always refine as we go.

@tempusfrangit tempusfrangit merged commit 10ef2f5 into main Feb 23, 2026
37 checks passed
@tempusfrangit tempusfrangit deleted the chore/release-process-v2 branch February 23, 2026 19:36
@tempusfrangit tempusfrangit added this to the 0.17.0 Release milestone Feb 24, 2026
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.

Fix codesigning on release binaries

2 participants