diff --git a/.gitignore b/.gitignore index dc798a18a86..e10cb30432a 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,6 @@ test-results # verdaccio .verdaccio + +scripts/.env +!scripts/.env.example diff --git a/.lintstagedrc.json b/.lintstagedrc.json index 652e81c30fa..c423d460bd2 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,4 +1,4 @@ { - "*.{js,jsx,ts,tsx}": ["npx prettier --write", "npx eslint --fix"], + "*.{mjs,js,jsx,ts,tsx}": ["npx prettier --write", "npx eslint --fix"], "*.{json,md,mdx}": ["npx prettier --write"] } diff --git a/docs/PUBLISH.md b/docs/PUBLISH.md index 8c25db122d5..1a8c347d0d4 100644 --- a/docs/PUBLISH.md +++ b/docs/PUBLISH.md @@ -2,8 +2,6 @@ _Note: Only core maintainers can publish packages._ -_Package versioning and publishing is currently handled by @clerkinc/frontend-team._ - ## Publishing stable package versions (`@latest`) We are using [changesets](https://github.com/changesets/changesets), so our CICD is using [`changesets/action`](https://github.com/changesets/action) to automate the release process when releasing stable package versions targeting the `@latest` tag. @@ -42,3 +40,17 @@ Notes: ## Publishing canary package versions (`@canary`) We're still considering whether switching the repo into a `canary` mode for big, experimental features makes sense. There is no use case for this right now, however, we might experiment with the [changesets prerelease mode](https://github.com/changesets/changesets/blob/main/docs/prereleases.md) in the future. + +## Backporting PRs + +> Backporting is the action of taking parts from a newer version of a software system or software component and porting them to an older version of the same software. + +If a PR got merged into `main` that should also be released in older versions (e.g. critical security fixes), you'll need to backport said PR. You can do this by using the [`backport` script](https://github.com/clerkinc/javascript/blob/main/scripts/backport.mjs) inside `scripts`. + +Duplicate the `.env.example` file inside `scripts` and rename it to `.env`. Fill out the `GITHUB_ACCESS_TOKEN` variable. Afterwards, you'll be able to run the CLI like so: + +```shell +node backports.mjs main-v4 1234 +``` + +The command above will backport the PR `1234` to the branch `main-v4`. diff --git a/package-lock.json b/package-lock.json index d33e6291ee4..802375cf8be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@commitlint/config-conventional": "^17.7.0", "@emotion/jest": "^11.11.0", "@faker-js/faker": "^8.1.0", + "@octokit/rest": "^20.0.2", "@playwright/test": "^1.39.0", "@testing-library/dom": "^8.19.0", "@testing-library/jest-dom": "^5.16.5", @@ -25,6 +26,7 @@ "@types/jest": "^29.3.1", "@types/react": "^18.2.28", "@types/react-dom": "^18.2.13", + "citty": "^0.1.4", "conventional-changelog-conventionalcommits": "^4.6.3", "cross-spawn": "^7.0.3", "dotenv": "^16.3.1", @@ -68,6 +70,7 @@ }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3914,6 +3917,7 @@ }, "node_modules/@eslint/eslintrc": { "version": "2.1.2", + "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.4", @@ -3935,10 +3939,12 @@ }, "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", + "dev": true, "license": "Python-2.0" }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.21.0", + "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -3952,6 +3958,7 @@ }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -3962,6 +3969,7 @@ }, "node_modules/@eslint/js": { "version": "8.49.0", + "dev": true, "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4218,6 +4226,7 @@ }, "node_modules/@fastify/ajv-compiler": { "version": "3.5.0", + "dev": true, "license": "MIT", "dependencies": { "ajv": "^8.11.0", @@ -4227,6 +4236,7 @@ }, "node_modules/@fastify/ajv-compiler/node_modules/ajv": { "version": "8.12.0", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -4241,18 +4251,22 @@ }, "node_modules/@fastify/ajv-compiler/node_modules/json-schema-traverse": { "version": "1.0.0", + "dev": true, "license": "MIT" }, "node_modules/@fastify/deepmerge": { "version": "1.3.0", + "dev": true, "license": "MIT" }, "node_modules/@fastify/error": { "version": "3.2.1", + "dev": true, "license": "MIT" }, "node_modules/@fastify/fast-json-stringify-compiler": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "fast-json-stringify": "^5.7.0" @@ -4851,6 +4865,7 @@ }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.11", + "dev": true, "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -4863,6 +4878,7 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.22" @@ -4874,6 +4890,7 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/@iarna/toml": { @@ -6276,6 +6293,181 @@ "node": ">= 8" } }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "dev": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz", + "integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==", + "dev": true, + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.0.0", + "@octokit/request": "^8.0.2", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.2.tgz", + "integrity": "sha512-qhKW8YLIi+Kmc92FQUFGr++DYtkx/1fBv+Thua6baqnjnOsgBYJDCvWZR1YcINuHGOEQt416WOfE+A/oG60NBQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^12.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", + "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", + "dev": true, + "dependencies": { + "@octokit/request": "^8.0.1", + "@octokit/types": "^12.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.2.tgz", + "integrity": "sha512-8li32fUDUeml/ACRp/njCWTsk5t17cfTM1jp9n08pBrqs5cDFJubtjsSnuz56r5Tad6jdEPJld7LxNp9dNcyjQ==", + "dev": true + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.2.tgz", + "integrity": "sha512-euDbNV6fxX6btsCDnZoZM4vw3zO1nj1Z7TskHAulO6mZ9lHoFTpwll6farf+wh31mlBabgU81bBYdflp0GLVAQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^12.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=5" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", + "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", + "dev": true, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.1.2.tgz", + "integrity": "sha512-JztgZ82CY4JNlPTuF0jh4iWuuGpEi5czFCoXyAbMg4F2XyFBbG5DWAKfa3odRvdZww6Df1tQgBKnqpd9X0WF9g==", + "dev": true, + "dependencies": { + "@octokit/types": "^12.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": ">=5" + } + }, + "node_modules/@octokit/request": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.4.tgz", + "integrity": "sha512-M0aaFfpGPEKrg7XoA/gwgRvc9MSXHRO2Ioki1qrPDbl1e9YhjIwVoHE7HIKmv/m3idzldj//xBujcFNqGX6ENA==", + "dev": true, + "dependencies": { + "@octokit/endpoint": "^9.0.0", + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^12.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", + "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^12.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@octokit/rest": { + "version": "20.0.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", + "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", + "dev": true, + "dependencies": { + "@octokit/core": "^5.0.0", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "^10.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.1.1.tgz", + "integrity": "sha512-qnJTldJ1NyGT5MTsCg/Zi+y2IFHZ1Jo5+njNCjJ9FcainV7LjuHgmB697kA0g4MjZeDAJsM3B45iqCVsCLVFZg==", + "dev": true, + "dependencies": { + "@octokit/openapi-types": "^19.0.2" + } + }, "node_modules/@parcel/bundler-default": { "version": "2.8.3", "dev": true, @@ -9675,6 +9867,7 @@ }, "node_modules/abort-controller": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" @@ -9690,6 +9883,7 @@ }, "node_modules/abstract-logging": { "version": "2.0.1", + "dev": true, "license": "MIT" }, "node_modules/accepts": { @@ -9706,6 +9900,7 @@ }, "node_modules/acorn": { "version": "8.10.0", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -9733,6 +9928,7 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -9778,6 +9974,7 @@ }, "node_modules/ajv": { "version": "6.12.6", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -9792,6 +9989,7 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", + "dev": true, "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -9807,6 +10005,7 @@ }, "node_modules/ajv-formats/node_modules/ajv": { "version": "8.12.0", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -9821,6 +10020,7 @@ }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", + "dev": true, "license": "MIT" }, "node_modules/ajv-keywords": { @@ -9890,6 +10090,7 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9975,6 +10176,7 @@ }, "node_modules/archy": { "version": "1.0.0", + "dev": true, "license": "MIT" }, "node_modules/are-we-there-yet": { @@ -10233,6 +10435,7 @@ }, "node_modules/atomic-sleep": { "version": "1.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8.0.0" @@ -10297,6 +10500,7 @@ }, "node_modules/avvio": { "version": "8.2.1", + "dev": true, "license": "MIT", "dependencies": { "archy": "^1.0.0", @@ -10821,6 +11025,12 @@ "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", "dev": true }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true + }, "node_modules/better-opn": { "version": "2.1.1", "dev": true, @@ -11680,6 +11890,15 @@ "node": ">=8" } }, + "node_modules/citty": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.4.tgz", + "integrity": "sha512-Q3bK1huLxzQrvj7hImJ7Z1vKYJRPQCDnd0EjXfHMidcjecGOMuLrmuQmtWmFkuKLcMThlGh1yCKG8IEc6VeNXQ==", + "dev": true, + "dependencies": { + "consola": "^3.2.3" + } + }, "node_modules/cjs-module-lexer": { "version": "1.2.2", "dev": true, @@ -12265,6 +12484,15 @@ "node": ">=0.8" } }, + "node_modules/consola": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", + "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", + "dev": true, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -12585,6 +12813,7 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -13109,6 +13338,7 @@ }, "node_modules/deep-is": { "version": "0.1.4", + "dev": true, "license": "MIT" }, "node_modules/deepmerge": { @@ -13209,6 +13439,12 @@ "node": ">= 0.6.0" } }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, "node_modules/dequal": { "version": "2.0.3", "license": "MIT", @@ -13422,6 +13658,7 @@ }, "node_modules/doctrine": { "version": "3.0.0", + "dev": true, "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" @@ -13534,8 +13771,9 @@ }, "node_modules/dotenv": { "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -14517,6 +14755,7 @@ }, "node_modules/eslint": { "version": "8.49.0", + "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", @@ -14871,6 +15110,7 @@ }, "node_modules/eslint-scope": { "version": "7.2.2", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -14976,6 +15216,7 @@ }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14989,10 +15230,12 @@ }, "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", + "dev": true, "license": "Python-2.0" }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -15007,6 +15250,7 @@ }, "node_modules/eslint/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -15017,10 +15261,12 @@ }, "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/eslint/node_modules/globals": { "version": "13.20.0", + "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -15034,6 +15280,7 @@ }, "node_modules/eslint/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -15041,6 +15288,7 @@ }, "node_modules/eslint/node_modules/js-yaml": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -15051,6 +15299,7 @@ }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -15061,6 +15310,7 @@ }, "node_modules/espree": { "version": "9.6.1", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", @@ -15088,6 +15338,7 @@ }, "node_modules/esquery": { "version": "1.5.0", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -15169,6 +15420,7 @@ }, "node_modules/event-target-shim": { "version": "5.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -15181,6 +15433,7 @@ }, "node_modules/events": { "version": "3.3.0", + "dev": true, "license": "MIT", "engines": { "node": ">=0.8.x" @@ -15627,14 +15880,17 @@ }, "node_modules/fast-content-type-parse": { "version": "1.0.0", + "dev": true, "license": "MIT" }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", + "dev": true, "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", + "dev": true, "license": "MIT" }, "node_modules/fast-fifo": { @@ -15669,10 +15925,12 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", + "dev": true, "license": "MIT" }, "node_modules/fast-json-stringify": { "version": "5.7.0", + "dev": true, "license": "MIT", "dependencies": { "@fastify/deepmerge": "^1.0.0", @@ -15685,6 +15943,7 @@ }, "node_modules/fast-json-stringify/node_modules/ajv": { "version": "8.12.0", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -15699,14 +15958,17 @@ }, "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { "version": "1.0.0", + "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", + "dev": true, "license": "MIT" }, "node_modules/fast-querystring": { "version": "1.1.2", + "dev": true, "license": "MIT", "dependencies": { "fast-decode-uri-component": "^1.0.1" @@ -15714,6 +15976,7 @@ }, "node_modules/fast-redact": { "version": "3.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -15727,6 +15990,7 @@ }, "node_modules/fast-uri": { "version": "2.2.0", + "dev": true, "license": "MIT" }, "node_modules/fastest-levenshtein": { @@ -15738,6 +16002,7 @@ }, "node_modules/fastify": { "version": "4.12.0", + "dev": true, "license": "MIT", "dependencies": { "@fastify/ajv-compiler": "^3.3.1", @@ -15759,6 +16024,7 @@ }, "node_modules/fastify-plugin": { "version": "4.5.0", + "dev": true, "license": "MIT" }, "node_modules/fastq": { @@ -15909,6 +16175,7 @@ }, "node_modules/file-entry-cache": { "version": "6.0.1", + "dev": true, "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" @@ -16008,6 +16275,7 @@ }, "node_modules/find-my-way": { "version": "7.6.2", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -16024,6 +16292,7 @@ }, "node_modules/find-up": { "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -16047,6 +16316,7 @@ }, "node_modules/flat-cache": { "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.1.0", @@ -16058,6 +16328,7 @@ }, "node_modules/flat-cache/node_modules/glob": { "version": "7.2.3", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -16076,6 +16347,7 @@ }, "node_modules/flat-cache/node_modules/rimraf": { "version": "3.0.2", + "dev": true, "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -16089,6 +16361,7 @@ }, "node_modules/flatted": { "version": "3.2.7", + "dev": true, "license": "ISC" }, "node_modules/follow-redirects": { @@ -16369,6 +16642,7 @@ }, "node_modules/forwarded": { "version": "0.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -16448,6 +16722,7 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", + "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -17922,6 +18197,7 @@ }, "node_modules/glob-parent": { "version": "6.0.2", + "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -18150,6 +18426,7 @@ }, "node_modules/graphemer": { "version": "1.4.0", + "dev": true, "license": "MIT" }, "node_modules/graphql": { @@ -18830,6 +19107,7 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", + "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" @@ -18845,6 +19123,7 @@ }, "node_modules/inflight": { "version": "1.0.6", + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -18853,6 +19132,7 @@ }, "node_modules/inherits": { "version": "2.0.4", + "dev": true, "license": "ISC" }, "node_modules/ini": { @@ -18998,6 +19278,7 @@ }, "node_modules/ipaddr.js": { "version": "1.9.1", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -19305,6 +19586,7 @@ }, "node_modules/is-path-inside": { "version": "3.0.3", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -19582,6 +19864,7 @@ }, "node_modules/isexe": { "version": "2.0.0", + "dev": true, "license": "ISC" }, "node_modules/isobject": { @@ -21580,10 +21863,12 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", + "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", + "dev": true, "license": "MIT" }, "node_modules/json-stringify-safe": { @@ -21810,6 +22095,7 @@ }, "node_modules/levn": { "version": "0.4.1", + "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", @@ -21821,6 +22107,7 @@ }, "node_modules/light-my-request": { "version": "5.9.2", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "cookie": "^0.5.0", @@ -22202,6 +22489,7 @@ }, "node_modules/locate-path": { "version": "6.0.0", + "dev": true, "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -22349,6 +22637,7 @@ }, "node_modules/lodash.merge": { "version": "4.6.2", + "dev": true, "license": "MIT" }, "node_modules/lodash.mergewith": { @@ -23356,6 +23645,7 @@ }, "node_modules/natural-compare": { "version": "1.4.0", + "dev": true, "license": "MIT" }, "node_modules/natural-compare-lite": { @@ -24276,6 +24566,7 @@ }, "node_modules/on-exit-leak-free": { "version": "2.1.0", + "dev": true, "license": "MIT" }, "node_modules/on-finished": { @@ -24299,6 +24590,7 @@ }, "node_modules/once": { "version": "1.4.0", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -24352,6 +24644,7 @@ }, "node_modules/optionator": { "version": "0.9.3", + "dev": true, "license": "MIT", "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", @@ -24455,6 +24748,7 @@ }, "node_modules/p-locate": { "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -24468,6 +24762,7 @@ }, "node_modules/p-locate/node_modules/p-limit": { "version": "3.1.0", + "dev": true, "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -24807,6 +25102,7 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -24814,6 +25110,7 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -24821,6 +25118,7 @@ }, "node_modules/path-key": { "version": "3.1.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -24963,6 +25261,7 @@ }, "node_modules/pino": { "version": "8.14.1", + "dev": true, "license": "MIT", "dependencies": { "atomic-sleep": "^1.0.0", @@ -24983,6 +25282,7 @@ }, "node_modules/pino-abstract-transport": { "version": "1.0.0", + "dev": true, "license": "MIT", "dependencies": { "readable-stream": "^4.0.0", @@ -24991,6 +25291,7 @@ }, "node_modules/pino-abstract-transport/node_modules/buffer": { "version": "6.0.3", + "dev": true, "funding": [ { "type": "github", @@ -25013,6 +25314,7 @@ }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { "version": "4.4.0", + "dev": true, "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -25026,6 +25328,7 @@ }, "node_modules/pino-abstract-transport/node_modules/split2": { "version": "4.2.0", + "dev": true, "license": "ISC", "engines": { "node": ">= 10.x" @@ -25033,6 +25336,7 @@ }, "node_modules/pino-std-serializers": { "version": "6.2.1", + "dev": true, "license": "MIT" }, "node_modules/pirates": { @@ -25846,6 +26150,7 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8.0" @@ -25938,6 +26243,7 @@ }, "node_modules/process": { "version": "0.11.10", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6.0" @@ -25950,6 +26256,7 @@ }, "node_modules/process-warning": { "version": "2.2.0", + "dev": true, "license": "MIT" }, "node_modules/progress": { @@ -26038,6 +26345,7 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", + "dev": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -26212,6 +26520,7 @@ }, "node_modules/quick-format-unescaped": { "version": "4.0.4", + "dev": true, "license": "MIT" }, "node_modules/quick-lru": { @@ -26318,6 +26627,7 @@ }, "node_modules/react": { "version": "18.2.0", + "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -26453,6 +26763,7 @@ }, "node_modules/react-dom": { "version": "18.2.0", + "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", @@ -26769,6 +27080,7 @@ }, "node_modules/real-require": { "version": "0.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 12.13.0" @@ -27098,6 +27410,7 @@ }, "node_modules/require-from-string": { "version": "2.0.2", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -27212,6 +27525,7 @@ }, "node_modules/ret": { "version": "0.2.2", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -27235,6 +27549,7 @@ }, "node_modules/rfdc": { "version": "1.3.0", + "dev": true, "license": "MIT" }, "node_modules/rimraf": { @@ -27429,6 +27744,7 @@ }, "node_modules/safe-regex2": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "ret": "~0.2.0" @@ -27436,6 +27752,7 @@ }, "node_modules/safe-stable-stringify": { "version": "2.4.3", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -27464,6 +27781,7 @@ }, "node_modules/scheduler": { "version": "0.23.0", + "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -27488,6 +27806,7 @@ }, "node_modules/secure-json-parse": { "version": "2.7.0", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/select-hose": { @@ -27708,6 +28027,7 @@ }, "node_modules/set-cookie-parser": { "version": "2.6.0", + "dev": true, "license": "MIT" }, "node_modules/set-function-name": { @@ -27785,6 +28105,7 @@ }, "node_modules/shebang-command": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -27795,6 +28116,7 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28294,6 +28616,7 @@ }, "node_modules/sonic-boom": { "version": "3.3.0", + "dev": true, "license": "MIT", "dependencies": { "atomic-sleep": "^1.0.0" @@ -28877,6 +29200,7 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -28938,6 +29262,7 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29484,6 +29809,7 @@ }, "node_modules/text-table": { "version": "0.2.0", + "dev": true, "license": "MIT" }, "node_modules/thenify": { @@ -29507,6 +29833,7 @@ }, "node_modules/thread-stream": { "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { "real-require": "^0.2.0" @@ -29579,6 +29906,7 @@ }, "node_modules/tiny-lru": { "version": "10.4.1", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=12" @@ -30275,6 +30603,7 @@ }, "node_modules/type-check": { "version": "0.4.0", + "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" @@ -30293,6 +30622,7 @@ }, "node_modules/type-fest": { "version": "0.20.2", + "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -30392,6 +30722,7 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -30510,6 +30841,12 @@ "node": ">=8" } }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "dev": true + }, "node_modules/universalify": { "version": "0.1.2", "dev": true, @@ -30601,6 +30938,7 @@ }, "node_modules/uri-js": { "version": "4.4.1", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -31664,6 +32002,7 @@ }, "node_modules/which": { "version": "2.0.2", + "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -31918,6 +32257,7 @@ }, "node_modules/wrappy": { "version": "1.0.2", + "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { @@ -32150,6 +32490,7 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=10" diff --git a/package.json b/package.json index c001b32c06a..9e8b48118d1 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "@commitlint/config-conventional": "^17.7.0", "@emotion/jest": "^11.11.0", "@faker-js/faker": "^8.1.0", + "@octokit/rest": "^20.0.2", "@playwright/test": "^1.39.0", "@testing-library/dom": "^8.19.0", "@testing-library/jest-dom": "^5.16.5", @@ -60,6 +61,7 @@ "@types/jest": "^29.3.1", "@types/react": "^18.2.28", "@types/react-dom": "^18.2.13", + "citty": "^0.1.4", "conventional-changelog-conventionalcommits": "^4.6.3", "cross-spawn": "^7.0.3", "dotenv": "^16.3.1", diff --git a/scripts/.env.example b/scripts/.env.example new file mode 100644 index 00000000000..35e6bb809a7 --- /dev/null +++ b/scripts/.env.example @@ -0,0 +1,2 @@ +# Use CLERK_COOKIE_PAT or your personal access token +GITHUB_ACCESS_TOKEN=ghp_TODO \ No newline at end of file diff --git a/scripts/backport.mjs b/scripts/backport.mjs new file mode 100644 index 00000000000..69bc42b348b --- /dev/null +++ b/scripts/backport.mjs @@ -0,0 +1,125 @@ +import 'dotenv/config'; + +import { Octokit } from '@octokit/rest'; +import childProcess from 'child_process'; +import { defineCommand, runMain } from 'citty'; + +if (!process.env.GITHUB_ACCESS_TOKEN) { + throw new Error(`GITHUB_ACCESS_TOKEN environment variable must be set.`); +} + +const repo = 'javascript'; +const owner = 'clerkinc'; + +const octokit = new Octokit({ + auth: `token ${process.env.GITHUB_ACCESS_TOKEN}`, +}); + +/** + * Get the details of the PR, create a new branch, cherry-pick the commit, push the branch, and create a PR. + */ +async function github({ pull_number, branch }) { + const prDetails = await octokit.pulls.get({ + owner, + repo, + pull_number, + }); + + if (!prDetails.data.merged_at) { + throw new Error(`PR ${pull_number} is not merged yet.`); + } + + const commitSha = prDetails.data.merge_commit_sha; + + if (!commitSha) { + throw new Error(`PR ${pull_number} does not have a merge commit sha.`); + } + + const commitMeta = await octokit.git.getCommit({ + owner, + repo, + commit_sha: commitSha, + }); + + // Get the first line of the commit + const commitMessage = commitMeta.data.message.split('\n')[0]; + console.log(`Commit message: ${commitMessage}`); + + const targetBranchName = branch; + const backportBranchName = `backport-${branch}-${pull_number}`; + + childProcess.execSync(`git fetch origin ${targetBranchName}`, { + stdio: `inherit`, + }); + + try { + childProcess.execSync(`git branch -D "${backportBranchName}"`, { + stdio: `inherit`, + }); + // eslint-disable-next-line no-empty + } catch {} + + childProcess.execSync(`git checkout -b "${backportBranchName}" "origin/${targetBranchName}" --no-track`, { + stdio: `inherit`, + }); + + childProcess.execSync(`git cherry-pick -x ${commitSha}`, { + stdio: `inherit`, + }); + + childProcess.execSync(`git push origin +${backportBranchName}`, { + stdio: `inherit`, + }); + + const pr = await octokit.pulls.create({ + owner, + repo, + title: commitMessage, + head: backportBranchName, + base: targetBranchName, + body: `Backporting #${pull_number} to the ${targetBranchName} branch\n\n(cherry picked from commit ${commitSha})`, + }); + + console.log(`\n---\n\nPR opened: ${pr.data.html_url}`); + + await octokit.issues.addLabels({ + owner, + repo, + issue_number: pr.data.number, + labels: [`cherry`], + }); +} + +/** + * @example node backport.mjs + * @example node backport.mjs v4 1234 + */ +const main = defineCommand({ + meta: { + name: 'backport', + version: '1.0.0', + description: 'Backport merged PR into a branch & create a cherry-pick PR', + }, + args: { + branch: { + type: 'positional', + description: 'The branch on which to create the cherry-pick PR', + required: true, + }, + pr: { + type: 'positional', + description: 'The PR number to backport', + required: true, + }, + }, + setup() { + console.log('Starting backport script. If this script fails, finish the rest manually.'); + }, + async run({ args }) { + const { branch, pr } = args; + + await github({ branch, pull_number: Number(pr) }); + }, +}); + +void runMain(main); diff --git a/turbo.json b/turbo.json index 7652790fb93..8f1e07a66f8 100644 --- a/turbo.json +++ b/turbo.json @@ -25,7 +25,8 @@ "NODE_VERSION", "NPM_VERSION", "TZ", - "VERCEL" + "VERCEL", + "GITHUB_ACCESS_TOKEN" ], "pipeline": { "build": {