Adjust workflow to allow external contributors to run CI on maintainers approval (#2718)

Omar Hatem committed Dec 11, 2025 at 02:12 UTC 9b706263a88f61c5cc2614a9a23834cfce3dd53d
2 files changed +382 -338
.github/workflows/pr_test_build_android.yml
+31 -338
@@ -1,344 +1,37 @@
1 name: Cake Wallet Android
2
3 -on: [pull_request_target]
3 +on:
4 + # Trigger 1: For Maintainers (Automatic, No Approval)
5 + pull_request:
6 + types: [opened, synchronize, reopened]
7 +
8 + # Trigger 2: For Forks (Manual Approval via Environment)
9 + pull_request_target:
10 + types: [opened, synchronize, reopened]
11
5 -defaults:
6 - run:
7 - shell: bash
12 jobs:
9 - PR_test_build:
10 - runs-on: [Linux, amd64, android]
13 + # PATH A: Internal PRs (Runs immediately)
14 + internal-build:
15 + if: |
16 + github.event_name == 'pull_request' &&
17 + github.event.pull_request.head.repo.full_name == github.repository
18 + uses: ./.github/workflows/reusable-build.yml
19 + with:
20 + ref: ${{ github.event.pull_request.head.sha }}
21 + pr_number: ${{ github.head_ref || github.ref_name }}
22 + secrets: inherit # Passes all secrets automatically
23 +
24 + # PATH B: External Forks (Waits for Approval)
25 + external-build:
26 + if: |
27 + github.event_name == 'pull_request_target' &&
28 + github.event.pull_request.head.repo.full_name != github.repository
29 +
30 + # This applies the specific environment rule ONLY to forks
31 environment: external_contributors
12 - container:
13 - image: ghcr.io/cake-tech/cake_wallet:debian13-flutter3.32.0-ndkr28-go1.24.1-ruststablenightly
14 - env:
15 - STORE_PASS: test@cake_wallet
16 - KEY_PASS: test@cake_wallet
17 - MONEROC_CACHE_DIR_ROOT: /opt/generic_cache
18 - BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
19 - ANDROID_AVD_HOME: /root/.android/avd
20 - volumes:
21 - - /opt/cw_cache_android/root/.cache:/root/.cache
22 - - /opt/cw_cache_android/root/.android/avd/:/root/.android/avd
23 - - /opt/cw_cache_android/root/.ccache:/root/.ccache
24 - - /opt/cw_cache_android/root/.pub-cache/:/root/.pub-cache
25 - - /opt/cw_cache_android/root/.gradle/:/root/.gradle
26 - - /opt/cw_cache_android/root/.android/:/root/.android
27 - - /opt/cw_cache_android/root/go/pkg:/root/go/pkg
28 - - /opt/cw_cache_android/opt/generic_cache:/opt/generic_cache
29 - - /dev/kvm:/dev/kvm
30 - strategy:
31 - matrix:
32 - api-level: [29]
33 -
34 - steps:
35 - - name: Fix github actions messing up $HOME...
36 - run: 'echo HOME=/root | sudo tee -a $GITHUB_ENV'
37 - - uses: actions/checkout@v4
38 - with:
39 - ref: ${{ github.event.pull_request.head.sha }}
40 - - name: configure git
41 - run: |
42 - git config --global --add safe.directory '*'
43 - git config --global user.email "ci@cakewallet.com"
44 - git config --global user.name "CakeWallet CI"
45 - - name: Get the full commit message
46 - run: |
47 - FULL_MESSAGE="$(git log -1 --pretty=%B)"
48 - echo "message<<EOF" >> $GITHUB_ENV
49 - echo "$FULL_MESSAGE" >> $GITHUB_ENV
50 - echo "EOF" >> $GITHUB_ENV
51 -
52 - - name: Add secrets
53 - run: |
54 - touch lib/.secrets.g.dart
55 - touch cw_evm/lib/.secrets.g.dart
56 - touch cw_solana/lib/.secrets.g.dart
57 - touch cw_core/lib/.secrets.g.dart
58 - touch cw_nano/lib/.secrets.g.dart
59 - touch cw_tron/lib/.secrets.g.dart
60 - if [[ "x${{ secrets.SALT }}" == "x" ]];
61 - then
62 - echo "const salt = '954f787f12622067f7e548d9450c3832';" > lib/.secrets.g.dart
63 - else
64 - echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
65 - fi
66 - if [[ "x${{ secrets.KEY_CHAIN_SALT }}" == "x" ]];
67 - then
68 - echo "const keychainSalt = '2d2beba777dbf7dff7013b7a';" >> lib/.secrets.g.dart
69 - else
70 - echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
71 - fi
72 - if [[ "x${{ secrets.KEY }}" == "x" ]];
73 - then
74 - echo "const key = '638e98820ec10a2945e968435c9397a3';" >> lib/.secrets.g.dart
75 - else
76 - echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
77 - fi
78 - if [[ "x${{ secrets.WALLET_SALT }}" == "x" ]];
79 - then
80 - echo "const walletSalt = '8f7f1b70';" >> lib/.secrets.g.dart
81 - else
82 - echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
83 - fi
84 - if [[ "x${{ secrets.SHORT_KEY }}" == "x" ]];
85 - then
86 - echo "const shortKey = '653f270c2c152bc7ec864afe';" >> lib/.secrets.g.dart
87 - else
88 - echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
89 - fi
90 - if [[ "x${{ secrets.BACKUP_SALT }}" == "x" ]];
91 - then
92 - echo "const backupSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
93 - else
94 - echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
95 - fi
96 - if [[ "x${{ secrets.BACKUP_KEY_CHAIN_SALT }}" == "x" ]];
97 - then
98 - echo "const backupKeychainSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
99 - else
100 - echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
101 - fi
102 - echo "const changeNowCakeWalletApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
103 - echo "const changeNowMoneroApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
104 - echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
105 - echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
106 - echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
107 - echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
108 - echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
109 - echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
110 - echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
111 - echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
112 - echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
113 - echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
114 - echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
115 - echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
116 - echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart
117 - echo "const trocadorMoneroApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart
118 - echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
119 - echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart
120 - echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
121 - echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> lib/.secrets.g.dart
122 - echo "const chainStackApiKey = '${{ secrets.CHAIN_STACK_API_KEY }}';" >> lib/.secrets.g.dart
123 - echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
124 - echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
125 - echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
126 - echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
127 - echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
128 - echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
129 - echo "const exolixCakeWalletApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
130 - echo "const exolixMoneroApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
131 - echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
132 - echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
133 - echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
134 - echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
135 - echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
136 - echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
137 - echo "const chainStackApiKey = '${{ secrets.CHAIN_STACK_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
138 - echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
139 - echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
140 - echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
141 - echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
142 - echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
143 - echo "const swapTradeExchangeMarkup = '${{ secrets.SWAPTRADE_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
144 - echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
145 - echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
146 - echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
147 - echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
148 - echo "const meldTestApiKey = '${{ secrets.MELD_TEST_API_KEY }}';" >> lib/.secrets.g.dart
149 - echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dart
150 - echo "const letsExchangeBearerToken = '${{ secrets.LETS_EXCHANGE_TOKEN }}';" >> lib/.secrets.g.dart
151 - echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
152 - echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
153 - echo "const stealthExAdditionalFeePercent = '${{ secrets.STEALTH_EX_ADDITIONAL_FEE_PERCENT }}';" >> lib/.secrets.g.dart
154 - # for tests
155 - echo "const moneroTestWalletSeeds ='${{ secrets.MONERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
156 - echo "const moneroLegacyTestWalletSeeds = '${{ secrets.MONERO_LEGACY_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
157 - echo "const bitcoinTestWalletSeeds = '${{ secrets.BITCOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
158 - echo "const ethereumTestWalletSeeds = '${{ secrets.ETHEREUM_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
159 - echo "const litecoinTestWalletSeeds = '${{ secrets.LITECOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
160 - echo "const bitcoinCashTestWalletSeeds = '${{ secrets.BITCOIN_CASH_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
161 - echo "const polygonTestWalletSeeds = '${{ secrets.POLYGON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
162 - echo "const baseTestWalletSeeds = '${{ secrets.BASE_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
163 - echo "const arbitrumTestWalletSeeds = '${{ secrets.ARBITRUM_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
164 - echo "const solanaTestWalletSeeds = '${{ secrets.SOLANA_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
165 - echo "const tronTestWalletSeeds = '${{ secrets.TRON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
166 - echo "const nanoTestWalletSeeds = '${{ secrets.NANO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
167 - echo "const wowneroTestWalletSeeds = '${{ secrets.WOWNERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
168 - echo "const zanoTestWalletSeeds = '${{ secrets.ZANO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
169 - echo "const moneroTestWalletReceiveAddress = '${{ secrets.MONERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
170 - echo "const bitcoinTestWalletReceiveAddress = '${{ secrets.BITCOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
171 - echo "const ethereumTestWalletReceiveAddress = '${{ secrets.ETHEREUM_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
172 - echo "const litecoinTestWalletReceiveAddress = '${{ secrets.LITECOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
173 - echo "const bitcoinCashTestWalletReceiveAddress = '${{ secrets.BITCOIN_CASH_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
174 - echo "const polygonTestWalletReceiveAddress = '${{ secrets.POLYGON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
175 - echo "const baseTestWalletReceiveAddress = '${{ secrets.BASE_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
176 - echo "const arbitrumTestWalletReceiveAddress = '${{ secrets.ARBITRUM_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
177 - echo "const solanaTestWalletReceiveAddress = '${{ secrets.SOLANA_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
178 - echo "const tronTestWalletReceiveAddress = '${{ secrets.TRON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
179 - echo "const nanoTestWalletReceiveAddress = '${{ secrets.NANO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
180 - echo "const wowneroTestWalletReceiveAddress = '${{ secrets.WOWNERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
181 - echo "const moneroTestWalletBlockHeight = '${{ secrets.MONERO_TEST_WALLET_BLOCK_HEIGHT }}';" >> lib/.secrets.g.dart
182 - # end of test secrets
183 - echo "const chainflipApiKey = '${{ secrets.CHAINFLIP_API_KEY }}';" >> lib/.secrets.g.dart
184 - echo "const chainflipAffiliateFee = '${{ secrets.CHAINFLIP_AFFILIATE_FEE }}';" >> lib/.secrets.g.dart
185 - echo "const kryptonimApiKey = '${{ secrets.KRYPTONIM_API_KEY }}';" >> lib/.secrets.g.dart
186 - echo "const walletGroupSalt = '${{ secrets.WALLET_GROUP_SALT }}';" >> lib/.secrets.g.dart
187 - echo "const swapsXyzApiKey = '${{ secrets.SWAPSXYZ_API_KEY }}';" >> lib/.secrets.g.dart
188 -
189 - - name: Generate KeyStore
190 - run: |
191 - pushd /opt/generic_cache
192 - if [[ ! -f key.jks ]];
193 - then
194 - keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
195 - else
196 - echo "$PWD/key.jks exist, not generating"
197 - fi
198 - popd
199 - cp /opt/generic_cache/key.jks android/app
200 -
201 - - name: Fetch prebuilt Torch
202 - run: |
203 - set -x -e
204 - pushd scripts
205 - wget https://github.com/MrCyjaneK/torch_dart/releases/download/v1.0.17/torch_dart-v1.0.17.tar.gz -O torch_dart.tar.gz
206 - mkdir torch_dart
207 - pushd torch_dart
208 - tar -xzf ../torch_dart.tar.gz
209 - popd
210 - rm ./torch_dart.tar.gz
211 - popd
212 -
213 - - name: Fetch prebuilt Reown
214 - run: |
215 - set -x -e
216 - pushd scripts
217 - # cleaning
218 - rm -rf reown_flutter
219 - rm -f reown_flutter.tar.gz
220 -
221 - wget https://github.com/cake-tech/reown_flutter/releases/download/v0.0.4/reown_flutter-v0.0.4.tar.gz -O reown_flutter.tar.gz
222 - mkdir reown_flutter
223 - pushd reown_flutter
224 - tar -xzf ../reown_flutter.tar.gz
225 - popd
226 - rm ./reown_flutter.tar.gz
227 - popd
228 -
229 - - name: Execute Build and Setup Commands
230 - run: |
231 - pushd scripts/android
232 - source ./app_env.sh cakewallet
233 - ./app_config.sh
234 - popd
235 -
236 - - name: Build monero_c
237 - run: |
238 - mkdir -p scripts/monero_c
239 - pushd scripts/monero_c
240 - wget https://github.com/MrCyjaneK/monero_c/releases/download/v0.18.4.0-RC9/release-bundle.zip
241 - unzip release-bundle.zip
242 - rm release-bundle.zip
243 - unxz -fv release/*/*.xz
244 - popd
245 -
246 - - name: Build Bitbox Flutter
247 - run: |
248 - set -x -e
249 - pushd scripts
250 - ./build_bitbox_flutter.sh
251 - popd
252 -
253 - - name: Install Flutter dependencies
254 - run: |
255 - flutter pub get
256 -
257 - - name: Build mwebd
258 - run: |
259 - set -x -e
260 - export MWEBD_HASH=$(cat scripts/android/build_mwebd.sh | grep 'git reset --hard' | xargs | awk '{ print $4 }')
261 - echo MWEBD_HASH=$MWEBD_HASH >> /etc/environment
262 - pushd scripts/android
263 - ./build_mwebd.sh
264 - popd
265 -
266 - - name: Build Decred
267 - run: |
268 - set -x -e
269 - pushd scripts/android
270 - ./build_decred.sh
271 - popd
272 -
273 - - name: Build generated code
274 - run: |
275 - flutter --version
276 - flutter clean
277 - rm -rf .dart_tool
278 - rm pubspec.lock
279 - flutter pub get
280 - ./model_generator.sh async
281 -
282 - - name: Generate key properties
283 - run: |
284 - dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
285 -
286 - - name: Generate localization
287 - run: |
288 - dart run tool/generate_localization.dart
289 -
290 - - name: Rename app
291 - run: |
292 - sanitized_branch_name=${BRANCH_NAME#origin/} # Remove 'origin/' prefix if it exists
293 - sanitized_branch_name=${sanitized_branch_name:0:16} # Take only the first 16 characters
294 - sanitized_branch_name=$(echo "$sanitized_branch_name" | tr '[:upper:]' '[:lower:]') # Convert to lowercase
295 - sanitized_branch_name=$(echo "$sanitized_branch_name" | sed 's/[^a-z0-9]//g') # Remove all special characters
296 -
297 - echo -e "id=com.cakewallet.test_${sanitized_branch_name}\nname=${BRANCH_NAME}" > android/app.properties
298 -
299 - - name: Build
300 - run: |
301 - flutter build apk --dart-define=hasDevOptions=true --release --split-per-abi
302 -
303 - - name: Rename apk file
304 - run: |
305 - cd build/app/outputs/flutter-apk
306 - mkdir test-apk
307 - cp app-arm64-v8a-release.apk test-apk/${BRANCH_NAME}.apk
308 - cp app-x86_64-release.apk test-apk/${BRANCH_NAME}_x86.apk
309 -
310 - - name: Find APK file
311 - id: find_apk
312 - run: |
313 - set -x
314 - apk_file=$(ls build/app/outputs/flutter-apk/test-apk/${BRANCH_NAME}.apk || exit 1)
315 - echo "APK_FILE=$apk_file" >> $GITHUB_ENV
316 - - name: Write BRANCH_NAME to env
317 - run: echo "BRANCH_NAME=${BRANCH_NAME}" >> $GITHUB_ENV
318 -
319 - - name: Upload to slack step
320 - uses: vaporif/slack-file-upload-action@v1
321 - with:
322 - token: ${{ secrets.SLACK_APP_TOKEN }}
323 - initial_comment: ${{ env.message }}
324 - files: >
325 - [
326 - {"file": "${{ env.APK_FILE }}", "filename": "${{ env.BRANCH_NAME }}.apk"}
327 - ]
328 - channel_id: ${{ secrets.SLACK_APK_CHANNEL }}
329 -
330 - - name: cleanup
331 - run: rm -rf build/app/outputs/flutter-apk/test-apk/
32
333 - - name: Upload Artifact to github
334 - uses: actions/upload-artifact@v4
335 - with:
336 - path: ${{ github.workspace }}/build/app/outputs/flutter-apk
337 - name: "android apk"
338 -
339 - - name: 16KB align
340 - run: |
341 - cd build/app/outputs/flutter-apk
342 - for i in arm64-v8a x86_64; do
343 - ../../../../scripts/android/check_16kb_align.sh app-$i-release.apk
344 - done
\ No newline at end of file
33 + uses: ./.github/workflows/reusable-build.yml
34 + with:
35 + ref: ${{ github.event.pull_request.head.sha }}
36 + pr_number: ${{ github.head_ref || github.ref_name }}
37 + secrets: inherit
\ No newline at end of file
.github/workflows/reusable-build.yml new
+351
@@ -0,0 +1,351 @@
1 +name: Reusable Build Logic
2 +
3 +on:
4 + workflow_call:
5 + inputs:
6 + ref:
7 + required: true
8 + type: string
9 + pr_number:
10 + required: true
11 + type: string
12 +
13 +defaults:
14 + run:
15 + shell: bash
16 +jobs:
17 + PR_test_build:
18 + runs-on: [Linux, amd64, android]
19 + container:
20 + image: ghcr.io/cake-tech/cake_wallet:debian13-flutter3.32.0-ndkr28-go1.24.1-ruststablenightly
21 + env:
22 + STORE_PASS: test@cake_wallet
23 + KEY_PASS: test@cake_wallet
24 + MONEROC_CACHE_DIR_ROOT: /opt/generic_cache
25 + BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
26 + ANDROID_AVD_HOME: /root/.android/avd
27 + volumes:
28 + - /opt/cw_cache_android/root/.cache:/root/.cache
29 + - /opt/cw_cache_android/root/.android/avd/:/root/.android/avd
30 + - /opt/cw_cache_android/root/.ccache:/root/.ccache
31 + - /opt/cw_cache_android/root/.pub-cache/:/root/.pub-cache
32 + - /opt/cw_cache_android/root/.gradle/:/root/.gradle
33 + - /opt/cw_cache_android/root/.android/:/root/.android
34 + - /opt/cw_cache_android/root/go/pkg:/root/go/pkg
35 + - /opt/cw_cache_android/opt/generic_cache:/opt/generic_cache
36 + - /dev/kvm:/dev/kvm
37 + strategy:
38 + matrix:
39 + api-level: [29]
40 +
41 + steps:
42 + - name: Fix github actions messing up $HOME...
43 + run: 'echo HOME=/root | sudo tee -a $GITHUB_ENV'
44 + - uses: actions/checkout@v4
45 + with:
46 + ref: ${{ inputs.ref }}
47 + - name: configure git
48 + run: |
49 + git config --global --add safe.directory '*'
50 + git config --global user.email "ci@cakewallet.com"
51 + git config --global user.name "CakeWallet CI"
52 + - name: Get the full commit message
53 + run: |
54 + FULL_MESSAGE="$(git log -1 --pretty=%B)"
55 + echo "message<<EOF" >> $GITHUB_ENV
56 + echo "$FULL_MESSAGE" >> $GITHUB_ENV
57 + echo "EOF" >> $GITHUB_ENV
58 +
59 + - name: Add secrets
60 + run: |
61 + touch lib/.secrets.g.dart
62 + touch cw_evm/lib/.secrets.g.dart
63 + touch cw_solana/lib/.secrets.g.dart
64 + touch cw_core/lib/.secrets.g.dart
65 + touch cw_nano/lib/.secrets.g.dart
66 + touch cw_tron/lib/.secrets.g.dart
67 + if [[ "x${{ secrets.SALT }}" == "x" ]];
68 + then
69 + echo "const salt = '954f787f12622067f7e548d9450c3832';" > lib/.secrets.g.dart
70 + else
71 + echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
72 + fi
73 + if [[ "x${{ secrets.KEY_CHAIN_SALT }}" == "x" ]];
74 + then
75 + echo "const keychainSalt = '2d2beba777dbf7dff7013b7a';" >> lib/.secrets.g.dart
76 + else
77 + echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
78 + fi
79 + if [[ "x${{ secrets.KEY }}" == "x" ]];
80 + then
81 + echo "const key = '638e98820ec10a2945e968435c9397a3';" >> lib/.secrets.g.dart
82 + else
83 + echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
84 + fi
85 + if [[ "x${{ secrets.WALLET_SALT }}" == "x" ]];
86 + then
87 + echo "const walletSalt = '8f7f1b70';" >> lib/.secrets.g.dart
88 + else
89 + echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
90 + fi
91 + if [[ "x${{ secrets.SHORT_KEY }}" == "x" ]];
92 + then
93 + echo "const shortKey = '653f270c2c152bc7ec864afe';" >> lib/.secrets.g.dart
94 + else
95 + echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
96 + fi
97 + if [[ "x${{ secrets.BACKUP_SALT }}" == "x" ]];
98 + then
99 + echo "const backupSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
100 + else
101 + echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
102 + fi
103 + if [[ "x${{ secrets.BACKUP_KEY_CHAIN_SALT }}" == "x" ]];
104 + then
105 + echo "const backupKeychainSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
106 + else
107 + echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
108 + fi
109 + echo "const changeNowCakeWalletApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
110 + echo "const changeNowMoneroApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
111 + echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
112 + echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart
113 + echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart
114 + echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart
115 + echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart
116 + echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
117 + echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
118 + echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
119 + echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
120 + echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
121 + echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
122 + echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
123 + echo "const trocadorApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart
124 + echo "const trocadorMoneroApiKey = '${{ secrets.TROCADOR_API_KEY }}';" >> lib/.secrets.g.dart
125 + echo "const trocadorExchangeMarkup = '${{ secrets.TROCADOR_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
126 + echo "const anonPayReferralCode = '${{ secrets.ANON_PAY_REFERRAL_CODE }}';" >> lib/.secrets.g.dart
127 + echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
128 + echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> lib/.secrets.g.dart
129 + echo "const chainStackApiKey = '${{ secrets.CHAIN_STACK_API_KEY }}';" >> lib/.secrets.g.dart
130 + echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
131 + echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
132 + echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
133 + echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
134 + echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
135 + echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
136 + echo "const exolixCakeWalletApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
137 + echo "const exolixMoneroApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
138 + echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
139 + echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart
140 + echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
141 + echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
142 + echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
143 + echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
144 + echo "const chainStackApiKey = '${{ secrets.CHAIN_STACK_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
145 + echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
146 + echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
147 + echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
148 + echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
149 + echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
150 + echo "const swapTradeExchangeMarkup = '${{ secrets.SWAPTRADE_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
151 + echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
152 + echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
153 + echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
154 + echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
155 + echo "const meldTestApiKey = '${{ secrets.MELD_TEST_API_KEY }}';" >> lib/.secrets.g.dart
156 + echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dart
157 + echo "const letsExchangeBearerToken = '${{ secrets.LETS_EXCHANGE_TOKEN }}';" >> lib/.secrets.g.dart
158 + echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
159 + echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
160 + echo "const stealthExAdditionalFeePercent = '${{ secrets.STEALTH_EX_ADDITIONAL_FEE_PERCENT }}';" >> lib/.secrets.g.dart
161 + # for tests
162 + echo "const moneroTestWalletSeeds ='${{ secrets.MONERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
163 + echo "const moneroLegacyTestWalletSeeds = '${{ secrets.MONERO_LEGACY_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
164 + echo "const bitcoinTestWalletSeeds = '${{ secrets.BITCOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
165 + echo "const ethereumTestWalletSeeds = '${{ secrets.ETHEREUM_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
166 + echo "const litecoinTestWalletSeeds = '${{ secrets.LITECOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
167 + echo "const bitcoinCashTestWalletSeeds = '${{ secrets.BITCOIN_CASH_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
168 + echo "const polygonTestWalletSeeds = '${{ secrets.POLYGON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
169 + echo "const baseTestWalletSeeds = '${{ secrets.BASE_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
170 + echo "const arbitrumTestWalletSeeds = '${{ secrets.ARBITRUM_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
171 + echo "const solanaTestWalletSeeds = '${{ secrets.SOLANA_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
172 + echo "const tronTestWalletSeeds = '${{ secrets.TRON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
173 + echo "const nanoTestWalletSeeds = '${{ secrets.NANO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
174 + echo "const wowneroTestWalletSeeds = '${{ secrets.WOWNERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
175 + echo "const zanoTestWalletSeeds = '${{ secrets.ZANO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
176 + echo "const moneroTestWalletReceiveAddress = '${{ secrets.MONERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
177 + echo "const bitcoinTestWalletReceiveAddress = '${{ secrets.BITCOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
178 + echo "const ethereumTestWalletReceiveAddress = '${{ secrets.ETHEREUM_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
179 + echo "const litecoinTestWalletReceiveAddress = '${{ secrets.LITECOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
180 + echo "const bitcoinCashTestWalletReceiveAddress = '${{ secrets.BITCOIN_CASH_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
181 + echo "const polygonTestWalletReceiveAddress = '${{ secrets.POLYGON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
182 + echo "const baseTestWalletReceiveAddress = '${{ secrets.BASE_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
183 + echo "const arbitrumTestWalletReceiveAddress = '${{ secrets.ARBITRUM_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
184 + echo "const solanaTestWalletReceiveAddress = '${{ secrets.SOLANA_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
185 + echo "const tronTestWalletReceiveAddress = '${{ secrets.TRON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
186 + echo "const nanoTestWalletReceiveAddress = '${{ secrets.NANO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
187 + echo "const wowneroTestWalletReceiveAddress = '${{ secrets.WOWNERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
188 + echo "const moneroTestWalletBlockHeight = '${{ secrets.MONERO_TEST_WALLET_BLOCK_HEIGHT }}';" >> lib/.secrets.g.dart
189 + # end of test secrets
190 + echo "const chainflipApiKey = '${{ secrets.CHAINFLIP_API_KEY }}';" >> lib/.secrets.g.dart
191 + echo "const chainflipAffiliateFee = '${{ secrets.CHAINFLIP_AFFILIATE_FEE }}';" >> lib/.secrets.g.dart
192 + echo "const kryptonimApiKey = '${{ secrets.KRYPTONIM_API_KEY }}';" >> lib/.secrets.g.dart
193 + echo "const walletGroupSalt = '${{ secrets.WALLET_GROUP_SALT }}';" >> lib/.secrets.g.dart
194 + echo "const swapsXyzApiKey = '${{ secrets.SWAPSXYZ_API_KEY }}';" >> lib/.secrets.g.dart
195 +
196 + - name: Generate KeyStore
197 + run: |
198 + pushd /opt/generic_cache
199 + if [[ ! -f key.jks ]];
200 + then
201 + keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
202 + else
203 + echo "$PWD/key.jks exist, not generating"
204 + fi
205 + popd
206 + cp /opt/generic_cache/key.jks android/app
207 +
208 + - name: Fetch prebuilt Torch
209 + run: |
210 + set -x -e
211 + pushd scripts
212 + wget https://github.com/MrCyjaneK/torch_dart/releases/download/v1.0.17/torch_dart-v1.0.17.tar.gz -O torch_dart.tar.gz
213 + mkdir torch_dart
214 + pushd torch_dart
215 + tar -xzf ../torch_dart.tar.gz
216 + popd
217 + rm ./torch_dart.tar.gz
218 + popd
219 +
220 + - name: Fetch prebuilt Reown
221 + run: |
222 + set -x -e
223 + pushd scripts
224 + # cleaning
225 + rm -rf reown_flutter
226 + rm -f reown_flutter.tar.gz
227 +
228 + wget https://github.com/cake-tech/reown_flutter/releases/download/v0.0.4/reown_flutter-v0.0.4.tar.gz -O reown_flutter.tar.gz
229 + mkdir reown_flutter
230 + pushd reown_flutter
231 + tar -xzf ../reown_flutter.tar.gz
232 + popd
233 + rm ./reown_flutter.tar.gz
234 + popd
235 +
236 + - name: Execute Build and Setup Commands
237 + run: |
238 + pushd scripts/android
239 + source ./app_env.sh cakewallet
240 + ./app_config.sh
241 + popd
242 +
243 + - name: Build monero_c
244 + run: |
245 + mkdir -p scripts/monero_c
246 + pushd scripts/monero_c
247 + wget https://github.com/MrCyjaneK/monero_c/releases/download/v0.18.4.0-RC9/release-bundle.zip
248 + unzip release-bundle.zip
249 + rm release-bundle.zip
250 + unxz -fv release/*/*.xz
251 + popd
252 +
253 + - name: Build Bitbox Flutter
254 + run: |
255 + set -x -e
256 + pushd scripts
257 + ./build_bitbox_flutter.sh
258 + popd
259 +
260 + - name: Install Flutter dependencies
261 + run: |
262 + flutter pub get
263 +
264 + - name: Build mwebd
265 + run: |
266 + set -x -e
267 + export MWEBD_HASH=$(cat scripts/android/build_mwebd.sh | grep 'git reset --hard' | xargs | awk '{ print $4 }')
268 + echo MWEBD_HASH=$MWEBD_HASH >> /etc/environment
269 + pushd scripts/android
270 + ./build_mwebd.sh
271 + popd
272 +
273 + - name: Build Decred
274 + run: |
275 + set -x -e
276 + pushd scripts/android
277 + ./build_decred.sh
278 + popd
279 +
280 + - name: Build generated code
281 + run: |
282 + flutter --version
283 + flutter clean
284 + rm -rf .dart_tool
285 + rm pubspec.lock
286 + flutter pub get
287 + ./model_generator.sh async
288 +
289 + - name: Generate key properties
290 + run: |
291 + dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
292 +
293 + - name: Generate localization
294 + run: |
295 + dart run tool/generate_localization.dart
296 +
297 + - name: Rename app
298 + run: |
299 + sanitized_branch_name=${BRANCH_NAME#origin/} # Remove 'origin/' prefix if it exists
300 + sanitized_branch_name=${sanitized_branch_name:0:16} # Take only the first 16 characters
301 + sanitized_branch_name=$(echo "$sanitized_branch_name" | tr '[:upper:]' '[:lower:]') # Convert to lowercase
302 + sanitized_branch_name=$(echo "$sanitized_branch_name" | sed 's/[^a-z0-9]//g') # Remove all special characters
303 +
304 + echo -e "id=com.cakewallet.test_${sanitized_branch_name}\nname=${BRANCH_NAME}" > android/app.properties
305 +
306 + - name: Build
307 + run: |
308 + flutter build apk --dart-define=hasDevOptions=true --release --split-per-abi
309 +
310 + - name: Rename apk file
311 + run: |
312 + cd build/app/outputs/flutter-apk
313 + mkdir test-apk
314 + cp app-arm64-v8a-release.apk test-apk/${BRANCH_NAME}.apk
315 + cp app-x86_64-release.apk test-apk/${BRANCH_NAME}_x86.apk
316 +
317 + - name: Find APK file
318 + id: find_apk
319 + run: |
320 + set -x
321 + apk_file=$(ls build/app/outputs/flutter-apk/test-apk/${BRANCH_NAME}.apk || exit 1)
322 + echo "APK_FILE=$apk_file" >> $GITHUB_ENV
323 + - name: Write BRANCH_NAME to env
324 + run: echo "BRANCH_NAME=${BRANCH_NAME}" >> $GITHUB_ENV
325 +
326 + - name: Upload to slack step
327 + uses: vaporif/slack-file-upload-action@v1
328 + with:
329 + token: ${{ secrets.SLACK_APP_TOKEN }}
330 + initial_comment: ${{ env.message }}
331 + files: >
332 + [
333 + {"file": "${{ env.APK_FILE }}", "filename": "${{ env.BRANCH_NAME }}.apk"}
334 + ]
335 + channel_id: ${{ secrets.SLACK_APK_CHANNEL }}
336 +
337 + - name: cleanup
338 + run: rm -rf build/app/outputs/flutter-apk/test-apk/
339 +
340 + - name: Upload Artifact to github
341 + uses: actions/upload-artifact@v4
342 + with:
343 + path: ${{ github.workspace }}/build/app/outputs/flutter-apk
344 + name: "android apk"
345 +
346 + - name: 16KB align
347 + run: |
348 + cd build/app/outputs/flutter-apk
349 + for i in arm64-v8a x86_64; do
350 + ../../../../scripts/android/check_16kb_align.sh app-$i-release.apk
351 + done
\ No newline at end of file