refactor: move release code to a package (@miodec) (#5743)

This commit is contained in:
Jack 2024-08-08 16:16:01 +02:00 committed by GitHub
parent f6ec006507
commit 1eebf748ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 245 additions and 27 deletions

View file

@ -6,7 +6,7 @@ describe("AdminUidsDal", () => {
it("should return true for existing admin user", async () => {
//GIVEN
const uid = new ObjectId().toHexString();
AdminUidsDal.getCollection().insertOne({
await AdminUidsDal.getCollection().insertOne({
_id: new ObjectId(),
uid: uid,
});
@ -17,7 +17,7 @@ describe("AdminUidsDal", () => {
it("should return false for non-existing admin user", async () => {
//GIVEN
AdminUidsDal.getCollection().insertOne({
await AdminUidsDal.getCollection().insertOne({
_id: new ObjectId(),
uid: "admin",
});

View file

@ -29,11 +29,11 @@
"start-fe": "turbo run start --filter @monkeytype/frontend",
"docker": "cd backend && docker compose up",
"audit-fe": "cd frontend && npm run audit",
"release": "node ./bin/release.mjs",
"release-fe": "node ./bin/release.mjs --fe",
"release-be": "node ./bin/release.mjs --be",
"release-no-deploy": "node ./bin/release.mjs --no-deploy",
"release-dry": "node ./bin/release.mjs --dry",
"release": "monkeytype-release",
"release-fe": "monkeytype-release --fe",
"release-be": "monkeytype-release --be",
"release-no-deploy": "monkeytype-release --no-deploy",
"release-dry": "monkeytype-release --dry",
"hotfix": "npm run build-fe && cd frontend && npm run deploy-live && cd .. && sh ./bin/purgeCfCache.sh",
"pretty-check": "prettier --check .",
"pretty-check-be": "prettier --check ./backend",
@ -54,6 +54,7 @@
"node": "20.16.0"
},
"devDependencies": {
"@monkeytype/release": "workspace:*",
"@commitlint/cli": "17.7.1",
"@commitlint/config-conventional": "17.7.0",
"conventional-changelog": "4.0.0",
@ -68,7 +69,6 @@
"lint-staged": "13.2.3",
"only-allow": "1.2.1",
"prettier": "2.5.1",
"readline-sync": "1.4.10",
"turbo": "2.0.9",
"typescript": "5.5.4",
"wait-for-localhost-cli": "3.2.0"

View file

@ -31,6 +31,14 @@ module.exports = {
"no-duplicate-imports": ["error"],
"no-constant-condition": ["error"],
"no-constant-binary-expression": "error",
"no-unused-vars": [
"warn",
{
argsIgnorePattern: "^(_|e|event)",
caughtErrorsIgnorePattern: "^(_|e|error)",
varsIgnorePattern: "^_",
},
],
"import/no-duplicates": "off",
"import/no-unresolved": [
"error",

View file

@ -0,0 +1,5 @@
/** @type {import("eslint").Linter.Config} */
module.exports = {
root: true,
extends: ["@monkeytype/eslint-config"],
};

View file

@ -0,0 +1,23 @@
{
"name": "@monkeytype/release",
"private": true,
"type": "module",
"scripts": {
"dev": "nodemon --watch src --exec 'node ./src/index.js --dry'",
"dev-changelog": "nodemon ./src/buildChangelog.js",
"lint": "eslint \"./**/*.js\""
},
"devDependencies": {
"@monkeytype/eslint-config": "workspace:*",
"eslint": "8.57.0",
"nodemon": "3.1.4"
},
"bin": {
"monkeytype-release": "./src/index.js"
},
"dependencies": {
"@octokit/rest": "20.1.1",
"dotenv": "16.4.5",
"readline-sync": "1.4.10"
}
}

View file

@ -1,4 +1,3 @@
import conventionalChangelog from "conventional-changelog";
import { exec } from "child_process";
// const stream = conventionalChangelog(
@ -41,7 +40,7 @@ async function getLog() {
return new Promise((resolve, reject) => {
exec(
`git log --oneline $(git describe --tags --abbrev=0 @^)..@ --pretty="format:${lineDelimiter}%H${logDelimiter}%h${logDelimiter}%s${logDelimiter}%b"`,
(err, stdout, stderr) => {
(err, stdout, _stderr) => {
if (err) {
reject(err);
}
@ -250,7 +249,7 @@ function convertStringToLog(logString) {
//split message using regex based on fix(language): spelling mistakes in Nepali wordlist and quotes (sapradhan) (#4528)
//scope is optional, username is optional, pr number is optional
const [__, type, scope, message, message2, message3] = title.split(
const [_, type, scope, message, message2, message3] = title.split(
/^(\w+)(?:\(([^)]+)\))?:\s+(.+?)\s*(?:\(([^)]+)\))?(?:\s+\(([^)]+)\))?(?:\s+\(([^)]+)\))?$/
);

57
bin/release.mjs → packages/release/src/index.js Normal file → Executable file
View file

@ -1,12 +1,10 @@
import { execSync } from "child_process";
import { Octokit } from "@octokit/rest";
import dotenv from "dotenv";
import { readFileSync } from "fs";
import fs, { readFileSync } from "fs";
import readlineSync from "readline-sync";
import path from "path";
import fs from "fs";
import path, { dirname } from "path";
import { fileURLToPath } from "url";
import { dirname } from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
@ -18,6 +16,9 @@ const isFrontend = args.includes("--fe");
const noDeploy = args.includes("--no-deploy");
const isBackend = args.includes("--be");
const isDryRun = args.includes("--dry");
const noSyncCheck = args.includes("--no-sync-check");
const PROJECT_ROOT = path.resolve(__dirname, "../../../");
const runCommand = (command, force) => {
if (isDryRun && !force) {
@ -35,19 +36,41 @@ const runCommand = (command, force) => {
}
};
const runProjectRootCommand = (command, force) => {
if (isDryRun && !force) {
console.log(`[Dry Run] Command: ${command}`);
return "[Dry Run] Command executed.";
} else {
try {
const output = execSync(`cd ${PROJECT_ROOT} && ${command}`, {
stdio: "pipe",
}).toString();
return output;
} catch (error) {
console.error(`Error executing command ${command}`);
console.error(error);
process.exit(1);
}
}
};
const checkBranchSync = () => {
console.log("Checking if local master branch is in sync with origin...");
if (isDryRun) {
if (noSyncCheck) {
console.log("Skipping sync check.");
} else if (isDryRun) {
console.log("[Dry Run] Checking sync...");
} else {
try {
// Fetch the latest changes from the remote repository
runCommand("git fetch origin");
runProjectRootCommand("git fetch origin");
// Get the commit hashes of the local and remote master branches
const localMaster = runCommand("git rev-parse master").trim();
const remoteMaster = runCommand("git rev-parse origin/master").trim();
const localMaster = runProjectRootCommand("git rev-parse master").trim();
const remoteMaster = runProjectRootCommand(
"git rev-parse origin/master"
).trim();
if (localMaster !== remoteMaster) {
console.error(
@ -65,8 +88,12 @@ const checkBranchSync = () => {
const getCurrentVersion = () => {
console.log("Getting current version...");
const packageJson = JSON.parse(readFileSync("./package.json", "utf-8"));
return packageJson.version;
const rootPackageJson = JSON.parse(
readFileSync(`${PROJECT_ROOT}/package.json`, "utf-8")
);
return rootPackageJson.version;
};
const incrementVersion = (currentVersion) => {
@ -134,7 +161,7 @@ const buildProject = () => {
filter = "--filter @monkeytype/backend";
}
runCommand("npx turbo lint test validate-json build " + filter);
runProjectRootCommand("npx turbo lint test validate-json build " + filter);
};
const deployBackend = () => {
@ -144,7 +171,9 @@ const deployBackend = () => {
const deployFrontend = () => {
console.log("Deploying frontend...");
runCommand("cd frontend && npx firebase deploy -P live --only hosting");
runProjectRootCommand(
"cd frontend && npx firebase deploy -P live --only hosting"
);
};
const purgeCache = () => {
@ -155,7 +184,9 @@ const purgeCache = () => {
const generateChangelog = async () => {
console.log("Generating changelog...");
const changelog = runCommand("node bin/buildChangelog.mjs", true);
const p = path.resolve(__dirname, "./buildChangelog.js");
const changelog = runCommand(`node ${p}`, true);
return changelog;
};

158
pnpm-lock.yaml generated
View file

@ -14,6 +14,9 @@ importers:
'@commitlint/config-conventional':
specifier: 17.7.0
version: 17.7.0
'@monkeytype/release':
specifier: workspace:*
version: link:packages/release
conventional-changelog:
specifier: 4.0.0
version: 4.0.0
@ -50,9 +53,6 @@ importers:
prettier:
specifier: 2.5.1
version: 2.5.1
readline-sync:
specifier: 1.4.10
version: 1.4.10
turbo:
specifier: 2.0.9
version: 2.0.9
@ -528,6 +528,28 @@ importers:
specifier: 9.1.0
version: 9.1.0(eslint@8.57.0)
packages/release:
dependencies:
'@octokit/rest':
specifier: 20.1.1
version: 20.1.1
dotenv:
specifier: 16.4.5
version: 16.4.5
readline-sync:
specifier: 1.4.10
version: 1.4.10
devDependencies:
'@monkeytype/eslint-config':
specifier: workspace:*
version: link:../eslint-config
eslint:
specifier: 8.57.0
version: 8.57.0
nodemon:
specifier: 3.1.4
version: 3.1.4
packages/shared-types:
dependencies:
'@monkeytype/contracts':
@ -2196,6 +2218,58 @@ packages:
resolution: {integrity: sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
'@octokit/auth-token@4.0.0':
resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==}
engines: {node: '>= 18'}
'@octokit/core@5.2.0':
resolution: {integrity: sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==}
engines: {node: '>= 18'}
'@octokit/endpoint@9.0.5':
resolution: {integrity: sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==}
engines: {node: '>= 18'}
'@octokit/graphql@7.1.0':
resolution: {integrity: sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==}
engines: {node: '>= 18'}
'@octokit/openapi-types@22.2.0':
resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==}
'@octokit/plugin-paginate-rest@11.3.1':
resolution: {integrity: sha512-ryqobs26cLtM1kQxqeZui4v8FeznirUsksiA+RYemMPJ7Micju0WSkv50dBksTuZks9O5cg4wp+t8fZ/cLY56g==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '5'
'@octokit/plugin-request-log@4.0.1':
resolution: {integrity: sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '5'
'@octokit/plugin-rest-endpoint-methods@13.2.2':
resolution: {integrity: sha512-EI7kXWidkt3Xlok5uN43suK99VWqc8OaIMktY9d9+RNKl69juoTyxmLoWPIZgJYzi41qj/9zU7G/ljnNOJ5AFA==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': ^5
'@octokit/request-error@5.1.0':
resolution: {integrity: sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==}
engines: {node: '>= 18'}
'@octokit/request@8.4.0':
resolution: {integrity: sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==}
engines: {node: '>= 18'}
'@octokit/rest@20.1.1':
resolution: {integrity: sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw==}
engines: {node: '>= 18'}
'@octokit/types@13.5.0':
resolution: {integrity: sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==}
'@one-ini/wasm@0.1.1':
resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
@ -3172,6 +3246,9 @@ packages:
resolution: {integrity: sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==}
engines: {node: '>= 10.0.0'}
before-after-hook@2.2.3:
resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==}
bignumber.js@9.1.2:
resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==}
@ -4009,6 +4086,9 @@ packages:
engines: {node: ^10.13 || ^12 || >=14}
hasBin: true
deprecation@2.3.1:
resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==}
destroy@1.2.0:
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
@ -8971,6 +9051,9 @@ packages:
resolution: {integrity: sha512-HXSMyIcf2XTvwZ6ZZQLfxfViRm/yTGoRgDeTbojtq6rezeyKB0sTBcKH2fhddnteAHRcHiKgr/ACpbgjGOC6RQ==}
engines: {node: '>=12.18.2'}
universal-user-agent@6.0.1:
resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==}
universalify@2.0.1:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}
@ -11525,6 +11608,69 @@ snapshots:
'@npmcli/name-from-folder@2.0.0': {}
'@octokit/auth-token@4.0.0': {}
'@octokit/core@5.2.0':
dependencies:
'@octokit/auth-token': 4.0.0
'@octokit/graphql': 7.1.0
'@octokit/request': 8.4.0
'@octokit/request-error': 5.1.0
'@octokit/types': 13.5.0
before-after-hook: 2.2.3
universal-user-agent: 6.0.1
'@octokit/endpoint@9.0.5':
dependencies:
'@octokit/types': 13.5.0
universal-user-agent: 6.0.1
'@octokit/graphql@7.1.0':
dependencies:
'@octokit/request': 8.4.0
'@octokit/types': 13.5.0
universal-user-agent: 6.0.1
'@octokit/openapi-types@22.2.0': {}
'@octokit/plugin-paginate-rest@11.3.1(@octokit/core@5.2.0)':
dependencies:
'@octokit/core': 5.2.0
'@octokit/types': 13.5.0
'@octokit/plugin-request-log@4.0.1(@octokit/core@5.2.0)':
dependencies:
'@octokit/core': 5.2.0
'@octokit/plugin-rest-endpoint-methods@13.2.2(@octokit/core@5.2.0)':
dependencies:
'@octokit/core': 5.2.0
'@octokit/types': 13.5.0
'@octokit/request-error@5.1.0':
dependencies:
'@octokit/types': 13.5.0
deprecation: 2.3.1
once: 1.4.0
'@octokit/request@8.4.0':
dependencies:
'@octokit/endpoint': 9.0.5
'@octokit/request-error': 5.1.0
'@octokit/types': 13.5.0
universal-user-agent: 6.0.1
'@octokit/rest@20.1.1':
dependencies:
'@octokit/core': 5.2.0
'@octokit/plugin-paginate-rest': 11.3.1(@octokit/core@5.2.0)
'@octokit/plugin-request-log': 4.0.1(@octokit/core@5.2.0)
'@octokit/plugin-rest-endpoint-methods': 13.2.2(@octokit/core@5.2.0)
'@octokit/types@13.5.0':
dependencies:
'@octokit/openapi-types': 22.2.0
'@one-ini/wasm@0.1.1': {}
'@opentelemetry/api@1.8.0': {}
@ -12581,6 +12727,8 @@ snapshots:
- encoding
- supports-color
before-after-hook@2.2.3: {}
bignumber.js@9.1.2: {}
binary-extensions@1.13.1: {}
@ -13495,6 +13643,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
deprecation@2.3.1: {}
destroy@1.2.0: {}
detect-file@1.0.0: {}
@ -19600,6 +19750,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
universal-user-agent@6.0.1: {}
universalify@2.0.1: {}
unpipe@1.0.0: {}