17 changed files with 286 additions and 238 deletions
@ -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 }}" |
|
||||||
@ -1,5 +1,5 @@ |
|||||||
{ |
{ |
||||||
"outputDirectory": "dist", |
"outputDirectory": "dist", |
||||||
"installCommand": "yarn install", |
"installCommand": "yarn install", |
||||||
"buildCommand": "yarn build:package && yarn build" |
"buildCommand": "yarn build:packages && yarn build" |
||||||
} |
} |
||||||
|
|||||||
@ -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(); |
|
||||||
}); |
|
||||||
@ -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 { execSync } = require("child_process"); |
||||||
|
|
||||||
const excalidrawDir = `${__dirname}/../packages/excalidraw`; |
const updateChangelog = require("./updateChangelog"); |
||||||
const excalidrawPackage = `${excalidrawDir}/package.json`; |
|
||||||
const pkg = require(excalidrawPackage); |
// skipping utils for now, as it has independent release process
|
||||||
|
const PACKAGES = ["common", "math", "element", "excalidraw"]; |
||||||
const publish = () => { |
const PACKAGES_DIR = path.resolve(__dirname, "../packages"); |
||||||
try { |
|
||||||
console.info("Installing the dependencies in root folder..."); |
/** |
||||||
execSync(`yarn --frozen-lockfile`); |
* Returns the arguments for the release script. |
||||||
console.info("Installing the dependencies in excalidraw directory..."); |
* |
||||||
execSync(`yarn --frozen-lockfile`, { cwd: excalidrawDir }); |
* Usage examples: |
||||||
console.info("Building ESM Package..."); |
* - yarn release --help -> prints this help message |
||||||
execSync(`yarn run build:esm`, { cwd: excalidrawDir }); |
* - yarn release -> publishes `@excalidraw` packages with "test" tag and "-[hash]" version suffix |
||||||
console.info("Publishing the package..."); |
* - yarn release --tag=test -> same as above |
||||||
execSync(`yarn --cwd ${excalidrawDir} publish`); |
* - yarn release --tag=next -> publishes `@excalidraw` packages with "next" tag and version "-[hash]" suffix |
||||||
} catch (error) { |
* - yarn release --tag=next --non-interactive -> skips interactive prompts (runs on CI/CD), otherwise same as above |
||||||
console.error(error); |
* - 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); |
process.exit(1); |
||||||
} |
} |
||||||
}; |
}; |
||||||
|
|
||||||
const release = () => { |
const getPackageJsonPath = (packageName) => { |
||||||
publish(); |
validatePackageName(packageName); |
||||||
console.info(`Published ${pkg.version}!`); |
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); |
||||||
|
} |
||||||
|
})(); |
||||||
|
|||||||
Loading…
Reference in new issue