Skip to content

Release

Release #116

Workflow file for this run

name: Release
on:
schedule:
- cron: "0 */6 * * *"
workflow_dispatch:
inputs:
force_contracts:
description: "Bypass contract gate (set to true when extraction legitimately changed)"
required: false
default: "false"
type: boolean
permissions:
contents: write
id-token: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
token: ${{ secrets.RELEASE_PAT }}
fetch-tags: true
- uses: actions/setup-node@v6
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Check for new version
id: check
run: |
LATEST=$(npm view @anthropic-ai/claude-code version)
echo "latest=$LATEST" >> "$GITHUB_OUTPUT"
echo "Latest npm: $LATEST"
# Check if we already have a git tag for this version
if git rev-parse "v$LATEST" >/dev/null 2>&1; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "Tag v$LATEST already exists — nothing to do."
else
echo "skip=false" >> "$GITHUB_OUTPUT"
echo "No tag v$LATEST — will create release."
fi
- name: Extract contracts
if: steps.check.outputs.skip == 'false'
env:
FORCE_CONTRACTS: ${{ inputs.force_contracts && '1' || '0' }}
run: |
npx tsx scripts/extract-contracts.ts --changelog
npx tsx scripts/generate-contracts.ts
- name: Build and test
if: steps.check.outputs.skip == 'false'
run: |
npm run build
npm test
- name: Prepare release
if: steps.check.outputs.skip == 'false'
run: |
VERSION="${{ steps.check.outputs.latest }}"
# Bump package.json version
node -e "
const fs = require('fs');
const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
p.version = process.argv[1];
fs.writeFileSync('package.json', JSON.stringify(p, null, '\t') + '\n');
" "$VERSION"
npm install --package-lock-only
# Prepend changelog entry
if [ -f CHANGELOG.md ]; then
tail -n +2 CHANGELOG.md > CHANGELOG_OLD.md
echo "# Changelog" > CHANGELOG.md
echo "" >> CHANGELOG.md
cat CHANGELOG_ENTRY.md >> CHANGELOG.md
cat CHANGELOG_OLD.md >> CHANGELOG.md
rm CHANGELOG_OLD.md
else
echo "# Changelog" > CHANGELOG.md
echo "" >> CHANGELOG.md
cat CHANGELOG_ENTRY.md >> CHANGELOG.md
fi
# Create tarball
npm pack --ignore-scripts
echo "tarball=$(ls *.tgz)" >> "$GITHUB_ENV"
- name: Commit, tag, and push
if: steps.check.outputs.skip == 'false'
run: |
VERSION="${{ steps.check.outputs.latest }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git commit -m "release: sync with Claude Code v$VERSION"
git tag -a "v$VERSION" -m "v$VERSION"
git push origin HEAD --tags
- name: Publish to npm
if: steps.check.outputs.skip == 'false'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
echo "//registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN" > ~/.npmrc
npm publish --ignore-scripts --access public --provenance
- name: Create GitHub Release
if: steps.check.outputs.skip == 'false'
env:
GH_TOKEN: ${{ github.token }}
run: |
VERSION="${{ steps.check.outputs.latest }}"
# Build release body
BODY=$(node -e "
const changelog = require('fs').readFileSync('CHANGELOG_ENTRY.md', 'utf8');
const install = [
'### Install',
'',
'\`\`\`bash',
'npm install claudecode-linter@$VERSION',
'\`\`\`',
'',
].join('\n');
process.stdout.write(install + changelog);
")
gh release create "v$VERSION" \
--title "v$VERSION" \
--notes "$BODY" \
"${{ env.tarball }}"
rm -f CHANGELOG_ENTRY.md *.tgz