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/README.md b/README.md index f451a66..8bb6439 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ TypeScript definitions for the renderer, event manager and chart designer of [Seats.io](https://www.seats.io/). -This replaces the legacy package [@types/seatsio](https://www.npmjs.com/package/@types/seatsio). \ No newline at end of file +This replaces the legacy package [@types/seatsio](https://www.npmjs.com/package/@types/seatsio). diff --git a/package.json b/package.json index 947c490..66a5b55 100644 --- a/package.json +++ b/package.json @@ -12,15 +12,11 @@ "url": "https://github.com/seatsio/seatsio-types" }, "devDependencies": { - "@actions/core": "1.10.1", - "cli-select-2": "2.0.0", - "typescript": "5.2.2", - "yargs": "17.7.2" + "typescript": "5.2.2" }, "scripts": { "build": "tsc", "test": "yarn tsc --noEmit src/index.test.ts", - "test:watch": "tsc --watch src/index.test.ts", - "bump-version": "node scripts/bumpVersion.mjs" + "test:watch": "tsc --watch src/index.test.ts" } -} \ No newline at end of file +} 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 + }) +} diff --git a/scripts/bumpVersion.mjs b/scripts/bumpVersion.mjs deleted file mode 100644 index 63d6224..0000000 --- a/scripts/bumpVersion.mjs +++ /dev/null @@ -1,70 +0,0 @@ -import core from '@actions/core' -import { execSync } from 'child_process' -import cliSelect from 'cli-select-2' -import fs from 'fs' -import { hideBin } from 'yargs/helpers' -import yargs from 'yargs/yargs' - -const argv = yargs(hideBin(process.argv)) - .option('versionChange', { - alias: 'v', - type: 'string', - description: 'Version change type. Possible values are patch, minor, major.' - }).parse() - -const validArgs = ['current', 'minor', 'major', 'patch'] - -const execute = cmd => { - execSync(cmd, { stdio: 'inherit' }) -} - -const bumpVersion = async (versionType) => { - if (versionType !== 'current') { - const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8')) - const currentVersion = packageJson.version - let [major, minor, patch] = currentVersion.split('.').map(v => parseInt(v, 10)) - - switch (versionType) { - case 'major': - major += 1 - minor = patch = 0 - break - case 'minor': - minor += 1 - patch = 0 - break - case 'patch': - patch += 1 - break - } - - const newVersion = `${major}.${minor}.${patch}` - packageJson.version = newVersion - core.setOutput('newVersion', newVersion) - fs.writeFileSync('package.json', JSON.stringify(packageJson, undefined, 4)) - console.log(`\nDone! Package file updated to ${newVersion}.`) - } -} - -const onSelect = (selection) => { - if (selection.value && typeof selection.value === 'string') { - bumpVersion(selection.value.toLowerCase()) - } -} - -const versionBump = argv.v -if (validArgs.indexOf(versionBump) !== -1) { - bumpVersion(versionBump) -} else { - const options = { - values: { - 'Keep current version': 'current', - 'Patch': 'patch', - 'Minor': 'minor', - 'Major': 'major', - }, - defautValue: 0 - } - - cliSelect(options, onSelect) -} \ No newline at end of file