enh(CI): Automatic Release Workflow #58
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.

Automatic Release Workflow
This PR introduces a
releaseworkflow that runs on the first day of every month, checks for changes onmasterand, if so, creates a new release after approval.Tag Selection
The
verifyjob selects a tag name with format%Y.%m.%d(e.g.2025.08.01), which always ends in01since it runs on the first day of each month. If the tag is newer than the previous one and there are changes inmaster, then the workflow generates a change summary and continues to thereleasejob, which requests a review and awaits for approval.The examples below use format
%Y.%m.%d-%Hfor faster (test) release cycles, but everything else is the same.Summary
The summary is generated with
git diff --histogram --stat $latest_tag..$release_commitandgit log --no-merges $latest_tag..$release_commit, so merge commits are not displayed.To prevent new commits from being integrated into the release without showing up on the summary, the
verifyjob also provides therelease_commitused.Release Summary
Checks
Each tag is checked to be newer using lexicographical order, which works for
%Y.%m.%d. Just be aware of any additional text after the date. For example,2025.07.01-2is considered newer than2025.07.01-10.After that, the last commit on
masteris compared to the$latest_tag, and the release is skipped if no change is reported.In both cases, skipping the relase is not considered a failure. The workflow just finishes early and no notification is sent anywhere.
Outdated Release
Release with No Changes
Manual Release
The job can also be triggered manually on Actions page, with an optional
release_tagdifferent from%Y.%m.%d. You can also change the deployenvironmentfor this manual run.Full Page
Workflow Review
Once
verifycompletes with a non-emptyrelease_tag, the workflow request reviews from defined members before starting thereleasejob.The
releasejob pins the release to exact$release_commitprovided byverify, independently of how long the review process take. Once a release is verified, its commit is fixed. To include newer commits you must cancel and rerun the workflow.Release Verified, Awaiting Review
Review Notification Sent to Email
Review Page
Release Approved
Release Created
GitHub Environment
Important
This step requires manual configuration in the repository Settings.
The review system uses deploy environments on Github. The workflow doesn't actually use any information from the environment, but if the environment is configured with "Required reviewers", then it won't run by itself. Here I used
releaseas the name of the environment.Environment Settings
Job Concurrency
To avoid multiple competing releases, I've set up a
concurrencygroupthat disallows concurrent runs of therelease.ymlworkflow. If a new workflow starts while the last one is still running, then the new one has priority and the other is cancelled. In practice, this should only happen if a release is left unapproved for more than a month.Unapproved Release
Release Creation
Once the
releasejob is approved and runs, it creates a tag with the name$release_tagprovided byverify, pointing to the pinned$release_commit. It also creates a GitHub release with automatically generated release notes, which can be configured in a.github/release.ymlfile. By default, the generated notes list all pull requests since the last release (which might be a lot for the first one here, you can create a first release to avoid this).Changelog Example
Implementation Notes
There's currently an issue (actions/checkout#1467) with
fetch_tagson Git 2.48 (ubunut-latest), which requires explicit fetching of the git history usingfetch-depthandref. I used the last 100 commits forfetch-depth, which should be more than enough for a month. The workaround implemented here can be removed after the fix actions/checkout#2200 lands.