name: Cake Wallet Linux permissions: contents: read packages: write on: [pull_request] defaults: run: shell: bash jobs: PR_test_build: # Fork PRs don't have access to repository secrets, so the generated # lib/.secrets.g.dart would be empty and the build fails to compile. # Skip for forks, mirroring the Android workflow's internal-build guard. if: github.event.pull_request.head.repo.fork == false runs-on: [Linux, amd64, forlinux] container: image: ghcr.io/cake-tech/cake_wallet:debian13-flutter3.41.9-ndkr28-go1.24.1-ruststablenightly env: STORE_PASS: test@cake_wallet KEY_PASS: test@cake_wallet MONEROC_CACHE_DIR_ROOT: /opt/generic_cache BRANCH_NAME: ${{ github.head_ref || github.ref_name }} DESKTOP_FORCE_MOBILE: Y volumes: - /opt/cw_cache_linux/root/.cache:/root/.cache - /opt/cw_cache_linux/root/.ccache:/root/.ccache - /opt/cw_cache_linux/root/.pub-cache/:/root/.pub-cache - /opt/cw_cache_linux/root/go/pkg:/root/go/pkg - /opt/cw_cache_linux/opt/generic_cache:/opt/generic_cache - /var/run/docker.sock:/var/run/docker.sock steps: - name: Fix github actions messing up $HOME... run: "echo HOME=/root | sudo tee -a $GITHUB_ENV" - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: configure git run: | git config --global --add safe.directory '*' git config --global user.email "ci@cakewallet.com" git config --global user.name "CakeWallet CI" - name: Get the full commit message run: | FULL_MESSAGE="$(git log -1 --pretty=%B)" echo "message<> $GITHUB_ENV echo "$FULL_MESSAGE" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV - name: Add secrets run: | touch cw_bitcoin/lib/.secrets.g.dart touch cw_evm/lib/.secrets.g.dart touch cw_solana/lib/.secrets.g.dart touch cw_core/lib/.secrets.g.dart touch cw_nano/lib/.secrets.g.dart touch cw_tron/lib/.secrets.g.dart echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const blinkApiKey = '${{ secrets.BLINK_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart echo "const chainStackApiKey = '${{ secrets.CHAIN_STACK_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart echo "const breezApiKey = '${{ secrets.BREEZ_API_KEY }}';" >> cw_bitcoin/lib/.secrets.g.dart echo "${{ secrets.MAIN_SECRETS_FILE }}" | base64 --decode > lib/.secrets.g.dart - name: Build dependencies utilizing ghcr cache run: | env \ CW_DOCKER_REGISTRY=ghcr.io/cake-tech/cake_wallet \ CW_DOCKER_USE_CLOUD=true \ ./scripts/linux/docker/build.sh - name: Execute Build and Setup Commands run: | pushd scripts/linux source ./app_env.sh cakewallet ./app_config.sh popd - name: Install Flutter dependencies run: | flutter pub get - name: Build generated code run: | ./model_generator.sh - name: Generate localization run: | dart run tool/generate_localization.dart - name: Compile graphics run: | ./compile_graphics.sh - name: Build linux run: | flutter build linux --dart-define=hasDevOptions=true --release - name: Compress release run: | pushd build/linux/x64/release zip -r cakewallet_linux.zip bundle popd - name: Upload Artifact to github uses: actions/upload-artifact@v4 with: path: ${{ github.workspace }}/build/linux/x64/release/cakewallet_linux.zip name: cakewallet_linux - name: Prepare virtual desktop if: ${{ contains(env.message, 'run tests') }} run: | nohup Xvfb :99 -screen 0 720x1280x16 & echo DISPLAY=:99 | sudo tee -a $GITHUB_ENV dbus-daemon --system --fork nohup NetworkManager & nohup ffmpeg -framerate 60 -video_size 720x1280 -f x11grab -i :99 -c:v libx264 -c:a aac /opt/screen_grab.mkv & # Note for people adding tests: # - Tests are ran on Linux, with some things being mocked out. # - Screen recording is being provided for the entire length of the test, you can download it in github articats. # - Screen recordeding is encrypted, look at step "Stop screen recording, encrypt and upload", and add your key if you want # Reason for encryption is the fact that we restore the wallet from seed, and we don't want to leak that, while there # isn't much in those wallets anyway, we still wouldn't like to leak it to anyone who is able to access github. - name: Test [confirm_seeds_flow_test] if: ${{ contains(env.message, 'run tests') }} timeout-minutes: 20 run: | xmessage -timeout 30 "confirm_seeds_flow_test" & rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet exec timeout --signal=SIGKILL 900 flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test_suites/confirm_seeds_flow_test.dart - name: Test [create_wallet_flow_test] if: ${{ contains(env.message, 'run tests') }} timeout-minutes: 20 run: | xmessage -timeout 30 "create_wallet_flow_test" & rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet exec timeout --signal=SIGKILL 900 flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test_suites/create_wallet_flow_test.dart # - name: Test [exchange_flow_test] # if: ${{ contains(env.message, 'run tests') }} # timeout-minutes: 20 # run: | # xmessage -timeout 30 "exchange_flow_test" & # rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet # exec timeout --signal=SIGKILL 900 flutter drive --driver=test_driver/integration_test.dart --target=integration_test/test_suites/exchange_flow_test.dart - name: Test [restore_wallet_through_seeds_flow_test] if: ${{ contains(env.message, 'run tests') }} timeout-minutes: 20 run: | xmessage -timeout 30 "restore_wallet_through_seeds_flow_test" & rm -rf ~/.local/share/com.example.cake_wallet/ ~/Documents/cake_wallet/ ~/cake_wallet 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 - name: Test [cw_core] timeout-minutes: 15 run: cd cw_core && flutter test - name: Test [cw_monero] timeout-minutes: 15 run: cd cw_monero && flutter test - name: Stop screen recording, encrypt and upload if: always() run: | if [[ ! -f "/opt/screen_grab.mkv" ]]; then exit 0; fi killall ffmpeg sleep 5 killall -9 ffmpeg || true sleep 5 # Feel free to add your own public key if you wish gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 6B3199AD9B3D23B8 # konstantin@cakewallet.com gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 35C8DBAFB8D9ACAC # cyjan@mrcyjanek.net gpg --trust-model always --encrypt --output /opt/screen_grab.mkv.gpg \ --recipient 6B3199AD9B3D23B8 \ --recipient 35C8DBAFB8D9ACAC \ /opt/screen_grab.mkv rm /opt/screen_grab.mkv mv /opt/screen_grab.mkv.gpg ./screen_grab.mkv.gpg - name: Upload Artifact to github if: always() continue-on-error: true uses: actions/upload-artifact@v4 with: path: ${{ github.workspace }}/screen_grab.mkv.gpg name: tests_screen_grab