diff --git a/tools/release.js b/tools/release.js new file mode 100644 index 0000000..cbcf739 --- /dev/null +++ b/tools/release.js @@ -0,0 +1,69 @@ +const exec = require('child_process').execSync; +const resolve = require('path').resolve; + +const getSHA = (s) => s.match(/^\s*([0-9a-fA-F]{40})\s*$/)[1]; + +const inherit = { stdio: 'inherit' }; +const utf8 = { encoding: 'utf8' }; + +let stdout; + +const version = process.argv[2]; +if (!/^\d+\.\d+\.\d+$/.test(version)) + throw new Error('usage: release.js {version}'); + +const distTag = `v${version}`; + +const projectRootDir = resolve(__dirname, '..'); +process.chdir(projectRootDir); + +stdout = exec('git.exe status --porcelain -uno', utf8); +if (stdout.match(/\S/)) + throw new Error('git index or working directory not clean'); + +exec('cmake.exe --build . --target dist', inherit); + +stdout = exec('git rev-parse --verify HEAD', utf8); +const sourceCommit = getSHA(stdout); + +stdout = exec('git write-tree', utf8); +const sourceTree = getSHA(stdout); + +stdout = exec('git log --pretty="%D"', utf8); +const previousTag = stdout.match(/tag: ([^\s,;]+)/)[1]; + +stdout = exec(`git rev-list -n 1 ${previousTag}`, utf8); +const previousTagCommit = getSHA(stdout); + +exec('git add -f dist/'); + +stdout = exec('git write-tree --prefix=dist/', utf8); +const distTree = getSHA(stdout); + +exec('git reset'); + +stdout = exec(`git commit-tree ${distTree} ` + + `-p ${previousTagCommit} ` + + `-p ${sourceCommit} ` + + `-m "version ${version}"`, utf8); +const distCommit = stdout.match(/[\w+]+/)[0]; + +stdout = exec(`git commit-tree ${sourceTree} ` + + `-p ${sourceCommit} ` + + `-p ${distCommit} ` + + `-m "dist: merge release tag ${distTag}"`, utf8); +const mergeCommit = stdout.match(/[\w+]+/)[0]; + +exec(`git diff --stat ${previousTagCommit}..${distCommit}`, inherit); + +console.log(''); +console.log(`Previous release tag: ${previousTag}`); +console.log(`New release tag ${distTag}`); + +exec(`git tag ${distTag} ${distCommit} ` + + `-sm "version ${version}"`, inherit); + +exec(`git branch -f dist ${distCommit}`, inherit); +exec(`git update-ref HEAD ${mergeCommit}`, inherit); + +exec('git log --graph --decorate -n 3', inherit);