From e6843ed5d1c6cba46aebe1966ff64287e4d5ea58 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Wed, 10 Sep 2025 07:25:51 +0800 Subject: [PATCH 1/7] feat: add auto version tagging workflow - Automatically creates git tags when version changes in config.gradle - Monitors config.gradle changes on main branch - Creates annotated tags in format v{version} - Triggers release workflow automatically via tag creation - Prevents duplicate tags and provides clear status summaries --- .github/workflows/version-change-trigger.yml | 88 ++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 .github/workflows/version-change-trigger.yml diff --git a/.github/workflows/version-change-trigger.yml b/.github/workflows/version-change-trigger.yml new file mode 100644 index 00000000..42131366 --- /dev/null +++ b/.github/workflows/version-change-trigger.yml @@ -0,0 +1,88 @@ +name: Version Change Trigger + +on: + push: + branches: + - main + paths: + - 'config.gradle' + +permissions: + contents: write + +jobs: + check-and-tag: + name: Check Version and Create Tag + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 2 # Need previous commit for comparison + + - name: Check if version changed + id: version_check + run: | + # Get version from current commit + CURRENT_VERSION=$(grep versionName config.gradle | cut -d'"' -f2) + CURRENT_CODE=$(grep versionCode config.gradle | grep -o '[0-9]*') + + # Get version from previous commit + git checkout HEAD~1 config.gradle 2>/dev/null || true + PREV_VERSION=$(grep versionName config.gradle | cut -d'"' -f2 || echo "") + PREV_CODE=$(grep versionCode config.gradle | grep -o '[0-9]*' || echo "0") + + # Restore current version + git checkout HEAD config.gradle + + echo "Previous: v$PREV_VERSION (code: $PREV_CODE)" + echo "Current: v$CURRENT_VERSION (code: $CURRENT_CODE)" + + if [ "$CURRENT_VERSION" != "$PREV_VERSION" ] || [ "$CURRENT_CODE" != "$PREV_CODE" ]; then + echo "version_changed=true" >> $GITHUB_OUTPUT + echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + echo "version_code=$CURRENT_CODE" >> $GITHUB_OUTPUT + else + echo "version_changed=false" >> $GITHUB_OUTPUT + fi + + - name: Check if tag exists + if: steps.version_check.outputs.version_changed == 'true' + id: tag_check + run: | + TAG_NAME="v${{ steps.version_check.outputs.version }}" + if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}$"; then + echo "tag_exists=true" >> $GITHUB_OUTPUT + else + echo "tag_exists=false" >> $GITHUB_OUTPUT + fi + + - name: Create and push tag + if: steps.version_check.outputs.version_changed == 'true' && steps.tag_check.outputs.tag_exists == 'false' + run: | + TAG_NAME="v${{ steps.version_check.outputs.version }}" + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # Create annotated tag + git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME} (code: ${{ steps.version_check.outputs.version_code }})" + git push origin "${TAG_NAME}" + + echo "✅ Created and pushed tag: ${TAG_NAME}" + + - name: Summary + if: steps.version_check.outputs.version_changed == 'true' + run: | + echo "## đŸ“Ļ Version Update Detected" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- **Version**: v${{ steps.version_check.outputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "- **Version Code**: ${{ steps.version_check.outputs.version_code }}" >> $GITHUB_STEP_SUMMARY + if [ "${{ steps.tag_check.outputs.tag_exists }}" == "false" ]; then + echo "- **Tag**: ✅ Created v${{ steps.version_check.outputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "The release workflow will be triggered automatically by the new tag." >> $GITHUB_STEP_SUMMARY + else + echo "- **Tag**: Already exists" >> $GITHUB_STEP_SUMMARY + fi \ No newline at end of file From 1d293edb9dd6e3380516683ae35b0bce7eaacbb9 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Wed, 10 Sep 2025 07:28:36 +0800 Subject: [PATCH 2/7] refactor: integrate auto version update into release workflow - Removes separate version-change-trigger.yml workflow - Adds auto version update step directly in release.yml prepare job - Automatically updates config.gradle when tag version differs - Ensures all build jobs use updated version from main branch - Prevents version mismatch issues like the v2.3.4 incident - Simplifies release process - just create tag and everything updates automatically --- .github/workflows/release.yml | 54 ++++++++++-- .github/workflows/version-change-trigger.yml | 88 -------------------- 2 files changed, 47 insertions(+), 95 deletions(-) delete mode 100644 .github/workflows/version-change-trigger.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 851b35ed..a8a057a8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,11 +38,15 @@ jobs: runs-on: ubuntu-latest outputs: version: ${{ steps.version.outputs.version }} - version_code: ${{ steps.version_info.outputs.version_code }} + version_code: ${{ steps.auto_update.outputs.version_code }} steps: - name: Checkout code uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ref: main + fetch-depth: 0 - name: Determine version id: version @@ -55,13 +59,45 @@ jobs: echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" - - name: Extract version code - id: version_info + - name: Auto update version in config.gradle + id: auto_update run: | - # Extract version code from config.gradle - VERSION_CODE=$(grep "versionCode:" config.gradle | sed 's/.*versionCode: \([0-9]*\).*/\1/') - echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT - echo "Version Code: $VERSION_CODE" + VERSION="${{ steps.version.outputs.version }}" + VERSION_NAME="${VERSION#v}" # Remove 'v' prefix if present + + # Get current version info from config.gradle + CURRENT_VERSION=$(grep versionName config.gradle | cut -d'"' -f2) + CURRENT_CODE=$(grep versionCode config.gradle | grep -o '[0-9]*') + + echo "Current version: $CURRENT_VERSION (code: $CURRENT_CODE)" + echo "Target version: $VERSION_NAME" + + # Check if version needs updating + if [ "$CURRENT_VERSION" = "$VERSION_NAME" ]; then + echo "✅ Version already matches $VERSION_NAME" + echo "version_code=$CURRENT_CODE" >> $GITHUB_OUTPUT + echo "updated=false" >> $GITHUB_OUTPUT + else + # Auto-increment version code + NEW_CODE=$((CURRENT_CODE + 1)) + echo "📝 Updating version to $VERSION_NAME (code: $NEW_CODE)" + + # Update config.gradle + sed -i "s/versionCode: [0-9]*/versionCode: $NEW_CODE/" config.gradle + sed -i "s/versionName: \"[^\"]*\"/versionName: \"$VERSION_NAME\"/" config.gradle + + # Commit and push the changes + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git add config.gradle + git commit -m "chore: auto-update version to $VERSION_NAME (code: $NEW_CODE) [skip ci]" + git push origin main + + echo "✅ Version updated and pushed to main" + echo "version_code=$NEW_CODE" >> $GITHUB_OUTPUT + echo "updated=true" >> $GITHUB_OUTPUT + fi build-apk: name: Build Release APK @@ -71,6 +107,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + with: + ref: main # Always use main branch with updated version - name: Set up JDK 17 uses: actions/setup-java@v4 @@ -146,6 +184,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + with: + ref: main # Always use main branch with updated version - name: Set up JDK 17 uses: actions/setup-java@v4 diff --git a/.github/workflows/version-change-trigger.yml b/.github/workflows/version-change-trigger.yml deleted file mode 100644 index 42131366..00000000 --- a/.github/workflows/version-change-trigger.yml +++ /dev/null @@ -1,88 +0,0 @@ -name: Version Change Trigger - -on: - push: - branches: - - main - paths: - - 'config.gradle' - -permissions: - contents: write - -jobs: - check-and-tag: - name: Check Version and Create Tag - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 2 # Need previous commit for comparison - - - name: Check if version changed - id: version_check - run: | - # Get version from current commit - CURRENT_VERSION=$(grep versionName config.gradle | cut -d'"' -f2) - CURRENT_CODE=$(grep versionCode config.gradle | grep -o '[0-9]*') - - # Get version from previous commit - git checkout HEAD~1 config.gradle 2>/dev/null || true - PREV_VERSION=$(grep versionName config.gradle | cut -d'"' -f2 || echo "") - PREV_CODE=$(grep versionCode config.gradle | grep -o '[0-9]*' || echo "0") - - # Restore current version - git checkout HEAD config.gradle - - echo "Previous: v$PREV_VERSION (code: $PREV_CODE)" - echo "Current: v$CURRENT_VERSION (code: $CURRENT_CODE)" - - if [ "$CURRENT_VERSION" != "$PREV_VERSION" ] || [ "$CURRENT_CODE" != "$PREV_CODE" ]; then - echo "version_changed=true" >> $GITHUB_OUTPUT - echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT - echo "version_code=$CURRENT_CODE" >> $GITHUB_OUTPUT - else - echo "version_changed=false" >> $GITHUB_OUTPUT - fi - - - name: Check if tag exists - if: steps.version_check.outputs.version_changed == 'true' - id: tag_check - run: | - TAG_NAME="v${{ steps.version_check.outputs.version }}" - if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}$"; then - echo "tag_exists=true" >> $GITHUB_OUTPUT - else - echo "tag_exists=false" >> $GITHUB_OUTPUT - fi - - - name: Create and push tag - if: steps.version_check.outputs.version_changed == 'true' && steps.tag_check.outputs.tag_exists == 'false' - run: | - TAG_NAME="v${{ steps.version_check.outputs.version }}" - - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - # Create annotated tag - git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME} (code: ${{ steps.version_check.outputs.version_code }})" - git push origin "${TAG_NAME}" - - echo "✅ Created and pushed tag: ${TAG_NAME}" - - - name: Summary - if: steps.version_check.outputs.version_changed == 'true' - run: | - echo "## đŸ“Ļ Version Update Detected" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "- **Version**: v${{ steps.version_check.outputs.version }}" >> $GITHUB_STEP_SUMMARY - echo "- **Version Code**: ${{ steps.version_check.outputs.version_code }}" >> $GITHUB_STEP_SUMMARY - if [ "${{ steps.tag_check.outputs.tag_exists }}" == "false" ]; then - echo "- **Tag**: ✅ Created v${{ steps.version_check.outputs.version }}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "The release workflow will be triggered automatically by the new tag." >> $GITHUB_STEP_SUMMARY - else - echo "- **Tag**: Already exists" >> $GITHUB_STEP_SUMMARY - fi \ No newline at end of file From d996637729570398d6060056332d0525c98a88d6 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Wed, 10 Sep 2025 07:47:19 +0800 Subject: [PATCH 3/7] feat: implement version-change-triggered release workflow - Add release-on-version-change.yml that monitors config.gradle changes - Auto-creates tags when version is updated in config.gradle - Simplifies release.yml by removing version update logic - Better workflow: update version -> auto tag -> auto release --- .../workflows/release-on-version-change.yml | 110 ++++++++++++++++++ .github/workflows/release.yml | 54 ++------- 2 files changed, 117 insertions(+), 47 deletions(-) create mode 100644 .github/workflows/release-on-version-change.yml diff --git a/.github/workflows/release-on-version-change.yml b/.github/workflows/release-on-version-change.yml new file mode 100644 index 00000000..c130d468 --- /dev/null +++ b/.github/workflows/release-on-version-change.yml @@ -0,0 +1,110 @@ +name: Release on Version Change + +on: + push: + branches: + - main + paths: + - 'config.gradle' + +permissions: + contents: write + +jobs: + check-version-and-release: + name: Check Version and Release + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 2 # Need previous commit for comparison + + - name: Check if version changed + id: version_check + run: | + # Get version from current commit + CURRENT_VERSION=$(grep versionName config.gradle | cut -d'"' -f2) + CURRENT_CODE=$(grep versionCode config.gradle | grep -o '[0-9]*') + + # Get version from previous commit + git checkout HEAD~1 config.gradle 2>/dev/null || true + PREV_VERSION=$(grep versionName config.gradle | cut -d'"' -f2 || echo "") + PREV_CODE=$(grep versionCode config.gradle | grep -o '[0-9]*' || echo "0") + + # Restore current version + git checkout HEAD config.gradle + + echo "Previous: v$PREV_VERSION (code: $PREV_CODE)" + echo "Current: v$CURRENT_VERSION (code: $CURRENT_CODE)" + + # Check if version actually changed + if [ "$CURRENT_VERSION" != "$PREV_VERSION" ] || [ "$CURRENT_CODE" != "$PREV_CODE" ]; then + echo "✅ Version changed from $PREV_VERSION to $CURRENT_VERSION" + echo "version_changed=true" >> $GITHUB_OUTPUT + echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + echo "version_code=$CURRENT_CODE" >> $GITHUB_OUTPUT + + # Check if this is a version increment (not decrement) + if [ "$CURRENT_CODE" -gt "$PREV_CODE" ]; then + echo "release_type=production" >> $GITHUB_OUTPUT + else + echo "âš ī¸ Version code decreased or same - skipping release" + echo "version_changed=false" >> $GITHUB_OUTPUT + fi + else + echo "â„šī¸ No version change detected" + echo "version_changed=false" >> $GITHUB_OUTPUT + fi + + - name: Check if tag exists + if: steps.version_check.outputs.version_changed == 'true' + id: tag_check + run: | + TAG_NAME="v${{ steps.version_check.outputs.version }}" + if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}$"; then + echo "âš ī¸ Tag ${TAG_NAME} already exists" + echo "tag_exists=true" >> $GITHUB_OUTPUT + else + echo "✅ Tag ${TAG_NAME} does not exist, will create" + echo "tag_exists=false" >> $GITHUB_OUTPUT + echo "tag_name=${TAG_NAME}" >> $GITHUB_OUTPUT + fi + + - name: Create and push tag + if: steps.version_check.outputs.version_changed == 'true' && steps.tag_check.outputs.tag_exists == 'false' + run: | + TAG_NAME="${{ steps.tag_check.outputs.tag_name }}" + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # Create annotated tag + git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME} (version code: ${{ steps.version_check.outputs.version_code }})" + git push origin "${TAG_NAME}" + + echo "đŸˇī¸ Created and pushed tag: ${TAG_NAME}" + echo "🚀 This will trigger the release workflow automatically" + + - name: Summary + if: always() + run: | + echo "## đŸ“Ļ Version Change Detection" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + if [ "${{ steps.version_check.outputs.version_changed }}" == "true" ]; then + echo "✅ **Version changed to: v${{ steps.version_check.outputs.version }}**" >> $GITHUB_STEP_SUMMARY + echo "- Version Code: ${{ steps.version_check.outputs.version_code }}" >> $GITHUB_STEP_SUMMARY + + if [ "${{ steps.tag_check.outputs.tag_exists }}" == "false" ]; then + echo "- Tag Created: ${{ steps.tag_check.outputs.tag_name }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### Next Steps" >> $GITHUB_STEP_SUMMARY + echo "The release workflow will be triggered automatically by the new tag." >> $GITHUB_STEP_SUMMARY + else + echo "- Tag Status: Already exists (skipped)" >> $GITHUB_STEP_SUMMARY + fi + else + echo "â„šī¸ No version change detected in config.gradle" >> $GITHUB_STEP_SUMMARY + fi \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a8a057a8..851b35ed 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,15 +38,11 @@ jobs: runs-on: ubuntu-latest outputs: version: ${{ steps.version.outputs.version }} - version_code: ${{ steps.auto_update.outputs.version_code }} + version_code: ${{ steps.version_info.outputs.version_code }} steps: - name: Checkout code uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - ref: main - fetch-depth: 0 - name: Determine version id: version @@ -59,45 +55,13 @@ jobs: echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" - - name: Auto update version in config.gradle - id: auto_update + - name: Extract version code + id: version_info run: | - VERSION="${{ steps.version.outputs.version }}" - VERSION_NAME="${VERSION#v}" # Remove 'v' prefix if present - - # Get current version info from config.gradle - CURRENT_VERSION=$(grep versionName config.gradle | cut -d'"' -f2) - CURRENT_CODE=$(grep versionCode config.gradle | grep -o '[0-9]*') - - echo "Current version: $CURRENT_VERSION (code: $CURRENT_CODE)" - echo "Target version: $VERSION_NAME" - - # Check if version needs updating - if [ "$CURRENT_VERSION" = "$VERSION_NAME" ]; then - echo "✅ Version already matches $VERSION_NAME" - echo "version_code=$CURRENT_CODE" >> $GITHUB_OUTPUT - echo "updated=false" >> $GITHUB_OUTPUT - else - # Auto-increment version code - NEW_CODE=$((CURRENT_CODE + 1)) - echo "📝 Updating version to $VERSION_NAME (code: $NEW_CODE)" - - # Update config.gradle - sed -i "s/versionCode: [0-9]*/versionCode: $NEW_CODE/" config.gradle - sed -i "s/versionName: \"[^\"]*\"/versionName: \"$VERSION_NAME\"/" config.gradle - - # Commit and push the changes - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - git add config.gradle - git commit -m "chore: auto-update version to $VERSION_NAME (code: $NEW_CODE) [skip ci]" - git push origin main - - echo "✅ Version updated and pushed to main" - echo "version_code=$NEW_CODE" >> $GITHUB_OUTPUT - echo "updated=true" >> $GITHUB_OUTPUT - fi + # Extract version code from config.gradle + VERSION_CODE=$(grep "versionCode:" config.gradle | sed 's/.*versionCode: \([0-9]*\).*/\1/') + echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT + echo "Version Code: $VERSION_CODE" build-apk: name: Build Release APK @@ -107,8 +71,6 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - with: - ref: main # Always use main branch with updated version - name: Set up JDK 17 uses: actions/setup-java@v4 @@ -184,8 +146,6 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - with: - ref: main # Always use main branch with updated version - name: Set up JDK 17 uses: actions/setup-java@v4 From 86227c8f3332340e83e2735bd7a162dec58d7c34 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Wed, 10 Sep 2025 08:10:51 +0800 Subject: [PATCH 4/7] refactor: integrate version monitoring into single release workflow - Merge version change detection directly into release.yml - Remove separate release-on-version-change.yml workflow - Fix Copilot review comments: - Handle first commit case properly (no HEAD~1) - Use more robust regex patterns for gradle parsing - Add tag existence check to prevent race conditions - Workflow now triggers on: - Tag push (v*) - config.gradle changes on main branch - Manual workflow dispatch - Auto-creates tags when version increases in config.gradle --- .../workflows/release-on-version-change.yml | 110 ------------------ .github/workflows/release.yml | 85 +++++++++++++- 2 files changed, 80 insertions(+), 115 deletions(-) delete mode 100644 .github/workflows/release-on-version-change.yml diff --git a/.github/workflows/release-on-version-change.yml b/.github/workflows/release-on-version-change.yml deleted file mode 100644 index c130d468..00000000 --- a/.github/workflows/release-on-version-change.yml +++ /dev/null @@ -1,110 +0,0 @@ -name: Release on Version Change - -on: - push: - branches: - - main - paths: - - 'config.gradle' - -permissions: - contents: write - -jobs: - check-version-and-release: - name: Check Version and Release - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 2 # Need previous commit for comparison - - - name: Check if version changed - id: version_check - run: | - # Get version from current commit - CURRENT_VERSION=$(grep versionName config.gradle | cut -d'"' -f2) - CURRENT_CODE=$(grep versionCode config.gradle | grep -o '[0-9]*') - - # Get version from previous commit - git checkout HEAD~1 config.gradle 2>/dev/null || true - PREV_VERSION=$(grep versionName config.gradle | cut -d'"' -f2 || echo "") - PREV_CODE=$(grep versionCode config.gradle | grep -o '[0-9]*' || echo "0") - - # Restore current version - git checkout HEAD config.gradle - - echo "Previous: v$PREV_VERSION (code: $PREV_CODE)" - echo "Current: v$CURRENT_VERSION (code: $CURRENT_CODE)" - - # Check if version actually changed - if [ "$CURRENT_VERSION" != "$PREV_VERSION" ] || [ "$CURRENT_CODE" != "$PREV_CODE" ]; then - echo "✅ Version changed from $PREV_VERSION to $CURRENT_VERSION" - echo "version_changed=true" >> $GITHUB_OUTPUT - echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT - echo "version_code=$CURRENT_CODE" >> $GITHUB_OUTPUT - - # Check if this is a version increment (not decrement) - if [ "$CURRENT_CODE" -gt "$PREV_CODE" ]; then - echo "release_type=production" >> $GITHUB_OUTPUT - else - echo "âš ī¸ Version code decreased or same - skipping release" - echo "version_changed=false" >> $GITHUB_OUTPUT - fi - else - echo "â„šī¸ No version change detected" - echo "version_changed=false" >> $GITHUB_OUTPUT - fi - - - name: Check if tag exists - if: steps.version_check.outputs.version_changed == 'true' - id: tag_check - run: | - TAG_NAME="v${{ steps.version_check.outputs.version }}" - if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}$"; then - echo "âš ī¸ Tag ${TAG_NAME} already exists" - echo "tag_exists=true" >> $GITHUB_OUTPUT - else - echo "✅ Tag ${TAG_NAME} does not exist, will create" - echo "tag_exists=false" >> $GITHUB_OUTPUT - echo "tag_name=${TAG_NAME}" >> $GITHUB_OUTPUT - fi - - - name: Create and push tag - if: steps.version_check.outputs.version_changed == 'true' && steps.tag_check.outputs.tag_exists == 'false' - run: | - TAG_NAME="${{ steps.tag_check.outputs.tag_name }}" - - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - # Create annotated tag - git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME} (version code: ${{ steps.version_check.outputs.version_code }})" - git push origin "${TAG_NAME}" - - echo "đŸˇī¸ Created and pushed tag: ${TAG_NAME}" - echo "🚀 This will trigger the release workflow automatically" - - - name: Summary - if: always() - run: | - echo "## đŸ“Ļ Version Change Detection" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - if [ "${{ steps.version_check.outputs.version_changed }}" == "true" ]; then - echo "✅ **Version changed to: v${{ steps.version_check.outputs.version }}**" >> $GITHUB_STEP_SUMMARY - echo "- Version Code: ${{ steps.version_check.outputs.version_code }}" >> $GITHUB_STEP_SUMMARY - - if [ "${{ steps.tag_check.outputs.tag_exists }}" == "false" ]; then - echo "- Tag Created: ${{ steps.tag_check.outputs.tag_name }}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Next Steps" >> $GITHUB_STEP_SUMMARY - echo "The release workflow will be triggered automatically by the new tag." >> $GITHUB_STEP_SUMMARY - else - echo "- Tag Status: Already exists (skipped)" >> $GITHUB_STEP_SUMMARY - fi - else - echo "â„šī¸ No version change detected in config.gradle" >> $GITHUB_STEP_SUMMARY - fi \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 851b35ed..0de879ce 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,10 @@ on: push: tags: - 'v*' + branches: + - main + paths: + - 'config.gradle' workflow_dispatch: inputs: version: @@ -39,18 +43,72 @@ jobs: outputs: version: ${{ steps.version.outputs.version }} version_code: ${{ steps.version_info.outputs.version_code }} + should_release: ${{ steps.check_version.outputs.should_release }} steps: - name: Checkout code uses: actions/checkout@v4 + with: + fetch-depth: 2 # Need history for version comparison + - name: Check if version changed (for config.gradle trigger) + id: check_version + if: github.event_name == 'push' && contains(github.event.head_commit.modified, 'config.gradle') + run: | + # Get current version from config.gradle + CURRENT_VERSION=$(grep versionName config.gradle | sed -E 's/.*versionName:\s*"([^"]+)".*/\1/') + CURRENT_CODE=$(grep versionCode config.gradle | sed -E 's/.*versionCode:\s*([0-9]+).*/\1/') + + # Get previous version - handle first commit case + if git rev-parse HEAD~1 >/dev/null 2>&1; then + git show HEAD~1:config.gradle > prev_config.gradle 2>/dev/null || echo "No previous config.gradle" + if [ -f prev_config.gradle ]; then + PREV_VERSION=$(grep versionName prev_config.gradle | sed -E 's/.*versionName:\s*"([^"]+)".*/\1/' || echo "") + PREV_CODE=$(grep versionCode prev_config.gradle | sed -E 's/.*versionCode:\s*([0-9]+).*/\1/' || echo "0") + rm prev_config.gradle + else + PREV_VERSION="" + PREV_CODE="0" + fi + else + # First commit in repo + PREV_VERSION="" + PREV_CODE="0" + fi + + echo "Previous: v$PREV_VERSION (code: $PREV_CODE)" + echo "Current: v$CURRENT_VERSION (code: $CURRENT_CODE)" + + # Check if version increased + if [ -n "$CURRENT_VERSION" ] && [ "$CURRENT_CODE" -gt "$PREV_CODE" ]; then + echo "✅ Version increased from $PREV_VERSION to $CURRENT_VERSION" + echo "should_release=true" >> $GITHUB_OUTPUT + echo "version=v$CURRENT_VERSION" >> $GITHUB_OUTPUT + + # Check if tag already exists + if git ls-remote --tags origin | grep -q "refs/tags/v${CURRENT_VERSION}$"; then + echo "âš ī¸ Tag v$CURRENT_VERSION already exists, skipping release" + echo "should_release=false" >> $GITHUB_OUTPUT + fi + else + echo "â„šī¸ No version increase detected or invalid version" + echo "should_release=false" >> $GITHUB_OUTPUT + fi + - name: Determine version id: version run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then VERSION="${{ github.event.inputs.version }}" - else + echo "should_release=true" >> $GITHUB_OUTPUT + elif [ "${{ steps.check_version.outputs.should_release }}" = "true" ]; then + VERSION="${{ steps.check_version.outputs.version }}" + elif [[ "${{ github.ref }}" == refs/tags/* ]]; then VERSION="${{ github.ref_name }}" + echo "should_release=true" >> $GITHUB_OUTPUT + else + VERSION="v0.0.0" + echo "should_release=false" >> $GITHUB_OUTPUT fi echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" @@ -58,14 +116,29 @@ jobs: - name: Extract version code id: version_info run: | - # Extract version code from config.gradle - VERSION_CODE=$(grep "versionCode:" config.gradle | sed 's/.*versionCode: \([0-9]*\).*/\1/') + # Extract version code from config.gradle - handle both formats + VERSION_CODE=$(grep "versionCode:" config.gradle | sed -E 's/.*versionCode:\s*([0-9]+).*/\1/') echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT echo "Version Code: $VERSION_CODE" + + - name: Create tag if version changed + if: steps.check_version.outputs.should_release == 'true' && github.event_name == 'push' && contains(github.event.head_commit.modified, 'config.gradle') + run: | + TAG_NAME="${{ steps.version.outputs.version }}" + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # Create annotated tag + git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME} (version code: ${{ steps.version_info.outputs.version_code }})" + git push origin "${TAG_NAME}" + + echo "đŸˇī¸ Created and pushed tag: ${TAG_NAME}" build-apk: name: Build Release APK needs: prepare + if: needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: @@ -141,6 +214,7 @@ jobs: build-aab: name: Build Release Bundle needs: prepare + if: needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: @@ -203,6 +277,7 @@ jobs: release: name: Create GitHub Release needs: [prepare, build-apk, build-aab] + if: needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: @@ -276,7 +351,7 @@ jobs: play-store-upload: name: Upload to Play Store needs: [prepare, build-aab] - if: ${{ vars.ENABLE_PLAY_STORE_UPLOAD == 'true' && vars.ENABLE_SIGNING == 'true' }} + if: ${{ (needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/')) && vars.ENABLE_PLAY_STORE_UPLOAD == 'true' && vars.ENABLE_SIGNING == 'true' }} runs-on: ubuntu-latest steps: @@ -386,7 +461,7 @@ jobs: download-signed-apk: name: Download Google Play Signed APK needs: [prepare, play-store-upload] - if: ${{ vars.ENABLE_PLAY_STORE_UPLOAD == 'true' && vars.ENABLE_SIGNING == 'true' }} + if: ${{ (needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/')) && vars.ENABLE_PLAY_STORE_UPLOAD == 'true' && vars.ENABLE_SIGNING == 'true' }} runs-on: ubuntu-latest steps: From 808fa2c4bb4bf054c4b014791e64a526d152485c Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Wed, 10 Sep 2025 08:21:36 +0800 Subject: [PATCH 5/7] refactor: single source of truth - config.gradle only - Remove tag push trigger completely - Keep only config.gradle as trigger source - Auto-create tags when version increases - Prevent duplicate releases with tag existence check - Manual workflow dispatch still available for re-runs This ensures config.gradle is the ONLY source of truth for releases --- .github/workflows/release.yml | 46 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0de879ce..c2543fbf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,8 +2,6 @@ name: Release on: push: - tags: - - 'v*' branches: - main paths: @@ -50,10 +48,11 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 2 # Need history for version comparison + token: ${{ secrets.GITHUB_TOKEN }} - - name: Check if version changed (for config.gradle trigger) + - name: Check version change id: check_version - if: github.event_name == 'push' && contains(github.event.head_commit.modified, 'config.gradle') + if: github.event_name == 'push' run: | # Get current version from config.gradle CURRENT_VERSION=$(grep versionName config.gradle | sed -E 's/.*versionName:\s*"([^"]+)".*/\1/') @@ -84,15 +83,11 @@ jobs: echo "✅ Version increased from $PREV_VERSION to $CURRENT_VERSION" echo "should_release=true" >> $GITHUB_OUTPUT echo "version=v$CURRENT_VERSION" >> $GITHUB_OUTPUT - - # Check if tag already exists - if git ls-remote --tags origin | grep -q "refs/tags/v${CURRENT_VERSION}$"; then - echo "âš ī¸ Tag v$CURRENT_VERSION already exists, skipping release" - echo "should_release=false" >> $GITHUB_OUTPUT - fi + echo "version_code=$CURRENT_CODE" >> $GITHUB_OUTPUT else - echo "â„šī¸ No version increase detected or invalid version" + echo "â„šī¸ No version increase detected" echo "should_release=false" >> $GITHUB_OUTPUT + exit 0 fi - name: Determine version @@ -103,12 +98,9 @@ jobs: echo "should_release=true" >> $GITHUB_OUTPUT elif [ "${{ steps.check_version.outputs.should_release }}" = "true" ]; then VERSION="${{ steps.check_version.outputs.version }}" - elif [[ "${{ github.ref }}" == refs/tags/* ]]; then - VERSION="${{ github.ref_name }}" - echo "should_release=true" >> $GITHUB_OUTPUT else - VERSION="v0.0.0" - echo "should_release=false" >> $GITHUB_OUTPUT + echo "No release needed" + exit 0 fi echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" @@ -116,16 +108,22 @@ jobs: - name: Extract version code id: version_info run: | - # Extract version code from config.gradle - handle both formats + # Extract version code from config.gradle VERSION_CODE=$(grep "versionCode:" config.gradle | sed -E 's/.*versionCode:\s*([0-9]+).*/\1/') echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT echo "Version Code: $VERSION_CODE" - - name: Create tag if version changed - if: steps.check_version.outputs.should_release == 'true' && github.event_name == 'push' && contains(github.event.head_commit.modified, 'config.gradle') + - name: Create and push tag + if: steps.check_version.outputs.should_release == 'true' && github.event_name == 'push' run: | TAG_NAME="${{ steps.version.outputs.version }}" + # Check if tag already exists + if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}$"; then + echo "âš ī¸ Tag $TAG_NAME already exists" + exit 0 + fi + git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" @@ -138,7 +136,7 @@ jobs: build-apk: name: Build Release APK needs: prepare - if: needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') + if: needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: @@ -214,7 +212,7 @@ jobs: build-aab: name: Build Release Bundle needs: prepare - if: needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') + if: needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: @@ -277,7 +275,7 @@ jobs: release: name: Create GitHub Release needs: [prepare, build-apk, build-aab] - if: needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') + if: needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: @@ -351,7 +349,7 @@ jobs: play-store-upload: name: Upload to Play Store needs: [prepare, build-aab] - if: ${{ (needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/')) && vars.ENABLE_PLAY_STORE_UPLOAD == 'true' && vars.ENABLE_SIGNING == 'true' }} + if: ${{ (needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch') && vars.ENABLE_PLAY_STORE_UPLOAD == 'true' && vars.ENABLE_SIGNING == 'true' }} runs-on: ubuntu-latest steps: @@ -461,7 +459,7 @@ jobs: download-signed-apk: name: Download Google Play Signed APK needs: [prepare, play-store-upload] - if: ${{ (needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/')) && vars.ENABLE_PLAY_STORE_UPLOAD == 'true' && vars.ENABLE_SIGNING == 'true' }} + if: ${{ (needs.prepare.outputs.should_release == 'true' || github.event_name == 'workflow_dispatch') && vars.ENABLE_PLAY_STORE_UPLOAD == 'true' && vars.ENABLE_SIGNING == 'true' }} runs-on: ubuntu-latest steps: From 220657cbef436fa5e10b78aa3c9bc11949ad63ba Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Wed, 10 Sep 2025 08:29:07 +0800 Subject: [PATCH 6/7] fix: address all Copilot review comments - Add error handling for grep commands with validation - Validate version code is a valid number before comparison - Remove duplicate version code extraction logic - Fix tag exists exit code to use output variables instead All 4 new Copilot comments have been addressed with proper error handling --- .github/workflows/release.yml | 63 +++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c2543fbf..77fbd3de 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -54,9 +54,24 @@ jobs: id: check_version if: github.event_name == 'push' run: | - # Get current version from config.gradle - CURRENT_VERSION=$(grep versionName config.gradle | sed -E 's/.*versionName:\s*"([^"]+)".*/\1/') - CURRENT_CODE=$(grep versionCode config.gradle | sed -E 's/.*versionCode:\s*([0-9]+).*/\1/') + # Get current version from config.gradle with error handling + CURRENT_VERSION=$(grep versionName config.gradle | sed -E 's/.*versionName:\s*"([^"]+)".*/\1/' || echo "") + CURRENT_CODE=$(grep versionCode config.gradle | sed -E 's/.*versionCode:\s*([0-9]+).*/\1/' || echo "") + + # Validate extraction was successful + if [ -z "$CURRENT_VERSION" ] || [ -z "$CURRENT_CODE" ]; then + echo "❌ Error: Failed to extract version information from config.gradle" + echo "CURRENT_VERSION='$CURRENT_VERSION', CURRENT_CODE='$CURRENT_CODE'" + echo "should_release=false" >> $GITHUB_OUTPUT + exit 1 + fi + + # Validate CURRENT_CODE is a valid number + if ! [[ "$CURRENT_CODE" =~ ^[0-9]+$ ]]; then + echo "❌ Error: Version code is not a valid number: $CURRENT_CODE" + echo "should_release=false" >> $GITHUB_OUTPUT + exit 1 + fi # Get previous version - handle first commit case if git rev-parse HEAD~1 >/dev/null 2>&1; then @@ -75,11 +90,16 @@ jobs: PREV_CODE="0" fi + # Validate PREV_CODE is a valid number (default to 0 if not) + if ! [[ "$PREV_CODE" =~ ^[0-9]+$ ]]; then + PREV_CODE="0" + fi + echo "Previous: v$PREV_VERSION (code: $PREV_CODE)" echo "Current: v$CURRENT_VERSION (code: $CURRENT_CODE)" # Check if version increased - if [ -n "$CURRENT_VERSION" ] && [ "$CURRENT_CODE" -gt "$PREV_CODE" ]; then + if [ "$CURRENT_CODE" -gt "$PREV_CODE" ]; then echo "✅ Version increased from $PREV_VERSION to $CURRENT_VERSION" echo "should_release=true" >> $GITHUB_OUTPUT echo "version=v$CURRENT_VERSION" >> $GITHUB_OUTPUT @@ -108,30 +128,39 @@ jobs: - name: Extract version code id: version_info run: | - # Extract version code from config.gradle - VERSION_CODE=$(grep "versionCode:" config.gradle | sed -E 's/.*versionCode:\s*([0-9]+).*/\1/') + # Use version code from check_version step if available, otherwise extract it + if [ -n "${{ steps.check_version.outputs.version_code }}" ]; then + VERSION_CODE="${{ steps.check_version.outputs.version_code }}" + else + # Only extract if not already available (for workflow_dispatch) + VERSION_CODE=$(grep "versionCode:" config.gradle | sed -E 's/.*versionCode:\s*([0-9]+).*/\1/') + fi echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT echo "Version Code: $VERSION_CODE" - name: Create and push tag if: steps.check_version.outputs.should_release == 'true' && github.event_name == 'push' + id: create_tag run: | TAG_NAME="${{ steps.version.outputs.version }}" # Check if tag already exists if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}$"; then - echo "âš ī¸ Tag $TAG_NAME already exists" - exit 0 + echo "âš ī¸ Tag $TAG_NAME already exists, skipping tag creation" + echo "tag_created=false" >> $GITHUB_OUTPUT + echo "tag_exists=true" >> $GITHUB_OUTPUT + else + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # Create annotated tag + git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME} (version code: ${{ steps.version_info.outputs.version_code }})" + git push origin "${TAG_NAME}" + + echo "đŸˇī¸ Created and pushed tag: ${TAG_NAME}" + echo "tag_created=true" >> $GITHUB_OUTPUT + echo "tag_exists=false" >> $GITHUB_OUTPUT fi - - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - # Create annotated tag - git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME} (version code: ${{ steps.version_info.outputs.version_code }})" - git push origin "${TAG_NAME}" - - echo "đŸˇī¸ Created and pushed tag: ${TAG_NAME}" build-apk: name: Build Release APK From 503bf063f0766ebc945bbb0de079b960d9a01418 Mon Sep 17 00:00:00 2001 From: Gray Zhang Date: Wed, 10 Sep 2025 08:31:47 +0800 Subject: [PATCH 7/7] test: bump version to 2.3.5 for release pipeline testing --- config.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.gradle b/config.gradle index 7a137cfc..45789be8 100644 --- a/config.gradle +++ b/config.gradle @@ -1,7 +1,7 @@ ext { app = [ - versionCode: 234, - versionName: "2.3.4" + versionCode: 235, + versionName: "2.3.5" ] android = [ supportVersion: '26.1.0'