Skip to content

Add documentation #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
max_line_length = unset
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
# @metamask/create-release-branch

This is an interactive command-line tool that automates steps involved in preparing for a new release of a project. These steps include updating versions of one or more desired packages, adding a new section to said packages' changelogs which includes changes since ther previous releases, and then creating a new branch from which a pull request can be submitted for review before the release goes live.
This is an interactive command-line tool that automates steps involved in preparing for a new release of a project. These steps include updating versions of one or more desired packages, adding a new section to said packages' changelogs which includes changes since the previous releases, and then creating a new branch from which a pull request can be submitted for review before the release goes live.

## Installation

TODO
Add this tool as a development dependency to your project:

```
yarn add --dev @metamask/create-release-branch
```

or:

```
npm install --save-dev @metamask/create-release-branch
```

## Usage

TODO
For more on how to use this tool, please see the [docs](./docs).

## Contributing

Expand Down
8 changes: 8 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Documentation

This directory holds a collection of guides that explain what role this tool plays in the release process and how to use it for different kinds of projects. It's recommended you go through these in order if you're new to this tool:

- [Understanding your project](./understanding.md)
- [Setting up your project](./setup.md)
- [Using this tool](./usage.md)
- [Addendum: Maintaining the changelog](./changelog.md)
15 changes: 15 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Addendum: Maintaining the changelog

We use [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) as a guide for writing changelogs. To summarize, however, the goal of a changelog is to document the noteworthy changes that have been made to the project. Although this tool provides some automation around keeping changelogs up to date, they are designed to be maintained by hand.

After running this tool, you'll want to follow a few steps:

1. First, you'll want to ensure that each change entry has been placed into an appropriate change category (see [here](https://keepachangelog.com/en/1.0.0/#types) for the full list of change categories as well as the correct ordering).

2. Next, you'll want to curate the entries in each category. This could mean:

- **Rewording/rephrasing.** The changelog should be understandable by anyone who wants to use your project, regardless of their experience. Although references to modules/interfaces may be necessary, prefer abstract and non-technical language over jargon.
- **Consolidation.** A changelog entry represents a complete unit of work, and some work may be split across multiple commits. In this case, you can combine multiple entries together, listing multiple PRs instead of just one.
- **Omission.** Some changes do not affect end users of the project (e.g. lockfile changes, development environment changes, etc.). In these cases, you may remove these entries entirely. Exceptions may be made for changes that might be of interest despite not having an effect upon the published package (e.g. major test improvements, security improvements, improved documentation, etc.).

3. Once you're made your edits, make sure to run `yarn auto-changelog validate --rc` to check that the changelog is correctly formatted.
54 changes: 54 additions & 0 deletions docs/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Setting up your project

There are three different type of projects that this tool supports: packages that live within a polyrepo architecture (or stand alone), monorepos that use a "fixed" versioning strategy, and monorepos that use an "independent" versioning strategy (see [here](./understanding.md) for more about the implications between them). The tool has the ability to detect the difference between these at runtime, provided that some requirements are met.

## Polyrepos

By default, the tool will assume your project is within a polyrepo, so if that is the case, you can start using the tool right away — there's no additional setup needed.

## Monorepos

To determine whether a project is a monorepo, the tool will look at the project's `package.json` file for a non-empty `workspaces` field, which lists directories that hold packages you want to publish.

To determine which versioning strategy a monorepo is using, the tool will look for a `release.config.json` file within the root directory of the project. This file should define an object, and that object should have a `versioningStrategy` property. The expected value for this property and associated requirements are explained below.

### Monorepos with fixed versions

For a monorepo with fixed versions, you will want to add a `release.config.json` with a `versioningStrategy` of `"fixed"`.

Combined with the changes above, this might look like:

```
# package.json
{
"version": "1.0.0",
"workspaces": ["packages/*"],
}

# release.config.json
Copy link
Contributor Author

@mcmire mcmire Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I first opened this PR, I had placed this option in package.json. I changed it based on a discussion I had with Ricky, but from standup this morning, it sounds like we do want to keep this inside of package.json. So I can change this back — but that said we do need to put this option under a namespace. Initially that namespace was @metamask/create-release-branch, however, we also need action-publish-release to be able to access the versioning strategy as well. So what should the namespace be? Here are some options:

  • @metamask
  • @metamask/releases
  • @metamask/release-config
  • something else entirely

cc @Gudahtt @rickycodes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those three options all sounds reasonable to me.

If you want help choosing, I would choose @metamask/release-config, but I don't really have a preference.

Copy link
Member

@Gudahtt Gudahtt Jul 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and if you'd prefer keeping this setting in a separate config file, that is perfectly fine with me too. Ultimately I don't think it matters much.

That is what I meant to express when we talked about this at standup last week - that I didn't want to impose the requirement that the config be external for just a single boolean, even though I have a strong personal preference for using external config for dev tooling whenever possible. At the time I hadn't been aware this was updated to use a separate file already. Just clarifying in case I gave the impression that I had a strong preference for avoiding the extra file, that was not the intention.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. It sounds like both you and Ricky have said you'd prefer a separate file than keeping it in package.json so I'll go with this for now and if we want to change it later we can :)

{
"versioningStrategy": "fixed"
}
```

### Monorepos with independent versions

For a monorepo with independent versions, you will want to:

1. Add a `release.config.json` with a `versioningStrategy` of `"independent"`.
2. Change the format of the `version` within the root `package.json` from `<major>.<minor>.<patch>` to `<yyyymmdd>.1.0` (where `yyyymmdd` is a date in ISO format without the dashes, and `1` is the build number, which will be incremented with successive releases).

Combined with the changes above, this might look like:

```
# package.json
{
"version": "20220607.1.0",
"workspaces": ["packages/*"],
}

# release.config.json
{
"versioningStrategy": "independent"
}
```
27 changes: 27 additions & 0 deletions docs/understanding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Understanding your project

Before you use this tool, you'll want to answer a couple of questions about your project:

1. Are you using the tool within a monorepo architecture?
2. If you have a monorepo, are you using a fixed versioning strategy for your packages or an independent versioning strategy?

The answers to these questions impact how you use this tool.

## Structure

This tool is designed for two methods of organizing publishable code within an ecosystem:

- Multiple-package repository (also called a **monorepo** architecture). In this type of setup, you have a suite of NPM packages that are contained within a single repository. When you issue a release, you may want to publish a new version of a subset — or the entirety of — these packages.
- Single-package repository (also called a **polyrepo** architecture). Here, you have a suite of packages spread out across multiple repositories, where one repository houses exactly one NPM package. When you issue a release, you will publish a new version of that package and only that package.

The nature of your project changes the workflow behind this tool. For a monorepo specifically, the process involved in preparing a release is more complex than in the polyrepo case, as the tool needs to discover and operate on files within multiple directories within your project instead of just one.

## Versioning strategy (monorepo only)

If you have a monorepo, there are a couple of different ways that you can maintain versions across your packages.

If you are following a **fixed** versioning strategy, it means that your monorepo has a top-level version, and when you issue a new release, you will update this version along with any packages you want to include in the release to the same version.

If you are following an **independent** versioning strategy, your monorepo has no such top-level version, so when you issue a new release, you may update the versions of packages without the need to synchronize those versions with any other packages.

The strategy you're using also changes the workflow behind this tool. It's slightly more complex if you're using the "independent" strategy, as in the fixed case, you will need to specify only one release version, which will be applied across all packages you want to release, whereas in the independent case, you will need to specify a version for each of the packages you want to release.
39 changes: 39 additions & 0 deletions docs/usage-monorepo-fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Using the tool in a monorepo with fixed versions

For a monorepo using a "fixed" versioning strategy, the tool needs to know not only which version you want to release, but also which packages you want to release.

Start by running:

```
create-release-branch
```

The tool will generate a "release specification", which is a YAML file, and open it in your editor (or, if it cannot detect an appropriate editor, output the path to the file for you to open yourself). This file represents an object which contains two properties:

- **`releaseVersion`:** Specifies the new version that you want to release. The value of this property can either be:
- `major` if you want to bump the major part of the current version (e.g., if the current version is 1.0.0, then the release version would be 2.0.0).
- `minor` if you want to bump the minor part of the current version (e.g. if the current version is 1.0.0, then the release version would be 1.1.0).
- `patch` if you want to bump the patch part of the current version (e.g. if the current version is 1.0.0, then the release version would be 1.0.1).
- An exact version such as `1.2.3`.
- **`packages`:** An array that lists the names of workspace packages that you want to release. The versions of the packages provided here will be changed to the `releaseVersion`. This list will be populated with all of the packages that have any changed since the previous release. You should not change this list.

A typical release spec, once edited, might look like this:

```
releaseVersion: major
packages:
- @metamask/base-controller
- @metamask/controller-utils
- @metamask/transaction-controller
- @metamask/assets-controllers
```

Once you've filled out the release spec, save and close it, and the tool will continue. (Or, if the tool couldn't detect your editor and you had to edit the file manually, then run `create-release-branch` again to resume.)

At this point, the tool will:

1. Adjust the `version` of the root package, and all of the specified packages, to the specified version.
2. Go through each workspace package specified, and:
1. Read the Git history of the repo to extract the names of the commits which have made any changes to any files within the package since the Git tag that corresponds to the current version of the package.
2. Add a new section to the changelog for the package which is titled by the release version and which lists the commits gathered.
3. Commit the changes to a new branch called `release/<release-version>` (e.g. `release/1.2.3`) and switch to that branch.
41 changes: 41 additions & 0 deletions docs/usage-monorepo-independent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Using the tool in a monorepo with independent versions

For a monorepo using an "independent" versioning strategy, the tool needs to know which packages you want to release and how to set the version for each package.

Start by running:

```
create-release-branch
```

The tool will generate a "release specification", which is a YAML file, and open it in your editor (or, if it cannot detect an appropriate editor, output the path to the file for you to open yourself). This file represents an object that contains one property, `packages`. The value of this property is also an object, where:

- Each property is the name of the workspace package you want to release.
- Each value specifies the new version the package should receive. This can either be:
- `major` if you want to bump the major part of the current version (e.g., if the current version is 1.0.0, then the release version would be 2.0.0).
- `minor` if you want to bump the minor part of the current version (e.g. if the current version is 1.0.0, then the release version would be 1.1.0).
- `patch` if you want to bump the patch part of the current version (e.g. if the current version is 1.0.0, then the release version would be 1.0.1).
- An exact version such as `1.2.3`.

The `packages` object will be populated with all of the packages that have changed since the previous release. You should not change this list.

A typical release spec, once edited, might look like this:

```
packages:
"@metamask/base-controller": major
"@metamask/controller-utils": minor
"@metamask/transaction-controller": patch
"@metamask/assets-controllers": 1.2.3
```

Once you've filled out the release spec, save and close it, and the tool will continue. (Or, if the tool couldn't detect your editor and you had to edit the file manually, then run `create-release-branch` again to resume).

At this point, the tool will:

1. Calculate a new release version by extracting the build number from the current version, incrementing it, and combining it with the current date, then setting the `version` of the root package to this new version.
2. Go through each workspace package specified, and:
1. Adjust the `version` of the package to the version specified.
2. Read the Git history of the repo to extract the names of the commits which have made any changes to any files within the package since the Git tag that corresponds to the current version of the package.
3. Add a new section to the changelog for the package which is titled by the release version and which lists the commits gathered.
3. Commit the changes to a new branch called `release/<release-version>`, where `<release-version>` is the version calculated in step one (e.g. `release/2022.6.8-123`), and switch to that branch.
39 changes: 39 additions & 0 deletions docs/usage-polyrepo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Using the tool for a polyrepo package

For a package within a polyrepo architecture, the tool needs to know the new version of the package you want to release. This can happen one of two ways:

1. You can have the tool determine the release version automatically by bumping the major, minor, or patch part of the current version.

For instance, if the current version is 1.0.0, then this command would bump the version to 2.0.0:

```
create-release-branch --bump major
```

If the current version is 1.0.0, then this command would bump the version to 1.1.0:

```
create-release-branch --bump minor
```

If the current version is 1.0.0, then this command would bump the version to 1.0.1:

```
create-release-branch --bump patch
```

2. You can provide the version exactly. For instance, this command would change the version to 1.2.3 regardless of the current version:

```
create-release-branch --version 1.2.3
```

After you run the command, the tool will:

1. Adjust the version of the package to the version specified.
2. Read the Git history of the repo to extract the names of the commits which have occurred since the Git tag that corresponds to the current version.
3. Add a new section to the changelog for the release version which lists the commits gathered.
4. Commit the changes to a new branch called `release/<release-version>` (e.g. `release/1.2.3`) and switch to that branch.

At this point, you'll need to revise the changelog to place the newly added entries within the appropriate categories and to edit them to be more easily understood by users of the project.
Read [this guide](./changelog.md) for more on how to do this.
7 changes: 7 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Using this tool

You will follow a slightly different workflow depending on what kind of package architecture and/or versioning strategy you are using:

- [Package within a polyrepo](./usage-polyrepo.md)
- [Monorepo with fixed versions](./usage-monorepo-fixed.md)
- [Monorepo with independent versions](./usage-monorepo-independent.md)