diff --git a/.github/actions/rust-toolchain/action.yml b/.github/actions/rust-toolchain/action.yml new file mode 100644 index 000000000..03aef0df7 --- /dev/null +++ b/.github/actions/rust-toolchain/action.yml @@ -0,0 +1,123 @@ +name: rustup toolchain install +author: David Tolnay +description: Install the Rust toolchain +branding: + icon: activity + color: purple + +inputs: + toolchain: + description: Rust toolchain specification -- see https://rust-lang.github.io/rustup/concepts/toolchains.html#toolchain-specification + required: true + targets: + description: Comma-separated list of target triples to install for this toolchain + required: false + target: + description: Alias for `targets` + required: false + components: + description: Comma-separated list of components to be additionally installed + required: false + +outputs: + cachekey: + description: A short hash of the rustc version, appropriate for use as a cache key. "20220627a831" + value: ${{steps.rustc-version.outputs.cachekey}} + name: + description: Rustup's name for the selected version of the toolchain. "1.62.0" # suitable for use with `cargo +${{steps.toolchain.outputs.name}}` + value: ${{steps.parse.outputs.toolchain}} + +runs: + using: composite + steps: + - id: parse + run: | + : parse toolchain version + if [[ $toolchain =~ ^stable' '[0-9]+' '(year|month|week|day)s?' 'ago$ ]]; then + if [[ ${{runner.os}} == macOS ]]; then + echo "toolchain=1.$((($(date -v-$(sed 's/stable \([0-9]*\) \(.\).*/\1\2/' <<< $toolchain) +%s)/60/60/24-16569)/7/6))" >> $GITHUB_OUTPUT + else + echo "toolchain=1.$((($(date --date "${toolchain#stable }" +%s)/60/60/24-16569)/7/6))" >> $GITHUB_OUTPUT + fi + elif [[ $toolchain =~ ^stable' 'minus' '[0-9]+' 'releases?$ ]]; then + echo "toolchain=1.$((($(date +%s)/60/60/24-16569)/7/6-${toolchain//[^0-9]/}))" >> $GITHUB_OUTPUT + else + echo "toolchain=$toolchain" >> $GITHUB_OUTPUT + fi + env: + toolchain: ${{inputs.toolchain}} + shell: bash + + - id: flags + run: | + : construct rustup command line + echo "targets=$(for t in ${targets//,/ }; do echo -n ' --target' $t; done)" >> $GITHUB_OUTPUT + echo "components=$(for c in ${components//,/ }; do echo -n ' --component' $c; done)" >> $GITHUB_OUTPUT + echo "downgrade=${{inputs.toolchain == 'nightly' && inputs.components && ' --allow-downgrade' || ''}}" >> $GITHUB_OUTPUT + env: + targets: ${{inputs.targets || inputs.target || ''}} + components: ${{inputs.components}} + shell: bash + + - run: | + : install rustup if needed + if ! command -v rustup &>/dev/null; then + curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused --location --silent --show-error --fail "https://sh.rustup.rs" | sh -s -- --default-toolchain none -y + echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH + fi + if: runner.os != 'Windows' + shell: bash + + - name: rustup toolchain install ${{steps.parse.outputs.toolchain}} + run: rustup toolchain install ${{steps.parse.outputs.toolchain}}${{steps.flags.outputs.targets}}${{steps.flags.outputs.components}} --profile minimal${{steps.flags.outputs.downgrade}} --no-self-update + shell: bash + + - run: rustup default ${{steps.parse.outputs.toolchain}} + shell: bash + + - id: rustc-version + run: | + : create cachekey + DATE=$(rustc +${{steps.parse.outputs.toolchain}} --version --verbose | sed -ne 's/^commit-date: \(20[0-9][0-9]\)-\([01][0-9]\)-\([0-3][0-9]\)$/\1\2\3/p') + HASH=$(rustc +${{steps.parse.outputs.toolchain}} --version --verbose | sed -ne 's/^commit-hash: //p') + echo "cachekey=$(echo $DATE$HASH | head -c12)" >> $GITHUB_OUTPUT + shell: bash + + - run: | + : disable incremental compilation + if [ -z "${CARGO_INCREMENTAL+set}" ]; then + echo CARGO_INCREMENTAL=0 >> $GITHUB_ENV + fi + shell: bash + + - run: | + : enable colors in Cargo output + if [ -z "${CARGO_TERM_COLOR+set}" ]; then + echo CARGO_TERM_COLOR=always >> $GITHUB_ENV + fi + shell: bash + + - run: | + : enable Cargo sparse registry + # implemented in 1.66, stabilized in 1.68, made default in 1.70 + if [ -z "${CARGO_REGISTRIES_CRATES_IO_PROTOCOL+set}" -o -f "${{runner.temp}}"/.implicit_cargo_registries_crates_io_protocol ]; then + if rustc +${{steps.parse.outputs.toolchain}} --version --verbose | grep -q '^release: 1\.6[89]\.'; then + touch "${{runner.temp}}"/.implicit_cargo_registries_crates_io_protocol || true + echo CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse >> $GITHUB_ENV + elif rustc +${{steps.parse.outputs.toolchain}} --version --verbose | grep -q '^release: 1\.6[67]\.'; then + touch "${{runner.temp}}"/.implicit_cargo_registries_crates_io_protocol || true + echo CARGO_REGISTRIES_CRATES_IO_PROTOCOL=git >> $GITHUB_ENV + fi + fi + shell: bash + + - run: | + : work around spurious network errors in curl 8.0 + # https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/timeout.20investigation + if rustc +${{steps.parse.outputs.toolchain}} --version --verbose | grep -q '^release: 1\.7[01]\.'; then + echo CARGO_HTTP_MULTIPLEXING=false >> $GITHUB_ENV + fi + shell: bash + + - run: rustc +${{steps.parse.outputs.toolchain}} --version --verbose + shell: bash diff --git a/.github/workflows/validate_and_build.yaml b/.github/workflows/build.yaml similarity index 80% rename from .github/workflows/validate_and_build.yaml rename to .github/workflows/build.yaml index 796f8b94e..810803a4f 100644 --- a/.github/workflows/validate_and_build.yaml +++ b/.github/workflows/build.yaml @@ -3,44 +3,13 @@ # # validate_and_build.yaml - GitHub actions for Passport -name: Validate and Build +name: Build on: [push] jobs: - lint: - name: Lint + firmware: + name: Firmware runs-on: ubuntu-20.04 - services: - registry: - image: registry:2 - ports: - - 5000:5000 - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: docker/setup-buildx-action@v3 - with: - driver-opts: network=host - - uses: docker/build-push-action@v5 - with: - push: true - context: . - cache-from: type=gha - cache-to: type=gha - tags: localhost:5000/foundation-devices/passport2:latest - - uses: extractions/setup-just@69d82fb0233557aec017ef13706851d0694e0f1d - - run: echo "DOCKER_IMAGE=localhost:5000/foundation-devices/passport2:latest" >> $GITHUB_ENV - - - name: Lint the codebase - run: just lint - - build-firmware: - name: Build Firmware - runs-on: ubuntu-20.04 - needs: [lint] - strategy: matrix: build: @@ -69,7 +38,11 @@ jobs: cache-from: type=gha cache-to: type=gha tags: localhost:5000/foundation-devices/passport2:latest - - uses: extractions/setup-just@69d82fb0233557aec017ef13706851d0694e0f1d + - uses: ./.github/actions/rust-toolchain + with: + toolchain: 1.70.0 + targets: thumbv7em-none-eabihf + - run: cargo install just@1.23.0 --locked - run: | echo "DOCKER_IMAGE=localhost:5000/foundation-devices/passport2:latest" >> $GITHUB_ENV echo "SCREEN_MODE=$(echo "${{ matrix.build.screen }}" | tr a-z A-Z)" >> $GITHUB_ENV @@ -120,12 +93,12 @@ jobs: name: v${{env.version}}${{ matrix.build.hash_suffix }}-hashes.md path: ports/stm32/build-Passport/v${{env.version}}-beta${{ matrix.build.hash_suffix }}-hashes.md - build-bootloader: - name: Build Bootloader + bootloader: + name: Bootloader runs-on: ubuntu-20.04 - needs: [lint, build-firmware] + needs: [firmware] - # TODO: PASS1-665. + # TODO: SFT-1077. strategy: matrix: screen: ['color'] @@ -150,7 +123,11 @@ jobs: cache-from: type=gha cache-to: type=gha tags: localhost:5000/foundation-devices/passport2:latest - - uses: extractions/setup-just@69d82fb0233557aec017ef13706851d0694e0f1d + - uses: ./.github/actions/rust-toolchain + with: + toolchain: 1.70.0 + targets: thumbv7em-none-eabihf + - run: cargo install just@1.23.0 --locked - run: | echo "DOCKER_IMAGE=localhost:5000/foundation-devices/passport2:latest" >> $GITHUB_ENV echo "SCREEN_MODE=$(echo ${{ matrix.screen }} | tr a-z A-Z)" >> $GITHUB_ENV @@ -164,10 +141,10 @@ jobs: name: bootloader-${{ env.SCREEN_MODE }}.bin path: ports/stm32/boards/Passport/bootloader/arm/release/bootloader-${{ env.SCREEN_MODE }}.bin - build-simulator: - name: Build Simulator + simulator: + name: Simulator runs-on: ubuntu-20.04 - needs: [lint, build-firmware] + needs: [firmware] strategy: matrix: @@ -193,16 +170,19 @@ jobs: cache-from: type=gha cache-to: type=gha tags: localhost:5000/foundation-devices/passport2:latest - - uses: extractions/setup-just@69d82fb0233557aec017ef13706851d0694e0f1d + - uses: ./.github/actions/rust-toolchain + with: + toolchain: 1.70.0 + targets: thumbv7em-none-eabihf + - run: cargo install just@1.23.0 --locked - run: echo "DOCKER_IMAGE=localhost:5000/foundation-devices/passport2:latest" >> $GITHUB_ENV - name: Build run: just build-simulator ${{ matrix.screen }} build-tools: - name: Build Tools + name: Tools runs-on: ubuntu-20.04 - needs: [lint] services: registry: @@ -224,7 +204,11 @@ jobs: cache-from: type=gha cache-to: type=gha tags: localhost:5000/foundation-devices/passport2:latest - - uses: extractions/setup-just@69d82fb0233557aec017ef13706851d0694e0f1d + - uses: ./.github/actions/rust-toolchain + with: + toolchain: 1.70.0 + targets: thumbv7em-none-eabihf + - run: cargo install just@1.23.0 --locked - run: echo "DOCKER_IMAGE=localhost:5000/foundation-devices/passport2:latest" >> $GITHUB_ENV - name: Build diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 000000000..f3360a55d --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,81 @@ +# SPDX-FileCopyrightText: © 2024 Foundation Devices, Inc. +# SPDX-License-Identifier: GPL-3.0-or-later + +name: Lint +on: [push, pull_request] +jobs: + is-reuse-compliant: + name: Is REUSE compliant? + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: fsfe/reuse-action@v2 + + rust-code-compiles: + name: Rust code compiles? + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/rust-toolchain + with: + toolchain: 1.70.0 + targets: thumbv7em-none-eabihf + - run: | + cargo check --manifest-path extmod/foundation-rust/Cargo.toml + # Required by secp256k1-sys. + - run: sudo apt-get install -y gcc-arm-none-eabi + - run: | + cargo check --manifest-path extmod/foundation-rust/Cargo.toml \ + --target thumbv7em-none-eabihf + + is-the-rust-code-formatted: + name: Is the Rust code formatted? + needs: [rust-code-compiles] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/rust-toolchain + with: + toolchain: 1.70.0 + components: rustfmt + - run: | + cargo fmt --manifest-path extmod/foundation-rust/Cargo.toml \ + --all -- --check + + is-the-python-code-formatted: + name: Is the Python code formatted? + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: sudo apt-get install -y pycodestyle + - run: pycodestyle --statistics --exclude translations ports/stm32/boards/Passport + + is-foundation-header-up-to-date: + name: Is foundation.h header file up to date? + needs: [rust-code-compiles] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/rust-toolchain + with: + toolchain: 1.70.0 + - run: cargo install cbindgen@^0.24 --locked + - run: | + cbindgen --config extmod/foundation-rust/cbindgen.toml \ + --output extmod/foundation-rust/include/foundation.h \ + --verify \ + extmod/foundation-rust/ + + rust-tests-pass: + name: Rust tests pass? + needs: [rust-code-compiles] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/rust-toolchain + with: + toolchain: 1.70.0 + targets: + - run: | + cargo test --manifest-path extmod/foundation-rust/Cargo.toml \ + --features std diff --git a/.reuse/dep5 b/.reuse/dep5 index baa1d61ef..38fbe44ff 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -104,3 +104,7 @@ Files: version.txt Copyright: © 2021 Foundation Devices, Inc. License: GPL-3.0-or-later + +Files: .github/actions/rust-toolchain/action.yml +Copyright: 2021 David Tolnay +License: MIT