The Laminas Project has close to 200 repositories between the main project, Laminas API Tools, and Mezzio.
It’s a lot to maintain, and keeping on top of incoming patches can be a gargantuan task, much less creating releases.
That’s why this past year, we’ve spent a bunch of time on streamlining our processes; we want to be able to review, merge, and release changes quickly and confidently.
To that end, we have developed a number of GitHub Actions to make these processes as easy as possible for our maintainers.
Automated Releases
The first was a brainchild of Marco Pivetta (aka Ocramius).
He wanted a way to make releases as simple as possible.
Before this, we had a rather convoluted process:
- If a pull request was against our “master” branch:
- Merge to “master”
- Merge to “develop” (which generally resulted in merge conflicts, due to differences in the
CHANGELOG.md
file between branches) - Create a branch off of “master” to set the release version
- Bump the release version in the
CHANGELOG.md
- Merge the release branch into “master”
- Merge the release branch into “develop” (again, merge conflicts)
- Tag the release, copying the relevant
CHANGELOG.md
entry into the tag description - Push the release
- Create a release on GitHub from the tag, and, again, copy the
CHANGELOG.md
entry into the description
- If a pull request was against our “develop” branch:
- Merge to “develop”
- Merge “develop” to “master”
- Create a branch off of “master” to set the release version
- Bump the release version in the
CHANGELOG.md
- Merge the release branch into “master”
- Merge the release branch into “develop”
- Bump the release version in the
CHANGELOG.md
file in the “develop” branch to the next minor version - Tag the release from “master”, copying the relevant
CHANGELOG.md
entry into the tag description - Push the release
- Create a release on GitHub from the tag, and, again, copy the
CHANGELOG.md
entry into the description
A lot of the work around tagging and creating the GitHub release are handled by my keep-a-changelog tooling, but it was still work, and there was a lot of boilerplate and busywork involved.
Marco’s big idea: what if we assigned issues and pull requests to GitHub milestones, and, when the milestone was closed, the release was created automatically?
This led to the creation of our automatic-releases GitHub action.
To work with it, you need to create release branches in your repository, named after semantic versions, and of the form {MAJOR}.{MINOR}.x
(that’s a literal “.x” at the end).
(This has a nice side benefit of removing the “master” verbiage from our branches as well.)
You then create milestones named for the next releases you want to create: 1.2.3
, 1.3.0
, 2.0.0
.
From there, you add a small workflow to your application, along with a few secrets (a GPG signing key, a Git author and email for tagging the release, and potentially a privileged GitHub token to allow creating a merge-up request; more on that later).
As you triage, assign your issues and pull requests to milestones.
When all issues and pull requests related to a milestone are complete, you close the milestone, and the workflow takes it from there.
What the workflow does:
- It pulls the milestone description.
- It pulls the list of issues and pull requests, along with the people who created them, to create a list of release notes detailing the issues/pull requests closed.
- If you have a
CHANGELOG.md
in the Keep A Changelog format, it will update the entry for the release to append the milestone description and release notes pulled in the previous steps, as well as set the release date, pushing the changes back to the branch. - It creates a tag using the signing key and git author/email, setting the description to the the changelog entry, or the information from the first two steps, pushing the tag on completion.
- It creates a release on GitHub, using the same notes provided in the tag description.
- If a newer release branch exists (e.g., if you were rele
Truncated by Planet PHP, read more at the original (another 9599 bytes)