Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .github/scripts/bump-version.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env node
import { readFileSync, writeFileSync } from 'node:fs';
import { resolve } from 'node:path';

const args = process.argv.slice(2);
let explicitVersion;
let bumpType = 'patch';

for (let i = 0; i < args.length; i += 1) {
const value = args[i];
if (value === '--set') {
explicitVersion = args[i + 1];
if (!explicitVersion) {
console.error('Expected value after --set');
process.exit(1);
}
i += 1;
} else {
bumpType = value.toLowerCase();
}
}

const pkgPath = resolve(process.cwd(), 'package.json');
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));

const nextVersion = explicitVersion
? normalizeVersion(explicitVersion)
: bumpVersion(pkg.version, bumpType);

pkg.version = nextVersion;
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`, 'utf8');

console.log(nextVersion);

function normalizeVersion(candidate) {
const clean = String(candidate).trim().replace(/^v/, '');
if (!/^\d+\.\d+\.\d+$/.test(clean)) {
throw new Error(`Invalid semantic version: ${candidate}`);
}
return clean;
}

function bumpVersion(version, type) {
const allowed = new Set(['major', 'minor', 'patch']);
if (!allowed.has(type)) {
throw new Error(`Unsupported bump type: ${type}`);
}

const [core] = String(version).split('-');
const parts = core.split('.').map((part) => {
const value = Number.parseInt(part, 10);
if (Number.isNaN(value)) {
throw new Error(`Invalid semver component: ${part}`);
}
return value;
});

if (parts.length !== 3) {
throw new Error(`Version must have three numeric parts (got "${version}")`);
}

if (type === 'major') {
parts[0] += 1;
parts[1] = 0;
parts[2] = 0;
} else if (type === 'minor') {
parts[1] += 1;
parts[2] = 0;
} else {
parts[2] += 1;
}

return parts.join('.');
}
65 changes: 65 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ on:
merge_group:
types:
- checks_requested
release:
types:
- published

permissions:
contents: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down Expand Up @@ -198,6 +204,65 @@ jobs:
npm version "$CANARY_VERSION" --no-git-tag-version
npm publish --access public --tag canary

publish-release:
name: Publish release to npm
if: github.event_name == 'release' && github.event.release.draft == false
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
ref: ${{ github.event.release.target_commitish }}

- name: Setup
uses: ./.github/actions/setup

- name: Bump package version
id: bump
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
if [ -z "$RELEASE_TAG" ]; then
echo "Release tag is required to set package version" >&2
exit 1
fi
NEW_VERSION=$(node .github/scripts/bump-version.mjs --set "$RELEASE_TAG")
echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT"

- name: Commit version bump
id: commit
env:
VERSION: ${{ steps.bump.outputs.version }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if git diff --quiet; then
echo "did_commit=false" >> "$GITHUB_OUTPUT"
echo "Package version already up to date"
exit 0
fi
git commit -am "chore: bump version to ${VERSION}"
echo "did_commit=true" >> "$GITHUB_OUTPUT"

- name: Push version bump
if: steps.commit.outputs.did_commit == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git push

- name: Build package
run: yarn prepare

- name: Configure npm auth
run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish release
run: npm publish --access public

publish:
name: Publish to npm (push to main)
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
Expand Down
Loading