Closed Gudahtt closed 1 year ago
Here are my thoughts on what sort of changes we could make to this action in order to achieve this goal.
It's important to know up front that right now this action reads the version we want to release (the "release version") from the branch being merged. This is being changed in #46 to read from the version in package.json
, so we will assume that.
Once we know what the release version is, we follow one of two workflows:
CHANGELOG.md
and extract the section of the changelog that matches the release version.gh
command-line utility to create a new GitHub release which is titled the same as the release version and has the content of the section of the changelog as obtained in the previous step.v${releaseVersion}
(e.g. if the release version is 1.2.3
, the tag will be called v1.2.3
).CHANGELOG.md
in the root, we go through all of the packages that the monorepo holds (as specified via the root package.json
's workspaces
field), and for each package, we extract the section of its CHANGELOG.md
that matches the release version. We stitch these sections into one big changelog, where each section is headered by the package that it belongs to.gh
command-line utility to create a new GitHub release, using the release version for the title and the big changelog as obtained in the previous step as the release notes. This will end up also creating a Git tag which is named v${releaseVersion}
(e.g. if the release version is 1.2.3
, the tag will be called v1.2.3
).For polyrepos, everything should work how it works now.
But for monorepos, there's a problem with the existing flow: it assumes that when a release is created, all packages will be bumped to the same version. This may continue to be true for snaps-skunkworks
and eslint-config
, but will not be true for controllers
, because we will be following an independent versioning strategy, where 1) every package can have a different version and 2) not every package may be bumped when a new release is issued.
Therefore, the changes we need to make are as follows:
snaps-skunkworks
or eslint-config
, we can default this strategy to "fixed", but allow it to be set to "independent".version
listed in the root package's package.json
. The root package is private, so as it stands, assigning a version like <major>.<minor>.<patch>
to this package doesn't make sense. It may make more sense to assign a date, such as <year>.<month>.<day>
. To account for the case in which we want to create more than one release in a day, we may want to add a fourth part, so in order to stay SemVer-compatible, the format could be <year>.<month>.<day>-<release number>
. (The semver
library should be able to handle this, but we can check.) The "release number" here would be a number that would be incremented for each new release. We would probably want to ensure that this number is valid by pulling the latest of the set of Git tags that matches this format, and (assuming that such a tag exists) confirm that the new version increases the number at the end by 1.package.json
to its currently published version on NPM. Any packages where these two versions differ we can assume require new releases.CHANGELOG.md
— only instead of using the release version to find the appropriate section, we use the version in package.json
for that package. As before, though, we then stitch the sections of the changelogs from each package into one big changelog, where each section is headered by the package that it belongs to.gh
command-line utility to create a new GitHub release, using the big changelog from the previous step as the release notes. For the title, however, we can parse the date from the release version, so for example, 2022.6.30-1234
might turn into "June 30, 2022 (release 1234)". We can also instruct the gh
command to create a Git tag named after the release version — although we can drop the v
, since it's not a real version.git tag <new version>
, then call git push --tags
at the end. (Note that in order to do this, we may want to move the entire of contents of scripts/create-github-release.sh
into the TypeScript script. That may make things easier to test.)In summary, here are the things we need to decide, in the case of a monorepo with an independent versioning strategy:
scripts/create-github-release.sh
be folded into the TypeScript code?For inspiration, take a look at Vercel, which more or less follows the same process that we want to follow: https://github.com/vercel/vercel
Just an update on this: Instead of having this action take a second input, we should read the value of versionSynchronizationStrategy
from some sort of configuration object that is kept in the repo as described here: https://github.com/MetaMask/create-release-branch/blob/88ec7e222c8c8e3fa88534c0ebda331a117911db/docs/setup.md. @rickycodes and I are discussing in Slack whether this configuration object lives in package.json
or in a separate file entirely, so until that's resolved we can work around it for now by continuing to have a second action input, and then tweak it in a later PR.
Another update: instead of using a version format of <year>.<month>.<day>-<release number>
for the root package, we should use <yyyy><mm><dd>.<release number>.0
, so that we don't create a prerelease version.
Here's the relevant part of the Notion doc which describes how this action fits into the larger workflow. This might be helpful to gain more context: https://www.notion.so/Core-Monorepo-Release-Automation-a65b28ab89a14c9d82dcf9fabc3eb1e1#aa00c0fc1e404448884f41c4998602e6
Currently this action only supports monorepos with synchronized versions. We will soon be using monorepos that don't use synchronized versions, so this will need to be updated to support that.