Skip to content

Merge branch 'break/2.0.0-venus-version-v2' into break/2.0.0-venus-ve… #5

Merge branch 'break/2.0.0-venus-version-v2' into break/2.0.0-venus-ve…

Merge branch 'break/2.0.0-venus-version-v2' into break/2.0.0-venus-ve… #5

name: Auto Publish Beta to NPM
# This workflow automatically publishes beta versions on push to break/* branches and main
# Beta versions follow the pattern: X.Y.Z-beta.N (e.g., 2.0.0-beta.38)
#
# Required secrets:
# 1. NPM_TOKEN: NPM automation token for publishing packages
# 2. RELEASE_TOKEN: GitHub PAT with bypass permissions (optional but recommended)
on:
push:
branches:
- 'break/**'
permissions:
contents: write
pull-requests: write
packages: write
actions: read
id-token: write # Required for NPM provenance
jobs:
auto-publish-beta:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Validate package integrity
run: |
# Verify that package.json is well-formed
PACKAGE_NAME=$(node -p "require('./package.json').name")
echo "Package name: $PACKAGE_NAME"
# Verify that required scripts exist
node -e "
const pkg = require('./package.json');
const scripts = pkg.scripts || {};
if (!scripts['test'] && !scripts['test:ci']) {
console.error('Missing test script in package.json');
process.exit(1);
}
if (!scripts['build'] && !scripts['dist']) {
console.error('Missing build or dist script in package.json');
process.exit(1);
}
console.log('✅ Required scripts found');
"
- name: Install dependencies
run: |
pnpm --version
# Check if pnpm-lock.yaml exists and install accordingly
if [ -f "pnpm-lock.yaml" ]; then
echo "pnpm-lock.yaml found - installing with frozen lockfile"
pnpm install --frozen-lockfile
else
echo "No pnpm-lock.yaml found - running fresh install"
pnpm install
echo "Dependencies installed successfully"
fi
- name: Run quality checks
run: |
# Linting
if pnpm run --help 2>&1 | grep -q "lint"; then
echo "Running linter..."
pnpm lint
fi
# Type checking
if pnpm run --help 2>&1 | grep -q "typecheck"; then
echo "Type checking..."
pnpm typecheck
fi
- name: Run tests
run: |
echo "Running tests..."
if pnpm run --help 2>&1 | grep -q "test:ci"; then
pnpm test:ci
else
pnpm test
fi
- name: Build package
run: |
echo "Building package..."
if pnpm run --help 2>&1 | grep -q "dist"; then
pnpm dist
else
pnpm build
fi
# Verify that the build generated files
if [ ! -d "dist" ] && [ ! -d "lib" ] && [ ! -d "build" ] && [ ! -d "bundle" ]; then
echo "❌ No build output found"
exit 1
fi
echo "✅ Build output generated"
- name: Configure Git
run: |
git config --local user.email "[email protected]"
git config --local user.name "Kubit Release Bot"
# Set up authentication for push operations
if [ -n "${{ secrets.RELEASE_TOKEN }}" ]; then
echo "Using RELEASE_TOKEN with branch protection bypass permissions"
git remote set-url origin https://x-access-token:${{ secrets.RELEASE_TOKEN }}@github.com/${{ github.repository }}.git
else
echo "Using default GITHUB_TOKEN"
fi
- name: Determine next beta version
id: version-bump
run: |
BRANCH_NAME="${GITHUB_REF#refs/heads/}"
echo "Branch: $BRANCH_NAME"
# Get current version from package.json
CURRENT_VERSION=$(node -p "require('./package.json').version")
echo "Current version: $CURRENT_VERSION"
# Calculate next beta version
NEW_VERSION=$(node -e "
const current = '$CURRENT_VERSION';
// Check if current version is already a beta
const betaMatch = current.match(/^(\d+\.\d+\.\d+)-beta\.(\d+)$/);
if (betaMatch) {
// Increment beta number
const baseVersion = betaMatch[1];
const betaNumber = parseInt(betaMatch[2], 10);
const newBetaNumber = betaNumber + 1;
console.log(\`\${baseVersion}-beta.\${newBetaNumber}\`);
} else {
// Current version is not beta, create first beta for next version
const parts = current.split('.').map(Number);
// For break branches, increment major
if ('$BRANCH_NAME'.startsWith('break/')) {
parts[0]++;
parts[1] = 0;
parts[2] = 0;
} else {
// For main branch, increment minor
parts[1]++;
parts[2] = 0;
}
console.log(\`\${parts.join('.')}-beta.1\`);
}
")
echo "New beta version: $NEW_VERSION"
echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
- name: Check if beta version already exists
run: |
NEW_VERSION="${{ steps.version-bump.outputs.new_version }}"
PACKAGE_NAME=$(node -p "require('./package.json').name")
# Check if version already exists in NPM
if npm view "$PACKAGE_NAME@$NEW_VERSION" version 2>/dev/null; then
echo "❌ Version $NEW_VERSION already exists in NPM"
exit 1
fi
echo "✅ Version $NEW_VERSION is available"
- name: Update version and commit
run: |
NEW_VERSION="${{ steps.version-bump.outputs.new_version }}"
BRANCH_NAME="${GITHUB_REF#refs/heads/}"
# Update package.json version
npm version $NEW_VERSION --no-git-tag-version
# Commit the version change
git add package.json
# Add lock file if it exists and is tracked
if [ -f "pnpm-lock.yaml" ] && ! git check-ignore pnpm-lock.yaml; then
git add pnpm-lock.yaml
fi
git commit -m "chore(release): $NEW_VERSION [beta]
Auto-published beta version from: $BRANCH_NAME
Previous version: ${{ steps.version-bump.outputs.current_version }}
[skip ci]"
# Create a git tag for tracking
git tag "v$NEW_VERSION" -m "Beta Release v$NEW_VERSION"
echo "✅ Version updated and committed"
- name: Verify NPM authentication
run: |
echo "Verifying NPM authentication..."
if [ -z "${{ secrets.NPM_TOKEN }}" ]; then
echo "❌ NPM_TOKEN secret is not configured"
exit 1
fi
echo "✅ NPM_TOKEN secret is present"
# Test authentication
if npm whoami; then
echo "✅ NPM authentication successful"
else
echo "❌ NPM authentication failed"
exit 1
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Dry run publish (verification)
run: |
echo "Performing dry run with provenance check..."
pnpm publish --dry-run --access public --tag beta --no-git-checks --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Publish beta to NPM with Provenance
id: npm-publish
run: |
NEW_VERSION="${{ steps.version-bump.outputs.new_version }}"
echo "Publishing beta version $NEW_VERSION to NPM..."
echo "Command: pnpm publish --access public --tag beta --no-git-checks --provenance"
# Publish with provenance for supply chain security
pnpm publish --access public --tag beta --no-git-checks --provenance
echo "✅ Successfully published $NEW_VERSION to NPM with beta tag and provenance attestation"
echo "published=true" >> $GITHUB_OUTPUT
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Push changes and tags
if: steps.npm-publish.outputs.published == 'true'
run: |
echo "Pushing changes to repository..."
BRANCH_NAME="${GITHUB_REF#refs/heads/}"
if [ -n "${{ secrets.RELEASE_TOKEN }}" ]; then
echo "Using RELEASE_TOKEN to bypass branch protection"
git push origin "$BRANCH_NAME"
git push origin --tags
echo "✅ Changes and tags pushed successfully to $BRANCH_NAME"
else
echo "Using GITHUB_TOKEN - attempting push"
if git push origin "$BRANCH_NAME" && git push origin --tags; then
echo "✅ Changes and tags pushed successfully"
else
echo "⚠️ Push failed - likely due to branch protection rules"
echo "Consider adding RELEASE_TOKEN secret with bypass permissions"
exit 1
fi
fi
- name: Create GitHub Release
if: steps.npm-publish.outputs.published == 'true'
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ steps.version-bump.outputs.new_version }}
name: Beta Release v${{ steps.version-bump.outputs.new_version }}
body: |
## 🧪 Beta Release v${{ steps.version-bump.outputs.new_version }}
**Type:** Beta release (experimental)
**Branch:** `${{ github.ref_name }}`
**Previous:** `${{ steps.version-bump.outputs.current_version }}`
**Commit:** `${{ github.sha }}`
### ⚠️ Beta Version Notice
This is a **beta release** for testing purposes. It may contain:
- Experimental features
- Breaking changes
- Incomplete functionality
- Known issues
**Not recommended for production use.**
### 📦 Installation
```bash
# Install specific beta version
npm install @kubit-ui-web/react-components@${{ steps.version-bump.outputs.new_version }}
# Or install latest beta
npm install @kubit-ui-web/react-components@beta
# With pnpm
pnpm add @kubit-ui-web/react-components@${{ steps.version-bump.outputs.new_version }}
```
### 🔗 Links
- [NPM Package](https://www.npmjs.com/package/@kubit-ui-web/react-components/v/${{ steps.version-bump.outputs.new_version }})
- [Full Changelog](https://github.com/${{ github.repository }}/compare/v${{ steps.version-bump.outputs.current_version }}...v${{ steps.version-bump.outputs.new_version }})
### ✅ Quality Checks
- [x] Linting passed
- [x] Type checking passed
- [x] Tests passed
- [x] Build successful
- [x] Published to NPM with provenance 🔒
draft: false
prerelease: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Success Summary
if: steps.npm-publish.outputs.published == 'true'
run: |
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🎉 BETA RELEASE SUCCESSFUL"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "📦 Package: @kubit-ui-web/react-components"
echo "🏷️ Version: ${{ steps.version-bump.outputs.new_version }}"
echo "🔖 Tag: beta"
echo "🌿 Branch: ${{ github.ref_name }}"
echo "🔒 Provenance: Enabled"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📥 Installation Command:"
echo "npm install @kubit-ui-web/react-components@${{ steps.version-bump.outputs.new_version }}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- name: Failure notification
if: failure()
run: |
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "❌ BETA RELEASE FAILED"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "🔍 Check the workflow logs for details:"
echo "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
echo ""
echo "🔧 Common issues:"
echo " • NPM_TOKEN not configured or invalid"
echo " • RELEASE_TOKEN needed for protected branches"
echo " • Version already exists in NPM"
echo " • Tests or build failures"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"