mirror of
				https://github.com/excalidraw/excalidraw.git
				synced 2025-10-31 02:44:50 +01:00 
			
		
		
		
	chore: release multiple packages (#9698)
This commit is contained in:
		
							
								
								
									
										2
									
								
								.github/workflows/autorelease-excalidraw.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/autorelease-excalidraw.yml
									
									
									
									
										vendored
									
									
								
							| @@ -24,4 +24,4 @@ jobs: | ||||
|       - name: Auto release | ||||
|         run: | | ||||
|           yarn add @actions/core -W | ||||
|           yarn autorelease | ||||
|           yarn release --tag=next --non-interactive | ||||
|   | ||||
							
								
								
									
										55
									
								
								.github/workflows/autorelease-preview.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										55
									
								
								.github/workflows/autorelease-preview.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,55 +0,0 @@ | ||||
| name: Auto release excalidraw preview | ||||
| on: | ||||
|   issue_comment: | ||||
|     types: [created, edited] | ||||
|  | ||||
| jobs: | ||||
|   Auto-release-excalidraw-preview: | ||||
|     name: Auto release preview | ||||
|     if: github.event.comment.body == '@excalibot trigger release' && github.event.issue.pull_request | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: React to release comment | ||||
|         uses: peter-evans/create-or-update-comment@v1 | ||||
|         with: | ||||
|           token: ${{ secrets.PUSH_TRANSLATIONS_COVERAGE_PAT }} | ||||
|           comment-id: ${{ github.event.comment.id }} | ||||
|           reactions: "+1" | ||||
|       - name: Get PR SHA | ||||
|         id: sha | ||||
|         uses: actions/github-script@v4 | ||||
|         with: | ||||
|           result-encoding: string | ||||
|           script: | | ||||
|             const { owner, repo, number } = context.issue; | ||||
|             const pr = await github.pulls.get({ | ||||
|               owner, | ||||
|               repo, | ||||
|               pull_number: number, | ||||
|             }); | ||||
|             return pr.data.head.sha | ||||
|       - uses: actions/checkout@v2 | ||||
|         with: | ||||
|           ref: ${{ steps.sha.outputs.result }} | ||||
|           fetch-depth: 2 | ||||
|       - name: Setup Node.js 18.x | ||||
|         uses: actions/setup-node@v2 | ||||
|         with: | ||||
|           node-version: 18.x | ||||
|       - name: Set up publish access | ||||
|         run: | | ||||
|           npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN} | ||||
|         env: | ||||
|           NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||||
|       - name: Auto release preview | ||||
|         id: "autorelease" | ||||
|         run: | | ||||
|           yarn add @actions/core -W | ||||
|           yarn autorelease preview ${{ github.event.issue.number }} | ||||
|       - name: Post comment post release | ||||
|         if: always() | ||||
|         uses: peter-evans/create-or-update-comment@v1 | ||||
|         with: | ||||
|           token: ${{ secrets.PUSH_TRANSLATIONS_COVERAGE_PAT }} | ||||
|           issue-number: ${{ github.event.issue.number }} | ||||
|           body: "@${{ github.event.comment.user.login }} ${{ steps.autorelease.outputs.result }}" | ||||
| @@ -28,32 +28,12 @@ To start the example app using the `@excalidraw/excalidraw` package, follow the | ||||
|  | ||||
| ## Releasing | ||||
|  | ||||
| ### Create a test release | ||||
|  | ||||
| You can create a test release by posting the below comment in your pull request: | ||||
|  | ||||
| ```bash | ||||
| @excalibot trigger release | ||||
| ``` | ||||
|  | ||||
| Once the version is released `@excalibot` will post a comment with the release version. | ||||
|  | ||||
| ### Creating a production release | ||||
|  | ||||
| To release the next stable version follow the below steps: | ||||
|  | ||||
| ```bash | ||||
| yarn prerelease:excalidraw | ||||
| yarn release --tag=latest --version=0.19.0 | ||||
| ``` | ||||
|  | ||||
| You need to pass the `version` for which you want to create the release. This will make the changes needed before making the release like updating `package.json`, `changelog` and more. | ||||
|  | ||||
| The next step is to run the `release` script: | ||||
|  | ||||
| ```bash | ||||
| yarn release:excalidraw | ||||
| ``` | ||||
|  | ||||
| This will publish the package. | ||||
|  | ||||
| Right now there are two steps to create a production release but once this works fine these scripts will be combined and more automation will be done. | ||||
| You will need to pass the `latest` tag with `version` for which you want to create the release. This will make the changes needed before publishing the packages into NPM, like updating dependencies of all `@excalidraw/*` packages, generating new entries in `CHANGELOG.md` and more. | ||||
|   | ||||
| @@ -3,7 +3,8 @@ | ||||
|   "version": "0.1.0", | ||||
|   "private": true, | ||||
|   "scripts": { | ||||
|     "build:workspace": "yarn workspace @excalidraw/excalidraw run build:esm && yarn copy:assets", | ||||
|     "build:packages": "yarn --cwd ../../ build:packages", | ||||
|     "build:workspace": "yarn build:packages && yarn copy:assets", | ||||
|     "copy:assets": "cp -r ../../packages/excalidraw/dist/prod/fonts ./public", | ||||
|     "dev": "yarn build:workspace && next dev -p 3005", | ||||
|     "build": "yarn build:workspace && next build", | ||||
|   | ||||
| @@ -17,6 +17,6 @@ | ||||
|     "build": "vite build", | ||||
|     "preview": "vite preview --port 5002", | ||||
|     "build:preview": "yarn build && yarn preview", | ||||
|     "build:package": "yarn workspace @excalidraw/excalidraw run build:esm" | ||||
|     "build:packages": "yarn --cwd ../../ build:packages" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| { | ||||
|   "outputDirectory": "dist", | ||||
|   "installCommand": "yarn install", | ||||
|   "buildCommand": "yarn build:package && yarn build" | ||||
|   "buildCommand": "yarn build:packages && yarn build" | ||||
| } | ||||
|   | ||||
							
								
								
									
										15
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								package.json
									
									
									
									
									
								
							| @@ -52,13 +52,17 @@ | ||||
|     "build-node": "node ./scripts/build-node.js", | ||||
|     "build:app:docker": "yarn --cwd ./excalidraw-app build:app:docker", | ||||
|     "build:app": "yarn --cwd ./excalidraw-app build:app", | ||||
|     "build:package": "yarn --cwd ./packages/excalidraw build:esm", | ||||
|     "build:common": "yarn --cwd ./packages/common build:esm", | ||||
|     "build:element": "yarn --cwd ./packages/element build:esm", | ||||
|     "build:excalidraw": "yarn --cwd ./packages/excalidraw build:esm", | ||||
|     "build:math": "yarn --cwd ./packages/math build:esm", | ||||
|     "build:packages": "yarn build:common && yarn build:math && yarn build:element && yarn build:excalidraw", | ||||
|     "build:version": "yarn --cwd ./excalidraw-app build:version", | ||||
|     "build": "yarn --cwd ./excalidraw-app build", | ||||
|     "build:preview": "yarn --cwd ./excalidraw-app build:preview", | ||||
|     "start": "yarn --cwd ./excalidraw-app start", | ||||
|     "start:production": "yarn --cwd ./excalidraw-app start:production", | ||||
|     "start:example": "yarn build:package && yarn --cwd ./examples/with-script-in-browser start", | ||||
|     "start:example": "yarn build:packages && yarn --cwd ./examples/with-script-in-browser start", | ||||
|     "test:all": "yarn test:typecheck && yarn test:code && yarn test:other && yarn test:app --watch=false", | ||||
|     "test:app": "vitest", | ||||
|     "test:code": "eslint --max-warnings=0 --ext .js,.ts,.tsx .", | ||||
| @@ -76,9 +80,10 @@ | ||||
|     "locales-coverage:description": "node scripts/locales-coverage-description.js", | ||||
|     "prepare": "husky install", | ||||
|     "prettier": "prettier \"**/*.{css,scss,json,md,html,yml}\" --ignore-path=.eslintignore", | ||||
|     "autorelease": "node scripts/autorelease.js", | ||||
|     "prerelease:excalidraw": "node scripts/prerelease.js", | ||||
|     "release:excalidraw": "node scripts/release.js", | ||||
|     "release": "node scripts/release.js", | ||||
|     "release:test": "node scripts/release.js --tag=test", | ||||
|     "release:next": "node scripts/release.js --tag=next", | ||||
|     "release:latest": "node scripts/release.js --tag=latest", | ||||
|     "rm:build": "rimraf --glob excalidraw-app/build excalidraw-app/dist excalidraw-app/dev-dist packages/*/dist packages/*/build examples/*/build examples/*/dist", | ||||
|     "rm:node_modules": "rimraf --glob node_modules excalidraw-app/node_modules packages/*/node_modules", | ||||
|     "clean-install": "yarn rm:node_modules && yarn install" | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@excalidraw/common", | ||||
|   "version": "0.1.0", | ||||
|   "version": "0.18.0", | ||||
|   "type": "module", | ||||
|   "types": "./dist/types/common/src/index.d.ts", | ||||
|   "main": "./dist/prod/index.js", | ||||
| @@ -13,7 +13,10 @@ | ||||
|       "default": "./dist/prod/index.js" | ||||
|     }, | ||||
|     "./*": { | ||||
|       "types": "./dist/types/common/src/*.d.ts" | ||||
|       "types": "./dist/types/common/src/*.d.ts", | ||||
|       "development": "./dist/dev/index.js", | ||||
|       "production": "./dist/prod/index.js", | ||||
|       "default": "./dist/prod/index.js" | ||||
|     } | ||||
|   }, | ||||
|   "files": [ | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@excalidraw/element", | ||||
|   "version": "0.1.0", | ||||
|   "version": "0.18.0", | ||||
|   "type": "module", | ||||
|   "types": "./dist/types/element/src/index.d.ts", | ||||
|   "main": "./dist/prod/index.js", | ||||
| @@ -13,7 +13,10 @@ | ||||
|       "default": "./dist/prod/index.js" | ||||
|     }, | ||||
|     "./*": { | ||||
|       "types": "./dist/types/element/src/*.d.ts" | ||||
|       "types": "./dist/types/element/src/*.d.ts", | ||||
|       "development": "./dist/dev/index.js", | ||||
|       "production": "./dist/prod/index.js", | ||||
|       "default": "./dist/prod/index.js" | ||||
|     } | ||||
|   }, | ||||
|   "files": [ | ||||
| @@ -52,5 +55,9 @@ | ||||
|   "scripts": { | ||||
|     "gen:types": "rimraf types && tsc", | ||||
|     "build:esm": "rimraf dist && node ../../scripts/buildBase.js && yarn gen:types" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@excalidraw/common": "0.18.0", | ||||
|     "@excalidraw/math": "0.18.0" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -66,12 +66,22 @@ | ||||
|       "last 1 safari version" | ||||
|     ] | ||||
|   }, | ||||
|   "repository": "https://github.com/excalidraw/excalidraw", | ||||
|   "bugs": "https://github.com/excalidraw/excalidraw/issues", | ||||
|   "homepage": "https://github.com/excalidraw/excalidraw/tree/master/packages/excalidraw", | ||||
|   "scripts": { | ||||
|     "gen:types": "rimraf types && tsc", | ||||
|     "build:esm": "rimraf dist && node ../../scripts/buildPackage.js && yarn gen:types" | ||||
|   }, | ||||
|   "peerDependencies": { | ||||
|     "react": "^17.0.2 || ^18.2.0 || ^19.0.0", | ||||
|     "react-dom": "^17.0.2 || ^18.2.0 || ^19.0.0" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@braintree/sanitize-url": "6.0.2", | ||||
|     "@excalidraw/common": "0.18.0", | ||||
|     "@excalidraw/element": "0.18.0", | ||||
|     "@excalidraw/math": "0.18.0", | ||||
|     "@excalidraw/laser-pointer": "1.3.1", | ||||
|     "@excalidraw/mermaid-to-excalidraw": "1.1.2", | ||||
|     "@excalidraw/random-username": "1.1.0", | ||||
| @@ -124,12 +134,5 @@ | ||||
|     "harfbuzzjs": "0.3.6", | ||||
|     "jest-diff": "29.7.0", | ||||
|     "typescript": "4.9.4" | ||||
|   }, | ||||
|   "repository": "https://github.com/excalidraw/excalidraw", | ||||
|   "bugs": "https://github.com/excalidraw/excalidraw/issues", | ||||
|   "homepage": "https://github.com/excalidraw/excalidraw/tree/master/packages/excalidraw", | ||||
|   "scripts": { | ||||
|     "gen:types": "rimraf types && tsc", | ||||
|     "build:esm": "rimraf dist && node ../../scripts/buildPackage.js && yarn gen:types" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@excalidraw/math", | ||||
|   "version": "0.1.0", | ||||
|   "version": "0.18.0", | ||||
|   "type": "module", | ||||
|   "types": "./dist/types/math/src/index.d.ts", | ||||
|   "main": "./dist/prod/index.js", | ||||
| @@ -13,7 +13,10 @@ | ||||
|       "default": "./dist/prod/index.js" | ||||
|     }, | ||||
|     "./*": { | ||||
|       "types": "./dist/types/math/src/*.d.ts" | ||||
|       "types": "./dist/types/math/src/*.d.ts", | ||||
|       "development": "./dist/dev/index.js", | ||||
|       "production": "./dist/prod/index.js", | ||||
|       "default": "./dist/prod/index.js" | ||||
|     } | ||||
|   }, | ||||
|   "files": [ | ||||
| @@ -56,5 +59,8 @@ | ||||
|   "scripts": { | ||||
|     "gen:types": "rimraf types && tsc", | ||||
|     "build:esm": "rimraf dist && node ../../scripts/buildBase.js && yarn gen:types" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@excalidraw/common": "0.18.0" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,71 +0,0 @@ | ||||
| const { exec, execSync } = require("child_process"); | ||||
| const fs = require("fs"); | ||||
|  | ||||
| const core = require("@actions/core"); | ||||
|  | ||||
| const excalidrawDir = `${__dirname}/../packages/excalidraw`; | ||||
| const excalidrawPackage = `${excalidrawDir}/package.json`; | ||||
| const pkg = require(excalidrawPackage); | ||||
| const isPreview = process.argv.slice(2)[0] === "preview"; | ||||
|  | ||||
| const getShortCommitHash = () => { | ||||
|   return execSync("git rev-parse --short HEAD").toString().trim(); | ||||
| }; | ||||
|  | ||||
| const publish = () => { | ||||
|   const tag = isPreview ? "preview" : "next"; | ||||
|  | ||||
|   try { | ||||
|     execSync(`yarn  --frozen-lockfile`); | ||||
|     execSync(`yarn run build:esm`, { cwd: excalidrawDir }); | ||||
|     execSync(`yarn --cwd ${excalidrawDir} publish --tag ${tag}`); | ||||
|     console.info(`Published ${pkg.name}@${tag}🎉`); | ||||
|     core.setOutput( | ||||
|       "result", | ||||
|       `**Preview version has been shipped** :rocket: | ||||
|     You can use [@excalidraw/excalidraw@${pkg.version}](https://www.npmjs.com/package/@excalidraw/excalidraw/v/${pkg.version}) for testing!`, | ||||
|     ); | ||||
|   } catch (error) { | ||||
|     core.setOutput("result", "package couldn't be published :warning:!"); | ||||
|     console.error(error); | ||||
|     process.exit(1); | ||||
|   } | ||||
| }; | ||||
| // get files changed between prev and head commit | ||||
| exec(`git diff --name-only HEAD^ HEAD`, async (error, stdout, stderr) => { | ||||
|   if (error || stderr) { | ||||
|     console.error(error); | ||||
|     core.setOutput("result", ":warning: Package couldn't be published!"); | ||||
|     process.exit(1); | ||||
|   } | ||||
|   const changedFiles = stdout.trim().split("\n"); | ||||
|  | ||||
|   const excalidrawPackageFiles = changedFiles.filter((file) => { | ||||
|     return ( | ||||
|       file.indexOf("packages/excalidraw") >= 0 || | ||||
|       file.indexOf("buildPackage.js") > 0 | ||||
|     ); | ||||
|   }); | ||||
|   if (!excalidrawPackageFiles.length) { | ||||
|     console.info("Skipping release as no valid diff found"); | ||||
|     core.setOutput("result", "Skipping release as no valid diff found"); | ||||
|     process.exit(0); | ||||
|   } | ||||
|  | ||||
|   // update package.json | ||||
|   let version = `${pkg.version}-${getShortCommitHash()}`; | ||||
|  | ||||
|   // update readme | ||||
|  | ||||
|   if (isPreview) { | ||||
|     // use pullNumber-commithash as the version for preview | ||||
|     const pullRequestNumber = process.argv.slice(3)[0]; | ||||
|     version = `${pkg.version}-${pullRequestNumber}-${getShortCommitHash()}`; | ||||
|   } | ||||
|   pkg.version = version; | ||||
|  | ||||
|   fs.writeFileSync(excalidrawPackage, JSON.stringify(pkg, null, 2), "utf8"); | ||||
|  | ||||
|   console.info("Publish in progress..."); | ||||
|   publish(); | ||||
| }); | ||||
| @@ -11,12 +11,9 @@ const getConfig = (outdir) => ({ | ||||
|   entryNames: "[name]", | ||||
|   assetNames: "[dir]/[name]", | ||||
|   alias: { | ||||
|     "@excalidraw/common": path.resolve(__dirname, "../packages/common/src"), | ||||
|     "@excalidraw/element": path.resolve(__dirname, "../packages/element/src"), | ||||
|     "@excalidraw/excalidraw": path.resolve(__dirname, "../packages/excalidraw"), | ||||
|     "@excalidraw/math": path.resolve(__dirname, "../packages/math/src"), | ||||
|     "@excalidraw/utils": path.resolve(__dirname, "../packages/utils/src"), | ||||
|   }, | ||||
|   external: ["@excalidraw/common", "@excalidraw/element", "@excalidraw/math"], | ||||
| }); | ||||
|  | ||||
| function buildDev(config) { | ||||
|   | ||||
| @@ -28,12 +28,9 @@ const getConfig = (outdir) => ({ | ||||
|   assetNames: "[dir]/[name]", | ||||
|   chunkNames: "[dir]/[name]-[hash]", | ||||
|   alias: { | ||||
|     "@excalidraw/common": path.resolve(__dirname, "../packages/common/src"), | ||||
|     "@excalidraw/element": path.resolve(__dirname, "../packages/element/src"), | ||||
|     "@excalidraw/excalidraw": path.resolve(__dirname, "../packages/excalidraw"), | ||||
|     "@excalidraw/math": path.resolve(__dirname, "../packages/math/src"), | ||||
|     "@excalidraw/utils": path.resolve(__dirname, "../packages/utils/src"), | ||||
|   }, | ||||
|   external: ["@excalidraw/common", "@excalidraw/element", "@excalidraw/math"], | ||||
|   loader: { | ||||
|     ".woff2": "file", | ||||
|   }, | ||||
|   | ||||
| @@ -1,38 +0,0 @@ | ||||
| const fs = require("fs"); | ||||
| const util = require("util"); | ||||
|  | ||||
| const exec = util.promisify(require("child_process").exec); | ||||
| const updateChangelog = require("./updateChangelog"); | ||||
|  | ||||
| const excalidrawDir = `${__dirname}/../packages/excalidraw/`; | ||||
| const excalidrawPackage = `${excalidrawDir}/package.json`; | ||||
|  | ||||
| const updatePackageVersion = (nextVersion) => { | ||||
|   const pkg = require(excalidrawPackage); | ||||
|   pkg.version = nextVersion; | ||||
|   const content = `${JSON.stringify(pkg, null, 2)}\n`; | ||||
|   fs.writeFileSync(excalidrawPackage, content, "utf-8"); | ||||
| }; | ||||
|  | ||||
| const prerelease = async (nextVersion) => { | ||||
|   try { | ||||
|     await updateChangelog(nextVersion); | ||||
|     updatePackageVersion(nextVersion); | ||||
|     await exec(`git add -u`); | ||||
|     await exec( | ||||
|       `git commit -m "docs: release @excalidraw/excalidraw@${nextVersion}  🎉"`, | ||||
|     ); | ||||
|  | ||||
|     console.info("Done!"); | ||||
|   } catch (error) { | ||||
|     console.error(error); | ||||
|     process.exit(1); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const nextVersion = process.argv.slice(2)[0]; | ||||
| if (!nextVersion) { | ||||
|   console.error("Pass the next version to release!"); | ||||
|   process.exit(1); | ||||
| } | ||||
| prerelease(nextVersion); | ||||
| @@ -1,28 +1,239 @@ | ||||
| const fs = require("fs"); | ||||
| const path = require("path"); | ||||
|  | ||||
| const { execSync } = require("child_process"); | ||||
|  | ||||
| const excalidrawDir = `${__dirname}/../packages/excalidraw`; | ||||
| const excalidrawPackage = `${excalidrawDir}/package.json`; | ||||
| const pkg = require(excalidrawPackage); | ||||
| const updateChangelog = require("./updateChangelog"); | ||||
|  | ||||
| const publish = () => { | ||||
|   try { | ||||
|     console.info("Installing the dependencies in root folder..."); | ||||
|     execSync(`yarn  --frozen-lockfile`); | ||||
|     console.info("Installing the dependencies in excalidraw directory..."); | ||||
|     execSync(`yarn --frozen-lockfile`, { cwd: excalidrawDir }); | ||||
|     console.info("Building ESM Package..."); | ||||
|     execSync(`yarn run build:esm`, { cwd: excalidrawDir }); | ||||
|     console.info("Publishing the package..."); | ||||
|     execSync(`yarn --cwd ${excalidrawDir} publish`); | ||||
|   } catch (error) { | ||||
|     console.error(error); | ||||
| // skipping utils for now, as it has independent release process | ||||
| const PACKAGES = ["common", "math", "element", "excalidraw"]; | ||||
| const PACKAGES_DIR = path.resolve(__dirname, "../packages"); | ||||
|  | ||||
| /** | ||||
|  * Returns the arguments for the release script. | ||||
|  * | ||||
|  * Usage examples: | ||||
|  * - yarn release --help                          -> prints this help message | ||||
|  * - yarn release                                 -> publishes `@excalidraw` packages with "test" tag and "-[hash]" version suffix | ||||
|  * - yarn release --tag=test                      -> same as above | ||||
|  * - yarn release --tag=next                      -> publishes `@excalidraw` packages with "next" tag and version "-[hash]" suffix | ||||
|  * - yarn release --tag=next --non-interactive    -> skips interactive prompts (runs on CI/CD), otherwise same as above | ||||
|  * - yarn release --tag=latest --version=0.19.0   -> publishes `@excalidraw` packages with "latest" tag and version "0.19.0" & prepares changelog for the release | ||||
|  * | ||||
|  * @returns [tag, version, nonInteractive] | ||||
|  */ | ||||
| const getArguments = () => { | ||||
|   let tag = "test"; | ||||
|   let version = ""; | ||||
|   let nonInteractive = false; | ||||
|  | ||||
|   for (const argument of process.argv.slice(2)) { | ||||
|     if (/--help/.test(argument)) { | ||||
|       console.info(`Available arguments: | ||||
|   --tag=<tag>                                    -> (optional) "test" (default), "next" for auto release, "latest" for stable release | ||||
|   --version=<version>                            -> (optional) for "next" and "test", (required) for "latest" i.e. "0.19.0" | ||||
|   --non-interactive                              -> (optional) disables interactive prompts`); | ||||
|  | ||||
|       console.info(`\nUsage examples: | ||||
|   - yarn release                                 -> publishes \`@excalidraw\` packages with "test" tag and "-[hash]" version suffix | ||||
|   - yarn release --tag=test                      -> same as above | ||||
|   - yarn release --tag=next                      -> publishes \`@excalidraw\` packages with "next" tag and version "-[hash]" suffix | ||||
|   - yarn release --tag=next --non-interactive    -> skips interactive prompts (runs on CI/CD), otherwise same as above | ||||
|   - yarn release --tag=latest --version=0.19.0   -> publishes \`@excalidraw\` packages with "latest" tag and version "0.19.0" & prepares changelog for the release`); | ||||
|  | ||||
|       process.exit(0); | ||||
|     } | ||||
|  | ||||
|     if (/--tag=/.test(argument)) { | ||||
|       tag = argument.split("=")[1]; | ||||
|     } | ||||
|  | ||||
|     if (/--version=/.test(argument)) { | ||||
|       version = argument.split("=")[1]; | ||||
|     } | ||||
|  | ||||
|     if (/--non-interactive/.test(argument)) { | ||||
|       nonInteractive = true; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (tag !== "latest" && tag !== "next" && tag !== "test") { | ||||
|     console.error(`Unsupported tag "${tag}", use "latest", "next" or "test".`); | ||||
|     process.exit(1); | ||||
|   } | ||||
|  | ||||
|   if (tag === "latest" && !version) { | ||||
|     console.error("Pass the version to make the latest stable release!"); | ||||
|     process.exit(1); | ||||
|   } | ||||
|  | ||||
|   if (!version) { | ||||
|     // set the next version based on the excalidraw package version + commit hash | ||||
|     const excalidrawPackageVersion = require(getPackageJsonPath( | ||||
|       "excalidraw", | ||||
|     )).version; | ||||
|  | ||||
|     const hash = getShortCommitHash(); | ||||
|  | ||||
|     if (!excalidrawPackageVersion.includes(hash)) { | ||||
|       version = `${excalidrawPackageVersion}-${hash}`; | ||||
|     } else { | ||||
|       // ensuring idempotency | ||||
|       version = excalidrawPackageVersion; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   console.info(`Running with tag "${tag}" and version "${version}"...`); | ||||
|  | ||||
|   return [tag, version, nonInteractive]; | ||||
| }; | ||||
|  | ||||
| const validatePackageName = (packageName) => { | ||||
|   if (!PACKAGES.includes(packageName)) { | ||||
|     console.error(`Package "${packageName}" not found!`); | ||||
|     process.exit(1); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const release = () => { | ||||
|   publish(); | ||||
|   console.info(`Published ${pkg.version}!`); | ||||
| const getPackageJsonPath = (packageName) => { | ||||
|   validatePackageName(packageName); | ||||
|   return path.resolve(PACKAGES_DIR, packageName, "package.json"); | ||||
| }; | ||||
|  | ||||
| release(); | ||||
| const updatePackageJsons = (nextVersion) => { | ||||
|   const packageJsons = new Map(); | ||||
|  | ||||
|   for (const packageName of PACKAGES) { | ||||
|     const pkg = require(getPackageJsonPath(packageName)); | ||||
|  | ||||
|     pkg.version = nextVersion; | ||||
|  | ||||
|     if (pkg.dependencies) { | ||||
|       for (const dependencyName of PACKAGES) { | ||||
|         if (!pkg.dependencies[`@excalidraw/${dependencyName}`]) { | ||||
|           continue; | ||||
|         } | ||||
|  | ||||
|         pkg.dependencies[`@excalidraw/${dependencyName}`] = nextVersion; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     packageJsons.set(packageName, `${JSON.stringify(pkg, null, 2)}\n`); | ||||
|   } | ||||
|  | ||||
|   // modify once, to avoid inconsistent state | ||||
|   for (const packageName of PACKAGES) { | ||||
|     const content = packageJsons.get(packageName); | ||||
|     fs.writeFileSync(getPackageJsonPath(packageName), content, "utf-8"); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const getShortCommitHash = () => { | ||||
|   return execSync("git rev-parse --short HEAD").toString().trim(); | ||||
| }; | ||||
|  | ||||
| const askToCommit = (tag, nextVersion) => { | ||||
|   if (tag !== "latest") { | ||||
|     return Promise.resolve(); | ||||
|   } | ||||
|  | ||||
|   return new Promise((resolve) => { | ||||
|     const rl = require("readline").createInterface({ | ||||
|       input: process.stdin, | ||||
|       output: process.stdout, | ||||
|     }); | ||||
|  | ||||
|     rl.question( | ||||
|       "Do you want to commit these changes to git? (Y/n): ", | ||||
|       (answer) => { | ||||
|         rl.close(); | ||||
|  | ||||
|         if (answer.toLowerCase() === "y") { | ||||
|           execSync(`git add -u`); | ||||
|           execSync( | ||||
|             `git commit -m "chore: release @excalidraw/excalidraw@${nextVersion} 🎉"`, | ||||
|           ); | ||||
|         } else { | ||||
|           console.warn( | ||||
|             "Skipping commit. Don't forget to commit manually later!", | ||||
|           ); | ||||
|         } | ||||
|  | ||||
|         resolve(); | ||||
|       }, | ||||
|     ); | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| const buildPackages = () => { | ||||
|   console.info("Running yarn install..."); | ||||
|   execSync(`yarn --frozen-lockfile`, { stdio: "inherit" }); | ||||
|  | ||||
|   console.info("Removing existing build artifacts..."); | ||||
|   execSync(`yarn rm:build`, { stdio: "inherit" }); | ||||
|  | ||||
|   for (const packageName of PACKAGES) { | ||||
|     console.info(`Building "@excalidraw/${packageName}"...`); | ||||
|     execSync(`yarn run build:esm`, { | ||||
|       cwd: path.resolve(PACKAGES_DIR, packageName), | ||||
|       stdio: "inherit", | ||||
|     }); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const askToPublish = (tag, version) => { | ||||
|   return new Promise((resolve) => { | ||||
|     const rl = require("readline").createInterface({ | ||||
|       input: process.stdin, | ||||
|       output: process.stdout, | ||||
|     }); | ||||
|  | ||||
|     rl.question( | ||||
|       "Do you want to publish these changes to npm? (Y/n): ", | ||||
|       (answer) => { | ||||
|         rl.close(); | ||||
|  | ||||
|         if (answer.toLowerCase() === "y") { | ||||
|           publishPackages(tag, version); | ||||
|         } else { | ||||
|           console.info("Skipping publish."); | ||||
|         } | ||||
|  | ||||
|         resolve(); | ||||
|       }, | ||||
|     ); | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| const publishPackages = (tag, version) => { | ||||
|   for (const packageName of PACKAGES) { | ||||
|     execSync(`yarn publish --tag ${tag}`, { | ||||
|       cwd: path.resolve(PACKAGES_DIR, packageName), | ||||
|       stdio: "inherit", | ||||
|     }); | ||||
|  | ||||
|     console.info( | ||||
|       `Published "@excalidraw/${packageName}@${tag}" with version "${version}"! 🎉`, | ||||
|     ); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** main */ | ||||
| (async () => { | ||||
|   const [tag, version, nonInteractive] = getArguments(); | ||||
|  | ||||
|   buildPackages(); | ||||
|  | ||||
|   if (tag === "latest") { | ||||
|     await updateChangelog(version); | ||||
|   } | ||||
|  | ||||
|   updatePackageJsons(version); | ||||
|  | ||||
|   if (nonInteractive) { | ||||
|     publishPackages(tag, version); | ||||
|   } else { | ||||
|     await askToCommit(tag, version); | ||||
|     await askToPublish(tag, version); | ||||
|   } | ||||
| })(); | ||||
|   | ||||
| @@ -20,14 +20,16 @@ const headerForType = { | ||||
|   perf: "Performance", | ||||
|   build: "Build", | ||||
| }; | ||||
|  | ||||
| const badCommits = []; | ||||
| const getCommitHashForLastVersion = async () => { | ||||
|   try { | ||||
|     const commitMessage = `"release @excalidraw/excalidraw@${lastVersion}"`; | ||||
|     const commitMessage = `"release @excalidraw/excalidraw"`; | ||||
|     const { stdout } = await exec( | ||||
|       `git log --format=format:"%H" --grep=${commitMessage}`, | ||||
|     ); | ||||
|     return stdout; | ||||
|     // take commit hash from latest release | ||||
|     return stdout.split(/\r?\n/)[0]; | ||||
|   } catch (error) { | ||||
|     console.error(error); | ||||
|   } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Marcel Mraz
					Marcel Mraz