This project is a Github Action that allows maintainers of open-source projects that follow SemVer to automate the automation of releases.
To use this automation in your own repository, copy the examples/.github
workflows into your own project:
cd /tmp
git clone https://github.com/laminas/automatic-releases.git
cd /path/to/your/project
cp -r /tmp/automatic-releases/examples/.github ./.github
git add .github
git commit -m "Added release automation"
To get started you need to create a branch for the next release. e.g. if your next milestone will be
3.2.0
a 3.2.x
branch is required.
Then add following secrets to your project or organization:
GIT_AUTHOR_NAME
- full name of the author of your releases: can be the name of a bot account.GIT_AUTHOR_EMAIL
- email address of the author of your releases: can be an email address of a bot account.SIGNING_SECRET_KEY
- a password-less private GPG key in ASCII format, to be used for signing your releases: please use a dedicated GPG subkey for this purpose. Unsigned releases are not supported, and won't be supported.ORGANIZATION_ADMIN_TOKEN
- if you use the file fromexamples/.github/workflows/release-on-milestone-closed.yml
, then you have to provide aORGANIZATION_ADMIN_TOKEN
(with a full repo scope), which is a github token with administrative rights over your organization (issued by a user that has administrative rights over your project). This is required for thelaminas:automatic-releases:switch-default-branch-to-next-minor
command, because changing default branch of a repository currently requires administrative token rights. You can generate a token from your personal access tokens page.
Assuming your project has Github Actions enabled, each time you close a milestone, this action will perform all following steps (or stop with an error):
- determine if all issues and pull requests associated with this milestone are closed
- determine if the milestone is named with the SemVer
x.y.z
format - create a changelog by looking at the milestone description and associated issues and pull requests
- select branch
x.y.z
for the release (e.g.1.1.x
for a1.1.0
release) - create a tag named
x.y.z
on the selected branch, with the generated changelog - publish a release named
x.y.z
, with the generated tag and changelog - create (if applicable), a pull request from the selected branch to the next release branch
- create (if necessary) a "next minor" release branch
x.y+1.z
- switch default repository branch to newest release branch
Please read the feature/
specification for more detailed scenarios on how the tool is supposed
to operate.
In this model we operate with release branches (e.g. 1.0.x
, 1.1.x
, 1.2.x
).
This provides a lot of flexibility whilst keeping a single workflow.
The current default release branch should be used. The default branch is always automatically changed after a new release is created.
An example is Mezzio that has 3.2.x
as the current default release branch for simple features and
deprecation notices and 4.0.x
for the next major release.
Bug fixes should be applied on the version which introduced the issue and then synchronized all way to the current default release branch via merge-ups.
When releasing a new version x.y.z
, a new branch will be created x.y+1.z
and will be set as the next
default release branch.
To keep branches synchronized merge-ups are used.
That consists in getting the changes of a specific released branch merged all the way up to the current default branch. This ensures that all release branches are up-to-date and will never present a bug which has already been fixed.
Example
Let's say we've released the versions 1.0.0
and 1.1.0
.
New features are being developed on 1.2.x
.
After a couple weeks, a bug was found on version 1.0.0
.
The fix for that bug should be done based on the branch 1.0.x
and, once merged, the branches should be updated in this way:
- Create a branch from the fixed
1.0.x
(git checkout 1.0.x && git checkout -b merge-up/1.0.x-into-1.1.x
) - Create a PR using
1.1.x
as destination - Create a branch from the fixed
1.1.x
(git checkout 1.1.x && git checkout -b merge-up/1.1.x-into-1.2.x
) - Create a PR using
1.2.x
as destination
- Checkout to merge-up branch (
git checkout -b merge-up/1.1.x-into-1.2.x
) - Sync merge-up branch (
git merge --no-ff origin/1.2.x
) - Solve conflicts (using
git mergetool
or through an IDE) - Resume merge (
git merge --continue
) - Push (
git push
)