Skip to content

chore: version packages #78

chore: version packages

chore: version packages #78

Workflow file for this run

name: Release
on:
push:
branches:
- main
workflow_dispatch:
concurrency: ${{ github.workflow }}-${{ github.ref }}
permissions:
contents: write
pull-requests: write
id-token: write
packages: write
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22.x"
- name: Upgrade npm for OIDC support
run: npm install -g npm@latest
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Type check
run: bun run typecheck
- name: Lint
run: bun run lint
- name: Test
run: bun test 2>/dev/null || true
- name: Build
run: bun run build
- name: Create Release Pull Request or Publish
id: changesets
uses: changesets/action@v1
with:
version: bun run changeset:version
publish: echo "skip"
commit: "chore: version packages"
title: "chore: version packages"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish to npm with OIDC
if: steps.changesets.outputs.hasChangesets == 'false'
run: |
# Check npm version (need 11.5.1+ for OIDC)
echo "npm version: $(npm --version)"
# Remove any existing .npmrc that might interfere with OIDC
rm -f ~/.npmrc
rm -f .npmrc
# Check if package version is already published
PACKAGE_NAME=$(node -p "require('./package.json').name")
LOCAL_VERSION=$(node -p "require('./package.json').version")
# Get published version (returns empty if not found)
PUBLISHED_VERSION=$(npm view "$PACKAGE_NAME" version 2>/dev/null || echo "")
if [ "$LOCAL_VERSION" != "$PUBLISHED_VERSION" ]; then
echo "Publishing $PACKAGE_NAME@$LOCAL_VERSION (current published: ${PUBLISHED_VERSION:-none})"
npm publish --access public
else
echo "Version $LOCAL_VERSION is already published, skipping"
fi
- name: Publish to GitHub Packages with OIDC
if: steps.changesets.outputs.hasChangesets == 'false'
run: |
# Get version info and save original package name
LOCAL_VERSION=$(node -p "require('./package.json').version")
SCOPED_PACKAGE_NAME='@mynameistito/github-archiver'
echo "Attempting to publish $SCOPED_PACKAGE_NAME@$LOCAL_VERSION to GitHub Packages"
# Temporarily modify package.json with scoped name
node -e "
const fs = require('fs');
const pkg = require('./package.json');
global.originalName = pkg.name;
pkg.name = '@mynameistito/github-archiver';
fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n');
console.log('Changed package name to scoped for GitHub Packages');
"
# Publish to GitHub Packages registry
npm publish --registry https://npm.pkg.github.com --access public || true
# Restore original package name
node -e "
const fs = require('fs');
const pkg = require('./package.json');
pkg.name = 'github-archiver';
fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n');
console.log('Restored original package name');
"
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create version tag
if: steps.changesets.outputs.hasChangesets == 'false'
run: |
VERSION=$(node -p "require('./package.json').version")
TAG="v${VERSION}"
echo "Creating tag ${TAG}"
git config --local user.name "github-actions[bot]"
git config --local user.email "github-actions[bot]@users.noreply.github.com"
# Check if tag already exists locally
if git rev-parse "${TAG}" >/dev/null 2>&1; then
echo "ℹ️ Tag ${TAG} already exists locally, skipping creation"
else
git tag "${TAG}"
git push origin "${TAG}"
echo "✅ Created and pushed tag ${TAG}"
fi
- name: Update latest tag
if: steps.changesets.outputs.hasChangesets == 'false'
run: |
git config --local user.name "github-actions[bot]"
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git tag -f latest
git push origin -f latest
- name: Extract release notes and create GitHub Release
if: steps.changesets.outputs.hasChangesets == 'false'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
// Read package.json to get version
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
const version = packageJson.version;
const tag = `v${version}`;
// Read CHANGELOG.md
const changelog = fs.readFileSync('./CHANGELOG.md', 'utf8');
const lines = changelog.split('\n');
// Find the section for this version by looking for "## " (level 2 header) with the version number
// This handles all formats: ## [1.1.2], ## 1.1.2, ## [1.1.2](link) (date), etc.
let startIdx = -1;
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
// Check if line is a level 2 header (## but not ###) and contains the version number
if (line.startsWith('## ') && line.includes(version)) {
startIdx = i;
break;
}
}
let releaseBody = 'No release notes available';
if (startIdx !== -1) {
// Find the next level 2 header (## but not ###) - marks end of this version's section
let endIdx = lines.length;
for (let i = startIdx + 1; i < lines.length; i++) {
if (lines[i].startsWith('## ') && !lines[i].startsWith('### ')) {
endIdx = i;
break;
}
}
// Extract content between headers and trim whitespace
const contentLines = lines.slice(startIdx + 1, endIdx);
releaseBody = contentLines.join('\n').trim();
}
// Create GitHub Release
try {
await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: tag,
name: `Release ${version}`,
body: releaseBody,
draft: false,
prerelease: false
});
console.log(`✅ Created GitHub Release for ${tag}`);
} catch (error) {
// Release might already exist, that's okay
if (error.status === 422) {
console.log(`ℹ️ Release for ${tag} already exists`);
} else {
throw error;
}
}