Mobile POS OTA - production #1
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: OTA Update Mobile POS | |
| run-name: "Mobile POS OTA - production" | |
| permissions: | |
| id-token: write | |
| contents: read | |
| actions: read | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| message: | |
| description: 'Update message (shown in EAS dashboard)' | |
| required: false | |
| type: string | |
| default: '' | |
| jobs: | |
| publish-update: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup | |
| uses: ./.github/actions/ci-setup | |
| with: | |
| root-path: dapps/pos-app | |
| package-manager: npm | |
| - name: Create env file | |
| run: | | |
| if [ -z "${{ secrets.POS_ENV_FILE }}" ]; then | |
| echo "Error: POS_ENV_FILE secret is empty or not set" | |
| exit 1 | |
| fi | |
| echo "${{ secrets.POS_ENV_FILE }}" > dapps/pos-app/.env | |
| - name: Compute current fingerprints | |
| id: fingerprints | |
| run: | | |
| cd dapps/pos-app | |
| ANDROID_FINGERPRINT=$(npx expo-updates fingerprint:generate --platform android 2>/dev/null | tail -1) | |
| IOS_FINGERPRINT=$(npx expo-updates fingerprint:generate --platform ios 2>/dev/null | tail -1) | |
| echo "android=$ANDROID_FINGERPRINT" >> "$GITHUB_OUTPUT" | |
| echo "ios=$IOS_FINGERPRINT" >> "$GITHUB_OUTPUT" | |
| echo "Current Android fingerprint: $ANDROID_FINGERPRINT" | |
| echo "Current iOS fingerprint: $IOS_FINGERPRINT" | |
| - name: Download last native build fingerprint (Android) | |
| id: download-fingerprint-android | |
| uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6 | |
| with: | |
| name: native-fingerprint-android-production | |
| workflow: release-pos.yaml | |
| if_no_artifact_found: warn | |
| path: /tmp/native-fingerprint/android | |
| - name: Download last native build fingerprint (iOS) | |
| id: download-fingerprint-ios | |
| uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6 | |
| with: | |
| name: native-fingerprint-ios-production | |
| workflow: release-pos.yaml | |
| if_no_artifact_found: warn | |
| path: /tmp/native-fingerprint/ios | |
| - name: Check for native changes | |
| id: native-check | |
| run: | | |
| HAS_NATIVE_CHANGES=false | |
| ANDROID_FINGERPRINT_PATH=/tmp/native-fingerprint/android/native-fingerprint.txt | |
| IOS_FINGERPRINT_PATH=/tmp/native-fingerprint/ios/native-fingerprint.txt | |
| if [ -f "$ANDROID_FINGERPRINT_PATH" ]; then | |
| LAST_ANDROID_FINGERPRINT=$(cat "$ANDROID_FINGERPRINT_PATH") | |
| CURRENT_ANDROID_FINGERPRINT="${{ steps.fingerprints.outputs.android }}" | |
| echo "Last native Android fingerprint: $LAST_ANDROID_FINGERPRINT" | |
| echo "Current Android fingerprint: $CURRENT_ANDROID_FINGERPRINT" | |
| if [ "$LAST_ANDROID_FINGERPRINT" != "$CURRENT_ANDROID_FINGERPRINT" ]; then | |
| HAS_NATIVE_CHANGES=true | |
| echo "::error::Android native changes detected. Current fingerprint does not match the last native Android build." | |
| fi | |
| else | |
| echo "⚠️ No previous native Android fingerprint found for channel 'production'." | |
| fi | |
| if [ -f "$IOS_FINGERPRINT_PATH" ]; then | |
| LAST_IOS_FINGERPRINT=$(cat "$IOS_FINGERPRINT_PATH") | |
| CURRENT_IOS_FINGERPRINT="${{ steps.fingerprints.outputs.ios }}" | |
| echo "Last native iOS fingerprint: $LAST_IOS_FINGERPRINT" | |
| echo "Current iOS fingerprint: $CURRENT_IOS_FINGERPRINT" | |
| if [ "$LAST_IOS_FINGERPRINT" != "$CURRENT_IOS_FINGERPRINT" ]; then | |
| HAS_NATIVE_CHANGES=true | |
| echo "::error::iOS native changes detected. Current fingerprint does not match the last native iOS build." | |
| fi | |
| else | |
| echo "⚠️ No previous native iOS fingerprint found for channel 'production'." | |
| fi | |
| if [ "$HAS_NATIVE_CHANGES" = "true" ]; then | |
| echo "has_native_changes=true" >> "$GITHUB_OUTPUT" | |
| echo "::error::Native changes detected. You must create a new native release before publishing an OTA update." | |
| exit 1 | |
| fi | |
| if [ ! -f "$ANDROID_FINGERPRINT_PATH" ] || [ ! -f "$IOS_FINGERPRINT_PATH" ]; then | |
| echo "⚠️ At least one platform fingerprint is missing. This can happen after initial OTA setup." | |
| echo "Proceeding with OTA publish." | |
| fi | |
| echo "has_native_changes=false" >> "$GITHUB_OUTPUT" | |
| echo "✅ Fingerprints match for all available platform artifacts — safe to publish OTA update." | |
| - name: Setup EAS CLI | |
| run: npm install -g eas-cli | |
| - name: Publish OTA update | |
| id: eas-update | |
| working-directory: dapps/pos-app | |
| env: | |
| EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} | |
| run: | | |
| eas update \ | |
| --channel production \ | |
| --message "${{ inputs.message || format('OTA update from {0}', github.ref_name) }}" \ | |
| --non-interactive | |
| - name: Send Slack notification | |
| if: always() && !cancelled() | |
| uses: slackapi/slack-github-action@v2.1.0 | |
| with: | |
| webhook: ${{ secrets.SLACK_WEBHOOK_URL }} | |
| webhook-type: incoming-webhook | |
| payload: | | |
| { | |
| "text": "OTA Update Report - Mobile POS", | |
| "blocks": [ | |
| { | |
| "type": "header", | |
| "text": { "type": "plain_text", "text": "📦 OTA Update Report - Mobile POS" } | |
| }, | |
| { | |
| "type": "section", | |
| "fields": [ | |
| { "type": "mrkdwn", "text": "*Channel:*\n`production`" }, | |
| { "type": "mrkdwn", "text": "*Branch:*\n`${{ github.ref_name }}`" }, | |
| { "type": "mrkdwn", "text": "*Status:*\n`${{ steps.native-check.outputs.has_native_changes == 'true' && '❌ Blocked — native changes require full release' || (steps.eas-update.outcome == 'success' && '✅ Published' || '❌ Failed') }}`" }, | |
| { "type": "mrkdwn", "text": "*Message:*\n`${{ inputs.message || 'No message' }}`" } | |
| ] | |
| }, | |
| { | |
| "type": "actions", | |
| "elements": [ | |
| { | |
| "type": "button", | |
| "text": { "type": "plain_text", "text": "View Workflow Run" }, | |
| "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| } | |
| ] | |
| } | |
| ] | |
| } |