Add libsignal-client Android interop build integration test #1692
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Test | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: # all target branches | |
| workflow_dispatch: {} | |
| env: | |
| CARGO_TERM_COLOR: always | |
| NDK_VERSION: 28.0.13004108 | |
| RUST_BACKTRACE: 1 | |
| # For dev builds, include limited debug info in the output. See | |
| # https://doc.rust-lang.org/cargo/reference/profiles.html#debug | |
| CARGO_PROFILE_DEV_DEBUG: limited | |
| jobs: | |
| changes: | |
| name: Classify changes | |
| permissions: | |
| # Needed for dorny/paths-filter | |
| contents: read | |
| pull-requests: read | |
| runs-on: ubuntu-latest | |
| outputs: | |
| rust: ${{ steps.filter.outputs.rust }} | |
| java: ${{ steps.filter.outputs.java }} | |
| node: ${{ steps.filter.outputs.node }} | |
| swift: ${{ steps.filter.outputs.swift }} | |
| rust_ios: ${{ steps.filter.outputs.rust_ios }} | |
| steps: | |
| - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
| with: | |
| submodules: recursive | |
| - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0 | |
| id: filter | |
| with: | |
| filters: | | |
| all: &all | |
| - '.github/workflows/build_and_test.yml' | |
| - 'bin/**' | |
| - 'rust/*' | |
| - 'rust/!(bridge|protocol)/**' | |
| - 'rust/bridge/shared/**' | |
| - 'rust/protocol/*' | |
| - 'rust/protocol/!(cross-version-testing)/**' | |
| - 'rust-toolchain' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - '.cargo/**' # overly conservative, but it's fine | |
| rust: | |
| - *all | |
| - '.clippy.toml' | |
| - '.rustfmt.license-template' | |
| - '.rustfmt.toml' | |
| - 'acknowledgments/**' | |
| - 'rust/**' # deliberately re-include rust/bridge/* and rust/protocol/cross-version-testing | |
| java: | |
| - *all | |
| - '.dockerignore' | |
| - 'java/**' | |
| - 'rust/bridge/jni/**' | |
| node: | |
| - *all | |
| - '.nvmrc' | |
| - '.prettierrc.js' | |
| - 'node/**' | |
| - 'rust/bridge/node/**' | |
| rust_ios: &rust_ios | |
| - *all | |
| - 'rust/bridge/ffi/**' | |
| swift: | |
| - *rust_ios | |
| - 'swift/**' | |
| - 'LibSignalClient.podspec' | |
| ignored: | |
| - 'LICENSE' | |
| - '*.md' | |
| - '.github/FUNDING.yml' | |
| - '.github/stale.yml' | |
| - '.github/workflows/**' | |
| - '.gitignore' | |
| - '.gitattributes' | |
| - '.editorconfig' | |
| - '.tool-versions' | |
| - 'justfile' | |
| - 'doc/**' | |
| - name: Check pattern completeness | |
| run: echo "::error file=.github/workflows/build_and_test.yml::File not included in any filter" && false | |
| if: ${{ !contains(steps.filter.outputs.*, 'true') }} | |
| rust: | |
| name: Rust | |
| runs-on: ubuntu-latest-4-cores | |
| needs: changes | |
| if: ${{ needs.changes.outputs.rust == 'true' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| version: [nightly, stable] | |
| include: | |
| - version: nightly | |
| toolchain: "$(cat rust-toolchain)" | |
| - version: stable | |
| # Extract 'rust-version' value from Cargo.toml. | |
| toolchain: "$(yq '.workspace.package.rust-version' $(git rev-parse --show-toplevel)/Cargo.toml)" | |
| timeout-minutes: 45 | |
| steps: | |
| - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
| with: | |
| submodules: recursive | |
| - run: sudo apt-get update && sudo apt-get install protobuf-compiler | |
| - run: rustup toolchain install ${{ matrix.toolchain }} --profile minimal --component rustfmt,clippy | |
| - name: Cache locally-built tools | |
| uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 | |
| with: | |
| path: local-tools | |
| key: ${{ runner.os }}-local-tools-${{ matrix.version }}-${{ hashFiles('acknowledgments/cargo-about-version', '.taplo-cli-version') }} | |
| - name: Build cargo-about if needed | |
| run: cargo +stable install --version $(cat acknowledgments/cargo-about-version) --locked cargo-about --root local-tools | |
| if: matrix.version == 'nightly' | |
| - name: Build taplo-cli if needed | |
| run: cargo +stable install --version $(cat .taplo-cli-version) --locked taplo-cli --root local-tools | |
| if: matrix.version == 'nightly' | |
| # This should be done before anything else | |
| # because it also checks that the lockfile is up to date. | |
| - name: Check for duplicate dependencies | |
| run: ./bin/verify_duplicate_crates | |
| if: matrix.version == 'nightly' | |
| - name: Cargo.toml formatting check | |
| run: PATH="$PATH:$PWD/local-tools/bin" taplo format -c .taplo.toml --check | |
| if: matrix.version == 'nightly' | |
| - name: Rustfmt check | |
| run: cargo fmt --all -- --check | |
| if: matrix.version == 'nightly' | |
| - name: Rustfmt check for cross-version-testing | |
| run: cargo fmt --all -- --check | |
| working-directory: rust/protocol/cross-version-testing | |
| if: matrix.version == 'nightly' | |
| - name: Check acknowledgments | |
| run: PATH="$PATH:$PWD/local-tools/bin" ./bin/regenerate_acknowledgments.sh && git diff --exit-code acknowledgments | |
| if: matrix.version == 'nightly' | |
| - name: Build | |
| run: cargo +${{ matrix.toolchain }} build --workspace --features libsignal-ffi/signal-media --verbose --keep-going | |
| - name: Run tests | |
| run: cargo +${{ matrix.toolchain }} test --workspace --all-features --verbose --no-fail-fast -- --include-ignored | |
| - name: Test run benches | |
| # Run with a match-all regex to select all the benchmarks, which (confusingly) causes other tests to be skipped. | |
| run: cargo +${{ matrix.toolchain }} test --workspace --benches --all-features --verbose --no-fail-fast '.*' | |
| - name: Build bins and examples | |
| run: cargo +${{ matrix.toolchain }} build --workspace --bins --examples --all-features --verbose --keep-going | |
| - name: Clippy | |
| run: cargo clippy --workspace --all-targets --all-features --keep-going -- -D warnings | |
| if: matrix.version == 'nightly' | |
| - name: Rust docs | |
| run: cargo +${{ matrix.toolchain }} doc --workspace --all-features --keep-going | |
| if: matrix.version == 'stable' | |
| env: | |
| RUSTDOCFLAGS: -D warnings | |
| # We check the fuzz targets on stable because they don't have lockfiles, | |
| # and crates don't generally support arbitrary nightly versions. | |
| # See https://github.com/dtolnay/proc-macro2/issues/307 for an example. | |
| - name: Check that the protocol fuzz target still builds | |
| run: cargo +${{ matrix.toolchain }} check --all-targets --keep-going | |
| working-directory: rust/protocol/fuzz | |
| env: | |
| RUSTFLAGS: --cfg fuzzing | |
| if: matrix.version == 'stable' | |
| - name: Check that the attest fuzz target still builds | |
| run: cargo +${{ matrix.toolchain }} check --all-targets --keep-going | |
| working-directory: rust/attest/fuzz | |
| env: | |
| RUSTFLAGS: --cfg fuzzing | |
| if: matrix.version == 'stable' | |
| rust32: | |
| name: Rust (32-bit testing) | |
| runs-on: ubuntu-latest | |
| needs: changes | |
| if: ${{ needs.changes.outputs.rust == 'true' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| version: [nightly, stable] | |
| include: | |
| - version: nightly | |
| toolchain: "$(cat rust-toolchain)" | |
| - version: stable | |
| # Extract 'rust-version' value from Cargo.toml. | |
| toolchain: "$(yq '.workspace.package.rust-version' $(git rev-parse --show-toplevel)/Cargo.toml)" | |
| timeout-minutes: 45 | |
| steps: | |
| - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
| with: | |
| submodules: recursive | |
| - run: sudo apt-get update && sudo apt-get install gcc-multilib g++-multilib protobuf-compiler | |
| - run: rustup toolchain install ${{ matrix.toolchain }} --profile minimal --target i686-unknown-linux-gnu | |
| - name: Run tests (32-bit) | |
| # Exclude signal-neon-futures because those tests run Node | |
| run: cargo +${{ matrix.toolchain }} test --workspace --all-features --verbose --target i686-unknown-linux-gnu --exclude signal-neon-futures --no-fail-fast -- --include-ignored | |
| java: | |
| name: Java | |
| runs-on: ubuntu-latest-4-cores | |
| needs: changes | |
| permissions: | |
| # Needed for check_code_size.py to examine previous runs. | |
| actions: read | |
| contents: read | |
| if: ${{ needs.changes.outputs.java == 'true' }} | |
| timeout-minutes: 45 | |
| steps: | |
| - run: echo "JAVA_HOME=$JAVA_HOME_17_X64" >> "$GITHUB_ENV" | |
| - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
| with: | |
| submodules: recursive | |
| # Download all commits so we can search for the merge base with origin/main. | |
| fetch-depth: 0 | |
| - name: Install NDK | |
| run: ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --install "ndk;${NDK_VERSION}" | |
| - run: sudo apt-get update && sudo apt-get install protobuf-compiler | |
| - run: cargo +stable install cbindgen | |
| - run: rustup toolchain install $(cat rust-toolchain) --profile minimal --target aarch64-linux-android,armv7-linux-androideabi,x86_64-linux-android,i686-linux-android | |
| - name: Verify that the JNI bindings are up to date | |
| run: rust/bridge/jni/bin/gen_java_decl.py --verify | |
| - run: ./gradlew --dependency-verification strict build assembleAndroidTest android:lintDebug -PandroidArchs=arm,arm64 | tee ./gradle-output.txt | |
| working-directory: java | |
| shell: bash # Explicitly setting the shell turns on pipefail in GitHub Actions | |
| # Check for -Xcheck:jni warnings manually; Gradle doesn't capture them for some reason. | |
| - run: "! grep WARNING ./gradle-output.txt" | |
| working-directory: java | |
| - run: java/check_code_size.py | tee ./check_code_size-output.txt | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| - run: grep -v -F '***' ./check_code_size-output.txt >> $GITHUB_STEP_SUMMARY | |
| node: | |
| name: Node | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-15] | |
| needs: changes | |
| if: ${{ needs.changes.outputs.node == 'true' }} | |
| timeout-minutes: 45 | |
| steps: | |
| - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
| with: | |
| submodules: recursive | |
| - run: rustup toolchain install $(cat rust-toolchain) --profile minimal | |
| # install nasm compiler for boring | |
| - name: Install nasm | |
| if: startsWith(matrix.os, 'windows') | |
| run: choco install nasm | |
| shell: cmd | |
| - run: sudo apt-get update && sudo apt-get install protobuf-compiler | |
| if: matrix.os == 'ubuntu-latest' | |
| - run: choco install protoc | |
| if: matrix.os == 'windows-latest' | |
| - run: brew install protobuf | |
| if: startsWith(matrix.os, 'macos-') | |
| - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 | |
| with: | |
| node-version-file: '.nvmrc' | |
| - name: Verify that the Node bindings are up to date | |
| run: rust/bridge/node/bin/gen_ts_decl.py --verify | |
| if: matrix.os == 'ubuntu-latest' | |
| - run: npm ci | |
| working-directory: node | |
| - run: npm run build | |
| working-directory: node | |
| - run: npm run tsc | |
| working-directory: node | |
| - run: npm run lint | |
| if: matrix.os == 'ubuntu-latest' | |
| working-directory: node | |
| - run: npm run format-check | |
| if: matrix.os == 'ubuntu-latest' | |
| working-directory: node | |
| - run: npm run test | |
| working-directory: node | |
| swift_package: | |
| name: Swift Package | |
| runs-on: ubuntu-latest | |
| needs: changes | |
| if: ${{ needs.changes.outputs.swift == 'true' }} | |
| timeout-minutes: 45 | |
| steps: | |
| - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
| with: | |
| submodules: recursive | |
| - run: rustup toolchain install $(cat rust-toolchain) --profile minimal | |
| - run: sudo apt-get update && sudo apt-get install protobuf-compiler | |
| - run: cargo +stable install cbindgen | |
| - run: swift/verify_error_codes.sh | |
| - name: Build libsignal-ffi | |
| run: swift/build_ffi.sh -d -v --verify-ffi | |
| - name: Build Swift and run tests | |
| run: swift test -v | |
| working-directory: swift | |
| - name: Build and run Swift benchmarks (in debug mode) | |
| run: swift run -v Benchmarks --allow-debug-build | |
| working-directory: swift/Benchmarks | |
| # Disabled for now, broken on Linux in the Swift 6.0 release. | |
| # See https://forums.swift.org/t/generate-documentation-failing-for-swift-6-pre-release/74534 | |
| # - name: Build Swift package documentation | |
| # run: swift package plugin generate-documentation --analyze --warnings-as-errors | |
| # working-directory: swift | |
| swift_cocoapod: | |
| name: Swift CocoaPod | |
| runs-on: macos-15 | |
| needs: changes | |
| if: ${{ needs.changes.outputs.swift == 'true' }} | |
| timeout-minutes: 45 | |
| steps: | |
| - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | |
| with: | |
| submodules: recursive | |
| - run: brew install protobuf swiftlint | |
| - name: Check formatting | |
| run: swift format --in-place --parallel --recursive . && git diff --exit-code . | |
| working-directory: swift | |
| - name: Run lint | |
| run: swiftlint lint --strict --reporter github-actions-logging | |
| working-directory: swift | |
| - run: rustup toolchain install $(cat rust-toolchain) --profile minimal --target x86_64-apple-ios,aarch64-apple-ios-sim | |
| # Build only the targets that `pod lib lint` will test building. | |
| - name: Build for x86_64-apple-ios | |
| run: swift/build_ffi.sh --release | |
| env: | |
| CARGO_BUILD_TARGET: x86_64-apple-ios | |
| - name: Build for aarch64-apple-ios-sim | |
| run: swift/build_ffi.sh --release | |
| env: | |
| CARGO_BUILD_TARGET: aarch64-apple-ios-sim | |
| - name: Run pod lint | |
| run: pod lib lint --verbose --platforms=ios --skip-tests |