CW-827 CI/CD update (#1948)

* CI update - use existing build outputs in build_monero_all.sh - update $HOME, fix gh actions - add secrets earlier in the runtime (potentially speed up 'Build generated code' step) - add windows dockerfile - add linux/android dockerfile - update android/linux ci script * [skip slack] [run tests] Run tests on CI, fix tests * [skip slack] [run tests] force enable kvm in android * [skip slack] [run tests] remove inexisting flag * [run tests] [skip slack] update tests * add extra dependencies [skip ci] * [skip slack] [run tests] Add secrets * [skip slack] [run tests] Timeout test cases, continue on error * [skip slack] [run tests] Xvfb fix, timeout fix * [skip slack] [run tests] Start dbus to clean up the logs, use SIGKILL * [skip slack] [run tests] Enable network manager * [skip slack] [run tests] Screen record test, resize screen * [skip slack] [run tests] Improve status report for tests * [skip slack] [run tests] Increase framerate * [skip slack] [run tests] Remove test that I am unable to fix locally easily from CI * [skip slack] [run tests] Simplify ffmpeg command * [skip slack] [run tests] Increase timeout, add comment * [skip slack] Update dockerfile, migrate from mrcyjanek to cake-tech for the ghcr org * Update lib/entities/default_settings_migration.dart Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

cyan committed Jan 15, 2025 at 12:09 UTC 3e10023e187ec098de80ee2c984401ef2ef664b4
32 files changed +854 -546
.github/workflows/cache_dependencies.yml deleted
-84
@@ -1,84 +0,0 @@
1 -name: Cache Dependencies
2 -
3 -on:
4 - workflow_dispatch:
5 - push:
6 - branches: [ main ]
7 -
8 -jobs:
9 - test:
10 -
11 - runs-on: ubuntu-20.04
12 -
13 - steps:
14 - - name: Free Disk Space (Ubuntu)
15 - uses: insightsengineering/disk-space-reclaimer@v1
16 - with:
17 - tools-cache: true
18 - android: false
19 - dotnet: true
20 - haskell: true
21 - large-packages: true
22 - swap-storage: true
23 - docker-images: true
24 -
25 - - uses: actions/checkout@v2
26 - - uses: actions/setup-java@v2
27 - with:
28 - distribution: "temurin"
29 - java-version: "17"
30 - - name: Configure placeholder git details
31 - run: |
32 - git config --global user.email "CI@cakewallet.com"
33 - git config --global user.name "Cake Github Actions"
34 - - name: Flutter action
35 - uses: subosito/flutter-action@v1
36 - with:
37 - flutter-version: "3.24.4"
38 - channel: stable
39 -
40 - - name: Install package dependencies
41 - run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
42 -
43 - - name: Execute Build and Setup Commands
44 - run: |
45 - sudo mkdir -p /opt/android
46 - sudo chown $USER /opt/android
47 - cd /opt/android
48 - -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
49 - cargo install cargo-ndk
50 - git clone https://github.com/cake-tech/cake_wallet.git --branch main
51 - cd cake_wallet/scripts/android/
52 - ./install_ndk.sh
53 - source ./app_env.sh cakewallet
54 - chmod +x pubspec_gen.sh
55 - ./app_config.sh
56 -
57 - - name: Cache Externals
58 - id: cache-externals
59 - uses: actions/cache@v3
60 - with:
61 - path: |
62 - /opt/android/cake_wallet/cw_haven/android/.cxx
63 - /opt/android/cake_wallet/scripts/monero_c/release
64 - key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
65 -
66 - - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
67 - name: Generate Externals
68 - run: |
69 - cd /opt/android/cake_wallet/scripts/android/
70 - source ./app_env.sh cakewallet
71 - ./build_monero_all.sh
72 -
73 - - name: Cache Keystore
74 - id: cache-keystore
75 - uses: actions/cache@v3
76 - with:
77 - path: /opt/android/cake_wallet/android/app
78 - key: keystore
79 -
80 - - if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
81 - name: Generate KeyStore
82 - run: |
83 - cd /opt/android/cake_wallet/android/app
84 - 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
.github/workflows/pr_test_build_android.yml
+195 -205
@@ -1,169 +1,93 @@
1 -name: PR Test Build
1 +name: Cake Wallet Android
2
3 -on:
4 - pull_request:
5 - branches: [main]
6 - workflow_dispatch:
7 - inputs:
8 - branch:
9 - description: "Branch name to build"
10 - required: true
11 - default: "main"
3 +on: [push]
4
5 +defaults:
6 + run:
7 + shell: bash
8 jobs:
9 PR_test_build:
15 - runs-on: ubuntu-20.04
10 + runs-on: linux-amd64
11 + container:
12 + image: ghcr.io/cake-tech/cake_wallet:main-linux
13 + env:
14 + STORE_PASS: test@cake_wallet
15 + KEY_PASS: test@cake_wallet
16 + MONEROC_CACHE_DIR_ROOT: /opt/generic_cache
17 + BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
18 + ANDROID_AVD_HOME: /root/.android/avd
19 + volumes:
20 + - /opt/cw_cache_android/root/.cache:/root/.cache
21 + - /opt/cw_cache_android/root/.android/avd/:/root/.android/avd
22 + - /opt/cw_cache_android/root/.ccache:/root/.ccache
23 + - /opt/cw_cache_android/root/.pub-cache/:/root/.pub-cache
24 + - /opt/cw_cache_android/root/.gradle/:/root/.gradle
25 + - /opt/cw_cache_android/root/.android/:/root/.android
26 + - /opt/cw_cache_android/root/go/pkg:/root/go/pkg
27 + - /opt/cw_cache_android/opt/generic_cache:/opt/generic_cache
28 + - /dev/kvm:/dev/kvm
29 strategy:
30 matrix:
31 api-level: [29]
19 - env:
20 - STORE_PASS: test@cake_wallet
21 - KEY_PASS: test@cake_wallet
22 - PR_NUMBER: ${{ github.event.number }}
32
33 steps:
25 - - name: is pr
26 - if: github.event_name == 'pull_request'
27 - run: echo "BRANCH_NAME=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
28 -
29 - - name: is not pr
30 - if: github.event_name != 'pull_request'
31 - run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENV
32 -
33 - - name: Free Disk Space (Ubuntu)
34 - uses: insightsengineering/disk-space-reclaimer@v1
35 - with:
36 - tools-cache: true
37 - android: false
38 - dotnet: true
39 - haskell: true
40 - large-packages: true
41 - swap-storage: true
42 - docker-images: true
43 -
44 - - uses: actions/checkout@v2
45 - - uses: actions/setup-java@v2
46 - with:
47 - distribution: "temurin"
48 - java-version: "17"
49 - - name: Configure placeholder git details
50 - run: |
51 - git config --global user.email "CI@cakewallet.com"
52 - git config --global user.name "Cake Github Actions"
53 - - name: Flutter action
54 - uses: subosito/flutter-action@v1
55 - with:
56 - flutter-version: "3.24.0"
57 - channel: stable
58 -
59 - - name: Install package dependencies
60 - run: |
61 - sudo apt update
62 - sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang
63 -
64 -
65 - - name: Clone Repo
66 - run: |
67 - sudo mkdir -p /opt/android
68 - sudo chown $USER /opt/android
69 - cd /opt/android
70 - git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
71 -
72 -# - name: Cache Keystore
73 -# id: cache-keystore
74 -# uses: actions/cache@v3
75 -# with:
76 -# path: /opt/android/cake_wallet/android/app
77 -# key: keystore
78 -#
79 -# - if: ${{ steps.cache-keystore.outputs.cache-hit != 'true' }}
80 - - name: Generate KeyStore
81 - run: |
82 - cd /opt/android/cake_wallet/android/app
83 - 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
84 -
85 - - name: Execute Build and Setup Commands
86 - run: |
87 - cd /opt/android
88 - -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
89 - cargo install cargo-ndk
90 - cd cake_wallet/scripts/android/
91 - ./install_ndk.sh
92 - source ./app_env.sh cakewallet
93 - chmod +x pubspec_gen.sh
94 - ./app_config.sh
95 -
96 - - name: Cache Externals
97 - id: cache-externals
98 - uses: actions/cache@v3
99 - with:
100 - path: |
101 - /opt/android/cake_wallet/cw_haven/android/.cxx
102 - /opt/android/cake_wallet/scripts/monero_c/release
103 - key: ${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
104 -
105 - - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
106 - name: Generate Externals
107 - run: |
108 - cd /opt/android/cake_wallet/scripts/android/
109 - source ./app_env.sh cakewallet
110 - ./build_monero_all.sh
111 -
112 - - name: Install Flutter dependencies
113 - run: |
114 - cd /opt/android/cake_wallet
115 - flutter pub get
116 -
117 -
118 - - name: Install go and gomobile
119 - run: |
120 - # install go > 1.23:
121 - wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz
122 - sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz
123 - export PATH=$PATH:/usr/local/go/bin
124 - export PATH=$PATH:~/go/bin
125 - go install golang.org/x/mobile/cmd/gomobile@latest
126 - gomobile init
127 -
128 - - name: Build mwebd
129 - run: |
130 - # paths are reset after each step, so we need to set them again:
131 - export PATH=$PATH:/usr/local/go/bin
132 - export PATH=$PATH:~/go/bin
133 - cd /opt/android/cake_wallet/scripts/android/
134 - ./build_mwebd.sh --dont-install
135 -
136 - - name: Generate key properties
137 - run: |
138 - cd /opt/android/cake_wallet
139 - dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
140 -
141 - - name: Generate localization
142 - run: |
143 - cd /opt/android/cake_wallet
144 - dart run tool/generate_localization.dart
145 -
146 - - name: Build generated code
34 + - name: Fix github actions messing up $HOME...
35 + run: 'echo HOME=/root | sudo tee -a $GITHUB_ENV'
36 + - uses: actions/checkout@v4
37 + - name: configure git
38 run: |
148 - cd /opt/android/cake_wallet
149 - ./model_generator.sh
150 -
39 + git config --global user.email "ci@cakewallet.com"
40 + git config --global user.name "CakeWallet CI"
41 - name: Add secrets
42 run: |
153 - cd /opt/android/cake_wallet
43 touch lib/.secrets.g.dart
44 touch cw_evm/lib/.secrets.g.dart
45 touch cw_solana/lib/.secrets.g.dart
46 touch cw_core/lib/.secrets.g.dart
47 touch cw_nano/lib/.secrets.g.dart
48 touch cw_tron/lib/.secrets.g.dart
160 - echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
161 - echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
162 - echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
163 - echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
164 - echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
165 - echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
166 - echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
49 + if [[ "x${{ secrets.SALT }}" == "x" ]];
50 + then
51 + echo "const salt = '954f787f12622067f7e548d9450c3832';" > lib/.secrets.g.dart
52 + else
53 + echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
54 + fi
55 + if [[ "x${{ secrets.KEY_CHAIN_SALT }}" == "x" ]];
56 + then
57 + echo "const keychainSalt = '2d2beba777dbf7dff7013b7a';" >> lib/.secrets.g.dart
58 + else
59 + echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
60 + fi
61 + if [[ "x${{ secrets.KEY }}" == "x" ]];
62 + then
63 + echo "const key = '638e98820ec10a2945e968435c9397a3';" >> lib/.secrets.g.dart
64 + else
65 + echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
66 + fi
67 + if [[ "x${{ secrets.WALLET_SALT }}" == "x" ]];
68 + then
69 + echo "const walletSalt = '8f7f1b70';" >> lib/.secrets.g.dart
70 + else
71 + echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
72 + fi
73 + if [[ "x${{ secrets.SHORT_KEY }}" == "x" ]];
74 + then
75 + echo "const shortKey = '653f270c2c152bc7ec864afe';" >> lib/.secrets.g.dart
76 + else
77 + echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
78 + fi
79 + if [[ "x${{ secrets.BACKUP_SALT }}" == "x" ]];
80 + then
81 + echo "const backupSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
82 + else
83 + echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
84 + fi
85 + if [[ "x${{ secrets.BACKUP_KEY_CHAIN_SALT }}" == "x" ]];
86 + then
87 + echo "const backupKeychainSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
88 + else
89 + echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
90 + fi
91 echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
92 echo "const changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
93 echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
@@ -213,86 +137,152 @@ jobs:
137 echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
138 echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
139 echo "const stealthExAdditionalFeePercent = '${{ secrets.STEALTH_EX_ADDITIONAL_FEE_PERCENT }}';" >> lib/.secrets.g.dart
140 + # for tests
141 + echo "const moneroTestWalletSeeds ='${{ secrets.MONERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
142 + echo "const moneroLegacyTestWalletSeeds = '${{ secrets.MONERO_LEGACY_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
143 + echo "const bitcoinTestWalletSeeds = '${{ secrets.BITCOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
144 + echo "const ethereumTestWalletSeeds = '${{ secrets.ETHEREUM_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
145 + echo "const litecoinTestWalletSeeds = '${{ secrets.LITECOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
146 + echo "const bitcoinCashTestWalletSeeds = '${{ secrets.BITCOIN_CASH_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
147 + echo "const polygonTestWalletSeeds = '${{ secrets.POLYGON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
148 + echo "const solanaTestWalletSeeds = '${{ secrets.SOLANA_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
149 + echo "const tronTestWalletSeeds = '${{ secrets.TRON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
150 + echo "const nanoTestWalletSeeds = '${{ secrets.NANO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
151 + echo "const wowneroTestWalletSeeds = '${{ secrets.WOWNERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
152 + echo "const moneroTestWalletReceiveAddress = '${{ secrets.MONERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
153 + echo "const bitcoinTestWalletReceiveAddress = '${{ secrets.BITCOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
154 + echo "const ethereumTestWalletReceiveAddress = '${{ secrets.ETHEREUM_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
155 + echo "const litecoinTestWalletReceiveAddress = '${{ secrets.LITECOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
156 + echo "const bitcoinCashTestWalletReceiveAddress = '${{ secrets.BITCOIN_CASH_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
157 + echo "const polygonTestWalletReceiveAddress = '${{ secrets.POLYGON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
158 + echo "const solanaTestWalletReceiveAddress = '${{ secrets.SOLANA_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
159 + echo "const tronTestWalletReceiveAddress = '${{ secrets.TRON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
160 + echo "const nanoTestWalletReceiveAddress = '${{ secrets.NANO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
161 + echo "const wowneroTestWalletReceiveAddress = '${{ secrets.WOWNERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
162 + echo "const moneroTestWalletBlockHeight = '${{ secrets.MONERO_TEST_WALLET_BLOCK_HEIGHT }}';" >> lib/.secrets.g.dart
163 + - name: prepare monero_c and cache
164 + run: |
165 + export MONEROC_HASH=$(cat scripts/prepare_moneroc.sh | grep 'git checkout' | xargs | awk '{ print $3 }')
166 + echo MONEROC_HASH=$MONEROC_HASH >> /etc/environment
167 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/moneroc-$MONEROC_HASH/monero_c"
168 + pushd scripts
169 + ln -s "$MONEROC_CACHE_DIR_ROOT/moneroc-$MONEROC_HASH/monero_c"
170 + ./prepare_moneroc.sh
171 + popd
172 + pushd scripts/monero_c
173 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/built" || true
174 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/built" || true
175 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/built" || true
176 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/sources" || true
177 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/sources" || true
178 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/sources" || true
179 +
180 + rm -rf "$PWD/contrib/depends/built" "$PWD/monero/contrib/depends/built" "$PWD/wownero/contrib/depends/built"
181 + rm -rf "$PWD/contrib/depends/sources" "$PWD/monero/contrib/depends/sources" "$PWD/wownero/contrib/depends/sources"
182 + mkdir -p contrib/depends || true
183 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/built" "$PWD/contrib/depends/built"
184 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/built" "$PWD/monero/contrib/depends/built"
185 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/built" "$PWD/wownero/contrib/depends/built"
186 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/sources" "$PWD/contrib/depends/sources"
187 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/sources" "$PWD/monero/contrib/depends/sources"
188 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/sources" "$PWD/wownero/contrib/depends/sources"
189 + popd
190
217 - - name: Rename app
191 + - name: Generate KeyStore
192 run: |
219 - echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
193 + pushd /opt/generic_cache
194 + if [[ ! -f key.jks ]];
195 + then
196 + 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
197 + else
198 + echo "$PWD/key.jks exist, not generating"
199 + fi
200 + popd
201 + cp /opt/generic_cache/key.jks android/app
202
221 - # Step 3: Download previous build number
222 - - name: Download previous build number
223 - id: download-build-number
203 + - name: Execute Build and Setup Commands
204 run: |
225 - # Download the artifact if it exists
226 - if [[ ! -f build_number.txt ]]; then
227 - echo "1" > build_number.txt
228 - fi
205 + pushd scripts/android
206 + source ./app_env.sh cakewallet
207 + ./app_config.sh
208 + popd
209
230 - # Step 4: Read and Increment Build Number
231 - - name: Increment Build Number
232 - id: increment-build-number
210 + - name: Build monero_c
211 run: |
234 - # Read current build number from file
235 - BUILD_NUMBER=$(cat build_number.txt)
236 - BUILD_NUMBER=$((BUILD_NUMBER + 1))
237 - echo "New build number: $BUILD_NUMBER"
212 + pushd scripts/android/
213 + source ./app_env.sh cakewallet
214 + ./build_monero_all.sh
215 + popd
216
239 - # Save the incremented build number
240 - echo "$BUILD_NUMBER" > build_number.txt
217 + - name: Install Flutter dependencies
218 + run: |
219 + flutter pub get
220
242 - # Export the build number to use in later steps
243 - echo "BUILD_NUMBER=$BUILD_NUMBER" >> $GITHUB_ENV
221 + - name: Build mwebd
222 + run: |
223 + set -x -e
224 + export MWEBD_HASH=$(cat scripts/android/build_mwebd.sh | grep 'git reset --hard' | xargs | awk '{ print $4 }')
225 + echo MWEBD_HASH=$MWEBD_HASH >> /etc/environment
226 + pushd scripts/android
227 + gomobile init;
228 + ./build_mwebd.sh --dont-install
229 + popd
230
245 - # Step 5: Update pubspec.yaml with new build number
246 - - name: Update build number
231 + - name: Build generated code
232 run: |
248 - cd /opt/android/cake_wallet
249 - sed -i "s/^version: .*/version: 1.0.$BUILD_NUMBER/" pubspec.yaml
233 + ./model_generator.sh async
234 +
235 + - name: Generate key properties
236 + run: |
237 + dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
238 +
239 + - name: Generate localization
240 + run: |
241 + dart run tool/generate_localization.dart
242 +
243 + - name: Rename app
244 + run: |
245 + sanitized_branch_name=${BRANCH_NAME#origin/} # Remove 'origin/' prefix if it exists
246 + sanitized_branch_name=${sanitized_branch_name:0:16} # Take only the first 16 characters
247 + sanitized_branch_name=$(echo "$sanitized_branch_name" | tr '[:upper:]' '[:lower:]') # Convert to lowercase
248 + sanitized_branch_name=$(echo "$sanitized_branch_name" | sed 's/[^a-z0-9]//g') # Remove all special characters
249 +
250 + echo -e "id=com.cakewallet.test_${sanitized_branch_name}\nname=${BRANCH_NAME}" > android/app.properties
251
252 - name: Build
253 run: |
253 - cd /opt/android/cake_wallet
254 flutter build apk --release --split-per-abi
255
256 - # - name: Push to App Center
257 - # run: |
258 - # echo 'Installing App Center CLI tools'
259 - # npm install -g appcenter-cli
260 - # echo "Publishing test to App Center"
261 - # appcenter distribute release \
262 - # --group "Testers" \
263 - # --file "/opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk" \
264 - # --release-notes ${{ env.BRANCH_NAME }} \
265 - # --app Cake-Labs/Cake-Wallet \
266 - # --token ${{ secrets.APP_CENTER_TOKEN }} \
267 - # --quiet
268 -
256 - name: Rename apk file
257 run: |
271 - cd /opt/android/cake_wallet/build/app/outputs/flutter-apk
258 + cd build/app/outputs/flutter-apk
259 mkdir test-apk
273 - cp app-arm64-v8a-release.apk test-apk/${{env.BRANCH_NAME}}.apk
274 - cp app-x86_64-release.apk test-apk/${{env.BRANCH_NAME}}_x86.apk
275 -
276 - - name: Upload Artifact
277 - uses: kittaakos/upload-artifact-as-is@v0
278 - with:
279 - path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/
260 + cp app-arm64-v8a-release.apk test-apk/${BRANCH_NAME}.apk
261 + cp app-x86_64-release.apk test-apk/${BRANCH_NAME}_x86.apk
262 + cd test-apk
263 + cp ${BRANCH_NAME}.apk ${BRANCH_NAME}_slack.apk
264
281 - # Re-upload updated build number for the next run
282 - - name: Upload updated build number
283 - uses: actions/upload-artifact@v3
284 - with:
285 - name: build_number
286 - path: build_number.txt
287 -
288 - - name: Send Test APK
265 + - name: Find APK file
266 + id: find_apk
267 + run: |
268 + set -x
269 + apk_file=$(ls build/app/outputs/flutter-apk/test-apk/*_slack.apk || exit 1)
270 + echo "APK_FILE=$apk_file" >> $GITHUB_ENV
271 +
272 + - name: Upload artifact to slack
273 + if: ${{ !contains(github.event.head_commit.message, 'skip slack') }}
274 continue-on-error: true
275 uses: adrey/slack-file-upload-action@1.0.5
276 with:
277 token: ${{ secrets.SLACK_APP_TOKEN }}
293 - path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/${{env.BRANCH_NAME}}.apk
278 + path: ${{ env.APK_FILE }}
279 channel: ${{ secrets.SLACK_APK_CHANNEL }}
295 - title: "${{ env.BRANCH_NAME }}.apk"
296 - filename: ${{ env.BRANCH_NAME }}.apk
280 initial_comment: ${{ github.event.head_commit.message }}
281
282 + - name: cleanup
283 + run: rm -rf build/app/outputs/flutter-apk/test-apk/
284 +
285 + - name: Upload Artifact to github
286 + uses: kittaakos/upload-artifact-as-is@v0
287 + with:
288 + path: ${{ github.workspace }}/build/app/outputs/flutter-apk
\ No newline at end of file
.github/workflows/pr_test_build_linux.yml
+226 -145
@@ -1,139 +1,89 @@
1 -name: PR Test Build linux
1 +name: Cake Wallet Linux
2
3 -on:
4 - pull_request:
5 - branches: [main]
6 - workflow_dispatch:
7 - inputs:
8 - branch:
9 - description: "Branch name to build"
10 - required: true
11 - default: "main"
3 +on: [push]
4
5 +defaults:
6 + run:
7 + shell: bash
8 jobs:
9 PR_test_build:
15 - runs-on: ubuntu-20.04
16 - env:
17 - STORE_PASS: test@cake_wallet
18 - KEY_PASS: test@cake_wallet
19 - PR_NUMBER: ${{ github.event.number }}
10 + runs-on: linux-amd64
11 + container:
12 + image: ghcr.io/cake-tech/cake_wallet:main-linux
13 + env:
14 + STORE_PASS: test@cake_wallet
15 + KEY_PASS: test@cake_wallet
16 + MONEROC_CACHE_DIR_ROOT: /opt/generic_cache
17 + BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
18 + DESKTOP_FORCE_MOBILE: Y
19 + volumes:
20 + - /opt/cw_cache_linux/root/.cache:/root/.cache
21 + - /opt/cw_cache_linux/root/.ccache:/root/.ccache
22 + - /opt/cw_cache_linux/root/.pub-cache/:/root/.pub-cache
23 + - /opt/cw_cache_linux/root/go/pkg:/root/go/pkg
24 + - /opt/cw_cache_linux/opt/generic_cache:/opt/generic_cache
25 + strategy:
26 + matrix:
27 + api-level: [29]
28
29 steps:
22 - - name: is pr
23 - if: github.event_name == 'pull_request'
24 - run: echo "BRANCH_NAME=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
25 -
26 - - name: is not pr
27 - if: github.event_name != 'pull_request'
28 - run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENVg
29 -
30 - - uses: actions/checkout@v2
31 - - uses: actions/setup-java@v1
32 - with:
33 - java-version: "17.x"
34 - - name: Configure placeholder git details
35 - run: |
36 - git config --global user.email "CI@cakewallet.com"
37 - git config --global user.name "Cake Github Actions"
38 - - name: Flutter action
39 - uses: subosito/flutter-action@v1
40 - with:
41 - flutter-version: "3.24.0"
42 - channel: stable
43 -
44 - - name: Install package dependencies
45 - run: |
46 - sudo apt update
47 - sudo apt-get install -y curl unzip automake build-essential file pkg-config git python-is-python3 libtool libtinfo5 cmake clang
48 -
49 - - name: Install desktop dependencies
50 - run: |
51 - sudo apt update
52 - sudo apt install -y ninja-build libgtk-3-dev gperf
53 - - name: Execute Build and Setup Commands
54 - run: |
55 - sudo mkdir -p /opt/android
56 - sudo chown $USER /opt/android
57 - cd /opt/android
58 - -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
59 - cargo install cargo-ndk
60 - git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
61 - cd scripts && ./gen_android_manifest.sh && cd ..
62 - cd cake_wallet/scripts/android/
63 - source ./app_env.sh cakewallet
64 - ./app_config.sh
65 - cd ../../..
66 - cd cake_wallet/scripts/linux/
67 - source ./app_env.sh cakewallet
68 - ./app_config.sh
69 - cd ../../..
70 -
71 - - name: Cache Externals
72 - id: cache-externals
73 - uses: actions/cache@v3
74 - with:
75 - path: |
76 - /opt/android/cake_wallet/cw_haven/android/.cxx
77 - /opt/android/cake_wallet/scripts/monero_c/release
78 - key: linux_${{ hashFiles('**/prepare_moneroc.sh' ,'**/build_monero_all.sh' ,'**/cache_dependencies.yml') }}
79 -
80 - - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
81 - name: Generate Externals
82 - run: |
83 - cd /opt/android/cake_wallet/scripts/linux/
84 - source ./app_env.sh cakewallet
85 - ./build_monero_all.sh
86 -
87 - - name: Install Flutter dependencies
88 - run: |
89 - cd /opt/android/cake_wallet
90 - flutter pub get
91 -
92 - - name: Install go and gomobile
93 - run: |
94 - # install go > 1.23:
95 - wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz
96 - sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz
97 - export PATH=$PATH:/usr/local/go/bin
98 - export PATH=$PATH:~/go/bin
99 - go install golang.org/x/mobile/cmd/gomobile@latest
100 - gomobile init
101 -
102 - - name: Build mwebd
103 - run: |
104 - # paths are reset after each step, so we need to set them again:
105 - export PATH=$PATH:/usr/local/go/bin
106 - export PATH=$PATH:~/go/bin
107 - # build mwebd:
108 - cd /opt/android/cake_wallet/scripts/android/
109 - ./build_mwebd.sh --dont-install
110 -
111 - - name: Generate localization
30 + - name: Fix github actions messing up $HOME...
31 + run: 'echo HOME=/root | sudo tee -a $GITHUB_ENV'
32 + - uses: actions/checkout@v4
33 + - name: configure git
34 run: |
113 - cd /opt/android/cake_wallet
114 - dart run tool/generate_localization.dart
115 -
116 - - name: Build generated code
117 - run: |
118 - cd /opt/android/cake_wallet
119 - ./model_generator.sh
120 -
35 + git config --global user.email "ci@cakewallet.com"
36 + git config --global user.name "CakeWallet CI"
37 - name: Add secrets
38 run: |
123 - cd /opt/android/cake_wallet
39 touch lib/.secrets.g.dart
40 touch cw_evm/lib/.secrets.g.dart
41 touch cw_solana/lib/.secrets.g.dart
42 touch cw_core/lib/.secrets.g.dart
43 touch cw_nano/lib/.secrets.g.dart
44 touch cw_tron/lib/.secrets.g.dart
130 - echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
131 - echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
132 - echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
133 - echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
134 - echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
135 - echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
136 - echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
45 + if [[ "x${{ secrets.SALT }}" == "x" ]];
46 + then
47 + echo "const salt = '954f787f12622067f7e548d9450c3832';" > lib/.secrets.g.dart
48 + else
49 + echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart
50 + fi
51 + if [[ "x${{ secrets.KEY_CHAIN_SALT }}" == "x" ]];
52 + then
53 + echo "const keychainSalt = '2d2beba777dbf7dff7013b7a';" >> lib/.secrets.g.dart
54 + else
55 + echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
56 + fi
57 + if [[ "x${{ secrets.KEY }}" == "x" ]];
58 + then
59 + echo "const key = '638e98820ec10a2945e968435c9397a3';" >> lib/.secrets.g.dart
60 + else
61 + echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart
62 + fi
63 + if [[ "x${{ secrets.WALLET_SALT }}" == "x" ]];
64 + then
65 + echo "const walletSalt = '8f7f1b70';" >> lib/.secrets.g.dart
66 + else
67 + echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart
68 + fi
69 + if [[ "x${{ secrets.SHORT_KEY }}" == "x" ]];
70 + then
71 + echo "const shortKey = '653f270c2c152bc7ec864afe';" >> lib/.secrets.g.dart
72 + else
73 + echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart
74 + fi
75 + if [[ "x${{ secrets.BACKUP_SALT }}" == "x" ]];
76 + then
77 + echo "const backupSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
78 + else
79 + echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart
80 + fi
81 + if [[ "x${{ secrets.BACKUP_KEY_CHAIN_SALT }}" == "x" ]];
82 + then
83 + echo "const backupKeychainSalt = 'bf630d24ff0b6f60';" >> lib/.secrets.g.dart
84 + else
85 + echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart
86 + fi
87 echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart
88 echo "const changeNowApiKeyDesktop = '${{ secrets.CHANGE_NOW_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
89 echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart
@@ -144,8 +94,6 @@ jobs:
94 echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
95 echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart
96 echo "const simpleSwapApiKeyDesktop = '${{ secrets.SIMPLE_SWAP_API_KEY_DESKTOP }}';" >> lib/.secrets.g.dart
147 - echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
148 - echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
97 echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart
98 echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart
99 echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart
@@ -156,8 +104,11 @@ jobs:
104 echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
105 echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> lib/.secrets.g.dart
106 echo "const chainStackApiKey = '${{ secrets.CHAIN_STACK_API_KEY }}';" >> lib/.secrets.g.dart
107 + echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
108 + echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> lib/.secrets.g.dart
109 echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
110 echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
111 + echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
112 echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
113 echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
114 echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
@@ -165,7 +116,6 @@ jobs:
116 echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart
117 echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
118 echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
168 - echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
119 echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
120 echo "const chainStackApiKey = '${{ secrets.CHAIN_STACK_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
121 echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
@@ -178,39 +128,170 @@ jobs:
128 echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
129 echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
130 echo "const meldTestApiKey = '${{ secrets.MELD_TEST_API_KEY }}';" >> lib/.secrets.g.dart
181 - echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dar
131 + echo "const meldTestPublicKey = '${{ secrets.MELD_TEST_PUBLIC_KEY}}';" >> lib/.secrets.g.dart
132 echo "const letsExchangeBearerToken = '${{ secrets.LETS_EXCHANGE_TOKEN }}';" >> lib/.secrets.g.dart
133 echo "const letsExchangeAffiliateId = '${{ secrets.LETS_EXCHANGE_AFFILIATE_ID }}';" >> lib/.secrets.g.dart
134 echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
135 echo "const stealthExAdditionalFeePercent = '${{ secrets.STEALTH_EX_ADDITIONAL_FEE_PERCENT }}';" >> lib/.secrets.g.dart
136 + # tests
137 + echo "const moneroTestWalletSeeds ='${{ secrets.MONERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
138 + echo "const moneroLegacyTestWalletSeeds = '${{ secrets.MONERO_LEGACY_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
139 + echo "const bitcoinTestWalletSeeds = '${{ secrets.BITCOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
140 + echo "const ethereumTestWalletSeeds = '${{ secrets.ETHEREUM_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
141 + echo "const litecoinTestWalletSeeds = '${{ secrets.LITECOIN_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
142 + echo "const bitcoinCashTestWalletSeeds = '${{ secrets.BITCOIN_CASH_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
143 + echo "const polygonTestWalletSeeds = '${{ secrets.POLYGON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
144 + echo "const solanaTestWalletSeeds = '${{ secrets.SOLANA_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
145 + echo "const tronTestWalletSeeds = '${{ secrets.TRON_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
146 + echo "const nanoTestWalletSeeds = '${{ secrets.NANO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
147 + echo "const wowneroTestWalletSeeds = '${{ secrets.WOWNERO_TEST_WALLET_SEEDS }}';" >> lib/.secrets.g.dart
148 + echo "const moneroTestWalletReceiveAddress = '${{ secrets.MONERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
149 + echo "const bitcoinTestWalletReceiveAddress = '${{ secrets.BITCOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
150 + echo "const ethereumTestWalletReceiveAddress = '${{ secrets.ETHEREUM_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
151 + echo "const litecoinTestWalletReceiveAddress = '${{ secrets.LITECOIN_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
152 + echo "const bitcoinCashTestWalletReceiveAddress = '${{ secrets.BITCOIN_CASH_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
153 + echo "const polygonTestWalletReceiveAddress = '${{ secrets.POLYGON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
154 + echo "const solanaTestWalletReceiveAddress = '${{ secrets.SOLANA_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
155 + echo "const tronTestWalletReceiveAddress = '${{ secrets.TRON_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
156 + echo "const nanoTestWalletReceiveAddress = '${{ secrets.NANO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
157 + echo "const wowneroTestWalletReceiveAddress = '${{ secrets.WOWNERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
158 + echo "const moneroTestWalletBlockHeight = '${{ secrets.MONERO_TEST_WALLET_BLOCK_HEIGHT }}';" >> lib/.secrets.g.dart
159 + - name: prepare monero_c and cache
160 + run: |
161 + export MONEROC_HASH=$(cat scripts/prepare_moneroc.sh | grep 'git checkout' | xargs | awk '{ print $3 }')
162 + echo MONEROC_HASH=$MONEROC_HASH >> /etc/environment
163 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/moneroc-$MONEROC_HASH/monero_c"
164 + pushd scripts
165 + ln -s "$MONEROC_CACHE_DIR_ROOT/moneroc-$MONEROC_HASH/monero_c"
166 + ./prepare_moneroc.sh
167 + popd
168 + pushd scripts/monero_c
169 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/built" || true
170 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/built" || true
171 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/built" || true
172 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/sources" || true
173 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/sources" || true
174 + mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/sources" || true
175 +
176 + rm -rf "$PWD/contrib/depends/built" "$PWD/monero/contrib/depends/built" "$PWD/wownero/contrib/depends/built"
177 + rm -rf "$PWD/contrib/depends/sources" "$PWD/monero/contrib/depends/sources" "$PWD/wownero/contrib/depends/sources"
178 + mkdir -p contrib/depends || true
179 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/built" "$PWD/contrib/depends/built"
180 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/built" "$PWD/monero/contrib/depends/built"
181 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/built" "$PWD/wownero/contrib/depends/built"
182 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/sources" "$PWD/contrib/depends/sources"
183 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/sources" "$PWD/monero/contrib/depends/sources"
184 + ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/sources" "$PWD/wownero/contrib/depends/sources"
185 + popd
186 +
187 + - name: Execute Build and Setup Commands
188 + run: |
189 + pushd scripts/linux
190 + source ./app_env.sh cakewallet
191 + ./app_config.sh
192 + popd
193 +
194 + - name: Build monero_c
195 + run: |
196 + pushd scripts/linux/
197 + source ./app_env.sh cakewallet
198 + ./build_monero_all.sh
199 + popd
200 +
201 + - name: Install Flutter dependencies
202 + run: |
203 + flutter pub get
204
187 - - name: Rename app
205 + - name: Build generated code
206 + run: |
207 + ./model_generator.sh async
208 +
209 + - name: Generate localization
210 run: |
189 - echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
211 + dart run tool/generate_localization.dart
212
191 - - name: Build
213 + - name: Build linux
214 run: |
193 - cd /opt/android/cake_wallet
215 flutter build linux --release
216
196 - - name: Prepare release zip file
217 + - name: Compress release
218 run: |
198 - cd /opt/android/cake_wallet/build/linux/x64/release
199 - zip -r ${{env.BRANCH_NAME}}.zip bundle
219 + pushd build/linux/x64/release
220 + zip -r cakewallet_linux.zip bundle
221 + popd
222
201 - - name: Upload Artifact
223 + - name: Upload Artifact to github
224 uses: kittaakos/upload-artifact-as-is@v0
225 with:
204 - path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
226 + path: ${{ github.workspace }}/build/linux/x64/release/cakewallet_linux.zip
227 +
228 + - name: Prepare virtual desktop
229 + if: ${{ contains(github.event.head_commit.message, 'run tests') }}
230 + run: |
231 + nohup Xvfb :99 -screen 0 720x1280x16 &
232 + echo DISPLAY=:99 | sudo tee -a $GITHUB_ENV
233 + dbus-daemon --system --fork
234 + nohup NetworkManager &
235 + nohup ffmpeg -framerate 60 -video_size 720x1280 -f x11grab -i :99 -c:v libx264 -c:a aac /opt/screen_grab.mkv &
236 +
237 + # Note for people adding tests:
238 + # - Tests are ran on Linux, with some things being mocked out.
239 + # - Screen recording is being provided for the entire length of the test, you can download it in github articats.
240 + # - Screen recordeding is encrypted, look at step "Stop screen recording, encrypt and upload", and add your key if you want
241 + # Reason for encryption is the fact that we restore the wallet from seed, and we don't want to leak that, while there
242 + # isn't much in those wallets anyway, we still wouldn't like to leak it to anyone who is able to access github.
243
206 -# Just as an artifact would be enough
207 -# - name: Send Test APK
208 -# continue-on-error: true
209 -# uses: adrey/slack-file-upload-action@1.0.5
210 -# with:
211 -# token: ${{ secrets.SLACK_APP_TOKEN }}
212 -# path: /opt/android/cake_wallet/build/linux/x64/release/${{env.BRANCH_NAME}}.zip
213 -# channel: ${{ secrets.SLACK_APK_CHANNEL }}
214 -# title: "${{ env.BRANCH_NAME }}_linux.zip"
215 -# filename: ${{ env.BRANCH_NAME }}_linux.zip
216 -# initial_comment: ${{ github.event.head_commit.message }}
244 + - name: Test [confirm_seeds_flow_test]
245 + if: ${{ contains(github.event.head_commit.message, 'run tests') }}
246 + timeout-minutes: 20
247 + run: |
248 + xmessage -timeout 30 "confirm_seeds_flow_test" &
249 + rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet
250 + exec timeout --signal=SIGKILL 900 flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test_suites/confirm_seeds_flow_test.dart
251 + - name: Test [create_wallet_flow_test]
252 + if: ${{ contains(github.event.head_commit.message, 'run tests') }}
253 + timeout-minutes: 20
254 + run: |
255 + xmessage -timeout 30 "create_wallet_flow_test" &
256 + rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet
257 + exec timeout --signal=SIGKILL 900 flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test_suites/create_wallet_flow_test.dart
258 + - name: Test [exchange_flow_test]
259 + if: ${{ contains(github.event.head_commit.message, 'run tests') }}
260 + timeout-minutes: 20
261 + run: |
262 + xmessage -timeout 30 "exchange_flow_test" &
263 + rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet
264 + exec timeout --signal=SIGKILL 900 flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test_suites/exchange_flow_test.dart
265 + - name: Test [restore_wallet_through_seeds_flow_test]
266 + if: ${{ contains(github.event.head_commit.message, 'run tests') }}
267 + timeout-minutes: 20
268 + run: |
269 + xmessage -timeout 30 "restore_wallet_through_seeds_flow_test" &
270 + rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet
271 + exec timeout --signal=SIGKILL 900 flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test_suites/restore_wallet_through_seeds_flow_test.dart
272 + - name: Stop screen recording, encrypt and upload
273 + if: always()
274 + run: |
275 + if [[ ! -f "/opt/screen_grab.mkv" ]];
276 + then
277 + exit 0;
278 + fi
279 + killall ffmpeg
280 + sleep 5
281 + killall -9 ffmpeg || true
282 + sleep 5
283 + # Feel free to add your own public key if you wish
284 + gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 6B3199AD9B3D23B8 # konstantin@cakewallet.com
285 + gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 35C8DBAFB8D9ACAC # cyjan@mrcyjanek.net
286 + gpg --trust-model always --encrypt --output /opt/screen_grab.mkv.gpg \
287 + --recipient 6B3199AD9B3D23B8 \
288 + --recipient 35C8DBAFB8D9ACAC \
289 + /opt/screen_grab.mkv
290 + rm /opt/screen_grab.mkv
291 + mv /opt/screen_grab.mkv.gpg ./screen_grab.mkv.gpg
292 + - name: Upload Artifact to github
293 + if: always()
294 + continue-on-error: true
295 + uses: kittaakos/upload-artifact-as-is@v0
296 + with:
297 + path: ${{ github.workspace }}/screen_grab.mkv.gpg
cw_monero/lib/api/wallet.dart
+3 -1
@@ -9,6 +9,8 @@ import 'package:flutter/foundation.dart';
9 import 'package:monero/monero.dart' as monero;
10 import 'package:mutex/mutex.dart';
11
12 +bool debugMonero = false;
13 +
14 int getSyncingHeight() {
15 // final height = monero.MONERO_cw_WalletListener_height(getWlptr());
16 final h2 = monero.Wallet_blockChainHeight(wptr!);
@@ -132,7 +134,7 @@ Future<bool> setupNodeSync(
134 }
135 }
136
135 - if (kDebugMode) {
137 + if (kDebugMode && debugMonero) {
138 monero.Wallet_init3(
139 wptr!, argv0: '',
140 defaultLogBaseName: 'moneroc',
integration_test/components/common_test_cases.dart
+5
@@ -32,6 +32,11 @@ class CommonTestCases {
32 expect(textWidget, hasWidget ? findsOneWidget : findsNothing);
33 }
34
35 + void hasTextAtLestOnce(String text, {bool hasWidget = true}) {
36 + final textWidget = find.text(text);
37 + expect(textWidget, hasWidget ? findsAny : findsNothing);
38 + }
39 +
40 void hasType<T>() {
41 final typeWidget = find.byType(T);
42 expect(typeWidget, findsOneWidget);
integration_test/components/common_test_flows.dart
+27 -7
@@ -1,3 +1,5 @@
1 +import 'dart:io';
2 +
3 import 'package:cake_wallet/entities/seed_type.dart';
4 import 'package:cake_wallet/reactions/bip39_wallet_utils.dart';
5 import 'package:cake_wallet/wallet_types.g.dart';
@@ -85,6 +87,7 @@ class CommonTestFlows {
87 await _confirmPreSeedInfo();
88
89 await _confirmWalletDetails();
90 + await _commonTestCases.defaultSleepTime();
91 }
92
93 //* ========== Handles flow from welcome to restoring wallet from seeds ===============
@@ -168,8 +171,8 @@ class CommonTestFlows {
171 await _walletListPageRobot.navigateToRestoreWalletOptionsPage();
172 await _commonTestCases.defaultSleepTime();
173
171 - await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
172 - await _commonTestCases.defaultSleepTime();
174 + if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
175 + if (!Platform.isLinux) await _commonTestCases.defaultSleepTime();
176
177 await _selectWalletTypeForWallet(walletType);
178 await _commonTestCases.defaultSleepTime();
@@ -180,6 +183,7 @@ class CommonTestFlows {
183
184 //* ========== Handles setting up pin code for wallet on first install ===============
185 Future<void> setupPinCodeForWallet(List<int> pin) async {
186 + if (Platform.isLinux) return;
187 // ----------- SetupPinCode Page -------------
188 // Confirm initial defaults - Widgets to be displayed etc
189 await _setupPinCodeRobot.isSetupPinCodePage();
@@ -212,7 +216,7 @@ class CommonTestFlows {
216
217 await _welcomePageRobot.navigateToRestoreWalletPage();
218
215 - await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
219 + if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
220
221 await _selectWalletTypeForWallet(walletTypeToRestore);
222 }
@@ -234,6 +238,12 @@ class CommonTestFlows {
238
239 await _newWalletPageRobot.generateWalletName();
240
241 + if (Platform.isLinux) {
242 + // manual pin input
243 + await _restoreFromSeedOrKeysPageRobot.enterPasswordForWalletRestore(CommonTestConstants.pin.join(""));
244 + await _restoreFromSeedOrKeysPageRobot.enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join(""));
245 + }
246 +
247 await _newWalletPageRobot.onNextButtonPressed();
248 }
249
@@ -252,11 +262,15 @@ class CommonTestFlows {
262
263 _walletSeedPageRobot.confirmWalletSeedReminderDisplays();
264
255 - await _walletSeedPageRobot.onCopySeedsButtonPressed();
256 -
257 - await _walletSeedPageRobot.onNextButtonPressed();
265 + // await _walletSeedPageRobot.onCopySeedsButtonPressed();
266
259 - await _walletSeedPageRobot.onConfirmButtonOnSeedAlertDialogPressed();
267 + await _walletSeedPageRobot.onSeedPageVerifyButtonPressed();
268 + // Turns out the popup about "Copied to clipboard" prevents
269 + //the button from being pressed on the first try, by just
270 + //tapping it again we fix it.
271 + // await _walletSeedPageRobot.onSeedPageVerifyButtonPressed();
272 +
273 + await _walletSeedPageRobot.onOpenWalletButtonPressed();
274 }
275
276 //* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Seeds Action
@@ -277,6 +291,12 @@ class CommonTestFlows {
291 .enterBlockHeightForWalletRestore(secrets.moneroTestWalletBlockHeight);
292 }
293
294 + if (Platform.isLinux) {
295 + // manual pin input
296 + await _restoreFromSeedOrKeysPageRobot.enterPasswordForWalletRestore(CommonTestConstants.pin.join(""));
297 + await _restoreFromSeedOrKeysPageRobot.enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join(""));
298 + }
299 +
300 await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed();
301 }
302
integration_test/funds_related_tests.dart
+5
@@ -67,6 +67,11 @@ void main() {
67 await authPageRobot.enterPinCode(CommonTestConstants.pin);
68 }
69
70 + final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
71 + if (onAuthPageDesktop) {
72 + await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
73 + }
74 +
75 // ----------- Exchange Confirm Page -------------
76 await exchangeConfirmPageRobot.isExchangeConfirmPage();
77
integration_test/robots/auth_page_robot.dart
+5
@@ -20,6 +20,11 @@ class AuthPageRobot extends PinCodeWidgetRobot {
20 return hasPin;
21 }
22
23 + bool onAuthPageDesktop() {
24 + final hasWalletPasswordInput = find.byKey(ValueKey('enter_wallet_password'));
25 + return hasWalletPasswordInput.tryEvaluate();
26 + }
27 +
28 Future<void> isAuthPage() async {
29 await commonTestCases.isSpecificPage<AuthPage>();
30 }
integration_test/robots/pin_code_widget_robot.dart
+14
@@ -24,6 +24,20 @@ class PinCodeWidgetRobot {
24 commonTestCases.hasValueKey('pin_code_button_0_key');
25 }
26
27 + Future<void> enterPassword(String password, {int pumpDuration = 100}) async {
28 + await commonTestCases.enterText(
29 + password,
30 + 'enter_wallet_password',
31 + );
32 + await tester.pumpAndSettle();
33 + await commonTestCases.tapItemByKey(
34 + 'unlock',
35 + );
36 + await tester.pumpAndSettle();
37 +
38 + await commonTestCases.defaultSleepTime();
39 + }
40 +
41 Future<void> enterPinCode(List<int> pinCode, {int pumpDuration = 100}) async {
42 for (int pin in pinCode) {
43 await commonTestCases.tapItemByKey(
integration_test/robots/restore_from_seed_or_key_robot.dart
+19 -1
@@ -1,7 +1,9 @@
1 import 'package:cake_wallet/entities/seed_type.dart';
2 import 'package:cake_wallet/generated/i18n.dart';
3 import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
4 +import 'package:cake_wallet/src/widgets/seed_widget.dart';
5 import 'package:cake_wallet/src/widgets/validable_annotated_editable_text.dart';
6 +import 'package:flutter/material.dart';
7 import 'package:flutter_test/flutter_test.dart';
8
9 import '../components/common_test_cases.dart';
@@ -65,12 +67,28 @@ class RestoreFromSeedOrKeysPageRobot {
67
68 Future<void> enterSeedPhraseForWalletRestore(String text) async {
69 ValidatableAnnotatedEditableTextState seedTextState =
68 - await tester.state(find.byType(ValidatableAnnotatedEditableText));
70 + await tester.state(find.byType(ValidatableAnnotatedEditableText));
71
72 seedTextState.widget.controller.text = text;
73 await tester.pumpAndSettle();
74 }
75
76 + Future<void> enterPasswordForWalletRestore(String text) async {
77 + await commonTestCases.enterText(
78 + text,
79 + 'password',
80 + );
81 + await tester.pumpAndSettle();
82 + }
83 +
84 + Future<void> enterPasswordRepeatForWalletRestore(String text) async {
85 + await commonTestCases.enterText(
86 + text,
87 + 'repeat_wallet_password',
88 + );
89 + await tester.pumpAndSettle();
90 + }
91 +
92 Future<void> enterBlockHeightForWalletRestore(String blockHeight) async {
93 await commonTestCases.enterText(
94 blockHeight,
integration_test/robots/send_page_robot.dart
+8 -25
@@ -183,32 +183,15 @@ class SendPageRobot {
183 }
184
185 Future<void> _handleAuthPage() async {
186 - tester.printToConsole('Inside _handleAuth');
187 - await tester.pump();
188 - tester.printToConsole('starting auth checks');
189 -
190 - final authPage = authPageRobot.onAuthPage();
191 -
192 - tester.printToConsole('hasAuth:$authPage');
193 -
194 - if (authPage) {
195 - await tester.pump();
196 - tester.printToConsole('Starting inner _handleAuth loop checks');
197 -
198 - try {
199 - await authPageRobot.enterPinCode(CommonTestConstants.pin, pumpDuration: 500);
200 - tester.printToConsole('Auth done');
201 -
202 - await tester.pump();
186 + final onAuthPage = authPageRobot.onAuthPage();
187 + if (onAuthPage) {
188 + await authPageRobot.enterPinCode(CommonTestConstants.pin);
189 + }
190
204 - tester.printToConsole('Auth pump done');
205 - } catch (e) {
206 - tester.printToConsole('Auth failed, retrying');
207 - await tester.pump();
208 - _handleAuthPage();
209 - }
191 + final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
192 + if (onAuthPageDesktop) {
193 + await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
194 }
211 - await tester.pump();
195 }
196
197 Future<void> handleSendResult() async {
@@ -221,7 +204,7 @@ class SendPageRobot {
204
205 tester.printToConsole('Has an Error in the handle: $hasError');
206
224 - int maxRetries = 20;
207 + int maxRetries = 3;
208 int retries = 0;
209
210 while (hasError && retries < maxRetries) {
integration_test/robots/wallet_seed_page_robot.dart
+12 -4
@@ -14,8 +14,13 @@ class WalletSeedPageRobot {
14 await commonTestCases.isSpecificPage<WalletSeedPage>();
15 }
16
17 - Future<void> onNextButtonPressed() async {
18 - await commonTestCases.tapItemByKey('wallet_seed_page_next_button_key');
17 + Future<void> onSeedPageVerifyButtonPressed() async {
18 + await commonTestCases.tapItemByKey('wallet_seed_page_verify_seed_button_key');
19 + await commonTestCases.defaultSleepTime();
20 + }
21 +
22 + Future<void> onOpenWalletButtonPressed() async {
23 + await commonTestCases.tapItemByKey('wallet_seed_page_open_wallet_button_key');
24 await commonTestCases.defaultSleepTime();
25 }
26
@@ -38,11 +43,14 @@ class WalletSeedPageRobot {
43 final walletSeeds = walletSeedViewModel.seed;
44
45 commonTestCases.hasText(walletName);
41 - commonTestCases.hasText(walletSeeds);
46 + final seedList = walletSeeds.trim().split(" ");
47 + for (final seedWord in seedList) {
48 + commonTestCases.hasTextAtLestOnce(seedWord);
49 + }
50 }
51
52 void confirmWalletSeedReminderDisplays() {
45 - commonTestCases.hasText(S.current.seed_reminder);
53 + commonTestCases.hasText(S.current.cake_seeds_save_disclaimer);
54 }
55
56 Future<void> onSaveSeedsButtonPressed() async {
integration_test/test_suites/confirm_seeds_flow_test.dart
+8
@@ -1,9 +1,13 @@
1 +import 'dart:io';
2 +
3 import 'package:cake_wallet/wallet_types.g.dart';
4 import 'package:cw_core/wallet_type.dart';
5 import 'package:flutter/foundation.dart';
6 +import 'package:flutter/material.dart';
7 import 'package:flutter_test/flutter_test.dart';
8 import 'package:integration_test/integration_test.dart';
9
10 +import '../components/common_test_cases.dart';
11 import '../components/common_test_constants.dart';
12 import '../components/common_test_flows.dart';
13 import '../robots/auth_page_robot.dart';
@@ -95,6 +99,10 @@ Future<void> _confirmSeedsFlowForWalletType(
99 await authPageRobot.enterPinCode(CommonTestConstants.pin);
100 }
101
102 + final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
103 + if (onAuthPageDesktop) {
104 + await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
105 + }
106 await tester.pumpAndSettle();
107
108 await walletKeysAndSeedPageRobot.isWalletKeysAndSeedPage();
integration_test/test_suites/exchange_flow_test.dart
+4
@@ -56,6 +56,10 @@ void main() {
56 await authPageRobot.enterPinCode(CommonTestConstants.pin);
57 }
58
59 + final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
60 + if (onAuthPageDesktop) {
61 + await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
62 + }
63 await exchangeConfirmPageRobot.onSavedTradeIdButtonPressed();
64 await exchangeTradePageRobot.onGotItButtonPressed();
65 });
integration_test/test_suites/restore_wallet_through_seeds_flow_test.dart
+3
@@ -1,4 +1,7 @@
1 +import 'dart:io';
2 +
3 import 'package:cake_wallet/wallet_types.g.dart';
4 +import 'package:cw_core/utils/print_verbose.dart';
5 import 'package:cw_core/wallet_type.dart';
6 import 'package:flutter/material.dart';
7 import 'package:flutter_test/flutter_test.dart';
integration_test_runner.sh
+5
@@ -1,4 +1,5 @@
1 #!/bin/bash
2 +export DESKTOP_FORCE_MOBILE="Y"
3
4 declare -a targets
5 declare -a passed_tests
@@ -12,6 +13,10 @@ done < <(find integration_test/test_suites -name "*.dart" -type f -print0)
13 # Run each test and collect results
14 for target in "${targets[@]}"
15 do
16 + if [[ "x$REMOVE_DATA_DIRECTORY" == "xY" ]];
17 + then
18 + rm -rf ~/.local/share/com.example.cake_wallet ~/Documents/cake_wallet
19 + fi
20 echo "Running test: $target"
21 if flutter drive \
22 --driver=test_driver/integration_test.dart \
lib/src/screens/new_wallet/new_wallet_page.dart
+2
@@ -221,6 +221,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
221 ),
222 if (_walletNewVM.hasWalletPassword) ...[
223 TextFormField(
224 + key: ValueKey('password'),
225 onChanged: (value) => _walletNewVM.walletPassword = value,
226 controller: _passwordController,
227 textAlign: TextAlign.center,
@@ -257,6 +258,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
258 ),
259 ),
260 TextFormField(
261 + key: ValueKey('repeat_wallet_password'),
262 onChanged: (value) => _walletNewVM.repeatedWalletPassword = value,
263 controller: _repeatedPasswordController,
264 textAlign: TextAlign.center,
lib/src/screens/restore/wallet_restore_from_keys_form.dart
+2
@@ -148,12 +148,14 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
148 ),
149 if (widget.displayWalletPassword)
150 ...[Container(
151 + key: ValueKey('password'),
152 padding: EdgeInsets.only(top: 20.0),
153 child: BaseTextFormField(
154 controller: passwordTextEditingController,
155 hintText: S.of(context).password,
156 obscureText: true)),
157 Container(
158 + key: ValueKey('repeat_wallet_password'),
159 padding: EdgeInsets.only(top: 20.0),
160 child: BaseTextFormField(
161 controller: repeatedPasswordTextEditingController,
lib/src/screens/restore/wallet_restore_from_seed_form.dart
+2
@@ -223,12 +223,14 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
223 ),
224 if (widget.displayWalletPassword)
225 ...[BaseTextFormField(
226 + key: ValueKey('password'),
227 controller: passwordTextEditingController,
228 hintText: S
229 .of(context)
230 .password,
231 obscureText: true),
232 BaseTextFormField(
233 + key: ValueKey('repeat_wallet_password'),
234 controller: repeatedPasswordTextEditingController,
235 hintText: S
236 .of(context)
lib/src/screens/wallet_unlock/wallet_unlock_page.dart
+2
@@ -170,6 +170,7 @@ class WalletUnlockPageState extends AuthPageState<WalletUnlockPage> {
170 SizedBox(height: 24),
171 Form(
172 child: TextFormField(
173 + key: ValueKey('enter_wallet_password'),
174 onChanged: (value) => null,
175 controller: _passwordController,
176 textAlign: TextAlign.center,
@@ -205,6 +206,7 @@ class WalletUnlockPageState extends AuthPageState<WalletUnlockPage> {
206 ),
207 ),
208 Padding(
209 + key: ValueKey('unlock'),
210 padding: EdgeInsets.only(bottom: 24),
211 child: Observer(
212 builder: (_) => LoadingPrimaryButton(
linux/my_application.cc
+5 -2
@@ -46,8 +46,11 @@ static void my_application_activate(GApplication* application) {
46 } else {
47 gtk_window_set_title(window, "Cake Wallet");
48 }
49 -
50 - gtk_window_set_default_size(window, 1280, 720);
49 + if (getenv("DESKTOP_FORCE_MOBILE")) {
50 + gtk_window_set_default_size(window, 720, 1280);
51 + } else {
52 + gtk_window_set_default_size(window, 1280, 720);
53 + }
54 gtk_widget_show(GTK_WIDGET(window));
55
56 g_autoptr(FlDartProject) project = fl_dart_project_new();
model_generator.sh
+20 -14
@@ -1,18 +1,24 @@
1 #!/bin/bash
2 set -x -e
3
4 -cd cw_core; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
5 -cd cw_evm; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
6 -cd cw_monero; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
7 -cd cw_bitcoin; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
8 -cd cw_haven; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
9 -cd cw_nano; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
10 -cd cw_bitcoin_cash; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
11 -cd cw_solana; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
12 -cd cw_tron; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
13 -cd cw_wownero; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd ..
14 -cd cw_polygon; flutter pub get; cd ..
15 -cd cw_ethereum; flutter pub get; cd ..
16 -cd cw_mweb && flutter pub get && cd ..
17 -dart run build_runner build --delete-conflicting-outputs
4 +for cwcoin in cw_{core,evm,monero,bitcoin,haven,nano,bitcoin_cash,solana,tron,wownero}
5 +do
6 + if [[ "x$1" == "xasync" ]];
7 + then
8 + bash -c "cd $cwcoin; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .." &
9 + else
10 + bash -c "cd $cwcoin; flutter pub get; dart run build_runner build --delete-conflicting-outputs; cd .."
11 + fi
12 +done
13 +for cwcoin in cw_{polygon,ethereum,mwebd};
14 +do
15 + if [[ "x$1" == "xasync" ]];
16 + then
17 + bash -c "cd $cwcoin; flutter pub get; cd .." &
18 + else
19 + bash -c "cd $cwcoin; flutter pub get; cd .."
20 + fi
21 +done
22
23 +flutter pub get
24 +dart run build_runner build --delete-conflicting-outputs
scripts/android/.gitignore new
+1
@@ -0,0 +1 @@
1 +mwebd
\ No newline at end of file
scripts/android/build_monero_all.sh
+15 -45
@@ -8,50 +8,20 @@ cd "$(dirname "$0")"
8
9 NPROC="-j$(nproc)"
10
11 -if [[ "x$(uname)" == "xDarwin" ]];
12 -then
13 - USE_DOCKER="ON"
14 - NPROC="-j1"
15 -fi
16 -
11 ../prepare_moneroc.sh
12
19 -if [[ ! "x$RUNNER_OS" == "x" ]];
20 -then
21 - REMOVE_CACHES=ON
22 -fi
23 -
24 -# NOTE: -j1 is intentional. Otherwise you will run into weird behaviour on macos
25 -if [[ ! "x$USE_DOCKER" == "x" ]];
26 -then
27 - for COIN in monero wownero;
28 - do
29 - pushd ../monero_c
30 - docker run --platform linux/amd64 -v$HOME/.cache/ccache:/root/.ccache -v$PWD:$PWD -w $PWD --rm -it git.mrcyjanek.net/mrcyjanek/debian:buster bash -c "git config --global --add safe.directory '*'; apt update; apt install -y ccache gcc g++ libtinfo5 gperf; ./build_single.sh ${COIN} x86_64-linux-android $NPROC"
31 - # docker run --platform linux/amd64 -v$PWD:$PWD -w $PWD --rm -it git.mrcyjanek.net/mrcyjanek/debian:buster bash -c "git config --global --add safe.directory '*'; apt update; apt install -y ccache gcc g++ libtinfo5 gperf; ./build_single.sh ${COIN} i686-linux-android $NPROC"
32 - docker run --platform linux/amd64 -v$HOME/.cache/ccache:/root/.ccache -v$PWD:$PWD -w $PWD --rm -it git.mrcyjanek.net/mrcyjanek/debian:buster bash -c "git config --global --add safe.directory '*'; apt update; apt install -y ccache gcc g++ libtinfo5 gperf; ./build_single.sh ${COIN} armv7a-linux-androideabi $NPROC"
33 - docker run --platform linux/amd64 -v$HOME/.cache/ccache:/root/.ccache -v$PWD:$PWD -w $PWD --rm -it git.mrcyjanek.net/mrcyjanek/debian:buster bash -c "git config --global --add safe.directory '*'; apt update; apt install -y ccache gcc g++ libtinfo5 gperf; ./build_single.sh ${COIN} aarch64-linux-android $NPROC"
34 - popd
35 - done
36 -else
37 - for COIN in monero wownero;
38 - do
39 - pushd ../monero_c
40 - env -i ./build_single.sh ${COIN} x86_64-linux-android $NPROC
41 - [[ ! "x$REMOVE_CACHES" == "x" ]] && rm -rf ${COIN}/contrib/depends/x86_64-linux-android
42 - # ./build_single.sh ${COIN} i686-linux-android $NPROC
43 - # [[ ! "x$REMOVE_CACHES" == "x" ]] && rm -rf ${COIN}/contrib/depends/i686-linux-android
44 - env -i ./build_single.sh ${COIN} armv7a-linux-androideabi $NPROC
45 - [[ ! "x$REMOVE_CACHES" == "x" ]] && rm -rf ${COIN}/contrib/depends/armv7a-linux-androideabi
46 - env -i ./build_single.sh ${COIN} aarch64-linux-android $NPROC
47 - [[ ! "x$REMOVE_CACHES" == "x" ]] && rm -rf ${COIN}/contrib/depends/aarch64-linux-android
48 -
49 - popd
50 - unxz -f ../monero_c/release/${COIN}/x86_64-linux-android_libwallet2_api_c.so.xz
51 -
52 - unxz -f ../monero_c/release/${COIN}/armv7a-linux-androideabi_libwallet2_api_c.so.xz
53 -
54 - unxz -f ../monero_c/release/${COIN}/aarch64-linux-android_libwallet2_api_c.so.xz
55 - [[ ! "x$REMOVE_CACHES" == "x" ]] && rm -rf ${COIN}/contrib/depends/{built,sources}
56 - done
57 -fi
13 +for COIN in monero wownero;
14 +do
15 + pushd ../monero_c
16 + for target in {x86_64,aarch64}-linux-android armv7a-linux-androideabi
17 + do
18 + if [[ -f "release/${COIN}/${target}_libwallet2_api_c.so" ]];
19 + then
20 + echo "file exist, not building monero_c for ${COIN}/$target.";
21 + else
22 + env -i ./build_single.sh ${COIN} $target $NPROC
23 + unxz -f ../monero_c/release/${COIN}/${target}_libwallet2_api_c.so.xz
24 + fi
25 + done
26 + popd
27 +done
\ No newline at end of file
scripts/android/build_mwebd.sh
+1 -4
@@ -16,7 +16,4 @@ cd mwebd
16 git reset --hard 555349415f76a42ec5c76152b64c4ab9aabc448f
17 gomobile bind -target=android -androidapi 21 .
18 mkdir -p ../../../cw_mweb/android/libs/
19 -mv ./mwebd.aar $_
20 -# cleanup:
21 -cd ..
22 -rm -rf mwebd
\ No newline at end of file
19 +cp ./mwebd.aar $_
\ No newline at end of file
scripts/linux/Dockerfile.linux new
+148
@@ -0,0 +1,148 @@
1 +# Usage:
2 +# docker build . -f Dockerfile.linux -t ghcr.io/cake-tech/cake_wallet:main-linux
3 +# docker push ghcr.io/cake-tech/cake_wallet:main-linux
4 +
5 +FROM --platform=linux/amd64 docker.io/debian:12
6 +
7 +LABEL org.opencontainers.image.source=https://github.com/cake-tech/cake_wallet
8 +
9 +ENV GOLANG_VERSION=1.23.4
10 +# comes from https://developer.android.com/studio/#command-tools
11 +ENV ANDROID_SDK_TOOLS_VERSION=11076708
12 +# https://developer.android.com/studio/releases/build-tools
13 +ENV ANDROID_PLATFORM_VERSION=34
14 +ENV ANDROID_BUILD_TOOLS_VERSION=34.0.0
15 +
16 +ENV FLUTTER_VERSION=3.24.0
17 +
18 +# If we ever need to migrate the home directory...
19 +RUN sed -i 's|^root:[^:]*:[^:]*:[^:]*:[^:]*:/root:|root:x:0:0:root:/root:|' /etc/passwd
20 +# mkdir -p /root && rm -rf /root && cp -a /root /root
21 +ENV HOME=/root
22 +# Heavily inspired by cirrusci images
23 +# https://github.com/cirruslabs/docker-images-android/blob/master/sdk/tools/Dockerfile
24 +# https://github.com/cirruslabs/docker-images-android/blob/master/sdk/34/Dockerfile
25 +# https://github.com/cirruslabs/docker-images-android/blob/master/sdk/34-ndk/Dockerfile
26 +# https://github.com/cirruslabs/docker-images-flutter/blob/master/sdk/Dockerfile
27 +
28 +ENV ANDROID_HOME=/opt/android-sdk-linux \
29 + LANG=en_US.UTF-8 \
30 + LC_ALL=en_US.UTF-8 \
31 + LANGUAGE=en_US:en
32 +
33 +ENV ANDROID_SDK_ROOT=$ANDROID_HOME \
34 + PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/emulator
35 +
36 +RUN set -o xtrace \
37 + && cd /opt \
38 + && apt-get update \
39 + && apt-get upgrade -y \
40 + && apt-get install -y jq \
41 + && apt-get install -y default-jdk \
42 + && apt-get install -y sudo wget zip unzip git openssh-client curl bc software-properties-common build-essential ruby-full ruby-bundler libstdc++6 libpulse0 libglu1-mesa locales lcov libsqlite3-dev --no-install-recommends \
43 + # for x86 emulators
44 + && apt-get install -y libxtst6 libnss3-dev libnspr4 libxss1 libatk-bridge2.0-0 libgtk-3-0 libgdk-pixbuf2.0-0 \
45 + && apt-get install -y -qq xxd \
46 + && apt-get install -y lftp \
47 + && apt-get install -qq -y sqlite3 libsqlite3-dev \
48 + # linux desktop dependencies
49 + && apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev \
50 + # monero_c dependencies
51 + && apt-get install -y ccache build-essential autoconf libtool gperf llvm \
52 + # extra stuff for KVM
53 + && apt-get install -y udev qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils \
54 + # for linux tests
55 + && apt-get install -y xvfb network-manager ffmpeg x11-utils \
56 + && rm -rf /var/lib/apt/lists/* \
57 + && sh -c 'echo "en_US.UTF-8 UTF-8" > /etc/locale.gen' \
58 + && locale-gen \
59 + && update-locale LANG=en_US.UTF-8
60 +
61 +# install nodejs for actions
62 +RUN apt-get update && \
63 + apt-get install -y curl && \
64 + curl -fsSL https://deb.nodesource.com/setup_23.x | bash - && \
65 + apt-get install -y nodejs && \
66 + apt-get clean && \
67 + rm -rf /var/lib/apt/lists/*
68 +
69 +RUN wget https://go.dev/dl/go${GOLANG_VERSION}.linux-amd64.tar.gz &&\
70 + rm -rf /usr/local/go &&\
71 + tar -C /usr/local -xzf go${GOLANG_VERSION}.linux-amd64.tar.gz
72 +
73 +ENV PATH=${PATH}:/usr/local/go/bin:${HOME}/go/bin
74 +ENV GOROOT=/usr/local/go
75 +ENV GOPATH=${HOME}/go
76 +RUN go install golang.org/x/mobile/cmd/gomobile@latest
77 +RUN gomobile init
78 +
79 +RUN wget -q https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip -O android-sdk-tools.zip \
80 + && mkdir -p ${ANDROID_HOME}/cmdline-tools/ \
81 + && unzip -q android-sdk-tools.zip -d ${ANDROID_HOME}/cmdline-tools/ \
82 + && mv ${ANDROID_HOME}/cmdline-tools/cmdline-tools ${ANDROID_HOME}/cmdline-tools/latest \
83 + && chown -R root:root $ANDROID_HOME \
84 + && rm android-sdk-tools.zip \
85 + && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \
86 + && yes | sdkmanager --licenses \
87 + && wget -O /usr/bin/android-wait-for-emulator https://raw.githubusercontent.com/travis-ci/travis-cookbooks/master/community-cookbooks/android-sdk/files/default/android-wait-for-emulator \
88 + && chmod +x /usr/bin/android-wait-for-emulator \
89 + && sdkmanager platform-tools \
90 + && mkdir -p ${HOME}/.android \
91 + && touch ${HOME}/.android/repositories.cfg \
92 + && git config --global user.email "czarek@cakewallet.com" \
93 + && git config --global user.name "CakeWallet CI"
94 +
95 +# emulator is not available on linux/arm64 (https://issuetracker.google.com/issues/227219818)
96 +RUN if [ $(uname -m) == "x86_64" ]; then sdkmanager emulator ; fi
97 +
98 +# Extra dependencies to not download them for cake wallet build
99 +RUN yes | sdkmanager \
100 + "platforms;android-$ANDROID_PLATFORM_VERSION" \
101 + "build-tools;$ANDROID_BUILD_TOOLS_VERSION" \
102 + "platforms;android-33" \
103 + "build-tools;33.0.2" \
104 + "build-tools;33.0.1" \
105 + "build-tools;33.0.0" \
106 + "build-tools;35.0.0"
107 +
108 +ENV ANDROID_NDK_VERSION=27.2.12479018
109 +
110 +# Extra ndk dependency for sp_scanner
111 +RUN yes | sdkmanager "ndk;$ANDROID_NDK_VERSION" \
112 + "ndk;27.0.12077973"
113 +
114 +# https://github.com/ReactiveCircus/android-emulator-runner dependencies for tests
115 +RUN yes | sdkmanager "system-images;android-29;default;x86" \
116 + "system-images;android-29;default;x86_64" \
117 + "system-images;android-31;default;x86_64" \
118 + "platforms;android-29"
119 +
120 +# fake the KVM status so android emulator doesn't complain (that much)
121 +RUN (addgroup kvm || true) && \
122 + adduser root kvm && \
123 + mkdir -p /etc/udev/rules.d/ && \
124 + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | tee /etc/udev/rules.d/99-kvm4all.rules
125 +
126 +ENV PATH=${HOME}/.cargo/bin:${PATH}
127 +
128 +RUN curl https://sh.rustup.rs -sSf | bash -s -- -y && \
129 + cargo install cargo-ndk && \
130 + for target in aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android x86_64-unknown-linux-gnu; \
131 + do \
132 + rustup target add --toolchain stable $target; \
133 + done
134 +
135 +
136 +ENV HOME=${HOME}
137 +ENV FLUTTER_HOME=${HOME}/sdks/flutter/${FLUTTER_VERSION}
138 +ENV FLUTTER_ROOT=$FLUTTER_HOME
139 +
140 +ENV PATH=${PATH}:${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin
141 +
142 +RUN git clone --depth 1 --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git ${FLUTTER_HOME}
143 +
144 +RUN yes | flutter doctor --android-licenses \
145 + && flutter doctor \
146 + && chown -R root:root ${FLUTTER_HOME}
147 +
148 +RUN flutter precache
scripts/linux/build_monero_all.sh
+11 -7
@@ -1,9 +1,5 @@
1 #!/bin/bash
2
3 -
4 -. ./config.sh
5 -
6 -
3 set -x -e
4
5 cd "$(dirname "$0")"
@@ -15,7 +11,15 @@ NPROC="-j$(nproc)"
11 for COIN in monero wownero;
12 do
13 pushd ../monero_c
18 - ./build_single.sh ${COIN} $(gcc -dumpmachine) $NPROC
14 + for target in x86_64-linux-gnu
15 + do
16 + if [[ -f "release/${COIN}/${target}_libwallet2_api_c.so" ]];
17 + then
18 + echo "file exist, not building monero_c for ${COIN}/$target.";
19 + else
20 + ./build_single.sh ${COIN} $target $NPROC
21 + unxz -f ../monero_c/release/${COIN}/${target}_libwallet2_api_c.so.xz
22 + fi
23 + done
24 popd
20 - unxz -f ../monero_c/release/${COIN}/$(gcc -dumpmachine)_libwallet2_api_c.so.xz
21 -done
25 +done
\ No newline at end of file
scripts/prepare_moneroc.sh
+2 -2
@@ -4,9 +4,9 @@ set -x -e
4
5 cd "$(dirname "$0")"
6
7 -if [[ ! -d "monero_c" ]];
7 +if [[ ! -d "monero_c/.git" ]];
8 then
9 - git clone https://github.com/mrcyjanek/monero_c --branch master
9 + git clone https://github.com/mrcyjanek/monero_c --branch master monero_c
10 cd monero_c
11 git checkout af5277f96073917185864d3596e82b67bee54e78
12 git reset --hard
scripts/windows/.gitignore new
+1
@@ -0,0 +1 @@
1 +actions-runner
\ No newline at end of file
scripts/windows/Dockerfile.windows new
+68
@@ -0,0 +1,68 @@
1 +# Usage:
2 +# docker build . -f Dockerfile.windows -t ghcr.io/cake-tech/cake_wallet:main-windows
3 +# docker push ghcr.io/cake-tech/cake_wallet:main-windows
4 +
5 +FROM mcr.microsoft.com/windows/servercore:ltsc2022
6 +
7 +ENV FLUTTER_VERSION=3.24.0
8 +ENV GIT_VERSION=2.47.1
9 +ENV VS_INSTALLED_DIR="C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools"
10 +ENV PATH="C:\Users\ContainerAdministrator\.cargo\bin;C:\ProgramData\chocolatey\bin;C:\flutter\flutter\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Users\ContainerAdministrator\AppData\Local\Microsoft\WindowsApps"
11 +ENV RUNNER_VERSION=2.321.0
12 +ENV RUNNER_URL=https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-win-x64-${RUNNER_VERSION}.zip
13 +ENV RUNNER_WORKDIR=_work
14 +
15 +RUN powershell -Command \
16 + curl.exe -L https://aka.ms/vs/17/release/vc_redist.x64.exe -o vc_redist.x64.exe ; \
17 + Start-Process -Wait -FilePath .\vc_redist.x64.exe -ArgumentList '/quiet', '/install' ; \
18 + Remove-Item -Force vc_redist.x64.exe
19 +
20 +RUN powershell -Command \
21 + $GIT_VERSION = [Environment]::GetEnvironmentVariable('GIT_VERSION'); \
22 + curl.exe -L https://github.com/git-for-windows/git/releases/download/v$($GIT_VERSION).windows.1/Git-$($GIT_VERSION)-64-bit.exe -o git_installer.exe ; \
23 + Start-Process -Wait -FilePath .\git_installer.exe -ArgumentList '/SILENT', '/NOICONS' ; \
24 + Remove-Item -Force git_installer.exe
25 +
26 +RUN powershell -NoProfile -ExecutionPolicy Bypass -Command \
27 + Set-ExecutionPolicy RemoteSigned -Scope Process; \
28 + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; \
29 + Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicP -OutFile install.ps1; \
30 + powershell -NoProfile -ExecutionPolicy Bypass -File install.ps1; \
31 + Remove-Item -Force install.ps1
32 +
33 +RUN choco install -y visualstudio2022community
34 +RUN choco install -y visualstudio2022-workload-nativedesktop
35 +RUN choco install -y nodejs
36 +RUN choco install -y go
37 +RUN choco install -y 7zip
38 +
39 +RUN powershell -Command \
40 + curl.exe -L https://win.rustup.rs -o rustup-init.exe; \
41 + Start-Process -Wait -FilePath .\rustup-init.exe -ArgumentList "-y"; \
42 + Remove-Item -Force .\rustup-init.exe
43 +
44 +RUN powershell -Command \
45 + curl.exe -L https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -o C:\Windows\System32\nuget.exe
46 +
47 +RUN powershell -Command \
48 + $FLUTTER_VERSION = [Environment]::GetEnvironmentVariable('FLUTTER_VERSION'); \
49 + curl.exe -L https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_windows_$($FLUTTER_VERSION)-stable.zip -o flutter.zip ; \
50 + 7z x flutter.zip -oC:\flutter -bsp1 -bse1 ; \
51 + Remove-Item -Force flutter.zip
52 +
53 +RUN flutter precache
54 +
55 +WORKDIR C:\\actions-runner
56 +
57 +RUN powershell -Command \
58 + curl.exe -L $env:RUNNER_URL -o 'actions-runner.zip'; \
59 + 7z x actions-runner.zip -oC:\actions-runner -bsp1 -bse1 ; \
60 + Remove-Item -Path 'actions-runner.zip'
61 +
62 +COPY actions-runner/.credentials /actions-runner/.credentials
63 +COPY actions-runner/.credentials_rsaparams /actions-runner/.credentials_rsaparams
64 +COPY actions-runner/.runner /actions-runner/.runner
65 +
66 +COPY ci_entrypoint.ps1 /actions-runner/ci_entrypoint.ps1
67 +
68 +ENTRYPOINT ["powershell", "-File", "ci_entrypoint.ps1"]
\ No newline at end of file
scripts/windows/ci_entrypoint.ps1 new
+5
@@ -0,0 +1,5 @@
1 +$runnerDir = "C:\actions-runner"
2 +$runCmd = "$runnerDir\run.cmd"
3 +
4 +Write-Host "Starting the runner..."
5 +& $runCmd
\ No newline at end of file
scripts/windows/ci_register.ps1 new
+30
@@ -0,0 +1,30 @@
1 +# Variables for paths and config
2 +$runnerDir = "C:\actions-runner"
3 +$configCmd = "$runnerDir\config.cmd"
4 +$runCmd = "$runnerDir\run.cmd"
5 +
6 +# Check required environment variables
7 +if (-not $env:RUNNER_TOKEN) {
8 + Write-Error "RUNNER_TOKEN is not set. Exiting."
9 + exit 1
10 +}
11 +if (-not $env:RUNNER_REPO_URL) {
12 + Write-Error "RUNNER_REPO_URL is not set. Exiting."
13 + exit 1
14 +}
15 +$env:RUNNER_NAME = "windows-amd64-cake"
16 +$env:RUNNER_WORKDIR = "_work"
17 +
18 +# Register the runner
19 +Write-Host "Registering the runner..."
20 +Write-Host "--url $env:RUNNER_REPO_URL"
21 +Write-Host "--token $env:RUNNER_TOKEN"
22 +Write-Host "--name $env:RUNNER_NAME"
23 +Write-Host "--work $env:RUNNER_WORKDIR"
24 +
25 +& $configCmd --url $env:RUNNER_REPO_URL `
26 + --token $env:RUNNER_TOKEN `
27 + --name $env:RUNNER_NAME `
28 + --work $env:RUNNER_WORKDIR `
29 + --unattended `
30 + --replace
\ No newline at end of file