Skip to content

Release automatically when the version changes - #14

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

jonathan-kosgei merged 1 commit into
masterfrom
auto-release

Conversation

@jonathan-kosgei

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

Copy link
Copy Markdown
Collaborator

Summary

A merge to master that puts a new ## x.y.z heading at the top of CHANGELOG.md is now enough to tag the release and create the GitHub release; Packagist picks the tag up through its webhook, so no manual tagging is needed. The README gets a maintainer-facing "Releasing" section and the changelog an entry under 0.1.3.

How it works

  • A release job in ci.yml runs on push to the default branch only (guarded by github.event_name == 'push' and github.ref == refs/heads/<default branch>), after build-lowest-version and build have succeeded, with permissions: contents: write and a release concurrency group that does not cancel runs in progress. On pull requests it is skipped.
  • It reads the version from the first ## x.y.z heading of CHANGELOG.md (composer.json has no version field; Packagist reads the versions from the tags) and uses it as the tag name without a v prefix, matching the existing tags 0.1.0 to 0.1.2.
  • git ls-remote --exit-code --tags origin refs/tags/<tag> decides what happens: exit 0 means the tag exists, so the job says so and ends with created=false; exit 2 means it is missing, so gh release create <tag> --target $GITHUB_SHA --title <tag> --generate-notes creates the tag and the release in one step with the workflow's GITHUB_TOKEN and the job ends with created=true; any other exit code fails the job.
  • The job exposes tag and created outputs so a publish job could be attached later; nothing publishes from CI here because Packagist is fed by its webhook.

Verification

  • python3 -c 'import yaml,sys; [yaml.safe_load(open(f)) for f in sys.argv[1:]]' .github/workflows/*.yml passes.
  • actionlint .github/workflows/*.yml (v1.7.12) reports nothing.
  • The version command sed -nE 's/^## ([0-9][^[:space:]]*).*/\1/p' CHANGELOG.md | head -1 prints 0.1.3 on this branch.
  • Both step scripts were run locally with a stub gh: for 0.1.2 (tagged) the job reports that the tag exists and sets created=false; for 0.1.3 (untagged) it calls gh release create 0.1.3 --target <sha> --title 0.1.3 --generate-notes and sets created=true. Against this repository git ls-remote --exit-code returns 0 for 0.1.2 and 2 for 0.1.3.
  • The push-triggered release job itself can only run after the merge. CHANGELOG.md already carries ## 0.1.3 at the top and no 0.1.3 tag exists, so the first push to master after merging this PR tags 0.1.3 at that merge commit and creates its release.

🤖 Generated with Claude Code

Add a release job to the CI workflow that runs on pushes to the default
branch once the test jobs have passed. It reads the first "## x.y.z"
heading of CHANGELOG.md and, when no tag of that name exists, creates
the tag and the GitHub release with generated notes in one step;
Packagist picks the tag up through its webhook. A push whose version is
already tagged releases nothing.

Document the flow in a README "Releasing" section and in the changelog.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@jonathan-kosgei
jonathan-kosgei merged commit 8b8be80 into master Nov 3, 2026
14 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