Skip to content

Commit

Permalink
feat: add intended release channel (#694)
Browse files Browse the repository at this point in the history
* feat: intended release channel

* refactor: prerelease to boolean

* chore: pr title

* refactor: remove prerelease flag
  • Loading branch information
iowillhoit authored Feb 27, 2023
1 parent 40e1088 commit ddcd1b1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 42 deletions.
6 changes: 2 additions & 4 deletions messages/cli.release.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@
"flags": {
"startFromNpmDistTag": "the npm dist-tag to start the release from, examples: nightly, latest-rc",
"startFromGithubRef": "a Github ref to start the release from, examples: main, 7.144.0, f476e8e",
"releaseChannel": "the channel intended for this release, examples: nightly, latest-rc, latest, dev, beta, etc...",
"resolutions": "bump the versions of packages listed in the resolutions section",
"pinnedDeps": "bump the versions of the packages listed in the pinnedDependencies section",
"jit": "bump the versions of the packages listed in the jitPlugins (just-in-time) section",
"label": "add one or more labels to the Github PR",
"only": "only bump the version of the packages passed in, uses latest if version is not provided",
"patch": "bump the release as a patch of an existing version, not a new minor version",
"prerelease": "name of the prerelease to create, examples: dev, alpha",
"buildOnly": "only build the release, do not git add/commit/push",
"snapshot": "update the snapshots and commit them to the PR",
"schema": "update the schemas and commit them to the PR"
"buildOnly": "only build the release, do not git add/commit/push"
}
}
67 changes: 29 additions & 38 deletions src/commands/cli/release/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export default class build extends SfCommand<void> {
char: 'g',
exactlyOne: ['start-from-npm-dist-tag', 'start-from-github-ref'],
}),
'release-channel': Flags.string({
summary: messages.getMessage('flags.releaseChannel'),
char: 'c',
required: true,
}),
'build-only': Flags.boolean({
summary: messages.getMessage('flags.buildOnly'),
default: false,
Expand Down Expand Up @@ -65,27 +70,23 @@ export default class build extends SfCommand<void> {
}),
patch: Flags.boolean({
summary: messages.getMessage('flags.patch'),
exclusive: ['prerelease'],
}),
prerelease: Flags.string({
summary: messages.getMessage('flags.prerelease'),
exclusive: ['patch'],
}),
snapshot: Flags.boolean({
summary: messages.getMessage('flags.snapshot'),
deprecated: true,
}),
schema: Flags.boolean({
summary: messages.getMessage('flags.schema'),
deprecated: true,
}),
};

/* eslint-disable complexity */
public async run(): Promise<void> {
const { flags } = await this.parse(build);

const pushChangesToGitHub = !flags['build-only'];

const isPrerelease = !['latest', 'latest-rc', 'nightly'].includes(flags['release-channel']);

if (isPrerelease) {
this.log(
`NOTE: The release channel '${flags['release-channel']}' is not one of 'latest', 'latest-rc', 'nightly'. It will released as a prerelease.`
);
}

const auth = pushChangesToGitHub
? ensureString(
new Env().getString('GH_TOKEN') ?? new Env().getString('GITHUB_TOKEN'),
Expand All @@ -108,11 +109,14 @@ export default class build extends SfCommand<void> {

// TODO: We might want to check and see if nextVersion exists in npm
// Determine the next version based on if --patch was passed in or if it is a prerelease
const nextVersion = repo.package.determineNextVersion(flags.patch, flags.prerelease);
const nextVersion = repo.package.determineNextVersion(
flags.patch,
isPrerelease ? flags['release-channel'] : undefined
);
repo.nextVersion = nextVersion;

// Prereleases and patches need special branch prefixes to trigger GitHub Actions
const branchPrefix = flags.patch ? 'patch/' : flags.prerelease ? 'prerelease/' : '';
const branchPrefix = flags.patch ? 'patch/' : isPrerelease ? 'prerelease/' : '';

const branchName = `${branchPrefix}${nextVersion}`;

Expand All @@ -128,16 +132,6 @@ export default class build extends SfCommand<void> {
// Create a new branch that matches the next version
await this.exec(`git switch -c ${branchName}`);

if (flags.patch && pushChangesToGitHub) {
// Since patches can be created from any previous dist-tag or github ref,
// it is unlikely that we would be able to merge these into main.
// Before we make any changes, push this branch to use as our PR `base`.
// The build-patch.yml GHA will watch for merges into this branch to trigger a patch release
// TODO: ^ update this GHA reference once it is decided

await this.exec(`git push -u origin ${branchName}`);
}

// bump the version in the pjson to the next version for this tag
this.log(`Setting the version to ${nextVersion}`);
repo.package.setNextVersion(nextVersion);
Expand Down Expand Up @@ -179,14 +173,6 @@ export default class build extends SfCommand<void> {
// Run an install with deduplicated dependencies (with scripts)
await this.exec('yarn install');

if (flags.snapshot) {
this.warn('snapshot flag is deprecated. Skipping snapshot updates.');
}

if (flags.schema) {
this.warn('schema flag is deprecated. Skipping schema updates.');
}

this.log('Updates complete');

if (pushChangesToGitHub) {
Expand All @@ -201,17 +187,22 @@ export default class build extends SfCommand<void> {

const [repoOwner, repoName] = repo.package.packageJson.repository.split('/');

// TODO: Review this after prerelease flow is solidified
const prereleaseDetails =
'\n**IMPORTANT:**\nPrereleases work differently than regular releases. Github Actions watches for branches prefixed with `prerelease/`. As long as the `package.json` contains a valid "prerelease tag" (1.2.3-dev.0), a new prerelease will be created for EVERY COMMIT pushed to that branch. If you would like to merge this PR into `main`, simply push one more commit to this branch that sets the version in the `package.json` to the version you\'d like to release.';
const releaseDetails = `
> **Note**
> Patches and prereleases often require very specific starting points and changes.
> These changes cannot always be shipped from \`main\` since it is likely ahead in commits.
> Because of this the release process is slightly different, they "ship" from the PR itself.
> Once your PR is ready to be released, add the "release-it" label.`;

const includeReleaseDetails = isPrerelease || (flags.patch && !flags.label.includes('nightly-automerge'));

const pr = await octokit.request('POST /repos/{owner}/{repo}/pulls', {
owner: repoOwner,
repo: repoName,
head: branchName,
base: 'main',
title: `Release PR for ${nextVersion}`,
body: `Building ${nextVersion} [skip-validate-pr]${flags.prerelease ? prereleaseDetails : ''}`,
title: `Release PR for ${nextVersion} as ${flags['release-channel']}`,
body: `Building ${nextVersion}\n[skip-validate-pr]\n${includeReleaseDetails ? releaseDetails : ''}`,
});

if (flags.label) {
Expand Down

0 comments on commit ddcd1b1

Please sign in to comment.