name: Promote to Stable "on": workflow_dispatch: inputs: version_bump: description: "Version bump type" required: true default: "minor" type: choice options: - patch - minor - major jobs: promote: runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" registry-url: "https://registry.npmjs.org" - name: Configure Git run: | git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" - name: Install dependencies run: npm ci - name: Get current version and calculate new version id: version run: | # Get current version from package.json CURRENT_VERSION=$(node -p "require('./package.json').version") echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT # Remove beta suffix if present BASE_VERSION=$(echo $CURRENT_VERSION | sed 's/-beta\.[0-9]\+//') echo "base_version=$BASE_VERSION" >> $GITHUB_OUTPUT # Calculate new version based on bump type IFS='.' read -ra VERSION_PARTS <<< "$BASE_VERSION" MAJOR=${VERSION_PARTS[0]} MINOR=${VERSION_PARTS[1]} PATCH=${VERSION_PARTS[2]} case "${{ github.event.inputs.version_bump }}" in "major") NEW_VERSION="$((MAJOR + 1)).0.0" ;; "minor") NEW_VERSION="$MAJOR.$((MINOR + 1)).0" ;; "patch") NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))" ;; *) NEW_VERSION="$BASE_VERSION" ;; esac # Check if calculated version already exists (either as NPM package or git tag) while npm view bmad-method@$NEW_VERSION version >/dev/null 2>&1 || git ls-remote --tags origin | grep -q "refs/tags/v$NEW_VERSION"; do echo "Version $NEW_VERSION already exists, incrementing..." IFS='.' read -ra NEW_VERSION_PARTS <<< "$NEW_VERSION" NEW_MAJOR=${NEW_VERSION_PARTS[0]} NEW_MINOR=${NEW_VERSION_PARTS[1]} NEW_PATCH=${NEW_VERSION_PARTS[2]} case "${{ github.event.inputs.version_bump }}" in "major") NEW_VERSION="$((NEW_MAJOR + 1)).0.0" ;; "minor") NEW_VERSION="$NEW_MAJOR.$((NEW_MINOR + 1)).0" ;; "patch") NEW_VERSION="$NEW_MAJOR.$NEW_MINOR.$((NEW_PATCH + 1))" ;; esac done echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT echo "Promoting from $CURRENT_VERSION to $NEW_VERSION" - name: Update package.json versions run: | # Update main package.json npm version ${{ steps.version.outputs.new_version }} --no-git-tag-version # Update installer package.json sed -i 's/"version": ".*"/"version": "${{ steps.version.outputs.new_version }}"/' tools/installer/package.json - name: Update package-lock.json run: npm install --package-lock-only - name: Commit stable release run: | git add . git commit -m "release: promote to stable ${{ steps.version.outputs.new_version }}" - name: Create and push stable tag run: | # Create new tag (version check already ensures it doesn't exist) git tag -a "v${{ steps.version.outputs.new_version }}" -m "Stable release v${{ steps.version.outputs.new_version }}" # Push the new tag git push origin "v${{ steps.version.outputs.new_version }}" - name: Push changes to main run: | git push origin HEAD:main - name: Publish to NPM with stable tag env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} run: | # Publish with the stable (latest) tag npm publish --tag latest # Also tag the previous beta version as stable if it exists if npm view bmad-method@${{ steps.version.outputs.current_version }} version >/dev/null 2>&1; then npm dist-tag add bmad-method@${{ steps.version.outputs.new_version }} stable || true fi - name: Summary run: | echo "🎉 Successfully promoted to stable!" echo "📦 Version: ${{ steps.version.outputs.new_version }}" echo "🏷️ Git tag: v${{ steps.version.outputs.new_version }}" echo "✅ Published to NPM with 'latest' tag" echo "✅ Users running 'npx bmad-method install' will now get version ${{ steps.version.outputs.new_version }}" echo "🚀 The stable release will be automatically published to NPM via semantic-release" echo "✅ Users running 'npx bmad-method install' will now get version ${{ steps.version.outputs.new_version }}"