name: 🚨 Product Hotfix on: workflow_dispatch: inputs: app: description: '📦 Product' required: true type: choice options: - worker - client production_tag: description: '🏷️ Current Production Tag (e.g., krow-withus-worker-mobile/prod-v0.1.0)' required: true type: string issue_description: description: '📝 Brief issue description' required: true type: string jobs: create-hotfix-branch: name: 🚨 Create Hotfix Branch runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - name: 📥 Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: 🔍 Validate production tag exists id: validate_tag run: | TAG="${{ github.event.inputs.production_tag }}" if ! git rev-parse "$TAG" >/dev/null 2>&1; then echo "❌ Error: Production tag '$TAG' does not exist" echo "Available tags:" git tag -l "krow-withus-*-mobile/prod-*" | tail -10 exit 1 fi echo "✅ Production tag exists: $TAG" # Extract version from tag VERSION=$(echo "$TAG" | grep -oP 'v\K[0-9]+\.[0-9]+\.[0-9]+' || echo "") if [ -z "$VERSION" ]; then echo "❌ Error: Could not extract version from tag" exit 1 fi echo "current_version=${VERSION}" >> $GITHUB_OUTPUT echo "📌 Current production version: $VERSION" - name: 🔢 Calculate hotfix version id: hotfix_version run: | CURRENT="${{ steps.validate_tag.outputs.current_version }}" # Split version into parts IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT" # Increment PATCH version NEW_PATCH=$((PATCH + 1)) HOTFIX_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}" echo "hotfix_version=${HOTFIX_VERSION}" >> $GITHUB_OUTPUT echo "🆕 Hotfix version: $HOTFIX_VERSION" - name: 🌿 Generate branch name id: branch run: | APP="${{ github.event.inputs.app }}" VERSION="${{ steps.hotfix_version.outputs.hotfix_version }}" BRANCH_NAME="hotfix/krow-withus-${APP}-mobile-v${VERSION}" echo "branch_name=${BRANCH_NAME}" >> $GITHUB_OUTPUT echo "🌿 Branch to create: $BRANCH_NAME" - name: 🔍 Check if hotfix branch already exists run: | BRANCH="${{ steps.branch.outputs.branch_name }}" if git ls-remote --heads origin "$BRANCH" | grep -q "$BRANCH"; then echo "❌ Error: Branch $BRANCH already exists" exit 1 fi echo "✅ Branch does not exist, proceeding..." - name: 🌿 Create hotfix branch from production tag run: | TAG="${{ github.event.inputs.production_tag }}" BRANCH="${{ steps.branch.outputs.branch_name }}" git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" # Checkout the production tag git checkout "$TAG" # Create new branch git checkout -b "$BRANCH" echo "✅ Created branch $BRANCH from tag $TAG" - name: 📝 Update version files id: update_versions run: | APP="${{ github.event.inputs.app }}" HOTFIX_VERSION="${{ steps.hotfix_version.outputs.hotfix_version }}" if [ "$APP" = "worker" ]; then PUBSPEC_PATH="apps/mobile/apps/staff/pubspec.yaml" CHANGELOG_PATH="apps/mobile/apps/staff/CHANGELOG.md" APP_NAME="Staff Product" else PUBSPEC_PATH="apps/mobile/apps/client/pubspec.yaml" CHANGELOG_PATH="apps/mobile/apps/client/CHANGELOG.md" APP_NAME="Client Product" fi # Update pubspec.yaml version if [ -f "$PUBSPEC_PATH" ]; then # Extract current version and build number CURRENT_VERSION_LINE=$(grep "^version:" "$PUBSPEC_PATH") CURRENT_BUILD=$(echo "$CURRENT_VERSION_LINE" | grep -oP '\+\K[0-9]+' || echo "1") NEW_BUILD=$((CURRENT_BUILD + 1)) # Update version line sed -i "s/^version:.*/version: ${HOTFIX_VERSION}+${NEW_BUILD}/" "$PUBSPEC_PATH" echo "✅ Updated $PUBSPEC_PATH to ${HOTFIX_VERSION}+${NEW_BUILD}" echo "updated_files=true" >> $GITHUB_OUTPUT else echo "⚠️ Warning: $PUBSPEC_PATH not found" echo "updated_files=false" >> $GITHUB_OUTPUT fi - name: 📋 Add CHANGELOG entry run: | APP="${{ github.event.inputs.app }}" HOTFIX_VERSION="${{ steps.hotfix_version.outputs.hotfix_version }}" ISSUE="${{ github.event.inputs.issue_description }}" if [ "$APP" = "worker" ]; then CHANGELOG_PATH="apps/mobile/apps/staff/CHANGELOG.md" APP_NAME="Staff Product" else CHANGELOG_PATH="apps/mobile/apps/client/CHANGELOG.md" APP_NAME="Client Product" fi if [ -f "$CHANGELOG_PATH" ]; then DATE=$(date +%Y-%m-%d) # Create hotfix entry HOTFIX_ENTRY="## [${HOTFIX_VERSION}] - ${DATE} - HOTFIX ### Fixed - ${ISSUE} --- " # Insert after the first line (title) sed -i "1 a\\ \\ $HOTFIX_ENTRY" "$CHANGELOG_PATH" echo "✅ Added CHANGELOG entry for hotfix $HOTFIX_VERSION" else echo "⚠️ Warning: $CHANGELOG_PATH not found" fi - name: 💾 Commit version changes run: | HOTFIX_VERSION="${{ steps.hotfix_version.outputs.hotfix_version }}" ISSUE="${{ github.event.inputs.issue_description }}" git add -A git commit -m "chore: prepare hotfix v${HOTFIX_VERSION} HOTFIX: ${ISSUE} - Bump version to ${HOTFIX_VERSION} - Add CHANGELOG entry - Ready for bug fix commits From production tag: ${{ github.event.inputs.production_tag }}" echo "✅ Committed version changes" - name: 🚀 Push hotfix branch run: | BRANCH="${{ steps.branch.outputs.branch_name }}" git push origin "$BRANCH" echo "✅ Pushed branch: $BRANCH" - name: 📄 Create Pull Request id: create_pr env: GH_TOKEN: ${{ github.token }} run: | BRANCH="${{ steps.branch.outputs.branch_name }}" HOTFIX_VERSION="${{ steps.hotfix_version.outputs.hotfix_version }}" ISSUE="${{ github.event.inputs.issue_description }}" APP="${{ github.event.inputs.app }}" if [ "$APP" = "worker" ]; then APP_DISPLAY="Worker Product" else APP_DISPLAY="Client Product" fi PR_TITLE="🚨 HOTFIX: ${APP_DISPLAY} v${HOTFIX_VERSION} - ${ISSUE}" PR_BODY="## 🚨 HOTFIX - URGENT PRODUCTION FIX **App:** ${APP_DISPLAY} **Version:** ${HOTFIX_VERSION} **From:** \`${{ github.event.inputs.production_tag }}\` ### Issue ${ISSUE} ### Impact ### Solution ### Testing --- ## ⚠️ Hotfix Process 1. ✅ Hotfix branch created 2. ⏳ **NEXT:** Make your bug fix commits to this branch 3. ⏳ Test the fix locally 4. ⏳ Request expedited review (< 15 minutes) 5. ⏳ Merge to main and create production tag ### To add your fix: \`\`\`bash git checkout $BRANCH # Make your changes git commit -m \"fix: [description]\" git push origin $BRANCH \`\`\` ### After merging: \`\`\`bash # Tag and release git checkout main git pull origin main git tag -a krow-withus-${APP}-mobile/prod-v${HOTFIX_VERSION} -m \"HOTFIX: ${ISSUE}\" git push origin krow-withus-${APP}-mobile/prod-v${HOTFIX_VERSION} \`\`\` --- **Ref:** [Hotfix Process Documentation](../docs/release/HOTFIX_PROCESS.md)" # Create PR PR_URL=$(gh pr create \ --base main \ --head "$BRANCH" \ --title "$PR_TITLE" \ --body "$PR_BODY" \ --label "hotfix,urgent,production") echo "pr_url=${PR_URL}" >> $GITHUB_OUTPUT echo "✅ Pull Request created: $PR_URL" - name: 📊 Hotfix Summary run: | echo "## 🚨 Hotfix Branch Created" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**App:** ${{ github.event.inputs.app }}" >> $GITHUB_STEP_SUMMARY echo "**Issue:** ${{ github.event.inputs.issue_description }}" >> $GITHUB_STEP_SUMMARY echo "**From Tag:** \`${{ github.event.inputs.production_tag }}\`" >> $GITHUB_STEP_SUMMARY echo "**Current Version:** ${{ steps.validate_tag.outputs.current_version }}" >> $GITHUB_STEP_SUMMARY echo "**Hotfix Version:** ${{ steps.hotfix_version.outputs.hotfix_version }}" >> $GITHUB_STEP_SUMMARY echo "**Branch:** \`${{ steps.branch.outputs.branch_name }}\`" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### 🔧 Next Steps" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "1. **Checkout the hotfix branch:**" >> $GITHUB_STEP_SUMMARY echo " \`\`\`bash" >> $GITHUB_STEP_SUMMARY echo " git fetch origin" >> $GITHUB_STEP_SUMMARY echo " git checkout ${{ steps.branch.outputs.branch_name }}" >> $GITHUB_STEP_SUMMARY echo " \`\`\`" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "2. **Make your bug fix(es)** - Keep changes minimal!" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "3. **Test locally** - Verify the fix works" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "4. **Request expedited review** - Target < 15 minutes" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "5. **Merge PR and create production tag:**" >> $GITHUB_STEP_SUMMARY echo " \`\`\`bash" >> $GITHUB_STEP_SUMMARY echo " git checkout main" >> $GITHUB_STEP_SUMMARY echo " git pull origin main" >> $GITHUB_STEP_SUMMARY echo " git tag -a krow-withus-${{ github.event.inputs.app }}-mobile/prod-v${{ steps.hotfix_version.outputs.hotfix_version }} -m \"HOTFIX: ${{ github.event.inputs.issue_description }}\"" >> $GITHUB_STEP_SUMMARY echo " git push origin krow-withus-${{ github.event.inputs.app }}-mobile/prod-v${{ steps.hotfix_version.outputs.hotfix_version }}" >> $GITHUB_STEP_SUMMARY echo " \`\`\`" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY if [ -n "${{ steps.create_pr.outputs.pr_url }}" ]; then echo "**Pull Request:** ${{ steps.create_pr.outputs.pr_url }}" >> $GITHUB_STEP_SUMMARY fi