snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
This commit is contained in:
1
packages/release-action/.gitignore
vendored
Normal file
1
packages/release-action/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
dist/
|
||||
166
packages/release-action/CHANGELOG.md
Normal file
166
packages/release-action/CHANGELOG.md
Normal file
@@ -0,0 +1,166 @@
|
||||
# @rocket.chat/release-action
|
||||
|
||||
## 2.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ([#41653](https://github.com/RocketChat/Rocket.Chat/pull/41653)) Bumps patch-level dependency updates: `react`, `react-dom` and `react-is` to 19.2.8, `ws` to 8.21.3, `nodemailer` to 9.0.5, `mailparser` to 3.9.15, `google-libphonenumber` to 3.2.46, `twitter-api-v2` to 1.29.1, `ip-range-check` to 0.2.1, `esbuild` to 0.28.2, `@octokit/core` to 7.0.7 and `@octokit/plugin-throttling` to 11.0.5, plus build and test tooling (`@swc/core`, `ts-jest`, `rollup`, `html-webpack-plugin`, `@vitejs/plugin-react`, `@testing-library/user-event`, and the `@types/*` packages). No behavior changes are expected.
|
||||
|
||||
## 2.2.5-rc.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ([#41653](https://github.com/RocketChat/Rocket.Chat/pull/41653)) Bumps patch-level dependency updates: `react`, `react-dom` and `react-is` to 19.2.8, `ws` to 8.21.3, `nodemailer` to 9.0.5, `mailparser` to 3.9.15, `google-libphonenumber` to 3.2.46, `twitter-api-v2` to 1.29.1, `ip-range-check` to 0.2.1, `esbuild` to 0.28.2, `@octokit/core` to 7.0.7 and `@octokit/plugin-throttling` to 11.0.5, plus build and test tooling (`@swc/core`, `ts-jest`, `rollup`, `html-webpack-plugin`, `@vitejs/plugin-react`, `@testing-library/user-event`, and the `@types/*` packages). No behavior changes are expected.
|
||||
|
||||
## 2.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ([#38989](https://github.com/RocketChat/Rocket.Chat/pull/38989)) chore(eslint): Upgrades ESLint and its configuration
|
||||
|
||||
## 2.2.4-rc.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ([#38989](https://github.com/RocketChat/Rocket.Chat/pull/38989)) chore(eslint): Upgrades ESLint and its configuration
|
||||
|
||||
## 2.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- <details><summary>Updated dependencies [b7f5035442]:</summary>
|
||||
|
||||
- @rocket.chat/eslint-config@0.7.0
|
||||
</details>
|
||||
|
||||
## 2.2.3-rc.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- <details><summary>Updated dependencies [b7f5035442]:</summary>
|
||||
|
||||
- @rocket.chat/eslint-config@0.7.0-rc.0
|
||||
</details>
|
||||
|
||||
## 2.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- <details><summary>Updated dependencies [7ac473df7a]:</summary>
|
||||
|
||||
- @rocket.chat/eslint-config@0.6.2
|
||||
</details>
|
||||
|
||||
## 2.2.2-rc.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- <details><summary>Updated dependencies [7ac473df7a]:</summary>
|
||||
|
||||
- @rocket.chat/eslint-config@0.6.2-rc.0
|
||||
</details>
|
||||
|
||||
## 2.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ([#31138](https://github.com/RocketChat/Rocket.Chat/pull/31138)) feat(uikit): Move `@rocket.chat/ui-kit` package to the main monorepo
|
||||
|
||||
- <details><summary>Updated dependencies [642745f289, b223cbde14]:</summary>
|
||||
|
||||
- @rocket.chat/eslint-config@0.6.1
|
||||
</details>
|
||||
|
||||
## 2.2.1-rc.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b223cbde14: feat(uikit): Move `@rocket.chat/ui-kit` package to the main monorepo
|
||||
- Updated dependencies [642745f289]
|
||||
- Updated dependencies [b223cbde14]
|
||||
- @rocket.chat/eslint-config@0.6.1-rc.0
|
||||
|
||||
## 2.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- f93648a5df: Add back "Engine Versions" to the release notes
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [0f56aacc4d]
|
||||
- @rocket.chat/eslint-config@0.6.0
|
||||
|
||||
## 2.2.0-rc.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- f93648a5df: Add back "Engine Versions" to the release notes
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [0f56aacc4d]
|
||||
- @rocket.chat/eslint-config@0.6.0-rc.0
|
||||
|
||||
## 2.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- a56f5f0a5f: Add back "Engine Versions" to the release notes
|
||||
|
||||
## 2.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- 956dbb5520: New action to publish package releases
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 0f2f37d4db: Use `release-automation` branch to perform the release
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 677919a23e: Use CI user PAT token
|
||||
- a430336869: Create patch changeset file on every publish
|
||||
- 677919a23e: Update versions in configured files
|
||||
|
||||
## 2.0.0-rc.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a430336869: Create patch changeset file on every publish
|
||||
|
||||
## 2.0.0-rc.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- 956dbb5520: New action to publish package releases
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 0f2f37d4db: Use `release-automation` branch to perform the release
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 677919a23e: Use CI user PAT token
|
||||
- 677919a23e: Update versions in configured files
|
||||
|
||||
## 1.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 63c91f24a9: Use `release-automation` branch to perform the release
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#29596](https://github.com/RocketChat/Rocket.Chat/pull/29596) [`a19359b3f5`](https://github.com/RocketChat/Rocket.Chat/commit/a19359b3f5b09270fe1644df0706c6b1ebb979ef) Thanks [@rocketchat-github-ci](https://github.com/rocketchat-github-ci)! - Use CI user PAT token
|
||||
|
||||
- [#29596](https://github.com/RocketChat/Rocket.Chat/pull/29596) [`a19359b3f5`](https://github.com/RocketChat/Rocket.Chat/commit/a19359b3f5b09270fe1644df0706c6b1ebb979ef) Thanks [@rocketchat-github-ci](https://github.com/rocketchat-github-ci)! - Update versions in configured files
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- [#29545](https://github.com/RocketChat/Rocket.Chat/pull/29545) [`a728082848`](https://github.com/RocketChat/Rocket.Chat/commit/a72808284870af04a6457af6f2f79b0a0c38b7cb) Thanks [@github-actions](https://github.com/apps/github-actions)! - New action to publish package releases
|
||||
1
packages/release-action/README.md
Normal file
1
packages/release-action/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# release-action
|
||||
18
packages/release-action/action.yml
Normal file
18
packages/release-action/action.yml
Normal file
@@ -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: "node24"
|
||||
main: "dist/index.js"
|
||||
|
||||
branding:
|
||||
icon: "package"
|
||||
color: "blue"
|
||||
32
packages/release-action/package.json
Normal file
32
packages/release-action/package.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "@rocket.chat/release-action",
|
||||
"version": "2.2.5",
|
||||
"private": true,
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc --noEmit && esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --outfile=dist/index.js",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint --fix src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^3.0.1",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/github": "^9.1.1",
|
||||
"@octokit/core": "^7.0.7",
|
||||
"@octokit/plugin-throttling": "^11.0.5",
|
||||
"mdast-util-to-string": "2.0.0",
|
||||
"remark-parse": "9.0.0",
|
||||
"remark-stringify": "9.0.1",
|
||||
"semver": "^7.6.3",
|
||||
"unified": "9.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "~24.13.2",
|
||||
"esbuild": "~0.28.2",
|
||||
"eslint": "~9.39.5",
|
||||
"typescript": "~5.9.3"
|
||||
},
|
||||
"volta": {
|
||||
"extends": "../../package.json"
|
||||
}
|
||||
}
|
||||
99
packages/release-action/src/bumpNextVersion.ts
Normal file
99
packages/release-action/src/bumpNextVersion.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import * as core from '@actions/core';
|
||||
import { exec } from '@actions/exec';
|
||||
import * as github from '@actions/github';
|
||||
|
||||
import { createNpmFile } from './createNpmFile';
|
||||
import { fixWorkspaceVersionsBeforePublish } from './fixWorkspaceVersionsBeforePublish';
|
||||
import { commitChanges, createBranch, createTag, pushNewBranch } from './gitUtils';
|
||||
import { setupOctokit } from './setupOctokit';
|
||||
import { getChangelogEntry, bumpFileVersions, readPackageJson, getEngineVersionsMd, createTempReleaseNotes } from './utils';
|
||||
|
||||
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
|
||||
|
||||
const { version: currentVersion } = await readPackageJson(cwd);
|
||||
|
||||
// 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 { version: newVersion } = await readPackageJson(mainPackagePath);
|
||||
|
||||
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 = (await getEngineVersionsMd(cwd)) + changelogEntry.content;
|
||||
|
||||
const finalVersion = newVersion.split('-')[0];
|
||||
|
||||
const newBranch = `release-${finalVersion}`;
|
||||
|
||||
// update root package.json
|
||||
core.info('update version in all files to new');
|
||||
await bumpFileVersions(cwd, currentVersion, newVersion);
|
||||
|
||||
// TODO check if branch exists
|
||||
await createBranch(newBranch);
|
||||
|
||||
await commitChanges(`Release ${newVersion}`);
|
||||
|
||||
core.info('fix dependencies in workspace packages');
|
||||
await fixWorkspaceVersionsBeforePublish();
|
||||
|
||||
await exec('yarn', ['changeset', 'publish', '--no-git-tag']);
|
||||
|
||||
await createTag(newVersion);
|
||||
|
||||
await pushNewBranch(newBranch, true);
|
||||
|
||||
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: createTempReleaseNotes(finalVersion, prBody),
|
||||
...github.context.repo,
|
||||
});
|
||||
} else {
|
||||
core.info('no pull request created: release is not the first candidate');
|
||||
}
|
||||
|
||||
core.info('create release');
|
||||
await octokit.rest.repos.createRelease({
|
||||
name: newVersion,
|
||||
tag_name: newVersion,
|
||||
body: prBody,
|
||||
prerelease: newVersion.includes('-'),
|
||||
...github.context.repo,
|
||||
});
|
||||
}
|
||||
33
packages/release-action/src/createNpmFile.ts
Normal file
33
packages/release-action/src/createNpmFile.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import fs from 'node:fs';
|
||||
import fsPromise from 'node:fs/promises';
|
||||
|
||||
import * as core from '@actions/core';
|
||||
|
||||
export async function createNpmFile() {
|
||||
// With trusted publishing (OIDC) there is no token, and a bogus auth line in .npmrc
|
||||
// takes precedence over the OIDC exchange, so leave the file alone.
|
||||
if (!process.env.NPM_TOKEN) {
|
||||
core.info('No NPM_TOKEN provided, relying on the registry authentication already in place');
|
||||
return;
|
||||
}
|
||||
|
||||
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`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// 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';
|
||||
|
||||
import { readPackageJson } from './utils';
|
||||
|
||||
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 (const workspace of workspaces) {
|
||||
const packageJson = await readPackageJson(workspace.location);
|
||||
workspaceVersions.set(workspace.name, packageJson.version);
|
||||
}
|
||||
|
||||
// Replace any `workspace:^` version ranges with the actual version.
|
||||
for (const workspace of workspaces) {
|
||||
const packageJson = await readPackageJson(workspace.location);
|
||||
|
||||
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:')) {
|
||||
const realVersion = workspaceVersions.get(dependency);
|
||||
if (!realVersion) {
|
||||
throw new Error(`Could not find version for workspace ${dependency}`);
|
||||
}
|
||||
|
||||
const semver = dependencyVersion.slice('workspace:'.length);
|
||||
|
||||
if (semver === '*') {
|
||||
packageJson[dependencyType][dependency] = `=${realVersion}`;
|
||||
} else if (semver === '^') {
|
||||
packageJson[dependencyType][dependency] = `^${realVersion}`;
|
||||
} else if (semver === '~') {
|
||||
packageJson[dependencyType][dependency] = `~${realVersion}`;
|
||||
} else {
|
||||
packageJson[dependencyType][dependency] = semver;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await fs.writeFile(path.join(workspace.location, 'package.json'), `${JSON.stringify(packageJson, null, 2)}\n`);
|
||||
}
|
||||
}
|
||||
54
packages/release-action/src/getMetadata.ts
Normal file
54
packages/release-action/src/getMetadata.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { EOL } from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
import { readPackageJson } from './utils';
|
||||
|
||||
export async function getMongoVersion(cwd: string) {
|
||||
try {
|
||||
const workflows = await readFile(path.join(cwd, '.github/workflows/ci.yml'), 'utf8');
|
||||
|
||||
const mongoMatch = workflows.match(/compatibleMongoVersions\\": \[([^\]]+)\]/);
|
||||
if (!mongoMatch) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return mongoMatch[1].replace(/["'\\ ]/g, '').split(',');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
export async function getNodeNpmVersions(cwd: string): Promise<{ node: string; yarn: string; npm: string }> {
|
||||
const packageJson = await readPackageJson(cwd);
|
||||
|
||||
return packageJson.engines;
|
||||
}
|
||||
|
||||
export async function getAppsEngineVersion(cwd: string) {
|
||||
try {
|
||||
const result = await readPackageJson(path.join(cwd, 'packages/apps-engine'));
|
||||
|
||||
return result.version ?? 'Not Available';
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getDenoVersion(cwd: string) {
|
||||
try {
|
||||
const toolVersionsContent = await readFile(path.join(cwd, '.tool-versions'));
|
||||
const data = toolVersionsContent.toString().replace(EOL, ' ').split(' ');
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
if (data[i] === 'deno') {
|
||||
return data[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return 'Not available';
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
52
packages/release-action/src/gitUtils.ts
Normal file
52
packages/release-action/src/gitUtils.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { exec, getExecOutput } from '@actions/exec';
|
||||
|
||||
export async function setupGitUser() {
|
||||
await exec('git', ['config', 'user.name', '"rocketchat-github-ci"']);
|
||||
await exec('git', ['config', 'user.email', '"buildmaster@rocket.chat"']);
|
||||
}
|
||||
|
||||
export async function createBranch(newBranch: string) {
|
||||
await exec('git', ['checkout', '-b', newBranch]);
|
||||
}
|
||||
|
||||
export async function checkoutBranch(branchName: string) {
|
||||
await exec('git', ['checkout', branchName]);
|
||||
}
|
||||
|
||||
export async function mergeBranch(branchName: string) {
|
||||
await exec('git', ['merge', '--no-edit', branchName]);
|
||||
}
|
||||
|
||||
export async function commitChanges(commitMessage: string) {
|
||||
await exec('git', ['add', '.']);
|
||||
await exec('git', ['commit', '-m', commitMessage]);
|
||||
}
|
||||
|
||||
export async function createTag(version: string) {
|
||||
// create an annotated tag so git push --follow-tags will push the tag
|
||||
await exec('git', ['tag', version, '-m', version]);
|
||||
}
|
||||
|
||||
export async function getCurrentBranch() {
|
||||
const { stdout: branchName } = await getExecOutput('git', ['rev-parse', '--abbrev-ref', 'HEAD']);
|
||||
|
||||
return branchName.trim();
|
||||
}
|
||||
|
||||
export async function pushChanges() {
|
||||
await exec('git', ['push', '--follow-tags']);
|
||||
}
|
||||
|
||||
export async function pushNewBranch(newBranch: string, force = false) {
|
||||
const params = ['push'];
|
||||
|
||||
if (force) {
|
||||
params.push('--force');
|
||||
}
|
||||
|
||||
params.push('--follow-tags');
|
||||
params.push('origin');
|
||||
params.push(`HEAD:refs/heads/${newBranch}`);
|
||||
|
||||
await exec('git', params);
|
||||
}
|
||||
55
packages/release-action/src/index.ts
Normal file
55
packages/release-action/src/index.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import * as core from '@actions/core';
|
||||
|
||||
import { bumpNextVersion } from './bumpNextVersion';
|
||||
import { setupGitUser } from './gitUtils';
|
||||
import { publishRelease } from './publishRelease';
|
||||
import { startPatchRelease } from './startPatchRelease';
|
||||
import { updatePRDescription } from './updatePRDescription';
|
||||
|
||||
// const getOptionalInput = (name: string) => core.getInput(name) || undefined;
|
||||
|
||||
(async () => {
|
||||
const githubToken = process.env.GITHUB_TOKEN;
|
||||
if (!githubToken) {
|
||||
core.setFailed('Please add the GITHUB_TOKEN to the changesets action');
|
||||
return;
|
||||
}
|
||||
|
||||
// const inputCwd = core.getInput('cwd');
|
||||
// if (inputCwd) {
|
||||
// core.info('changing directory to the one given as the input');
|
||||
// process.chdir(inputCwd);
|
||||
// }
|
||||
|
||||
core.info('setting git user');
|
||||
await setupGitUser();
|
||||
|
||||
core.info('setting GitHub credentials');
|
||||
fs.writeFileSync(`${process.env.HOME}/.netrc`, `machine github.com\nlogin github-actions[bot]\npassword ${githubToken}`);
|
||||
|
||||
const action = core.getInput('action');
|
||||
const baseRef = core.getInput('base-ref');
|
||||
|
||||
const cwd = process.cwd();
|
||||
|
||||
// TODO this could be configurable
|
||||
const mainPackagePath = path.join(cwd, 'apps', 'meteor');
|
||||
|
||||
if (action === 'publish-final') {
|
||||
await publishRelease({ githubToken, mergeFinal: true, mainPackagePath });
|
||||
} else if (action === 'cut') {
|
||||
await publishRelease({ githubToken, baseRef, mainPackagePath });
|
||||
} else if (action === 'next') {
|
||||
await bumpNextVersion({ githubToken, mainPackagePath });
|
||||
} else if (action === 'patch') {
|
||||
await startPatchRelease({ baseRef, githubToken, mainPackagePath });
|
||||
} else if (action === 'update-pr-description') {
|
||||
await updatePRDescription({ githubToken, mainPackagePath });
|
||||
}
|
||||
})().catch((err) => {
|
||||
core.error(err);
|
||||
core.setFailed(err.message);
|
||||
});
|
||||
127
packages/release-action/src/publishRelease.ts
Normal file
127
packages/release-action/src/publishRelease.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import * as core from '@actions/core';
|
||||
import { exec } from '@actions/exec';
|
||||
import * as github from '@actions/github';
|
||||
import semver from 'semver';
|
||||
|
||||
import { createNpmFile } from './createNpmFile';
|
||||
import { fixWorkspaceVersionsBeforePublish } from './fixWorkspaceVersionsBeforePublish';
|
||||
import { checkoutBranch, commitChanges, createTag, getCurrentBranch, mergeBranch, pushChanges } from './gitUtils';
|
||||
import { setupOctokit } from './setupOctokit';
|
||||
import { bumpFileVersions, createBumpFile, getChangelogEntry, getEngineVersionsMd, isPreRelease, readPackageJson } from './utils';
|
||||
|
||||
export async function publishRelease({
|
||||
githubToken,
|
||||
mainPackagePath,
|
||||
mergeFinal = false,
|
||||
baseRef,
|
||||
cwd = process.cwd(),
|
||||
}: {
|
||||
githubToken: string;
|
||||
mainPackagePath: string;
|
||||
baseRef?: string;
|
||||
mergeFinal?: boolean;
|
||||
cwd?: string;
|
||||
}) {
|
||||
const octokit = setupOctokit(githubToken);
|
||||
|
||||
// TODO do this only if publishing to npm
|
||||
await createNpmFile();
|
||||
|
||||
if (baseRef) {
|
||||
await checkoutBranch(baseRef);
|
||||
}
|
||||
|
||||
const { version: currentVersion } = await readPackageJson(cwd);
|
||||
|
||||
const startAsPreRelease = isPreRelease(cwd);
|
||||
|
||||
if (mergeFinal && startAsPreRelease) {
|
||||
// finish release candidate
|
||||
await exec('yarn', ['changeset', 'pre', 'exit']);
|
||||
}
|
||||
|
||||
const prerelease = !mergeFinal && startAsPreRelease;
|
||||
|
||||
const { name: mainPkgName } = await readPackageJson(mainPackagePath);
|
||||
|
||||
// by creating a changeset we make sure we'll always bump the version
|
||||
core.info('create a changeset for main package');
|
||||
await createBumpFile(cwd, mainPkgName);
|
||||
|
||||
// bump version of all packages
|
||||
await exec('yarn', ['changeset', 'version']);
|
||||
|
||||
// get version from main package
|
||||
const { version: newVersion } = await readPackageJson(mainPackagePath);
|
||||
|
||||
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 releaseBody = (await getEngineVersionsMd(cwd)) + changelogEntry.content;
|
||||
|
||||
core.info('update version in all files to new');
|
||||
await bumpFileVersions(cwd, currentVersion, newVersion);
|
||||
|
||||
await commitChanges(`Release ${newVersion}\n\n[no ci]`);
|
||||
|
||||
const { data: latestRelease } = await octokit.rest.repos.getLatestRelease({
|
||||
...github.context.repo,
|
||||
});
|
||||
|
||||
core.info(`latest release tag: ${latestRelease.tag_name}`);
|
||||
|
||||
const isLatestRelease = semver.gt(newVersion, latestRelease.tag_name) && !prerelease;
|
||||
|
||||
/**
|
||||
* These conditions are set to allow a patch release, which will be the latest, to be made without the need to merge into master (normalizing how patch releases are done, always via the 'cut' action)
|
||||
*
|
||||
* Strangely before, if mergeFinal was true a checkout was performed and then a push was made, which didn’t make sense because in theory mergeFinal is when merging into master (it was redundant but didn’t cause any issues)
|
||||
*
|
||||
* Today, we want that if the action is `cut` and the version is a patch, the merge should be performed, the pull request will automatically be closed, and the release will be made.
|
||||
* However, if the `cut` is for a pre-release version, the merge to master should not be performed, because minor/major releases are still done manually.
|
||||
*
|
||||
* by `mergeFinal` we can know it was triggered by a pull request merge to master
|
||||
*/
|
||||
|
||||
if (!mergeFinal && isLatestRelease) {
|
||||
// get current branch name
|
||||
const branchName = await getCurrentBranch();
|
||||
|
||||
// merge release changes to master
|
||||
await checkoutBranch('master');
|
||||
await mergeBranch(branchName);
|
||||
|
||||
await pushChanges();
|
||||
|
||||
await checkoutBranch(branchName);
|
||||
}
|
||||
|
||||
core.info('fix dependencies in workspace packages');
|
||||
await fixWorkspaceVersionsBeforePublish();
|
||||
|
||||
await exec('yarn', ['changeset', 'publish', '--no-git-tag']);
|
||||
|
||||
await createTag(newVersion);
|
||||
|
||||
await pushChanges();
|
||||
|
||||
core.info('create release');
|
||||
await octokit.rest.repos.createRelease({
|
||||
name: newVersion,
|
||||
tag_name: newVersion,
|
||||
body: releaseBody,
|
||||
prerelease,
|
||||
make_latest: isLatestRelease ? 'true' : 'false',
|
||||
...github.context.repo,
|
||||
});
|
||||
}
|
||||
28
packages/release-action/src/setupOctokit.ts
Normal file
28
packages/release-action/src/setupOctokit.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import * as core from '@actions/core';
|
||||
import { GitHub, getOctokitOptions } from '@actions/github/lib/utils';
|
||||
import { throttling } from '@octokit/plugin-throttling';
|
||||
|
||||
export const setupOctokit = (githubToken: string) => {
|
||||
return new (GitHub.plugin(throttling))(
|
||||
getOctokitOptions(githubToken, {
|
||||
throttle: {
|
||||
onRateLimit: (retryAfter: number, options: object, _octokit: unknown, retryCount: number) => {
|
||||
core.warning(`Request quota exhausted for request ${(options as any).method} ${(options as any).url}`);
|
||||
|
||||
if (retryCount <= 2) {
|
||||
core.info(`Retrying after ${retryAfter} seconds!`);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
onSecondaryRateLimit: (retryAfter: number, options: object, _octokit: unknown, retryCount: number) => {
|
||||
core.warning(`SecondaryRateLimit detected for request ${(options as any).method} ${(options as any).url}`);
|
||||
|
||||
if (retryCount <= 2) {
|
||||
core.info(`Retrying after ${retryAfter} seconds!`);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
};
|
||||
60
packages/release-action/src/startPatchRelease.ts
Normal file
60
packages/release-action/src/startPatchRelease.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as github from '@actions/github';
|
||||
import semver from 'semver';
|
||||
|
||||
import { checkoutBranch, commitChanges, createBranch, pushNewBranch } from './gitUtils';
|
||||
import { setupOctokit } from './setupOctokit';
|
||||
import { createBumpFile, readPackageJson } from './utils';
|
||||
|
||||
export async function startPatchRelease({
|
||||
githubToken,
|
||||
baseRef,
|
||||
mainPackagePath,
|
||||
cwd = process.cwd(),
|
||||
}: {
|
||||
baseRef: string;
|
||||
mainPackagePath: string;
|
||||
githubToken: string;
|
||||
cwd?: string;
|
||||
}) {
|
||||
const octokit = setupOctokit(githubToken);
|
||||
|
||||
await checkoutBranch(baseRef);
|
||||
|
||||
// get version from main package
|
||||
const { version, name: mainPkgName } = await readPackageJson(mainPackagePath);
|
||||
|
||||
const newVersion = semver.inc(version, 'patch');
|
||||
if (!newVersion) {
|
||||
throw new Error(`Could not increment version ${version}`);
|
||||
}
|
||||
|
||||
const newBranch = `release-${newVersion}`;
|
||||
|
||||
// TODO check if branch exists
|
||||
await createBranch(newBranch);
|
||||
|
||||
// by creating a changeset we make sure we'll always bump the version
|
||||
core.info('create a changeset for main package');
|
||||
await createBumpFile(cwd, mainPkgName);
|
||||
|
||||
await commitChanges(`Bump ${newVersion}`);
|
||||
|
||||
await pushNewBranch(newBranch);
|
||||
|
||||
// create a pull request only if the patch is for current version
|
||||
if (baseRef === 'master') {
|
||||
const finalPrTitle = `Release ${newVersion}`;
|
||||
|
||||
core.info('creating pull request');
|
||||
await octokit.rest.pulls.create({
|
||||
base: 'master',
|
||||
head: newBranch,
|
||||
title: finalPrTitle,
|
||||
body: '',
|
||||
...github.context.repo,
|
||||
});
|
||||
} else {
|
||||
core.info('no pull request created: patch is not for current version');
|
||||
}
|
||||
}
|
||||
69
packages/release-action/src/updatePRDescription.ts
Normal file
69
packages/release-action/src/updatePRDescription.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import * as core from '@actions/core';
|
||||
import { exec } from '@actions/exec';
|
||||
import * as github from '@actions/github';
|
||||
|
||||
import { setupOctokit } from './setupOctokit';
|
||||
import { createTempReleaseNotes, getChangelogEntry, getEngineVersionsMd, isPreRelease, readPackageJson } from './utils';
|
||||
|
||||
export async function updatePRDescription({
|
||||
githubToken,
|
||||
mainPackagePath,
|
||||
cwd = process.cwd(),
|
||||
}: {
|
||||
githubToken: string;
|
||||
mainPackagePath: string;
|
||||
cwd?: string;
|
||||
}) {
|
||||
const octokit = setupOctokit(githubToken);
|
||||
|
||||
// in case it is a pre release we exit to get the changelog of the final version
|
||||
if (isPreRelease(cwd)) {
|
||||
await exec('yarn', ['changeset', 'pre', 'exit']);
|
||||
}
|
||||
|
||||
// generate change logs from changesets
|
||||
await exec('yarn', ['changeset', 'version']);
|
||||
|
||||
// get version from main package
|
||||
const { version: newVersion } = await readPackageJson(mainPackagePath);
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
core.info('get PR description');
|
||||
const result = await octokit.rest.pulls.get({
|
||||
pull_number: github.context.issue.number,
|
||||
...github.context.repo,
|
||||
});
|
||||
|
||||
const { body: originalBody = '' } = result.data;
|
||||
|
||||
const cleanBody = originalBody?.replace(/<!-- release-notes-start -->.*<!-- release-notes-end -->/s, '').trim() || '';
|
||||
|
||||
const releaseBody = (await getEngineVersionsMd(cwd)) + changelogEntry.content;
|
||||
|
||||
const bodyUpdated = `${cleanBody}\n${createTempReleaseNotes(newVersion, releaseBody)}`;
|
||||
|
||||
if (bodyUpdated === originalBody) {
|
||||
core.info('no changes to PR description');
|
||||
return;
|
||||
}
|
||||
|
||||
core.info('update PR description');
|
||||
await octokit.rest.pulls.update({
|
||||
owner: github.context.repo.owner,
|
||||
repo: github.context.repo.repo,
|
||||
pull_number: github.context.issue.number,
|
||||
body: bodyUpdated,
|
||||
});
|
||||
}
|
||||
149
packages/release-action/src/utils.ts
Normal file
149
packages/release-action/src/utils.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import fs from 'node:fs';
|
||||
import { readFile, writeFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
|
||||
import mdastToString from 'mdast-util-to-string';
|
||||
import remarkParse from 'remark-parse';
|
||||
import remarkStringify from 'remark-stringify';
|
||||
import unified from 'unified';
|
||||
|
||||
import { getAppsEngineVersion, getDenoVersion, getMongoVersion, getNodeNpmVersions } from './getMetadata';
|
||||
|
||||
export const BumpLevels = {
|
||||
dep: 0,
|
||||
patch: 1,
|
||||
minor: 2,
|
||||
major: 3,
|
||||
} as const;
|
||||
|
||||
export function getChangelogEntry(changelog: string, version: string) {
|
||||
const ast = unified().use(remarkParse).parse(changelog);
|
||||
|
||||
let highestLevel: number = BumpLevels.dep;
|
||||
|
||||
const nodes = (ast as any).children as Array<any>;
|
||||
let headingStartInfo:
|
||||
| {
|
||||
index: number;
|
||||
depth: number;
|
||||
}
|
||||
| undefined;
|
||||
let endIndex: number | undefined;
|
||||
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
const node = nodes[i];
|
||||
if (node.type === 'heading') {
|
||||
const stringified: string = mdastToString(node);
|
||||
const match = stringified.toLowerCase().match(/(major|minor|patch)/);
|
||||
if (match !== null) {
|
||||
const level = BumpLevels[match[0] as 'major' | 'minor' | 'patch'];
|
||||
highestLevel = Math.max(level, highestLevel);
|
||||
}
|
||||
if (headingStartInfo === undefined && stringified === version) {
|
||||
headingStartInfo = {
|
||||
index: i,
|
||||
depth: node.depth,
|
||||
};
|
||||
continue;
|
||||
}
|
||||
if (endIndex === undefined && headingStartInfo !== undefined && headingStartInfo.depth === node.depth) {
|
||||
endIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (headingStartInfo) {
|
||||
(ast as any).children = ((ast as any).children as any).slice(headingStartInfo.index + 1, endIndex);
|
||||
}
|
||||
return {
|
||||
content: unified().use(remarkStringify).stringify(ast),
|
||||
highestLevel,
|
||||
};
|
||||
}
|
||||
|
||||
export async function readPackageJson(cwd: string) {
|
||||
const filePath = path.resolve(cwd, 'package.json');
|
||||
return JSON.parse(await readFile(filePath, 'utf-8'));
|
||||
}
|
||||
|
||||
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');
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export async function createBumpFile(cwd: string, pkgName: string) {
|
||||
const filePath = path.join(cwd, '.changeset', `bump-patch-${Date.now()}.md`);
|
||||
|
||||
const data = `---
|
||||
'${pkgName}': patch
|
||||
---
|
||||
|
||||
Bump ${pkgName} version.
|
||||
`;
|
||||
|
||||
await writeFile(filePath, data, 'utf8');
|
||||
}
|
||||
|
||||
export async function getEngineVersionsMd(cwd: string) {
|
||||
const { node } = await getNodeNpmVersions(cwd);
|
||||
const appsEngine = await getAppsEngineVersion(cwd);
|
||||
const deno = await getDenoVersion(cwd);
|
||||
const mongo = await getMongoVersion(cwd);
|
||||
|
||||
return `### Engine versions
|
||||
|
||||
- Node: \`${node}\`
|
||||
- Deno: \`${deno}\`
|
||||
- MongoDB: \`${mongo.join(', ')}\`
|
||||
- Apps-Engine: \`${appsEngine}\`
|
||||
|
||||
`;
|
||||
}
|
||||
|
||||
export function isPreRelease(cwd: string) {
|
||||
try {
|
||||
fs.accessSync(path.resolve(cwd, '.changeset', 'pre.json'));
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
// nothing to do, not a pre release
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function createTempReleaseNotes(version: string, releaseBody: string) {
|
||||
return `
|
||||
<!-- release-notes-start -->
|
||||
<!-- This content is automatically generated. Changing this will not reflect on the final release log -->
|
||||
|
||||
_You can see below a preview of the release change log:_
|
||||
|
||||
# ${version}
|
||||
|
||||
${releaseBody}
|
||||
<!-- release-notes-end -->`;
|
||||
}
|
||||
109
packages/release-action/tsconfig.json
Normal file
109
packages/release-action/tsconfig.json
Normal file
@@ -0,0 +1,109 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "esnext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "commonjs", /* Specify what module code is generated. */
|
||||
"rootDir": "src/", /* Specify the root folder within your source files. */
|
||||
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
||||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
||||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
||||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "dist/", /* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user