Skip to content

ci: publish only on release tags and verify tag matches version - #825

Open
fern-support wants to merge 1 commit into
mainfrom
fix/ci-publish-only-on-version-tags
Open

fern-support wants to merge 1 commit into
mainfrom
fix/ci-publish-only-on-version-tags

Conversation

@fern-support

@fern-support fern-support commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

 on(push tag)
-  if ref is any tag
+  if ref is a tag and not fern-*
     poetry install
+    if tag != pyproject version
+      fail "Bump the version in pyproject.toml before tagging"
     poetry publish --build

Fern pushes fern-generation-base--fernapi--fern-python-sdk during regeneration, and that tag was triggering a real PyPI upload. When the release tag landed later, its run failed with 400 File already exists. This happened for both 7.3.0 and 7.3.1.

poetry publish --build takes the version from pyproject.toml, not the tag name. So bumping only the tag (7.3.2 → same commit as 7.3.1) rebuilt 7.3.1 and failed again.

Evidence

  • Before:

    • 41850606088: fern-generation-base--* tag → publish ✅ (7.3.1 on PyPI 14:47 UTC)
    • 41899473479: 7.3.1 tag → ❌ File already exists ('cohere-7.3.1.tar.gz')
    • 41902228322: 7.3.2 tag → ❌ File already exists ('cohere-7.3.1.tar.gz')
    • 39622333985: 7.3.0 tag → ❌ same pattern (Fern tag published it 43 min earlier)
  • After:

    • fern-* tag → publish job skipped
    • 7.3.2 tag on a commit where pyproject says 7.3.1 → fails at "Verify tag matches package version" with a clear error, before anything is uploaded
    • X.Y.Z tag matching pyproject → publishes as before

    The new paths haven't run in CI yet; the YAML was checked by parsing it locally.

Merge Danger

Door: two-way

Revert restores the old trigger. ci.yml is in .fernignore, so Fern regeneration won't overwrite it.

Blast Radius: releases

Publishing now happens only from the release tag. Releases need pyproject.toml to match the tag exactly (no v prefix), which is true of all existing tags.

Generated with Claude Code


Note

Medium Risk
Changes release automation and PyPI publishing gates; a misconfigured condition could skip or block legitimate releases, but behavior for matching release tags stays the same.

Overview
Tightens the publish job so PyPI uploads no longer run on Fern’s fern-* regeneration tags—only on normal release tags—and adds a guard so the git tag must match poetry version --short from pyproject.toml before poetry publish --build.

The publish if condition now uses startsWith(github.ref, 'refs/tags/') and explicitly excludes refs/tags/fern-*, with comments documenting why. A new Verify tag matches package version step fails the job with a GitHub Actions error if GITHUB_REF_NAME and the package version differ, avoiding mistaken uploads when the tag name and built artifact version are out of sync.

Reviewed by Cursor Bugbot for commit 989ae22. Bugbot is set up for automated code reviews on this repo. Configure here.

Fern's `fern-generation-base--*` tag was triggering the publish job,
uploading the version to PyPI before the release tag was pushed. The
release tag run then failed with "File already exists" (7.3.0, 7.3.1).

Also fail fast when the tag name doesn't match pyproject.toml, since
`poetry publish --build` uses the pyproject version, not the tag
(7.3.2 tag rebuilt and re-uploaded 7.3.1).

Co-Authored-By: Claude <noreply@anthropic.com>
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