name: Core on: pull_request: types: - opened - reopened - synchronize # branch head update - labeled workflow_dispatch: schedule: - cron: '15 23 * * *' # every day @ 23:15 permissions: id-token: write # for fetching the OIDC token contents: read # for actions/checkout pull-requests: write # For dflook comments on PR env: PULL_COMMENT: | |core UI changes|device test|click test|persistence test| |---------------|-----------|----------|----------------| |T2T1 Model T | [test](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_device_test/index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_device_test/differing_screens.html)) [main](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_device_test/master_index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_device_test/master_diff.html)) | [test](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_click_test/index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_click_test/differing_screens.html)) [main](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_click_test/master_index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_click_test/master_diff.html)) | [test](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_persistence_test/index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_persistence_test/differing_screens.html)) [main](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_persistence_test/master_index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T2T1-en-core_persistence_test/master_diff.html))|| |T3B1 Safe 3 | [test](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_device_test/index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_device_test/differing_screens.html)) [main](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_device_test/master_index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_device_test/master_diff.html)) | [test](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_click_test/index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_click_test/differing_screens.html)) [main](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_click_test/master_index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_click_test/master_diff.html)) | [test](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_persistence_test/index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_persistence_test/differing_screens.html)) [main](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_persistence_test/master_index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3B1-en-core_persistence_test/master_diff.html))|| |T3T1 | [test](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_device_test/index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_device_test/differing_screens.html)) [main](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_device_test/master_index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_device_test/master_diff.html)) | [test](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_click_test/index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_click_test/differing_screens.html)) [main](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_click_test/master_index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_click_test/master_diff.html)) | [test](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_persistence_test/index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_persistence_test/differing_screens.html)) [main](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_persistence_test/master_index.html)([screens](https://data.trezor.io/dev/firmware/ui_report/${{ github.run_id }}/T3T1-en-core_persistence_test/master_diff.html))|| |All | [main](https://data.trezor.io/dev/firmware/master_diff/${{ github.run_id }}/index.html)([screens](https://data.trezor.io/dev/firmware/master_diff/${{ github.run_id }}/master_diff.html)) || jobs: param: name: Determine pipeline parameters runs-on: ubuntu-latest outputs: test_lang: ${{ steps.set_vars.outputs.test_lang }} asan: ${{ steps.set_vars.outputs.asan }} steps: - id: set_vars name: Set variables run: | echo test_lang=${{ github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'translations') && '[\"en\", \"cs\", \"fr\", \"de\", \"es\", \"pt\"]' || '[\"en\"]' }} >> $GITHUB_OUTPUT echo asan=${{ github.event_name == 'schedule' && '[\"noasan\", \"asan\"]' || '[\"noasan\"]' }} >> $GITHUB_OUTPUT cat $GITHUB_OUTPUT core_firmware: name: Build firmware runs-on: ubuntu-latest strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] coins: [universal, btconly] type: ${{ fromJSON(github.event_name == 'schedule' && '["normal", "debuglink", "production"]' || '["normal", "debuglink"]') }} include: - model: D001 coins: universal type: normal env: TREZOR_MODEL: ${{ matrix.model == 'T2T1' && 'T' || matrix.model == 'D001' && 'DISC1' || matrix.model }} BITCOIN_ONLY: ${{ matrix.coins == 'universal' && '0' || '1' }} PYOPT: ${{ matrix.type == 'debuglink' && '0' || '1' }} PRODUCTION: ${{ matrix.type == 'production' && '1' || '0' }} steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core build_boardloader" if: matrix.coins == 'universal' && matrix.type != 'debuglink' - run: nix-shell --run "poetry run make -C core build_bootloader" if: matrix.coins == 'universal' && matrix.type != 'debuglink' - run: nix-shell --run "poetry run make -C core build_bootloader_ci" if: matrix.coins == 'universal' && matrix.type != 'debuglink' && matrix.model == 'T2T1' - run: nix-shell --run "poetry run make -C core build_prodtest" if: matrix.coins == 'universal' && matrix.type != 'debuglink' - run: nix-shell --run "poetry run make -C core build_firmware" - run: nix-shell --run "poetry run make -C core sizecheck" if: matrix.coins == 'universal' && matrix.type != 'debuglink' - run: nix-shell --run "poetry run ./tools/check-bitcoin-only core/build/firmware/firmware.bin" if: matrix.coins == 'btconly' && matrix.type != 'debuglink' - uses: actions/upload-artifact@v4 with: name: core-firmware-${{ matrix.model }}-${{ matrix.coins }}-${{ matrix.type }} path: | core/build/boardloader/*.bin core/build/bootloader/*.bin core/build/bootloader_ci/*.bin core/build/prodtest/*.bin core/build/firmware/firmware.elf core/build/firmware/firmware-*.bin retention-days: 7 core_emu: name: Build emu runs-on: ubuntu-latest needs: param strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] coins: [universal, btconly] # type: [normal, debuglink] type: [debuglink] asan: ${{ fromJSON(needs.param.outputs.asan) }} exclude: - type: normal asan: asan env: TREZOR_MODEL: ${{ matrix.model == 'T2T1' && 'T' || matrix.model }} BITCOIN_ONLY: ${{ matrix.coins == 'universal' && '0' || '1' }} PYOPT: ${{ matrix.type == 'debuglink' && '0' || '1' }} ADDRESS_SANITIZER: ${{ matrix.asan == 'asan' && '1' || '0' }} LSAN_OPTIONS: "suppressions=../../asan_suppressions.txt" steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core build_bootloader_emu" if: matrix.coins == 'universal' - run: nix-shell --run "poetry run make -C core build_unix_frozen" - run: cp core/build/unix/trezor-emu-core core/build/unix/trezor-emu-core-${{ matrix.model }}-${{ matrix.coins }} - uses: actions/upload-artifact@v4 with: name: core-emu-${{ matrix.model }}-${{ matrix.coins }}-${{ matrix.type }}-${{ matrix.asan }} path: | core/build/unix/trezor-emu-core* core/build/bootloader_emu/bootloader.elf retention-days: 7 core_emu_arm: if: github.event_name == 'schedule' name: Build emu arm runs-on: ubuntu-latest-arm64 needs: param strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] coins: [universal] type: [debuglink] asan: [noasan] exclude: - type: normal asan: asan env: TREZOR_MODEL: ${{ matrix.model == 'T2T1' && 'T' || matrix.model }} BITCOIN_ONLY: ${{ matrix.coins == 'universal' && '0' || '1' }} PYOPT: ${{ matrix.type == 'debuglink' && '0' || '1' }} ADDRESS_SANITIZER: ${{ matrix.asan == 'asan' && '1' || '0' }} LSAN_OPTIONS: "suppressions=../../asan_suppressions.txt" steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core build_bootloader_emu" if: matrix.coins == 'universal' - run: nix-shell --run "poetry run make -C core build_unix_frozen" - run: mv core/build/unix/trezor-emu-core core/build/unix/trezor-emu-arm-core-${{ matrix.model }}-${{ matrix.coins }} - uses: actions/upload-artifact@v4 with: name: core-emu-arm-${{ matrix.model }}-${{ matrix.coins }}-${{ matrix.type }}-${{ matrix.asan }} path: | core/build/unix/trezor-emu-* core/build/bootloader_emu/bootloader.elf retention-days: 2 core_unit_python_test: name: Python unit tests runs-on: ubuntu-latest needs: param strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] asan: ${{ fromJSON(needs.param.outputs.asan) }} env: TREZOR_MODEL: ${{ matrix.model == 'T2T1' && 'T' || matrix.model }} ADDRESS_SANITIZER: ${{ matrix.asan == 'asan' && '1' || '0' }} LSAN_OPTIONS: "suppressions=../../asan_suppressions.txt" steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core build_unix" - run: nix-shell --run "poetry run make -C core test" core_unit_rust_test: name: Rust unit tests runs-on: ubuntu-latest needs: - param - core_emu strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] asan: ${{ fromJSON(needs.param.outputs.asan) }} env: TREZOR_MODEL: ${{ matrix.model == 'T2T1' && 'T' || matrix.model }} ADDRESS_SANITIZER: ${{ matrix.asan == 'asan' && '1' || '0' }} RUSTC_BOOTSTRAP: ${{ matrix.asan == 'asan' && '1' || '0' }} RUSTFLAGS: ${{ matrix.asan == 'asan' && '-Z sanitizer=address' || '' }} LSAN_OPTIONS: "suppressions=../../asan_suppressions.txt" steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core build_unix_frozen" - run: nix-shell --run "poetry run make -C core clippy" - run: nix-shell --run "poetry run make -C core test_rust" core_rust_client_test: name: Rust trezor-client tests runs-on: ubuntu-latest needs: core_emu strategy: fail-fast: false matrix: model: [T2T1, T3B1] steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: name: core-emu-${{ matrix.model }}-universal-debuglink-noasan path: core/build - run: chmod +x core/build/unix/trezor-emu-core* - uses: ./.github/actions/environment - run: nix-shell --run "poetry run core/emu.py --headless -q --temporary-profile --slip0014 --command cargo test --manifest-path rust/trezor-client/Cargo.toml" # Device tests for Core. Running device tests and also comparing screens # with the expected UI result. # See artifacts for a comprehensive report of UI. # See [docs/tests/ui-tests](../tests/ui-tests.md) for more info. core_device_test: name: Device tests runs-on: ubuntu-latest needs: - param - core_emu strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] coins: [universal, btconly] asan: ${{ fromJSON(needs.param.outputs.asan) }} lang: ${{ fromJSON(needs.param.outputs.test_lang) }} env: TREZOR_PROFILING: ${{ matrix.asan == 'noasan' && '1' || '0' }} TREZOR_MODEL: ${{ matrix.model == 'T2T1' && 'T' || matrix.model }} TREZOR_PYTEST_SKIP_ALTCOINS: ${{ matrix.coins == 'btconly' && '1' || '0' }} ADDRESS_SANITIZER: ${{ matrix.asan == 'asan' && '1' || '0' }} PYTEST_TIMEOUT: ${{ matrix.asan == 'asan' && 600 || 400 }} ACTIONS_DO_UI_TEST: ${{ matrix.coins == 'universal' && matrix.asan == 'noasan' }} TEST_LANG: ${{ matrix.lang }} steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: name: core-emu-${{ matrix.model }}-${{ matrix.coins }}-debuglink-${{ matrix.asan }} path: core/build - run: chmod +x core/build/unix/trezor-emu-core* - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core ${{ env.ACTIONS_DO_UI_TEST == 'true' && 'test_emu_ui_multicore' || 'test_emu' }}" - run: tail -n50 tests/trezor.log || true if: failure() - uses: actions/upload-artifact@v4 with: name: core-test-device-${{ matrix.model }}-${{ matrix.coins }}-${{ matrix.lang }}-${{ matrix.asan }} path: tests/trezor.log retention-days: 7 if: always() - uses: ./.github/actions/ui-report with: model: ${{ matrix.model }} lang: ${{ matrix.lang }} status: ${{ job.status }} if: ${{ always() && env.ACTIONS_DO_UI_TEST == 'true' }} continue-on-error: true - uses: ./.github/actions/ui-comment if: ${{ failure() && env.ACTIONS_DO_UI_TEST == 'true' }} - uses: ./.github/actions/upload-coverage # Click tests - UI. # See [docs/tests/click-tests](../tests/click-tests.md) for more info. core_click_test: name: Click tests runs-on: ubuntu-latest needs: - param - core_emu timeout-minutes: 90 strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] asan: ${{ fromJSON(needs.param.outputs.asan) }} lang: ${{ fromJSON(needs.param.outputs.test_lang) }} env: TREZOR_PROFILING: ${{ matrix.asan == 'noasan' && '1' || '0' }} # MULTICORE: 4 # more could interfere with other jobs PYTEST_TIMEOUT: 400 TEST_LANG: ${{ matrix.lang }} steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }} path: core/build - run: chmod +x core/build/unix/trezor-emu-core* - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core test_emu_click_ui" if: ${{ matrix.asan == 'noasan' }} - run: nix-shell --run "poetry run make -C core test_emu_click" if: ${{ matrix.asan == 'asan' }} - uses: actions/upload-artifact@v4 with: name: core-test-click-${{ matrix.model }}-${{ matrix.lang }}-${{ matrix.asan }} path: tests/trezor.log retention-days: 7 if: always() - uses: ./.github/actions/ui-report with: model: ${{ matrix.model }} lang: ${{ matrix.lang }} status: ${{ job.status }} if: always() continue-on-error: true - uses: ./.github/actions/upload-coverage # Upgrade tests. # See [docs/tests/upgrade-tests](../tests/upgrade-tests.md) for more info. core_upgrade_test: name: Upgrade tests runs-on: ubuntu-latest needs: - param - core_emu strategy: fail-fast: false matrix: # FIXME: T3B1 https://github.com/trezor/trezor-firmware/issues/2724 # FIXME: T3T1 https://github.com/trezor/trezor-firmware/issues/3595 model: [T2T1] asan: ${{ fromJSON(needs.param.outputs.asan) }} env: TREZOR_UPGRADE_TEST: core PYTEST_TIMEOUT: 400 steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }} path: core/build - run: chmod +x core/build/unix/trezor-emu-core* - uses: ./.github/actions/environment - run: nix-shell --run "tests/download_emulators.sh" - run: nix-shell --run "poetry run pytest tests/upgrade_tests" # Persistence tests - UI. core_persistence_test: name: Persistence tests runs-on: ubuntu-latest needs: - param - core_emu timeout-minutes: 30 strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] asan: ${{ fromJSON(needs.param.outputs.asan) }} env: TREZOR_PROFILING: ${{ matrix.asan == 'noasan' && '1' || '0' }} PYTEST_TIMEOUT: 400 steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }} path: core/build - run: chmod +x core/build/unix/trezor-emu-core* - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core test_emu_persistence_ui" if: ${{ matrix.asan == 'noasan' }} - run: nix-shell --run "poetry run make -C core test_emu_persistence" if: ${{ matrix.asan == 'asan' }} - uses: ./.github/actions/ui-report with: model: ${{ matrix.model }} lang: en status: ${{ job.status }} if: always() continue-on-error: true - uses: ./.github/actions/upload-coverage core_hwi_test: name: HWI tests if: false # XXX currently failing continue-on-error: true runs-on: ubuntu-latest needs: core_emu strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: name: core-emu-${{ matrix.model }}-universal-debuglink-noasan path: core/build - run: chmod +x core/build/unix/trezor-emu-core* - uses: ./.github/actions/environment # XXX poetry maybe not needed - run: nix-shell --run "git clone --depth=1 https://github.com/bitcoin-core/HWI.git" # see python_test for explanation of _PYTHON_SYSCONFIGDATA_NAME - run: nix-shell --arg fullDeps true --run "unset _PYTHON_SYSCONFIGDATA_NAME && cd HWI && poetry install && poetry run ./test/test_trezor.py --model_t ../core/build/unix/trezor-emu-core bitcoind" - uses: actions/upload-artifact@v4 with: name: core-test-hwi-${{ matrix.model }} path: HWI/trezor-t-emulator.stdout retention-days: 7 core_memory_profile: name: Memory allocation report runs-on: ubuntu-latest env: TREZOR_MODEL: T TREZOR_MEMPERF: 1 PYOPT: 0 PYTEST_TIMEOUT: 900 steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core build_unix_frozen" - run: nix-shell --run "poetry run make -C core test_emu" - run: nix-shell --run "mkdir core/prof/memperf-html" - run: nix-shell --run "poetry run core/tools/alloc.py --alloc-data=core/src/alloc_data.txt html core/prof/memperf-html" - uses: actions/upload-artifact@v4 with: name: core-memperf-${{ matrix.model }} path: | tests/trezor.log core/prof/memperf-html retention-days: 7 if: always() # Flash size profiling # Finds out how much flash space we have left in the firmware build # Fails if the free space is less than certain threshold core_flash_size_check: name: Flash size check runs-on: ubuntu-latest needs: core_firmware strategy: fail-fast: false matrix: model: [T2T1] # FIXME: checker.py lacks awareness of U5 flash layout steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: name: core-firmware-${{ matrix.model }}-universal-normal # FIXME: s/normal/debuglink/ path: core/build - uses: ./.github/actions/environment - run: nix-shell --run "poetry run core/tools/size/checker.py core/build/firmware/firmware.elf" # Compares the current flash space with the situation in the current master # Fails if the new binary is significantly larger than the master one # (the threshold is defined in the script, currently 5kb). # Also generates a report with the current situation core_flash_size_compare: name: Flash size comparison runs-on: ubuntu-latest needs: core_firmware strategy: fail-fast: false matrix: model: [T2T1] # FIXME: T2T1 url is hardcoded in compare_master.py steps: - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - uses: actions/download-artifact@v4 with: name: core-firmware-${{ matrix.model }}-universal-normal path: core/build - uses: ./.github/actions/environment - run: nix-shell --run "poetry run core/tools/size/compare_master.py core/build/firmware/firmware.elf -r firmware_elf_size_report.txt" - uses: actions/upload-artifact@v4 with: name: core-test-flash-size-${{ matrix.model }} path: firmware_elf_size_report.txt retention-days: 7 # Monero tests. core_monero_test: name: Monero test runs-on: ubuntu-latest needs: - param - core_emu strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] asan: ${{ fromJSON(needs.param.outputs.asan) }} env: TREZOR_PROFILING: ${{ matrix.asan == 'noasan' && '1' || '0' }} PYTEST_TIMEOUT: 400 steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }} path: core/build - run: chmod +x core/build/unix/trezor-emu-core* - uses: cachix/install-nix-action@v23 with: nix_path: nixpkgs=channel:nixos-unstable # see python_test job for _PYTHON_SYSCONFIGDATA_NAME explanation - run: nix-shell --arg fullDeps true --run "unset _PYTHON_SYSCONFIGDATA_NAME && poetry install" - run: nix-shell --arg fullDeps true --run "unset _PYTHON_SYSCONFIGDATA_NAME && poetry run make -C core test_emu_monero" - uses: actions/upload-artifact@v4 with: name: core-test-monero-${{ matrix.model }}-${{ matrix.asan }} path: | tests/trezor.log core/tests/trezor_monero_tests.log retention-days: 7 if: always() - uses: ./.github/actions/upload-coverage # Tests for U2F and HID. core_u2f_test: name: U2F test runs-on: ubuntu-latest needs: - param - core_emu strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] asan: ${{ fromJSON(needs.param.outputs.asan) }} env: TREZOR_PROFILING: ${{ matrix.asan == 'noasan' && '1' || '0' }} PYTEST_TIMEOUT: 400 steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }} path: core/build - run: chmod +x core/build/unix/trezor-emu-core* - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C tests/fido_tests/u2f-tests-hid" - run: nix-shell --run "poetry run make -C core test_emu_u2f" - uses: actions/upload-artifact@v4 with: name: core-test-u2f-${{ matrix.model }}-${{ matrix.asan }} path: tests/trezor.log retention-days: 7 if: always() - uses: ./.github/actions/upload-coverage # FIDO2 device tests. core_fido2_test: name: FIDO2 test runs-on: ubuntu-latest needs: - param - core_emu strategy: fail-fast: false matrix: model: [T2T1, T3T1] # XXX T3B1 https://github.com/trezor/trezor-firmware/issues/2724 asan: ${{ fromJSON(needs.param.outputs.asan) }} env: TREZOR_PROFILING: ${{ matrix.asan == 'noasan' && '1' || '0' }} PYTEST_TIMEOUT: 400 steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }} path: core/build - run: chmod +x core/build/unix/trezor-emu-core* - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core test_emu_fido2" - uses: actions/upload-artifact@v4 with: name: core-test-fido2-${{ matrix.model }}-${{ matrix.asan }} path: | tests/trezor.log retention-days: 7 if: always() - uses: ./.github/actions/upload-coverage core_coverage_report: name: Coverage report runs-on: ubuntu-latest needs: - core_click_test - core_persistence_test - core_device_test - core_monero_test - core_u2f_test - core_fido2_test strategy: fail-fast: false matrix: model: [T2T1, T3B1, T3T1] # T3B1 fails due to https://github.com/trezor/trezor-firmware/issues/3280 # remove after single global layout is implemented (or bug above fixed): exclude: - model: T3B1 env: COVERAGE_THRESHOLD: ${{ matrix.model == 'T2T1' && 78 || 77 }} steps: - uses: actions/checkout@v4 with: submodules: recursive - uses: actions/download-artifact@v4 with: pattern: core-coverage-${{ matrix.model }}-* path: core merge-multiple: true - uses: ./.github/actions/environment - run: nix-shell --run "poetry run make -C core coverage" - uses: actions/upload-artifact@v4 with: name: core-coverage-report-${{ matrix.model }} path: core/htmlcov retention-days: 7 include-hidden-files: true core_ui_main: name: UI diff from main branch runs-on: ubuntu-latest needs: - core_click_test - core_persistence_test - core_device_test continue-on-error: true steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: pattern: ui-records-* merge-multiple: true - uses: ./.github/actions/environment - name: Configure aws credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::538326561891:role/gh_actions_deploy_dev_firmware_data aws-region: eu-west-1 continue-on-error: true - run: "for F in screens_*.tar; do tar xvf $F; done || true" - run: nix-shell --run "poetry run python -m tests.ui_tests.reporting master-diff TT TR" - run: | mv tests/ui_tests/reports/master_diff . if [ "${{ job.status }}" = "success" ]; then cp .github/actions/ui-report/success.png master_diff/status.png else cp .github/actions/ui-report/failure.png master_diff/status.png fi - name: Upload diff from main branch run: | aws s3 sync --no-progress master_diff s3://data.trezor.io/dev/firmware/master_diff/${{ github.run_id }} continue-on-error: true core_ui_comment: name: Post comment with UI diff URLs runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} - run: | git fetch origin main git diff --quiet origin/main...HEAD -- tests/ui_tests/fixtures.json || echo "FIXTURES_CHANGED=$?" >> $GITHUB_OUTPUT id: check-fixtures-changed - uses: ./.github/actions/ui-comment # TODO: always run if comment already exists if: ${{ steps.check-fixtures-changed.outputs.FIXTURES_CHANGED == '1' }} core_upload_emu: name: Upload emulator binaries if: github.event_name == 'schedule' runs-on: ubuntu-latest needs: - core_emu - core_emu_arm steps: - uses: actions/download-artifact@v4 with: pattern: core-emu*debuglink-noasan merge-multiple: true - name: Configure aws credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::538326561891:role/gh_actions_deploy_dev_firmware_data aws-region: eu-west-1 continue-on-error: true - run: | rm unix/trezor-emu-core aws s3 sync --no-progress unix s3://data.trezor.io/dev/firmware/emu-nightly # Connect # TODO: core_connect_test