Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/actions/create-version-bump-pr/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Create Version Bump PR
description: Creates a PR from staging changes onto dev branch
inputs:
platform:
description: Platform name (ios or android)
required: true
version:
description: Current version string
required: true
file_paths:
description: File paths to include in the PR (newline separated)
required: true
github_token:
description: GitHub token for creating PR
required: true

runs:
using: composite
steps:
- name: Create version bump PR
shell: bash
run: |
BRANCH_NAME="ci/bump-${{ inputs.platform }}-build-${{ github.run_id }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Check if there are changes
git add ${{ inputs.file_paths }}
if [[ -z $(git status -s) ]]; then
echo "No changes to commit. Skipping PR creation."
exit 0
fi
# Commit changes on temporary branch
git checkout -b temp-version-commit
git commit -m "chore: bump ${{ inputs.platform }} version for ${{ inputs.version }} [skip ci]"
# Create new branch from dev
git fetch origin dev
git checkout -b ${BRANCH_NAME} origin/dev
# Cherry-pick only the version changes
git cherry-pick temp-version-commit
# Clean up temporary branch
git branch -D temp-version-commit
# Push and create PR
git push --set-upstream origin ${BRANCH_NAME}
# Determine PR title based on platform
if [ "${{ inputs.platform }}" = "mobile" ]; then
PR_TITLE="chore: bump mobile app version to ${{ inputs.version }}"
else
PR_TITLE="chore: bump ${{ inputs.platform }} build for ${{ inputs.version }}"
fi
gh pr create \
--base dev \
--head ${BRANCH_NAME} \
--title "$PR_TITLE" \
--body "Automated version bump by CI"
env:
GH_TOKEN: ${{ inputs.github_token }}
209 changes: 73 additions & 136 deletions .github/workflows/mobile-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,26 @@ jobs:
echo "NODE_VERSION=$VERSION" >> "$GITHUB_ENV"
echo "NODE_VERSION_SANITIZED=${VERSION//\//-}" >> "$GITHUB_ENV"

- name: Determine version bump from PR labels or input
id: version-bump
run: |
VERSION_BUMP="${{ inputs.version_bump || 'build' }}"

# Override with PR label if present
if [ "${{ github.event_name }}" = "pull_request" ]; then
LABELS='${{ toJSON(github.event.pull_request.labels.*.name) }}'
if echo "$LABELS" | grep -q "version:major"; then
VERSION_BUMP="major"
elif echo "$LABELS" | grep -q "version:minor"; then
VERSION_BUMP="minor"
elif echo "$LABELS" | grep -q "version:patch"; then
VERSION_BUMP="patch"
fi
fi

echo "version_bump=$VERSION_BUMP" >> $GITHUB_OUTPUT
echo "📦 Version bump type: $VERSION_BUMP"

- name: Verify branch and commit (iOS)
if: inputs.platform != 'android'
run: |
Expand Down Expand Up @@ -526,7 +546,7 @@ jobs:

# Determine deployment track and version bump
DEPLOYMENT_TRACK="${{ inputs.deployment_track || 'internal' }}"
VERSION_BUMP="${{ inputs.version_bump || 'build' }}"
VERSION_BUMP="${{ steps.version-bump.outputs.version_bump }}"
TEST_MODE="${{ inputs.test_mode || false }}"

echo "📱 Deployment Configuration:"
Expand Down Expand Up @@ -593,26 +613,6 @@ jobs:
# Clean up
rm -f versions.txt

- name: Get version from package.json
if: inputs.platform != 'android'
uses: ./.github/actions/get-version
with:
app_path: ${{ env.APP_PATH }}

- name: Open PR for iOS build number bump
if: ${{ !env.ACT && (github.event_name != 'pull_request' || github.event.pull_request.merged == true) && success() }}
uses: peter-evans/create-pull-request@v6
with:
title: "chore: bump iOS build for ${{ env.VERSION }}"
body: "Automated bump of iOS build number by CI"
commit-message: "chore: incrementing ios build number for version ${{ env.VERSION }} [github action]"
branch: ci/bump-ios-build-${{ github.run_id }}
base: dev
add-paths: |
app/version.json
app/ios/Self.xcodeproj/project.pbxproj
app/ios/OpenPassport/Info.plist

- name: Monitor cache usage
if: always()
run: |
Expand Down Expand Up @@ -743,6 +743,26 @@ jobs:
echo "NODE_VERSION=$VERSION" >> "$GITHUB_ENV"
echo "NODE_VERSION_SANITIZED=${VERSION//\//-}" >> "$GITHUB_ENV"

- name: Determine version bump from PR labels or input
id: version-bump
run: |
VERSION_BUMP="${{ inputs.version_bump || 'build' }}"

# Override with PR label if present
if [ "${{ github.event_name }}" = "pull_request" ]; then
LABELS='${{ toJSON(github.event.pull_request.labels.*.name) }}'
if echo "$LABELS" | grep -q "version:major"; then
VERSION_BUMP="major"
elif echo "$LABELS" | grep -q "version:minor"; then
VERSION_BUMP="minor"
elif echo "$LABELS" | grep -q "version:patch"; then
VERSION_BUMP="patch"
fi
fi

echo "version_bump=$VERSION_BUMP" >> $GITHUB_OUTPUT
echo "📦 Version bump type: $VERSION_BUMP"

- name: Verify branch and commit (Android)
if: inputs.platform != 'ios'
run: |
Expand Down Expand Up @@ -937,7 +957,7 @@ jobs:

# Determine deployment track and version bump
DEPLOYMENT_TRACK="${{ inputs.deployment_track || 'internal' }}"
VERSION_BUMP="${{ inputs.version_bump || 'build' }}"
VERSION_BUMP="${{ steps.version-bump.outputs.version_bump }}"
TEST_MODE="${{ inputs.test_mode || false }}"

echo "🤖 Build Configuration:"
Expand Down Expand Up @@ -966,27 +986,6 @@ jobs:
--package-name "${{ secrets.ANDROID_PACKAGE_NAME }}" \
--track "$DEPLOYMENT_TRACK"

# Version updates moved to separate job to avoid race conditions

- name: Get version from package.json
if: inputs.platform != 'ios'
uses: ./.github/actions/get-version
with:
app_path: ${{ env.APP_PATH }}

- name: Open PR for Android build number bump
if: ${{ !env.ACT && (github.event_name != 'pull_request' || github.event.pull_request.merged == true) && success() }}
uses: peter-evans/create-pull-request@v6
with:
title: "chore: bump Android build for ${{ env.VERSION }}"
body: "Automated bump of Android build number by CI"
commit-message: "chore: incrementing android build version for version ${{ env.VERSION }} [github action]"
branch: ci/bump-android-build-${{ github.run_id }}
base: dev
add-paths: |
app/version.json
app/android/app/build.gradle

- name: Monitor cache usage
if: always()
run: |
Expand Down Expand Up @@ -1016,122 +1015,60 @@ jobs:
echo "===================================="
echo "💡 GitHub Actions cache limit: 10GB per repository"

# Separate job to update version files after successful deployment
# This avoids race conditions when both iOS and Android run in parallel
update-version:
# Consolidated version bump PR - runs after both platforms complete
create-version-bump-pr:
runs-on: ubuntu-latest
needs: [build-ios, build-android]
if: |
always() &&
(inputs.test_mode != true || github.event_name == 'pull_request') &&
(github.event_name != 'pull_request' || github.event.pull_request.merged == true) &&
(needs.build-ios.result == 'success' || needs.build-android.result == 'success')
env:
APP_PATH: ${{ github.workspace }}/app
steps:
- uses: actions/checkout@v4
with:
token: ${{ github.token }}
fetch-depth: 0
ref: dev
- name: Read and sanitize Node.js version
shell: bash
run: |
if [ ! -f .nvmrc ] || [ -z "$(cat .nvmrc)" ]; then
echo "❌ .nvmrc is missing or empty"; exit 1;
fi
VERSION="$(tr -d '\r\n' < .nvmrc)"
VERSION="${VERSION#v}"
if ! [[ "$VERSION" =~ ^[0-9]+(\.[0-9]+){0,2}$ ]]; then
echo "Invalid .nvmrc content: '$VERSION'"; exit 1;
fi
echo "NODE_VERSION=$VERSION" >> "$GITHUB_ENV"
echo "NODE_VERSION_SANITIZED=${VERSION//\//-}" >> "$GITHUB_ENV"
# Checkout staging where the builds ran
ref: ${{ github.event.pull_request.merge_commit_sha || 'staging' }}

- uses: actions/setup-node@v4
- name: Get version from package.json
uses: ./.github/actions/get-version
with:
node-version: ${{ env.NODE_VERSION }}

- name: Update package.json version
run: |
cd ${{ env.APP_PATH }}

# Get current version from package.json
CURRENT_VERSION=$(node -p "require('./package.json').version")

# Get new version from version.json (if it exists and has version field)
if [ -f version.json ] && grep -q '"version"' version.json; then
NEW_VERSION=$(node -pe 'require("./version.json").version' 2>/dev/null || echo "")
else
# Fallback: use current version from package.json
NEW_VERSION="$CURRENT_VERSION"
fi

# Only update if versions differ
if [ "$CURRENT_VERSION" != "$NEW_VERSION" ] && [ -n "$NEW_VERSION" ]; then
echo "📦 Updating package.json version:"
echo " From: v$CURRENT_VERSION"
echo " To: v$NEW_VERSION"

# Use yarn to update package.json and the lockfile
yarn version --new-version "$NEW_VERSION" --no-git-tag-version -y
else
echo "ℹ️ Version already up to date or no version field in version.json"
fi
app_path: ${{ env.APP_PATH }}

- name: Create PR with version files
- name: Determine platforms that succeeded
id: platforms
run: |
set -e

BRANCH_NAME="ci/update-version-${{ github.run_id }}"

git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

# Check if there are any changes to commit
git add app/version.json app/package.json yarn.lock
if [[ -z $(git status -s) ]]; then
echo "No version file changes to commit. Skipping PR creation."
exit 0
PLATFORMS=""
if [ "${{ needs.build-ios.result }}" = "success" ]; then
PLATFORMS="${PLATFORMS}iOS "
fi

if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
echo "🧪 Pull request event detected - running in dry-run mode."
echo "The following changes would be included in the version bump PR:"
git --no-pager diff --cached
exit 0
if [ "${{ needs.build-android.result }}" = "success" ]; then
PLATFORMS="${PLATFORMS}Android"
fi
echo "platforms=${PLATFORMS}" >> $GITHUB_OUTPUT
echo "📱 Successful builds: $PLATFORMS"

# Commit the changes on a temporary local branch
git checkout -b temp-for-version-commit
git commit -m "chore: update version files after deployment [skip ci]"

# Create a new branch from dev
git fetch origin dev
git checkout -b ${BRANCH_NAME} origin/dev

# Cherry-pick the commit with the version changes
git cherry-pick temp-for-version-commit

# Clean up temporary branch
git branch -D temp-for-version-commit

# Push the new branch and create the PR
git push --set-upstream origin ${BRANCH_NAME}

gh pr create \
--base dev \
--head ${BRANCH_NAME} \
--title "chore: update version files after deployment" \
--body "Automated update of version files after successful deployment."
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create consolidated version bump PR
uses: ./.github/actions/create-version-bump-pr
with:
platform: mobile
version: ${{ env.VERSION }}
file_paths: |
app/version.json
app/package.json
app/ios/Self.xcodeproj/project.pbxproj
app/ios/OpenPassport/Info.plist
app/android/app/build.gradle
github_token: ${{ secrets.GITHUB_TOKEN }}

# Create git tags after successful deployment
create-release-tags:
needs: [build-ios, build-android, update-version]
needs: [build-ios, build-android, create-version-bump-pr]
if: |
always() &&
needs.update-version.result == 'success' &&
needs.create-version-bump-pr.result == 'success' &&
(needs.build-ios.result == 'success' || needs.build-android.result == 'success') &&
(inputs.deployment_track == 'production')
runs-on: ubuntu-latest
Expand Down
8 changes: 4 additions & 4 deletions app/fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ platform :ios do

case version_bump
when "major", "minor", "patch"
# VersionManager doesn't handle semantic versions, use npm
sh("cd .. && npm version #{version_bump} --no-git-tag-version")
# Use Node.js with semver to bump version
sh("cd .. && node -e \"const fs = require('fs'); const pkg = require('./package.json'); const semver = require('semver'); pkg.version = semver.inc(pkg.version, '#{version_bump}'); fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\\n');\"")
UI.success("✅ Bumped #{version_bump} version")

# Sync the new version to iOS project files
Expand Down Expand Up @@ -304,8 +304,8 @@ platform :android do

case version_bump
when "major", "minor", "patch"
# For semantic version bumps, we need to use npm version
sh("cd .. && npm version #{version_bump} --no-git-tag-version")
# Use Node.js with semver to bump version
sh("cd .. && node -e \"const fs = require('fs'); const pkg = require('./package.json'); const semver = require('semver'); pkg.version = semver.inc(pkg.version, '#{version_bump}'); fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\\n');\"")
UI.success("✅ Bumped #{version_bump} version")
# Get the new version and sync to build.gradle
new_version = Fastlane::Helpers::VersionManager.get_current_version
Expand Down
Loading