Skip to content

Merge pull request #22 from Atharva0506/fix/npm-auth-check #6

Merge pull request #22 from Atharva0506/fix/npm-auth-check

Merge pull request #22 from Atharva0506/fix/npm-auth-check #6

name: Version Release
on:
push:
branches:
- main
paths:
- 'VERSION'
workflow_dispatch:
concurrency:
group: version-release
cancel-in-progress: false
permissions:
contents: write
jobs:
release:
if: ${{ github.repository_owner == 'AOSSIE-Org' }}
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.get_version.outputs.version }}
released: ${{ steps.publish_release.outputs.released }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: true
- name: Verify actor is a maintainer
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: context.actor,
}).catch(() => ({ data: { permission: 'none' } }));
if (permission.permission !== 'admin' && permission.permission !== 'write') {
core.setFailed(`Actor '${context.actor}' does not have write access to this repository. Aborting release.`);
} else {
console.log(`✓ Actor '${context.actor}' is a verified repository maintainer.`);
}
- name: Read VERSION file
id: get_version
run: |
VERSION=$(cat VERSION | tr -d '[:space:]')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version detected: $VERSION"
- name: Validate VERSION format
run: |
VERSION="${{ steps.get_version.outputs.version }}"
if ! [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: VERSION must follow semantic versioning (e.g., 1.0.0)"
exit 1
fi
echo "✓ Version format is valid: $VERSION"
- name: Check if tag already exists
run: |
VERSION="${{ steps.get_version.outputs.version }}"
if git show-ref --tags --verify --quiet "refs/tags/v$VERSION"; then
echo "Error: Tag v$VERSION already exists"
exit 1
fi
echo "✓ Tag v$VERSION does not exist yet"
- name: Create and push tag
run: |
VERSION="${{ steps.get_version.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "v$VERSION" -m "Release version $VERSION"
git push origin "v$VERSION"
echo "✓ Created and pushed tag v$VERSION"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Find and Publish Draft Release
id: publish_release
uses: actions/github-script@v7
env:
VERSION: v${{ steps.get_version.outputs.version }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const version = process.env.VERSION;
// Get all releases
const { data: releases } = await github.rest.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
});
// Find the draft release
const draftRelease = releases.find(release => release.draft === true);
if (draftRelease) {
console.log(`Found draft release: ${draftRelease.name}`);
// Update and publish the draft release
await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: draftRelease.id,
tag_name: version,
name: version,
draft: false,
});
console.log(`✓ Published draft release as ${version}`);
core.setOutput('released', 'true');
} else {
console.log('⚠️ No draft release found. Creating release automatically.');
await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: version,
name: version,
body: `## Release ${version}\n\nThis release was automatically created when the VERSION file was updated.`,
draft: false,
prerelease: false,
});
console.log(`✓ Created and published release ${version}`);
core.setOutput('released', 'true');
}
- name: Release Summary
run: |
echo "### Release Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Version:** v${{ steps.get_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Tag Created:** ✓" >> $GITHUB_STEP_SUMMARY
if [ "${{ steps.publish_release.outputs.released }}" = "true" ]; then
echo "- **GitHub Release:** ✓" >> $GITHUB_STEP_SUMMARY
else
echo "- **GitHub Release:** ✗ (no draft found)" >> $GITHUB_STEP_SUMMARY
fi
publish:
needs: release
if: ${{ github.repository_owner == 'AOSSIE-Org' && needs.release.outputs.released == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm ci
- name: Sync version from VERSION file
env:
VERSION: ${{ needs.release.outputs.version }}
run: |
echo "Syncing package.json version to $VERSION"
npm version "$VERSION" --no-git-tag-version --allow-same-version
echo "✓ package.json version set to $VERSION"
- name: Build
run: npm run build
- name: Run tests
run: npm test
- name: Verify package contents
run: npm pack --dry-run
- name: Verify npm authentication
env:
NODE_AUTH_TOKEN: ${{ secrets.NPMJS_TOKEN }}
run: |
if [ -z "$NODE_AUTH_TOKEN" ]; then
echo "::error::NPMJS_TOKEN secret is not set. Configure it in repo Settings → Secrets → Actions."
exit 1
fi
echo "✓ NPMJS_TOKEN secret is present"
echo "Node: $(node -v) | npm: $(npm -v)"
echo "Registry: $(npm config get registry)"
cat ~/.npmrc 2>/dev/null | sed 's/_authToken=.*/_authToken=***/' || true
NPM_USER=$(npm whoami 2>&1) || {
echo "::error::npm authentication failed. The NPMJS_TOKEN may be expired or invalid."
echo "npm whoami output: $NPM_USER"
exit 1
}
echo "✓ Authenticated as: $NPM_USER"
npm org ls aossie-org "$NPM_USER" 2>&1 || echo "⚠ Could not verify org membership"
- name: Publish to npm
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPMJS_TOKEN }}
- name: Publish Summary
run: |
echo "### npm Publish Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Package:** @aossie-org/thrubox-client" >> $GITHUB_STEP_SUMMARY
echo "- **Version:** ${{ needs.release.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Registry:** https://www.npmjs.com/package/@aossie-org/thrubox-client" >> $GITHUB_STEP_SUMMARY
echo "- **Provenance:** ✓ (supply-chain attestation enabled)" >> $GITHUB_STEP_SUMMARY