Skip to content
Snippets Groups Projects
Unverified Commit 677919a2 authored by Diego Sampaio's avatar Diego Sampaio Committed by GitHub
Browse files

ci: Fixes to publish automation (#29563)

parent 4187aed6
No related branches found
No related tags found
No related merge requests found
---
'@rocket.chat/release-action': patch
---
Use CI user PAT token
---
'@rocket.chat/release-action': patch
---
Update versions in configured files
...@@ -28,6 +28,7 @@ jobs: ...@@ -28,6 +28,7 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
token: ${{ secrets.CI_PAT }}
- name: Setup NodeJS - name: Setup NodeJS
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node
...@@ -48,7 +49,7 @@ jobs: ...@@ -48,7 +49,7 @@ jobs:
action: bump action: bump
env: env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.CI_PAT }}
- name: Start patch release - name: Start patch release
if: ${{ github.event.inputs.name == 'patch' }} if: ${{ github.event.inputs.name == 'patch' }}
...@@ -58,7 +59,7 @@ jobs: ...@@ -58,7 +59,7 @@ jobs:
base-ref: ${{ github.event.inputs.base-ref }} base-ref: ${{ github.event.inputs.base-ref }}
env: env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.CI_PAT }}
- name: Publish release - name: Publish release
if: ${{ github.event.inputs.name == 'publish' }} if: ${{ github.event.inputs.name == 'publish' }}
...@@ -68,4 +69,4 @@ jobs: ...@@ -68,4 +69,4 @@ jobs:
base-ref: ${{ github.event.inputs.base-ref }} base-ref: ${{ github.event.inputs.base-ref }}
env: env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.CI_PAT }}
...@@ -17,6 +17,8 @@ jobs: ...@@ -17,6 +17,8 @@ jobs:
steps: steps:
- name: Checkout Repo - name: Checkout Repo
uses: actions/checkout@v3 uses: actions/checkout@v3
with:
token: ${{ secrets.CI_PAT }}
- name: Setup NodeJS - name: Setup NodeJS
uses: ./.github/actions/setup-node uses: ./.github/actions/setup-node
...@@ -36,4 +38,4 @@ jobs: ...@@ -36,4 +38,4 @@ jobs:
action: publish-final action: publish-final
env: env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.CI_PAT }}
...@@ -7,7 +7,7 @@ import * as github from '@actions/github'; ...@@ -7,7 +7,7 @@ import * as github from '@actions/github';
import { setupOctokit } from './setupOctokit'; import { setupOctokit } from './setupOctokit';
import { createNpmFile } from './createNpmFile'; import { createNpmFile } from './createNpmFile';
import { getChangelogEntry, updateVersionPackageJson } from './utils'; import { getChangelogEntry, bumpFileVersions, readPackageJson } from './utils';
import { fixWorkspaceVersionsBeforePublish } from './fixWorkspaceVersionsBeforePublish'; import { fixWorkspaceVersionsBeforePublish } from './fixWorkspaceVersionsBeforePublish';
export async function bumpNextVersion({ export async function bumpNextVersion({
...@@ -27,6 +27,8 @@ export async function bumpNextVersion({ ...@@ -27,6 +27,8 @@ export async function bumpNextVersion({
// TODO need to check if there is any change to 'main package', if not, there is no need to enter rc // 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 // and instead a normal release of the other packages should be done
const { version: currentVersion } = await readPackageJson(cwd);
// start release candidate // start release candidate
await exec('yarn', ['changeset', 'pre', 'enter', 'rc']); await exec('yarn', ['changeset', 'pre', 'enter', 'rc']);
...@@ -34,9 +36,7 @@ export async function bumpNextVersion({ ...@@ -34,9 +36,7 @@ export async function bumpNextVersion({
await exec('yarn', ['changeset', 'version']); await exec('yarn', ['changeset', 'version']);
// get version from main package // get version from main package
const mainPackageJsonPath = path.join(mainPackagePath, 'package.json'); const { version: newVersion } = await readPackageJson(mainPackagePath);
// 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 mainPackageChangelog = path.join(mainPackagePath, 'CHANGELOG.md');
...@@ -55,8 +55,8 @@ export async function bumpNextVersion({ ...@@ -55,8 +55,8 @@ export async function bumpNextVersion({
const newBranch = `release-${finalVersion}`; const newBranch = `release-${finalVersion}`;
// update root package.json // update root package.json
core.info('bump main package.json version'); core.info('update version in all files to new');
updateVersionPackageJson(cwd, newVersion); await bumpFileVersions(cwd, currentVersion, newVersion);
// TODO check if branch exists // TODO check if branch exists
await exec('git', ['checkout', '-b', newBranch]); await exec('git', ['checkout', '-b', newBranch]);
...@@ -67,7 +67,9 @@ export async function bumpNextVersion({ ...@@ -67,7 +67,9 @@ export async function bumpNextVersion({
core.info('fix dependencies in workspace packages'); core.info('fix dependencies in workspace packages');
await fixWorkspaceVersionsBeforePublish(); await fixWorkspaceVersionsBeforePublish();
await exec('yarn', ['changeset', 'publish']); await exec('yarn', ['changeset', 'publish', '--no-git-tag']);
await exec('git', ['tag', newVersion]);
await exec('git', ['push', '--force', '--follow-tags', 'origin', `HEAD:refs/heads/${newBranch}`]); await exec('git', ['push', '--force', '--follow-tags', 'origin', `HEAD:refs/heads/${newBranch}`]);
......
...@@ -13,6 +13,8 @@ import path from 'node:path'; ...@@ -13,6 +13,8 @@ import path from 'node:path';
import { getExecOutput } from '@actions/exec'; import { getExecOutput } from '@actions/exec';
import { readPackageJson } from './utils';
const DEPENDENCY_TYPES = ['dependencies', 'devDependencies', 'peerDependencies']; const DEPENDENCY_TYPES = ['dependencies', 'devDependencies', 'peerDependencies'];
export async function fixWorkspaceVersionsBeforePublish() { export async function fixWorkspaceVersionsBeforePublish() {
...@@ -26,15 +28,13 @@ export async function fixWorkspaceVersionsBeforePublish() { ...@@ -26,15 +28,13 @@ export async function fixWorkspaceVersionsBeforePublish() {
// Get the version of each workspace package. // Get the version of each workspace package.
const workspaceVersions = new Map(); const workspaceVersions = new Map();
for await (const workspace of workspaces) { for await (const workspace of workspaces) {
const packageJsonPath = path.join(workspace.location, 'package.json'); const packageJson = await readPackageJson(workspace.location);
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
workspaceVersions.set(workspace.name, packageJson.version); workspaceVersions.set(workspace.name, packageJson.version);
} }
// Replace any `workspace:^` version ranges with the actual version. // Replace any `workspace:^` version ranges with the actual version.
for await (const workspace of workspaces) { for await (const workspace of workspaces) {
const packageJsonPath = path.join(workspace.location, 'package.json'); const packageJson = await readPackageJson(workspace.location);
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
for (const dependencyType of DEPENDENCY_TYPES) { for (const dependencyType of DEPENDENCY_TYPES) {
const dependencies = Object.keys(packageJson[dependencyType] ?? {}); const dependencies = Object.keys(packageJson[dependencyType] ?? {});
...@@ -55,6 +55,6 @@ export async function fixWorkspaceVersionsBeforePublish() { ...@@ -55,6 +55,6 @@ export async function fixWorkspaceVersionsBeforePublish() {
} }
} }
await fs.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`); await fs.writeFile(path.join(workspace.location, 'package.json'), `${JSON.stringify(packageJson, null, 2)}\n`);
} }
} }
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"']);
}
...@@ -4,7 +4,6 @@ import path from 'path'; ...@@ -4,7 +4,6 @@ import path from 'path';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { publishRelease } from './publishRelease'; import { publishRelease } from './publishRelease';
import { setupGitUser } from './gitUtils';
import { bumpNextVersion } from './bumpNextVersion'; import { bumpNextVersion } from './bumpNextVersion';
import { startPatchRelease } from './startPatchRelease'; import { startPatchRelease } from './startPatchRelease';
...@@ -23,9 +22,6 @@ import { startPatchRelease } from './startPatchRelease'; ...@@ -23,9 +22,6 @@ import { startPatchRelease } from './startPatchRelease';
// process.chdir(inputCwd); // process.chdir(inputCwd);
// } // }
core.info('setting git user');
await setupGitUser();
core.info('setting GitHub credentials'); core.info('setting GitHub credentials');
fs.writeFileSync(`${process.env.HOME}/.netrc`, `machine github.com\nlogin github-actions[bot]\npassword ${githubToken}`); fs.writeFileSync(`${process.env.HOME}/.netrc`, `machine github.com\nlogin github-actions[bot]\npassword ${githubToken}`);
......
...@@ -7,7 +7,7 @@ import * as core from '@actions/core'; ...@@ -7,7 +7,7 @@ import * as core from '@actions/core';
import { createNpmFile } from './createNpmFile'; import { createNpmFile } from './createNpmFile';
import { setupOctokit } from './setupOctokit'; import { setupOctokit } from './setupOctokit';
import { getChangelogEntry, updateVersionPackageJson } from './utils'; import { bumpFileVersions, getChangelogEntry, readPackageJson } from './utils';
import { fixWorkspaceVersionsBeforePublish } from './fixWorkspaceVersionsBeforePublish'; import { fixWorkspaceVersionsBeforePublish } from './fixWorkspaceVersionsBeforePublish';
export async function publishRelease({ export async function publishRelease({
...@@ -32,6 +32,8 @@ export async function publishRelease({ ...@@ -32,6 +32,8 @@ export async function publishRelease({
await exec('git', ['checkout', baseRef]); await exec('git', ['checkout', baseRef]);
} }
const { version: currentVersion } = await readPackageJson(cwd);
if (exitCandidate) { if (exitCandidate) {
let preRelease = false; let preRelease = false;
try { try {
...@@ -54,10 +56,7 @@ export async function publishRelease({ ...@@ -54,10 +56,7 @@ export async function publishRelease({
// TODO if main package has no changes, throw error // TODO if main package has no changes, throw error
// get version from main package // get version from main package
const mainPackageJsonPath = path.join(mainPackagePath, 'package.json'); const { version: newVersion } = await readPackageJson(mainPackagePath);
// 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 mainPackageChangelog = path.join(mainPackagePath, 'CHANGELOG.md');
...@@ -71,17 +70,18 @@ export async function publishRelease({ ...@@ -71,17 +70,18 @@ export async function publishRelease({
const releaseBody = changelogEntry.content; const releaseBody = changelogEntry.content;
// update root package.json core.info('update version in all files to new');
core.info('bump main package.json version'); await bumpFileVersions(cwd, currentVersion, newVersion);
updateVersionPackageJson(cwd, newVersion);
await exec('git', ['add', '.']); await exec('git', ['add', '.']);
await exec('git', ['commit', '-m', newVersion]); await exec('git', ['commit', '-m', `Release ${newVersion}`]);
core.info('fix dependencies in workspace packages'); core.info('fix dependencies in workspace packages');
await fixWorkspaceVersionsBeforePublish(); await fixWorkspaceVersionsBeforePublish();
await exec('yarn', ['changeset', 'publish']); await exec('yarn', ['changeset', 'publish', '--no-git-tag']);
await exec('git', ['tag', newVersion]);
await exec('git', ['push', '--follow-tags']); await exec('git', ['push', '--follow-tags']);
......
import path from 'path';
import semver from 'semver'; import semver from 'semver';
import { exec } from '@actions/exec'; import { exec } from '@actions/exec';
import * as github from '@actions/github'; import * as github from '@actions/github';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { setupOctokit } from './setupOctokit'; import { setupOctokit } from './setupOctokit';
import { updateVersionPackageJson } from './utils'; import { readPackageJson } from './utils';
export async function startPatchRelease({ export async function startPatchRelease({
githubToken, githubToken,
baseRef, baseRef,
mainPackagePath, mainPackagePath,
cwd = process.cwd(),
}: { }: {
baseRef: string; baseRef: string;
mainPackagePath: string; mainPackagePath: string;
...@@ -24,9 +21,7 @@ export async function startPatchRelease({ ...@@ -24,9 +21,7 @@ export async function startPatchRelease({
await exec('git', ['checkout', baseRef]); await exec('git', ['checkout', baseRef]);
// get version from main package // get version from main package
const mainPackageJsonPath = path.join(mainPackagePath, 'package.json'); const { version } = await readPackageJson(mainPackagePath);
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
const { version } = require(mainPackageJsonPath);
const newVersion = semver.inc(version, 'patch'); const newVersion = semver.inc(version, 'patch');
if (!newVersion) { if (!newVersion) {
...@@ -38,8 +33,9 @@ export async function startPatchRelease({ ...@@ -38,8 +33,9 @@ export async function startPatchRelease({
// TODO check if branch exists // TODO check if branch exists
await exec('git', ['checkout', '-b', newBranch]); await exec('git', ['checkout', '-b', newBranch]);
core.info('bump main package.json version'); // create empty changeset to have something to commit. the changeset file will be removed later in the process
updateVersionPackageJson(cwd, newVersion); core.info('create empty changeset');
await exec('yarn', ['changeset', 'add', '--empty']);
await exec('git', ['add', '.']); await exec('git', ['add', '.']);
await exec('git', ['commit', '-m', newVersion]); await exec('git', ['commit', '-m', newVersion]);
......
import fs from 'fs';
import path from 'path'; import path from 'path';
import { readFile, writeFile } from 'fs/promises';
import unified from 'unified'; import unified from 'unified';
import remarkParse from 'remark-parse'; import remarkParse from 'remark-parse';
...@@ -58,9 +58,35 @@ export function getChangelogEntry(changelog: string, version: string) { ...@@ -58,9 +58,35 @@ export function getChangelogEntry(changelog: string, version: string) {
}; };
} }
export function updateVersionPackageJson(cwd = process.cwd(), newVersion: string) { export async function readPackageJson(cwd: string) {
const rootPackageJsonPath = path.resolve(cwd, 'package.json'); const filePath = path.resolve(cwd, 'package.json');
const content = fs.readFileSync(rootPackageJsonPath, 'utf8'); return JSON.parse(await readFile(filePath, 'utf-8'));
const updatedContent = content.replace(/"version": ".*",$/m, `"version": "${newVersion}",`); }
fs.writeFileSync(rootPackageJsonPath, updatedContent);
async function getUpdateFilesList(cwd: string): Promise<string[]> {
const file = await readPackageJson(cwd);
if (!file.houston) {
return [];
}
const { houston } = file;
if (!houston.updateFiles) {
return [];
}
return houston.updateFiles;
}
export async function bumpFileVersions(cwd: string, oldVersion: string, newVersion: string) {
const files = await getUpdateFilesList(cwd);
await Promise.all(
files.map(async (file) => {
const filePath = path.join(cwd, file);
const data = await readFile(filePath, 'utf8');
await writeFile(filePath, data.replace(oldVersion, newVersion), 'utf8');
}),
);
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment