|
1 | 1 | name: Nightly Build |
2 | 2 |
|
3 | | -# Triggered by every push to chore/temp-nightly (which nightly-temp-branch-sync.yml |
4 | | -# force-pushes daily at 4 AM UTC to match main). |
5 | | -# Temporarily now this is pointing to test/temp-nightly instead of chore/temp-nightly. |
| 3 | +# Runs on a schedule (4 AM UTC) like the old nightly-temp-branch-sync. |
| 4 | +# Each build creates its own ephemeral branch via create-build-branch.yml, |
| 5 | +# so the persistent chore/temp-nightly branch is no longer needed. |
6 | 6 | # |
7 | | -# [skip ci] commits (e.g. version bumps pushed via update-latest-build-version.yml) |
8 | | -# are automatically skipped by GitHub Actions, so this workflow will NOT |
9 | | -# double-trigger on those commits. |
| 7 | +# iOS builds are handled end-to-end by upload-to-testflight.yml (build + upload). |
| 8 | +# Android builds use create-build-branch.yml + build.yml (build artifacts only). |
10 | 9 | # |
11 | | -# Version strategy: exp and rc builds share the same bundle ID (MetaMask) so |
12 | | -# TestFlight requires unique CFBundleVersion per upload. We call the external |
13 | | -# version generator once (→ version N for exp), then locally increment to N+1 |
14 | | -# for the rc build. Both builds run in parallel after their respective bumps. |
| 10 | +# rc depends on exp within each platform stream to ensure the external version |
| 11 | +# service produces sequential numbers (N for exp, N+1 for rc). |
| 12 | +# iOS and Android streams run in parallel; their version numbers will differ |
| 13 | +# but remain unique, which is all TestFlight / Play Store require. |
15 | 14 |
|
16 | 15 | on: |
17 | | - push: |
18 | | - branches: |
19 | | - - test/temp-nightly |
| 16 | + schedule: |
| 17 | + # NOTE: Scheduled workflows ALWAYS run from the default branch (main) |
| 18 | + - cron: '0 4 * * *' |
20 | 19 | workflow_dispatch: |
21 | 20 |
|
22 | | -# contents: write required by build.yml update-build-version job (version bump commit push) |
23 | 21 | permissions: |
24 | 22 | contents: write |
25 | 23 | id-token: write |
26 | 24 |
|
27 | 25 | jobs: |
28 | | - bump-version-exp: |
29 | | - name: Bump build version (exp) |
30 | | - uses: ./.github/workflows/update-latest-build-version.yml |
31 | | - permissions: |
32 | | - contents: write |
33 | | - id-token: write |
| 26 | + # ── iOS exp: build + TestFlight upload ───────────────────────────────── |
| 27 | + ios-exp: |
| 28 | + name: Nightly iOS exp |
| 29 | + uses: ./.github/workflows/upload-to-testflight.yml |
34 | 30 | with: |
35 | | - base-branch: ${{ github.ref_name }} |
| 31 | + source_branch: main |
| 32 | + environment: exp |
| 33 | + testflight_group: 'MetaMask BETA & Release Candidates' |
36 | 34 | secrets: inherit |
37 | 35 |
|
38 | | - bump-version-rc: |
39 | | - name: Bump build version (rc) |
40 | | - needs: [bump-version-exp] |
41 | | - runs-on: ubuntu-latest |
42 | | - permissions: |
43 | | - contents: write |
44 | | - outputs: |
45 | | - commit-hash: ${{ steps.bump.outputs.commit-hash }} |
46 | | - build-version: ${{ steps.bump.outputs.build-version }} |
47 | | - steps: |
48 | | - - uses: actions/checkout@v4 |
49 | | - with: |
50 | | - ref: ${{ needs.bump-version-exp.outputs.commit-hash }} |
51 | | - fetch-depth: 0 |
52 | | - token: ${{ secrets.PR_TOKEN || github.token }} |
| 36 | + # ── iOS rc: build + TestFlight upload (after exp for sequential versions) ─ |
| 37 | + ios-rc: |
| 38 | + name: Nightly iOS rc |
| 39 | + needs: [ios-exp] |
| 40 | + uses: ./.github/workflows/upload-to-testflight.yml |
| 41 | + with: |
| 42 | + source_branch: main |
| 43 | + environment: rc |
| 44 | + testflight_group: 'MetaMask BETA & Release Candidates' |
| 45 | + secrets: inherit |
53 | 46 |
|
54 | | - - name: Increment version for RC build |
55 | | - id: bump |
56 | | - env: |
57 | | - EXP_VERSION: ${{ needs.bump-version-exp.outputs.build-version }} |
58 | | - HEAD_REF: ${{ github.ref_name }} |
59 | | - run: | |
60 | | - RC_VERSION=$((EXP_VERSION + 1)) |
61 | | - echo "Exp version: $EXP_VERSION → RC version: $RC_VERSION" |
62 | | - ./scripts/set-build-version.sh "$RC_VERSION" |
63 | | - git config user.name metamaskbot |
64 | | - git config user.email metamaskbot@users.noreply.github.com |
65 | | - git add bitrise.yml package.json ios/MetaMask.xcodeproj/project.pbxproj android/app/build.gradle |
66 | | - git commit -m "[skip ci] Bump version number to ${RC_VERSION} (nightly rc)" |
67 | | - git push origin HEAD:"$HEAD_REF" --force-with-lease |
68 | | - echo "commit-hash=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" |
69 | | - echo "build-version=$RC_VERSION" >> "$GITHUB_OUTPUT" |
| 47 | + # ── Android exp: ephemeral branch + build ────────────────────────────── |
| 48 | + android-exp-branch: |
| 49 | + uses: ./.github/workflows/create-build-branch.yml |
| 50 | + with: |
| 51 | + source_branch: main |
| 52 | + secrets: inherit |
70 | 53 |
|
71 | | - build-exp: |
72 | | - name: Nightly exp build (main-exp) |
73 | | - needs: [bump-version-exp] |
| 54 | + android-exp: |
| 55 | + name: Nightly Android exp |
| 56 | + needs: [android-exp-branch] |
74 | 57 | uses: ./.github/workflows/build.yml |
75 | 58 | with: |
76 | 59 | build_name: main-exp |
77 | | - platform: both |
78 | | - skip_version_bump: true |
79 | | - source_branch: ${{ needs.bump-version-exp.outputs.commit-hash }} |
| 60 | + platform: android |
| 61 | + skip_version_bump: false |
| 62 | + source_branch: ${{ needs.android-exp-branch.outputs.build_branch }} |
80 | 63 | secrets: inherit |
81 | 64 |
|
82 | | - build-rc: |
83 | | - name: Nightly RC build (main-rc) |
84 | | - needs: [bump-version-rc] |
| 65 | + # ── Android rc: ephemeral branch + build (after exp for sequential versions) ─ |
| 66 | + android-rc-branch: |
| 67 | + needs: [android-exp] |
| 68 | + uses: ./.github/workflows/create-build-branch.yml |
| 69 | + with: |
| 70 | + source_branch: main |
| 71 | + secrets: inherit |
| 72 | + |
| 73 | + android-rc: |
| 74 | + name: Nightly Android rc |
| 75 | + needs: [android-rc-branch] |
85 | 76 | uses: ./.github/workflows/build.yml |
86 | 77 | with: |
87 | 78 | build_name: main-rc |
88 | | - platform: both |
89 | | - skip_version_bump: true |
90 | | - source_branch: ${{ needs.bump-version-rc.outputs.commit-hash }} |
| 79 | + platform: android |
| 80 | + skip_version_bump: false |
| 81 | + source_branch: ${{ needs.android-rc-branch.outputs.build_branch }} |
91 | 82 | secrets: inherit |
92 | 83 |
|
93 | | - upload-exp-testflight: |
94 | | - name: Upload exp to TestFlight |
95 | | - needs: [build-exp] |
96 | | - runs-on: ghcr.io/cirruslabs/macos-runner:sequoia-xl |
97 | | - environment: apple |
98 | | - steps: |
99 | | - - name: Checkout repository |
100 | | - uses: actions/checkout@v4 |
101 | | - with: |
102 | | - fetch-depth: 0 |
103 | | - |
104 | | - - name: Setup Ruby (iOS) |
105 | | - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb #v1 |
106 | | - with: |
107 | | - ruby-version: '3.2.9' |
108 | | - working-directory: ios |
109 | | - bundler-cache: true |
110 | | - |
111 | | - - name: Download iOS IPA artifact |
112 | | - uses: actions/download-artifact@v4 |
113 | | - with: |
114 | | - name: ios-ipa-main-exp |
115 | | - |
116 | | - - name: Find IPA path |
117 | | - id: ipa |
118 | | - run: | |
119 | | - IPA=$(find . -name '*.ipa' -type f | head -1) |
120 | | - if [ -z "$IPA" ]; then |
121 | | - echo "::error::No .ipa file found in artifact" |
122 | | - exit 1 |
123 | | - fi |
124 | | - case "$IPA" in /*) ABS="$IPA" ;; *) ABS="$PWD/$IPA" ;; esac |
125 | | - echo "path=$ABS" >> "$GITHUB_OUTPUT" |
126 | | -
|
127 | | - - name: Setup App Store Connect API Key |
128 | | - run: | |
129 | | - bash scripts/setup-app-store-connect-api-key.sh \ |
130 | | - "$APP_STORE_CONNECT_API_KEY_ISSUER_ID" \ |
131 | | - "$APP_STORE_CONNECT_API_KEY_KEY_ID" \ |
132 | | - "$APP_STORE_CONNECT_API_KEY_KEY_CONTENT" |
133 | | - env: |
134 | | - APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} |
135 | | - APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_ID }} |
136 | | - APP_STORE_CONNECT_API_KEY_KEY_CONTENT: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_CONTENT }} |
137 | | - |
138 | | - - name: Upload to TestFlight |
139 | | - run: | |
140 | | - bash scripts/upload-to-testflight.sh \ |
141 | | - "github_actions_main-exp" \ |
142 | | - "${{ github.ref_name }}" \ |
143 | | - "${{ steps.ipa.outputs.path }}" \ |
144 | | - "MetaMask BETA & Release Candidates" |
145 | | -
|
146 | | - - name: Cleanup API Key |
147 | | - if: always() |
148 | | - run: | |
149 | | - rm -f ios/AuthKey.p8 |
150 | | - echo "🧹 Cleaned up API key file" |
151 | | -
|
152 | | - upload-rc-testflight: |
153 | | - name: Upload RC to TestFlight |
154 | | - needs: [build-rc] |
155 | | - runs-on: ghcr.io/cirruslabs/macos-runner:sequoia-xl |
156 | | - environment: apple |
| 84 | + # ── Cleanup Android ephemeral branches ───────────────────────────────── |
| 85 | + # iOS branches are cleaned up by upload-to-testflight.yml internally. |
| 86 | + cleanup: |
| 87 | + name: Cleanup Android build branches |
| 88 | + needs: [android-exp-branch, android-rc-branch, android-exp, android-rc] |
| 89 | + if: always() |
| 90 | + runs-on: ubuntu-latest |
157 | 91 | steps: |
158 | | - - name: Checkout repository |
159 | | - uses: actions/checkout@v4 |
160 | | - with: |
161 | | - fetch-depth: 0 |
162 | | - |
163 | | - - name: Setup Ruby (iOS) |
164 | | - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb #v1 |
165 | | - with: |
166 | | - ruby-version: '3.2.9' |
167 | | - working-directory: ios |
168 | | - bundler-cache: true |
169 | | - |
170 | | - - name: Download iOS IPA artifact |
171 | | - uses: actions/download-artifact@v4 |
| 92 | + - uses: actions/checkout@v4 |
172 | 93 | with: |
173 | | - name: ios-ipa-main-rc |
174 | | - |
175 | | - - name: Find IPA path |
176 | | - id: ipa |
177 | | - run: | |
178 | | - IPA=$(find . -name '*.ipa' -type f | head -1) |
179 | | - if [ -z "$IPA" ]; then |
180 | | - echo "::error::No .ipa file found in artifact" |
181 | | - exit 1 |
182 | | - fi |
183 | | - case "$IPA" in /*) ABS="$IPA" ;; *) ABS="$PWD/$IPA" ;; esac |
184 | | - echo "path=$ABS" >> "$GITHUB_OUTPUT" |
185 | | -
|
186 | | - - name: Setup App Store Connect API Key |
187 | | - run: | |
188 | | - bash scripts/setup-app-store-connect-api-key.sh \ |
189 | | - "$APP_STORE_CONNECT_API_KEY_ISSUER_ID" \ |
190 | | - "$APP_STORE_CONNECT_API_KEY_KEY_ID" \ |
191 | | - "$APP_STORE_CONNECT_API_KEY_KEY_CONTENT" |
| 94 | + token: ${{ secrets.PR_TOKEN || github.token }} |
| 95 | + - name: Delete ephemeral branches |
192 | 96 | env: |
193 | | - APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }} |
194 | | - APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_ID }} |
195 | | - APP_STORE_CONNECT_API_KEY_KEY_CONTENT: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_CONTENT }} |
196 | | - |
197 | | - - name: Upload to TestFlight |
198 | | - run: | |
199 | | - # Group arg is required as positional placeholder for the 5th arg (distribute_external=false). |
200 | | - # With distribute_external=false the build is uploaded but NOT distributed to external testers. |
201 | | - bash scripts/upload-to-testflight.sh \ |
202 | | - "github_actions_main-rc" \ |
203 | | - "${{ github.ref_name }}" \ |
204 | | - "${{ steps.ipa.outputs.path }}" \ |
205 | | - "MetaMask BETA & Release Candidates" |
206 | | -
|
207 | | - - name: Cleanup API Key |
208 | | - if: always() |
| 97 | + EXP_BRANCH: ${{ needs.android-exp-branch.outputs.build_branch }} |
| 98 | + RC_BRANCH: ${{ needs.android-rc-branch.outputs.build_branch }} |
209 | 99 | run: | |
210 | | - rm -f ios/AuthKey.p8 |
211 | | - echo "🧹 Cleaned up API key file" |
| 100 | + for branch in "$EXP_BRANCH" "$RC_BRANCH"; do |
| 101 | + if [ -n "$branch" ]; then |
| 102 | + git push origin --delete "$branch" || true |
| 103 | + echo "🧹 Deleted: $branch" |
| 104 | + fi |
| 105 | + done |
0 commit comments