From b6d0d7e87061782c733ce2ca5b7dccfcbc0f9fd8 Mon Sep 17 00:00:00 2001 From: mroloux Date: Thu, 24 Oct 2024 10:00:28 +0200 Subject: [PATCH] Create releases in the npm registry and in github --- .github/workflows/release.yml | 48 +++++++++---------- release.mjs | 87 +++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 26 deletions(-) create mode 100755 release.mjs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 995ecd4..a00e6b0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,40 +20,36 @@ on: - major jobs: - updateVersionAndPublish: + release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - uses: fregante/setup-git-user@v2 - uses: actions/setup-node@v4 with: node-version: 20 registry-url: https://registry.npmjs.org/ - - - name: Checkout latest main - run: | - git checkout main - git pull origin main - - - name: Build types - run: | - yarn install - yarn build - - - name: Update package version + - run: yarn install + - run: yarn zx ./release.mjs -v $VERSION_TO_BUMP env: - VERSION: ${{ inputs.version }} - run: | - yarn bump-version --v $VERSION - - - name: Commit updated package.json - run: | - git add package.json - git commit -m "Update @seatsio/seatsio-types" - git push origin main + VERSION_TO_BUMP: ${{ inputs.versionToBump }} + GH_TOKEN: ${{ github.token }} + - run: yarn build + - run: yarn publish + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} - - name: Publish new version to NPM - uses: JS-DevTools/npm-publish@v3 + notify-slack-failure: + runs-on: ubuntu-latest + needs: [ release ] + if: failure() + steps: + - uses: voxmedia/github-action-slack-notify-build@v1 with: - token: ${{ secrets.NPM_TOKEN }} - package: './package.json' + status: FAILED + channel: build_status + color: danger + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} diff --git a/release.mjs b/release.mjs new file mode 100755 index 0000000..9cbe45c --- /dev/null +++ b/release.mjs @@ -0,0 +1,87 @@ +#!/usr/bin/env zx + +$.verbose = false + +const semver = require('semver') +const versionToBump = getVersionToBump() +const latestReleaseTag = await fetchLatestReleasedVersionNumber() +const latestVersion = removeLeadingV(latestReleaseTag) +const nextVersion = await determineNextVersionNumber(latestVersion) + +await assertChangesSinceRelease(latestReleaseTag) +await bumpVersionInFiles() +await commitAndPush() +await release() + +function getVersionToBump() { + if (!argv.v || !(argv.v === 'minor' || argv.v === 'major')) { + throw new Error ("Please specify -v major/minor") + } + return argv.v +} + +function removeLeadingV(tagName) { + if (tagName.startsWith('v')) { + return tagName.substring(1) + } + return tagName +} + +async function fetchLatestReleasedVersionNumber() { + let result = await $`gh release view --json tagName` + return JSON.parse(result).tagName +} + +async function determineNextVersionNumber(previous) { + return semver.inc(previous, versionToBump) +} + +async function bumpVersionInFiles() { + await replaceInFile("package.json", `"version": "${latestVersion}",`, `"version": "${nextVersion}",`) +} + +async function replaceInFile(filename, latestVersion, nextVersion) { + return await fs.readFile(filename, 'utf8') + .then(text => { + if (text.indexOf(latestVersion) < 0) { + throw new Error('Not the correct version. Could not find ' + latestVersion + ' in ' + filename) + } + return text + }) + .then(text => text.replace(latestVersion, nextVersion)) + .then(text => fs.writeFileSync(filename, text)) + .then(() => gitAdd(filename)) +} + +async function gitAdd(filename) { + return await $`git add ${filename}` +} + +async function commitAndPush() { + await $`git commit -m "version bump"` + await $`git push origin main` +} + +async function getCurrentCommitHash() { + return (await $`git rev-parse HEAD`).stdout.trim() +} + +async function getCommitHashOfTag(tag) { + return (await $`git rev-list -n 1 ${tag}`).stdout.trim() +} + +async function assertChangesSinceRelease(releaseTag) { + let mainCommitHash = await getCurrentCommitHash() + let releaseCommitHash = await getCommitHashOfTag(releaseTag) + if(mainCommitHash === releaseCommitHash) { + throw new Error("No changes on main since release tagged " + releaseTag) + } +} + +async function release() { + const newTag = 'v' + nextVersion + return await $`gh release create ${newTag} --generate-notes`.catch(error => { + console.error('something went wrong while creating the release. Please revert the version change!') + throw error + }) +}