forked from RocketChat/Rocket.Chat
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ci: New action to publish releases (RocketChat#29519)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
- Loading branch information
1 parent
db9e1f6
commit 956dbb5
Showing
20 changed files
with
1,196 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@rocket.chat/release-action': major | ||
--- | ||
|
||
New action to publish package releases |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
name: Start new release | ||
|
||
on: | ||
workflow_dispatch: | ||
inputs: | ||
name: | ||
type: choice | ||
description: Release type | ||
default: next | ||
required: true | ||
options: | ||
- next | ||
- patch | ||
- publish | ||
base-ref: | ||
description: Base version | ||
default: master | ||
required: false | ||
|
||
jobs: | ||
new-release: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: 0 | ||
# with: | ||
# ref: ${{ github.event.inputs.base-ref }} | ||
|
||
- name: Setup Node.js 16 | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: 16 | ||
|
||
- run: yarn install | ||
|
||
- name: Build | ||
run: yarn build | ||
|
||
- name: Start next release | ||
if: ${{ github.event.inputs.name == 'next' }} | ||
uses: ./packages/release-action | ||
with: | ||
action: bump | ||
env: | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Start patch release | ||
if: ${{ github.event.inputs.name == 'patch' }} | ||
uses: ./packages/release-action | ||
with: | ||
action: patch | ||
base-ref: ${{ github.event.inputs.base-ref }} | ||
env: | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Publish release | ||
if: ${{ github.event.inputs.name == 'publish' }} | ||
uses: ./packages/release-action | ||
with: | ||
action: publish | ||
base-ref: ${{ github.event.inputs.base-ref }} | ||
env: | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
name: Publish Final Release | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
|
||
concurrency: ${{ github.workflow }}-${{ github.ref }} | ||
|
||
jobs: | ||
release: | ||
name: Release | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout Repo | ||
uses: actions/checkout@v3 | ||
|
||
- name: Setup Node.js 16 | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: 16 | ||
|
||
- name: Install Dependencies | ||
run: yarn | ||
|
||
- name: Build | ||
run: yarn build | ||
|
||
- name: Publish final release | ||
uses: ./packages/release-action | ||
with: | ||
action: publish-final | ||
env: | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"extends": ["@rocket.chat/eslint-config"], | ||
"ignorePatterns": ["**/dist"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# @rocket.chat/release-action |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# release-action |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
name: Changeset release | ||
description: Action to cut and publish releases using changesets | ||
|
||
inputs: | ||
action: | ||
description: "The main action to perform: publish, publish-final, bump or patch" | ||
required: true | ||
base-ref: | ||
description: "Base ref to use for the release" | ||
required: false | ||
|
||
runs: | ||
using: "node16" | ||
main: "dist/index.js" | ||
|
||
branding: | ||
icon: "package" | ||
color: "blue" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "@rocket.chat/release-action", | ||
"version": "0.0.1", | ||
"private": true, | ||
"scripts": { | ||
"build": "tsc", | ||
"lint": "eslint src", | ||
"lint:fix": "eslint --fix src" | ||
}, | ||
"main": "dist/index.js", | ||
"packageManager": "[email protected]", | ||
"devDependencies": { | ||
"@types/eslint": "^8", | ||
"@types/node": "^16", | ||
"typescript": "^5.1.3" | ||
}, | ||
"dependencies": { | ||
"@actions/core": "^1.10.0", | ||
"@actions/exec": "^1.1.1", | ||
"@actions/github": "^5.1.1", | ||
"@octokit/plugin-throttling": "^6.0.0", | ||
"@rocket.chat/eslint-config": "workspace:^", | ||
"eslint": "^8.42.0", | ||
"mdast-util-to-string": "2", | ||
"remark-parse": "9", | ||
"remark-stringify": "9", | ||
"semver": "^7.5.1", | ||
"unified": "9" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
|
||
import { exec } from '@actions/exec'; | ||
import * as core from '@actions/core'; | ||
import * as github from '@actions/github'; | ||
|
||
import { setupOctokit } from './setupOctokit'; | ||
import { createNpmFile } from './createNpmFile'; | ||
import { getChangelogEntry, updateVersionPackageJson } from './utils'; | ||
import { fixWorkspaceVersionsBeforePublish } from './fixWorkspaceVersionsBeforePublish'; | ||
|
||
export async function bumpNextVersion({ | ||
githubToken, | ||
mainPackagePath, | ||
cwd = process.cwd(), | ||
}: { | ||
githubToken: string; | ||
mainPackagePath: string; | ||
cwd?: string; | ||
}) { | ||
const octokit = setupOctokit(githubToken); | ||
|
||
// TODO do this only if publishing to npm | ||
await createNpmFile(); | ||
|
||
// TODO need to check if there is any change to 'main package', if not, there is no need to enter rc | ||
// and instead a normal release of the other packages should be done | ||
|
||
// start release candidate | ||
await exec('yarn', ['changeset', 'pre', 'enter', 'rc']); | ||
|
||
// bump version of all packages to rc | ||
await exec('yarn', ['changeset', 'version']); | ||
|
||
// get version from main package | ||
const mainPackageJsonPath = path.join(mainPackagePath, 'package.json'); | ||
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires | ||
const { version: newVersion } = require(mainPackageJsonPath); | ||
|
||
const mainPackageChangelog = path.join(mainPackagePath, 'CHANGELOG.md'); | ||
|
||
const changelogContents = fs.readFileSync(mainPackageChangelog, 'utf8'); | ||
const changelogEntry = getChangelogEntry(changelogContents, newVersion); | ||
if (!changelogEntry) { | ||
// we can find a changelog but not the entry for this version | ||
// if this is true, something has probably gone wrong | ||
throw new Error('Could not find changelog entry for version newVersion'); | ||
} | ||
|
||
const prBody = changelogEntry.content; | ||
|
||
const finalVersion = newVersion.split('-')[0]; | ||
|
||
const newBranch = `release-${finalVersion}`; | ||
|
||
// update root package.json | ||
updateVersionPackageJson(cwd, newVersion); | ||
|
||
// TODO check if branch exists | ||
await exec('git', ['checkout', '-b', newBranch]); | ||
|
||
await exec('git', ['add', '.']); | ||
await exec('git', ['commit', '-m', newVersion]); | ||
|
||
await fixWorkspaceVersionsBeforePublish(); | ||
|
||
await exec('yarn', ['changeset', 'publish']); | ||
|
||
await exec('git', ['push', '--force', '--follow-tags', 'origin', `HEAD:refs/heads/${newBranch}`]); | ||
|
||
if (newVersion.includes('rc.0')) { | ||
const finalPrTitle = `Release ${finalVersion}`; | ||
|
||
core.info('creating pull request'); | ||
await octokit.rest.pulls.create({ | ||
base: 'master', | ||
head: newBranch, | ||
title: finalPrTitle, | ||
body: prBody, | ||
...github.context.repo, | ||
}); | ||
} | ||
|
||
await octokit.rest.repos.createRelease({ | ||
name: newVersion, | ||
tag_name: newVersion, | ||
body: prBody, | ||
prerelease: newVersion.includes('-'), | ||
...github.context.repo, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import fs from 'fs'; | ||
import fsPromise from 'fs/promises'; | ||
|
||
import * as core from '@actions/core'; | ||
|
||
export async function createNpmFile() { | ||
const userNpmrcPath = `${process.env.HOME}/.npmrc`; | ||
|
||
if (fs.existsSync(userNpmrcPath)) { | ||
core.info('Found existing user .npmrc file'); | ||
const userNpmrcContent = await fsPromise.readFile(userNpmrcPath, 'utf8'); | ||
const authLine = userNpmrcContent.split('\n').find((line) => { | ||
// check based on https://github.com/npm/cli/blob/8f8f71e4dd5ee66b3b17888faad5a7bf6c657eed/test/lib/adduser.js#L103-L105 | ||
return /^\s*\/\/registry\.npmjs\.org\/:[_-]authToken=/i.test(line); | ||
}); | ||
if (authLine) { | ||
core.info('Found existing auth token for the npm registry in the user .npmrc file'); | ||
} else { | ||
core.info("Didn't find existing auth token for the npm registry in the user .npmrc file, creating one"); | ||
fs.appendFileSync(userNpmrcPath, `\n//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}\n`); | ||
} | ||
} else { | ||
core.info('No user .npmrc file found, creating one'); | ||
fs.writeFileSync(userNpmrcPath, `//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}\n`); | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
packages/release-action/src/fixWorkspaceVersionsBeforePublish.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Changesets doesn't currently support workspace versions: | ||
// https://github.com/changesets/changesets/issues/432 | ||
// https://github.com/changesets/action/issues/246 | ||
// To work around that, we'll manually resolve any `workspace:` version ranges | ||
// with this tool prior to publishing. If/when changesets adds native support for | ||
// publishing with Yarn 3, we can remove this script. | ||
// | ||
// We'll only support the `workspace:^` range, which is the only one we | ||
// generally want to use. | ||
|
||
import fs from 'node:fs/promises'; | ||
import path from 'node:path'; | ||
|
||
import { getExecOutput } from '@actions/exec'; | ||
|
||
const DEPENDENCY_TYPES = ['dependencies', 'devDependencies', 'peerDependencies']; | ||
|
||
export async function fixWorkspaceVersionsBeforePublish() { | ||
const rawWorkspaces = await getExecOutput('yarn workspaces list --json'); | ||
const workspaces = rawWorkspaces.stdout | ||
.trim() | ||
.split('\n') | ||
.map((line) => JSON.parse(line)) | ||
.filter((workspace) => workspace.location !== '.'); | ||
|
||
// Get the version of each workspace package. | ||
const workspaceVersions = new Map(); | ||
for await (const workspace of workspaces) { | ||
const packageJsonPath = path.join(workspace.location, 'package.json'); | ||
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8')); | ||
workspaceVersions.set(workspace.name, packageJson.version); | ||
} | ||
|
||
// Replace any `workspace:^` version ranges with the actual version. | ||
for await (const workspace of workspaces) { | ||
const packageJsonPath = path.join(workspace.location, 'package.json'); | ||
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8')); | ||
|
||
for (const dependencyType of DEPENDENCY_TYPES) { | ||
const dependencies = Object.keys(packageJson[dependencyType] ?? {}); | ||
for (const dependency of dependencies) { | ||
const dependencyVersion = packageJson[dependencyType][dependency]; | ||
if (dependencyVersion.startsWith('workspace:')) { | ||
if (!dependencyVersion.startsWith('workspace:^')) { | ||
throw new Error(`Unsupported workspace version range: ${dependencyVersion}`); | ||
} | ||
|
||
const realVersion = workspaceVersions.get(dependency); | ||
if (!realVersion) { | ||
throw new Error(`Could not find version for workspace ${dependency}`); | ||
} | ||
|
||
packageJson[dependencyType][dependency] = `^${realVersion}`; | ||
} | ||
} | ||
} | ||
|
||
await fs.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { exec } from '@actions/exec'; | ||
|
||
export async function setupGitUser() { | ||
await exec('git', ['config', 'user.name', '"github-actions[bot]"']); | ||
await exec('git', ['config', 'user.email', '"github-actions[bot]@users.noreply.github.com"']); | ||
} |
Oops, something went wrong.