Skip to content

Release automatically when the version changes - #6

Merged
jonathan-kosgei merged 1 commit into
mainfrom
auto-release
Nov 3, 2026
Merged

jonathan-kosgei merged 1 commit into
mainfrom
auto-release

Conversation

@jonathan-kosgei

@jonathan-kosgei jonathan-kosgei commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Merging a pull request that bumps the version in the README install snippet is now enough to tag and publish a GitHub release; no manual tagging is needed. A release job is added to ci.yml after the two test matrices, and a maintainer-facing "Releasing" section is added to the README. Nothing else is published from CI: Swift Package Manager and the Swift Package Index resolve releases from the Git tags.

How it works

  • The release job runs only on push to the default branch (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)), after test-linux and test-macos succeed, with permissions: contents: write and concurrency: { group: release, cancel-in-progress: false } so two merges never race.
  • It reads the version from the from: argument of the README install snippet (sed -nE 's/.*from: *"([^"]+)".*/\1/p' README.md | head -1) and derives the tag v<version>.
  • git ls-remote --exit-code --tags origin "refs/tags/$TAG" decides what happens: exit 0 means the tag exists, so the job logs that and stops; exit 2 means it is missing, so gh release create "$TAG" --target "$GITHUB_SHA" --title "$TAG" --generate-notes (with GH_TOKEN: ${{ github.token }}) creates the tag and the release at the merge commit; any other exit status fails the job without releasing anything.
  • The job exposes tag and created outputs. On pull_request runs it is skipped.
  • The README currently names 1.0.2 and no v1.0.2 tag exists, so the first push to main after this merges will create v1.0.2 and its release.

Verification

  • python3 -c 'import yaml,sys; [yaml.safe_load(open(f)) for f in sys.argv[1:]]' .github/workflows/*.yml parses the workflow, and actionlint 1.7.12 reports nothing.
  • The version command prints 1.0.2 against the checked-out README. The new README text deliberately does not contain from: ", so it can never be picked up instead of the install snippet.
  • The two run: scripts were executed locally with bash -eo pipefail against the real remote and a stub gh: a missing tag (v1.0.2) calls gh release create v1.0.2 --target <sha> --title v1.0.2 --generate-notes and sets created=true; an existing tag (v1.0.1) sets created=false and does not call gh; a failing git ls-remote fails the job without calling gh; a README without a version fails the job.
  • The push-triggered release job itself cannot run before this is merged. The pull_request CI run on this branch shows it as skipped, with the test matrices unchanged.

🤖 Generated with Claude Code

Add a release job to ci.yml that runs on pushes to the default branch
after both test matrices succeed. It reads the version from the `from:`
argument of the README install snippet and, when the tag vX.Y.Z does not
exist yet, creates the tag and the GitHub release at the pushed commit
with generated notes. Swift Package Manager and the Swift Package Index
resolve releases from the tags, so no further publishing step is needed.
Document the flow in a Releasing section of the README.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@jonathan-kosgei
jonathan-kosgei merged commit 9a7d1ef into main Nov 3, 2026
10 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