Merge branch 'break/2.0.0-venus-version-v2' into break/2.0.0-venus-ve… #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" |