ci: Add AI security review workflow #10932
Workflow file for this run
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
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| schedule: | |
| # Run daily job at 8:00 AM and 8:00 PM PT. | |
| # The workflow is run in the morning to allow for the clippy job to resolve lints from new Rust | |
| # versions in a timely manner. | |
| - cron: '0 3,15 * * *' | |
| workflow_dispatch: | |
| name: ci | |
| env: | |
| CARGO_INCREMENTAL: 0 | |
| CARGO_NET_RETRY: 10 | |
| RUSTUP_MAX_RETRIES: 10 | |
| RUST_BACKTRACE: 1 | |
| # Pin the nightly toolchain to prevent breakage. | |
| # This should be occasionally updated. | |
| RUST_NIGHTLY_TOOLCHAIN: nightly-2025-11-09 | |
| CDN: https://dnglbrstg7yg.cloudfront.net | |
| # enable unstable features for testing | |
| S2N_UNSTABLE_CRYPTO_OPT_TX: 100 | |
| S2N_UNSTABLE_CRYPTO_OPT_RX: 100 | |
| CI_ARTIFACTS_BUCKET: s2n-quic-ci-artifacts | |
| # By default depandabot only receives read permissions. Explicitly give it write | |
| # permissions which is needed by the ouzi-dev/commit-status-updater task. | |
| # | |
| # Updating status is relatively safe (doesnt modify source code) and caution | |
| # should we taken before adding more permissions. | |
| permissions: | |
| statuses: write | |
| id-token: write # This is required for requesting the JWT/OIDC | |
| jobs: | |
| env: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| rust-versions: ${{ steps.definitions.outputs.versions }} | |
| msrv: ${{ steps.definitions.outputs.msrv }} | |
| examples: ${{ steps.definitions.outputs.examples }} | |
| crates: ${{ steps.definitions.outputs.crates }} | |
| workspaces: ${{ steps.definitions.outputs.workspaces }} | |
| start-time: ${{ steps.start-time.outputs.time }} | |
| steps: | |
| - name: Record workflow start time | |
| id: start-time | |
| run: echo "time=$(date +%s)" >> $GITHUB_OUTPUT | |
| - uses: actions/checkout@v7 | |
| # examples is populated by | |
| # find all child folders in the examples directory | |
| # jq -R - raw content is passed in (not json, just strings) | |
| # jq -s - slurp the content into an object | |
| # jq '. += ' adds the s2n-quic-xdp and s2n-quic-dc crates to the list of crates we build | |
| # Many of the xdp crates have much more complex build processes, so we | |
| # don't try to build all of them. | |
| # jq -c - output the object in (c)ompact mode on a single line, github | |
| # will fail to parse multi line output | |
| # | |
| # the output is echo'd to make debugging easier | |
| - name: Evaluate definitions | |
| id: definitions | |
| run: | | |
| rustup show active-toolchain | |
| # The MSRV is declared by the `rust-version` field of each crate. It is | |
| # deliberately not tied to the toolchain anyone happens to be building | |
| # with; jobs that need a specific toolchain install and override it | |
| # themselves. | |
| export MSRV=$(grep -m1 '^rust-version' quic/s2n-quic/Cargo.toml | sed -E 's/^rust-version *= *"(.+)"/\1/') | |
| if [ -z "$MSRV" ]; then | |
| echo "Error: MSRV did not parse correctly" | |
| exit 1 | |
| fi | |
| # The MSRV above is the floor s2n-quic promises to its users, so no | |
| # crate may declare a lower `rust-version` than it. A crate requiring a | |
| # higher one is allowed: the xdp and wireshark workspaces have needed | |
| # that in the past when their dependencies outpaced the repository | |
| # MSRV. Nothing pins these together anymore, so check it explicitly | |
| # rather than silently testing a version some crate does not support. | |
| export LOWEST=$(git ls-files '*Cargo.toml' | xargs grep -h '^rust-version' | sed -E 's/^rust-version *= *"(.+)"/\1/' | sort -V | head -1) | |
| if [ "$LOWEST" != "$MSRV" ]; then | |
| echo "Error: a crate declares rust-version $LOWEST, below the $MSRV MSRV of s2n-quic" | |
| git ls-files '*Cargo.toml' | xargs grep -H '^rust-version' | sort -u | |
| exit 1 | |
| fi | |
| echo "msrv=$MSRV" | |
| echo "msrv=$MSRV" >> $GITHUB_OUTPUT | |
| export RAW_VERSIONS="stable beta $MSRV" | |
| export VERSIONS=$(echo $RAW_VERSIONS | jq -scR 'rtrimstr("\n")|split(" ")|.') | |
| echo "versions=$VERSIONS" | |
| echo "versions=$VERSIONS" >> $GITHUB_OUTPUT | |
| export EXAMPLES=$(find examples/ -maxdepth 1 -mindepth 1 -type d | jq -R | jq -sc) | |
| echo "examples=$EXAMPLES" | |
| echo "examples=$EXAMPLES" >> $GITHUB_OUTPUT | |
| export CRATES=$(find quic common -name *Cargo.toml | jq -R | jq -s | jq '. += ["tools/xdp/s2n-quic-xdp/Cargo.toml","dc/s2n-quic-dc/Cargo.toml"]' | jq -c) | |
| echo "crates=$CRATES" | |
| echo "crates=$CRATES" >> $GITHUB_OUTPUT | |
| export WORKSPACES=$(find . -maxdepth 4 -name Cargo.toml -not -path './tools/xdp/ebpf/*' -exec grep -l '^\[workspace\]' {} \; | xargs -n1 dirname | sort | jq -R | jq -sc) | |
| echo "workspaces=$WORKSPACES" | |
| echo "workspaces=$WORKSPACES" >> $GITHUB_OUTPUT | |
| rustfmt: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install ${{ env.RUST_NIGHTLY_TOOLCHAIN }} --profile minimal --component rustfmt | |
| rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }} | |
| - name: Run cargo fmt | |
| run: | | |
| cargo fmt --all -- --check | |
| clippy: | |
| runs-on: ubuntu-latest | |
| needs: env | |
| # clippy bot requires write permission for contents and pull-requests when creating PRs. | |
| # create-pull-request action mandates this in https://github.com/marketplace/actions/create-pull-request#token | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal --component clippy | |
| rustup override set stable | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Determine if a PR should be opened | |
| id: should_fix | |
| run: | | |
| if [ "${{ github.event_name }}" == "schedule" ] || [ "${{ github.event_name }}" == "workflow_dispatch" ]; then | |
| echo "SHOULD_FIX=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "SHOULD_FIX=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| # TODO translate json reports to in-action warnings | |
| - name: Run cargo clippy on all workspaces | |
| run: | | |
| CLIPPY_FIX_FLAG="" | |
| if [ "${{ steps.should_fix.outputs.SHOULD_FIX }}" == "true" ]; then | |
| CLIPPY_FIX_FLAG='--fix --allow-dirty' | |
| fi | |
| WORKSPACES=$(echo '${{ needs.env.outputs.workspaces }}' | jq -r '.[]') | |
| for workspace in $WORKSPACES; do | |
| echo "Running clippy on $workspace" | |
| cd "$workspace" | |
| cargo clippy --all-features --all-targets --workspace $CLIPPY_FIX_FLAG -- -D warnings | |
| cd $GITHUB_WORKSPACE | |
| done | |
| - name: Create clippy pull request | |
| if: steps.should_fix.outputs.SHOULD_FIX == 'true' | |
| uses: peter-evans/create-pull-request@v8 | |
| with: | |
| commit-message: | | |
| chore: clippy lint updates | |
| title: 'chore: clippy lint updates' | |
| body: | | |
| ### Description of changes: | |
| Fixes new Clippy lints in the latest Rust release. For details on the new lints, see the [Rust Blog](https://blog.rust-lang.org/releases/latest). | |
| ### Testing: | |
| CI clippy test should pass. | |
| udeps: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install ${{ env.RUST_NIGHTLY_TOOLCHAIN }} --profile minimal | |
| rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }} | |
| - uses: camshaft/rust-cache@v1 | |
| # Ideally this would use the camshaft/install action to install cargo-udeps. However, | |
| # the --locked flag can't currently be provided to camshaft/install. After support for this | |
| # is added, camshaft/install should be used here instead: | |
| # https://github.com/aws/s2n-quic/issues/2593 | |
| - name: Install cargo-udeps | |
| run: cargo install cargo-udeps --locked | |
| - name: Run cargo udeps | |
| run: cargo udeps --workspace --all-targets | |
| env: | |
| RUSTC_WRAPPER: "" | |
| doc: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| # nightly docrs features are used | |
| - name: Install rust nightly toolchain | |
| id: nightly-toolchain | |
| run: | | |
| rustup toolchain install nightly --profile minimal | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Run cargo doc | |
| run: cargo +nightly doc --all-features --no-deps --workspace --exclude s2n-quic-qns | |
| env: | |
| RUSTDOCFLAGS: --cfg docsrs | |
| - uses: aws-actions/configure-aws-credentials@v6.2.3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| role-to-assume: arn:aws:iam::024603541914:role/GitHubOIDCRole | |
| role-session-name: S2nQuicGHAS3Session | |
| aws-region: us-west-2 | |
| - name: Upload to S3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| id: s3 | |
| run: | | |
| TARGET_SHA="${{ github.sha }}/doc" | |
| aws s3 sync target/doc "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" --acl private --follow-symlinks | |
| URL="$CDN/$TARGET_SHA/s2n_quic/index.html" | |
| echo "URL=$URL" >> $GITHUB_OUTPUT | |
| # Only upload to latest if the event is push to main | |
| if [ "${{ github.event_name }}" == "push" ]; then | |
| TARGET_LATEST="latest/doc" | |
| aws s3 cp "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_LATEST" --recursive | |
| fi | |
| - uses: ouzi-dev/commit-status-updater@v2.0.2 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| name: "doc / report" | |
| status: "success" | |
| url: "${{ steps.s3.outputs.URL }}" | |
| test: | |
| runs-on: ${{ matrix.os }} | |
| needs: env | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| rust: ${{ fromJson(needs.env.outputs.rust-versions) }} | |
| os: [ubuntu-latest, macOS-latest, windows-latest] | |
| target: [native] | |
| env: [default] | |
| include: | |
| - os: windows-latest | |
| # s2n-tls and s2n-quic-dc don't currently build on windows | |
| exclude: --exclude s2n-quic-tls --exclude s2n-quic-dc --exclude s2n-quic-dc-benches --exclude s2n-quic-dc-metrics | |
| - rust: stable | |
| os: ubuntu-latest | |
| target: aarch64-unknown-linux-gnu | |
| # s2n-quic-dc tests are too slow to be emulated with QEMU | |
| exclude: --exclude s2n-quic-dc --exclude s2n-quic-dc-benches --exclude s2n-quic-dc-metrics | |
| - rust: stable | |
| os: ubuntu-latest | |
| target: i686-unknown-linux-gnu | |
| # s2n-quic-dc requires a large number of threads for testing, which isn't supported on i686 | |
| exclude: --exclude s2n-quic-dc --exclude s2n-quic-dc-benches --exclude s2n-quic-dc-metrics | |
| - rust: stable | |
| os: ubuntu-latest | |
| target: x86_64-unknown-linux-musl | |
| args: --features aws-lc-bindgen | |
| # test with different platform features | |
| - rust: stable | |
| os: ubuntu-latest | |
| target: native | |
| env: S2N_QUIC_PLATFORM_FEATURES_OVERRIDE="" | |
| # s2n-quic-dc requires platform features | |
| exclude: --exclude s2n-quic-dc --exclude s2n-quic-dc-benches --exclude s2n-quic-dc-metrics --exclude s2n-quic-bench | |
| - rust: stable | |
| os: ubuntu-latest | |
| target: native | |
| env: S2N_QUIC_PLATFORM_FEATURES_OVERRIDE="mtu_disc,pktinfo,tos,socket_msg" >> $GITHUB_ENV; echo S2N_QUIC_RUN_VERSION_SPECIFIC_TESTS=1 | |
| steps: | |
| - uses: ilammy/setup-nasm@v1 | |
| - uses: actions/checkout@v7 | |
| with: | |
| lfs: true | |
| submodules: true | |
| - name: Install cross target | |
| if: ${{ matrix.target != 'native' }} | |
| run: | | |
| rustup target add ${{ matrix.target }} | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install ${{ matrix.rust }} | |
| rustup override set ${{ matrix.rust }} | |
| # if not 'native', this install the toolchain for target, otherwise it's a noop | |
| rustup toolchain install ${{ matrix.rust }} ${{ matrix.target != 'native' && format('--target {0}', matrix.target) || '' }} | |
| - name: Install cross | |
| if: ${{ matrix.target != 'native' }} | |
| run: cargo install cross --git https://github.com/cross-rs/cross | |
| - uses: camshaft/rust-cache@v1 | |
| with: | |
| key: ${{ matrix.target }} | |
| - name: Restore fuzz corpus | |
| shell: bash | |
| run: | | |
| find . -name 'corpus.tar.gz' -exec dirname {} ';' | xargs -L 1 bash -c 'cd "$0" && rm -rf corpus && tar xf corpus.tar.gz' | |
| - name: Set environment variables | |
| if: ${{ matrix.env != 'default' }} | |
| run: echo ${{ matrix.env }} >> $GITHUB_ENV | |
| # Build the tests before running to improve cross compilation speed | |
| - name: Run cargo/cross build | |
| run: | | |
| ${{ matrix.target != 'native' && 'cross' || 'cargo' }} build --tests --workspace ${{ matrix.exclude }} ${{ matrix.target != 'native' && format('--target {0}', matrix.target) || '' }} ${{ matrix.args }} | |
| - name: Run cargo/cross test | |
| run: | | |
| ${{ matrix.target != 'native' && 'cross' || 'cargo' }} test --workspace ${{ matrix.exclude }} ${{ matrix.target != 'native' && format('--target {0}', matrix.target) || '' }} ${{ matrix.args }} | |
| # The previous build runs on MSVC. s2n-quic can use s2n-tls, but only on MinGW, so we need a new job to test that. | |
| test-windows-gnu: | |
| runs-on: windows-latest | |
| name: Windows s2n-tls (${{ matrix.sys }}) | |
| env: | |
| # msys2 ships clang, not gcc, but cc-rs defaults to gcc for *-gnu. | |
| CC: clang | |
| # gnullvm doesn't auto-link winpthreads, so s2n's pthread/clock_gettime/nanosleep symbols | |
| # are undefined; -lpthread links it explicitly. Both vars are needed: RUSTFLAGS for the | |
| # normal link, RUSTDOCFLAGS for doctests. | |
| CARGO_TARGET_X86_64_PC_WINDOWS_GNULLVM_RUSTFLAGS: -Clink-arg=-lpthread | |
| CARGO_TARGET_X86_64_PC_WINDOWS_GNULLVM_RUSTDOCFLAGS: -Clink-arg=-lpthread | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - sys: ucrt64 | |
| pkg-prefix: mingw-w64-ucrt-x86_64 | |
| env-path: /ucrt64 | |
| rust-host: x86_64-pc-windows-gnu | |
| - sys: mingw64 | |
| pkg-prefix: mingw-w64-x86_64 | |
| env-path: /mingw64 | |
| rust-host: x86_64-pc-windows-gnu | |
| - sys: clang64 | |
| pkg-prefix: mingw-w64-clang-x86_64 | |
| env-path: /clang64 | |
| # clang64 targets gnullvm, which has no host toolchain, so cross-compile to it from | |
| # the gnu host. rust-host is the host we install; cargo-target is what we build for. | |
| rust-host: x86_64-pc-windows-gnu | |
| cargo-target: x86_64-pc-windows-gnullvm | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| lfs: true | |
| submodules: true | |
| - name: Setup MSYS2 | |
| uses: msys2/setup-msys2@v2 | |
| with: | |
| msystem: ${{ matrix.sys }} | |
| update: true | |
| install: >- | |
| ${{ matrix.pkg-prefix }}-clang | |
| ${{ matrix.pkg-prefix }}-clang-libs | |
| ${{ matrix.pkg-prefix }}-cmake | |
| ${{ matrix.pkg-prefix }}-ninja | |
| ${{ matrix.pkg-prefix }}-nasm | |
| ${{ matrix.pkg-prefix }}-rustup | |
| diffutils | |
| jq | |
| - name: Install Rust toolchain | |
| shell: msys2 {0} | |
| run: | | |
| set -eu | |
| # Force the MinGW gnu host; otherwise rustup picks the runner's MSVC host, which can't build the C dependencies. | |
| rustup set default-host ${{ matrix.rust-host }} | |
| rustup default stable | |
| rustup show active-toolchain | |
| # clang64 has no gnullvm host toolchain, so cross-compile to gnullvm from the gnu host. | |
| if [ -n "${{ matrix.cargo-target }}" ]; then | |
| rustup target add ${{ matrix.cargo-target }} | |
| echo "CARGO_BUILD_TARGET=${{ matrix.cargo-target }}" >> "$GITHUB_ENV" | |
| # aws-lc-sys has no prebuilt bindings for gnullvm, so it runs bindgen at build time. | |
| # Install bindgen-cli (on PATH) built for the gnullvm environment. | |
| cargo install --locked --target ${{ matrix.cargo-target }} \ | |
| --root "${{ matrix.env-path }}" bindgen-cli | |
| fi | |
| - name: Restore fuzz corpus | |
| shell: msys2 {0} | |
| run: | | |
| find . -name 'corpus.tar.gz' -exec dirname {} ';' | xargs -L 1 bash -c 'cd "$0" && rm -rf corpus && tar xf corpus.tar.gz' | |
| # Tests the workspace `default-members`, which excludes the `dc/` crates. Crates and tests | |
| # that can't build on the MinGW toolchains are gated in their own manifests. | |
| - name: Run cargo test | |
| shell: msys2 {0} | |
| run: | | |
| set -eu | |
| cargo test | |
| asan: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install ${{ env.RUST_NIGHTLY_TOOLCHAIN }} --component rust-src | |
| rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }} | |
| - uses: camshaft/rust-cache@v1 | |
| # asan expects a binary at /usr/bin/llvm-symbolizer but GHA runners include | |
| # multiple versioned binaries, like /usr/bin/llvm-symbolizer-13. This step | |
| # finds the latest symbolizer and use it as the "base" llvm-symbolizer binary. | |
| # | |
| # llvm-symbolizer is necessary to get nice stack traces from asan errors. | |
| # Otherwise the stack trace just contains a hex address like "0x55bc6a28a9b6" | |
| - name: set llvm symbolizer | |
| run: | | |
| sudo ln -s $(find /usr/bin/ -maxdepth 1 -name "llvm-symbolizer-*" | sort -V | tail -n 1) /usr/bin/llvm-symbolizer | |
| - name: Run Unit Tests under ASAN | |
| env: | |
| RUSTDOCFLAGS: -Zsanitizer=address | |
| RUSTFLAGS: -Zsanitizer=address | |
| # We got a few globals that aren't cleaned up. Need to | |
| # determine if we should reenable this in the future. | |
| ASAN_OPTIONS: detect_leaks=false | |
| run: | | |
| cargo test \ | |
| -Zbuild-std \ | |
| --target x86_64-unknown-linux-gnu \ | |
| --workspace | |
| fips: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust stable toolchain | |
| id: stable-toolchain | |
| run: | | |
| rustup toolchain install stable | |
| rustup override set stable | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Run test (rustls) | |
| run: | | |
| cargo test --no-default-features --features "provider-tls-fips provider-tls-rustls" | |
| - name: Run test (s2n-tls) | |
| run: | | |
| cargo test --no-default-features --features "provider-tls-fips provider-tls-s2n" | |
| miri: | |
| runs-on: | |
| labels: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| crate: [quic/s2n-quic-core, quic/s2n-quic-platform] | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install ${{ env.RUST_NIGHTLY_TOOLCHAIN }} --component miri,rust-src | |
| rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }} | |
| - uses: camshaft/rust-cache@v1 | |
| with: | |
| key: ${{ matrix.crate }} | |
| - name: ${{ matrix.crate }} | |
| # Disabling capture speeds up miri execution: https://github.com/rust-lang/miri/issues/1780#issuecomment-830664528 | |
| run: cd ${{ matrix.crate }} && cargo miri test -- --nocapture | |
| env: | |
| # needed to read corpus files from filesystem | |
| MIRIFLAGS: -Zmiri-disable-isolation | |
| no_std: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install ${{ env.RUST_NIGHTLY_TOOLCHAIN }} --component rust-src | |
| rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }} | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Run cargo build | |
| run: ./scripts/test_no_std ${{ env.RUST_NIGHTLY_TOOLCHAIN }} | |
| compliance: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - uses: awslabs/duvet-action@v1 | |
| with: | |
| report-script: ./scripts/compliance | |
| report-path: ./target/compliance/report.html | |
| role-to-assume: arn:aws:iam::024603541914:role/GitHubOIDCRole | |
| role-session-name: S2nQuicGHAS3Session | |
| aws-s3-region: us-west-2 | |
| aws-s3-bucket-name: ${{ env.CI_ARTIFACTS_BUCKET }} | |
| cdn: $CDN | |
| coverage: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| lfs: true | |
| submodules: true | |
| - name: Restore fuzz corpus | |
| run: | | |
| find . -name 'corpus.tar.gz' -exec dirname {} ';' | xargs -L 1 bash -c 'cd "$0" && rm -rf corpus && tar xf corpus.tar.gz' | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install ${{ env.RUST_NIGHTLY_TOOLCHAIN }} --component llvm-tools-preview | |
| rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }} | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Install cargo-llvm-cov | |
| run: curl -LsSf https://github.com/taiki-e/cargo-llvm-cov/releases/latest/download/cargo-llvm-cov-x86_64-unknown-linux-gnu.tar.gz | tar xzf - -C ~/.cargo/bin | |
| - name: Run cargo llvm-cov | |
| run: cargo llvm-cov --html --no-fail-fast --workspace --exclude s2n-quic-qns --all-features | |
| - uses: aws-actions/configure-aws-credentials@v6.2.3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| role-to-assume: arn:aws:iam::024603541914:role/GitHubOIDCRole | |
| role-session-name: S2nQuicGHAS3Session | |
| aws-region: us-west-2 | |
| - name: Upload results | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| id: s3 | |
| run: | | |
| TARGET_SHA="${{ github.sha }}/coverage" | |
| aws s3 sync target/llvm-cov/html "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" --acl private --follow-symlinks | |
| URL="$CDN/$TARGET_SHA/index.html" | |
| echo "URL=$URL" >> $GITHUB_OUTPUT | |
| # Only upload to latest if the event is push to main | |
| if [ "${{ github.event_name }}" == "push" ]; then | |
| TARGET_LATEST="latest/coverage" | |
| aws s3 cp "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_LATEST" --recursive | |
| fi | |
| - uses: ouzi-dev/commit-status-updater@v2.0.2 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| name: "coverage / report" | |
| status: "success" | |
| url: "${{ steps.s3.outputs.URL }}" | |
| # This CI step will directly build each crate in common/ and quic/ which is | |
| # useful because it sidesteps the feature resolution that normally occurs in a | |
| # workspace build. We make sure that the crates build with default features, | |
| # otherwise release to crates.io will be blocked | |
| crates: | |
| needs: env | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| crate: ${{ fromJson(needs.env.outputs.crates) }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal | |
| rustup override set stable | |
| - name: Run cargo build | |
| run: cargo build --manifest-path ${{ matrix.crate }} | |
| examples: | |
| needs: env | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| example: ${{ fromJson(needs.env.outputs.examples) }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| # nightly features are used for formatting | |
| - name: Install rust nightly toolchain | |
| id: nightly-toolchain | |
| run: | | |
| rustup toolchain install nightly --component rustfmt | |
| - name: Install rust stable toolchain | |
| id: stable-toolchain | |
| run: | | |
| rustup toolchain install stable | |
| rustup override set stable | |
| - uses: camshaft/rust-cache@v1 | |
| with: | |
| key: ${{ matrix.example }} | |
| - name: format | |
| working-directory: ${{ matrix.example }} | |
| run: cargo +nightly fmt --all -- --check | |
| # not all examples will build with the --manifest-path argument, since the | |
| # manifest-path argument will pull configuration from the current directory | |
| # instead of the directory with the Cargo.toml file | |
| - name: build | |
| working-directory: ${{ matrix.example }} | |
| # TODO make sure the example actually runs as well | |
| run: cargo build | |
| recovery-simulations: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal | |
| rustup override set stable | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Run simulations | |
| run: | | |
| ./scripts/recovery-sim | |
| - uses: aws-actions/configure-aws-credentials@v6.2.3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| role-to-assume: arn:aws:iam::024603541914:role/GitHubOIDCRole | |
| role-session-name: S2nQuicGHAS3Session | |
| aws-region: us-west-2 | |
| - name: Upload to S3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| id: s3 | |
| run: | | |
| TARGET_SHA="${{ github.sha }}/recovery-simulations" | |
| aws s3 sync target/recovery-sim "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" --acl private --follow-symlinks | |
| URL="$CDN/$TARGET_SHA/index.html" | |
| echo "URL=$URL" >> $GITHUB_OUTPUT | |
| # Only upload to latest if the event is push to main | |
| if [ "${{ github.event_name }}" == "push" ]; then | |
| TARGET_LATEST="latest/recovery-simulations" | |
| aws s3 cp "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_LATEST" --recursive | |
| fi | |
| - uses: ouzi-dev/commit-status-updater@v2.0.2 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| name: "recovery-simulations / report" | |
| status: "success" | |
| url: "${{ steps.s3.outputs.URL }}" | |
| sims: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal | |
| rustup override set stable | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Run cargo build | |
| run: cargo build --bin s2n-quic-sim --release | |
| - name: Run simulations | |
| run: | | |
| ./scripts/sim | |
| - uses: aws-actions/configure-aws-credentials@v6.2.3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| role-to-assume: arn:aws:iam::024603541914:role/GitHubOIDCRole | |
| role-session-name: S2nQuicGHAS3Session | |
| aws-region: us-west-2 | |
| - name: Upload to S3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| id: s3 | |
| run: | | |
| TARGET_SHA="${{ github.sha }}/sim" | |
| aws s3 sync target/s2n-quic-sim "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" --acl private --follow-symlinks | |
| URL="$CDN/$TARGET_SHA/index.html" | |
| echo "URL=$URL" >> $GITHUB_OUTPUT | |
| # Only upload to latest if the event is push to main | |
| if [ "${{ github.event_name }}" == "push" ]; then | |
| TARGET_LATEST="latest/sim" | |
| aws s3 cp "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_LATEST" --recursive | |
| fi | |
| - uses: ouzi-dev/commit-status-updater@v2.0.2 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| name: "sims / report" | |
| status: "success" | |
| url: "${{ steps.s3.outputs.URL }}" | |
| copyright: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Check | |
| run: | | |
| ./scripts/copyright_check | |
| s2n-events: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install ${{ env.RUST_NIGHTLY_TOOLCHAIN }} --profile minimal --component rustfmt | |
| rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }} | |
| - uses: camshaft/rust-cache@v1 | |
| - name: format | |
| working-directory: ./tools/s2n-events | |
| run: cargo fmt -- --check | |
| - name: generate test events | |
| run: | | |
| cargo run --manifest-path ./tools/s2n-events/Cargo.toml | |
| - name: ensure test events are up to date | |
| run: | | |
| # If this fails you need to run `cargo run --manifest-path ./tools/s2n-events/Cargo.toml` | |
| git diff --exit-code | |
| - name: test | |
| working-directory: ./tools/s2n-events | |
| run: cargo test | |
| # ensures the event codegen is up to date | |
| generate-events: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install ${{ env.RUST_NIGHTLY_TOOLCHAIN }} --profile minimal --component rustfmt | |
| rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }} | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Run events codegen | |
| run: | | |
| cargo run --manifest-path ./tools/event-generator/Cargo.toml | |
| - name: Check to make sure the generated events are up-to-date | |
| run: | | |
| # If this fails you need to run `cargo run --manifest-path ./tools/event-generator/Cargo.toml` | |
| git diff --exit-code | |
| # ensures there are no unused snapshots | |
| snapshots: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal | |
| rustup override set stable | |
| - name: Install cargo-insta | |
| uses: camshaft/install@v1 | |
| with: | |
| crate: cargo-insta | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Run cargo insta test | |
| run: | | |
| cargo insta test --all --delete-unreferenced-snapshots | |
| - name: Check to make sure there are no unused snapshots | |
| run: | | |
| # If this fails, a test that was asserting a snapshot is no longer being executed. | |
| git diff --exit-code | |
| # generates a report of time spent in compilation | |
| # https://doc.rust-lang.org/stable/cargo/reference/timings.html | |
| timing: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install ${{ env.RUST_NIGHTLY_TOOLCHAIN }} --profile minimal | |
| rustup override set ${{ env.RUST_NIGHTLY_TOOLCHAIN }} | |
| - name: Run cargo build | |
| run: | | |
| cd examples/echo | |
| cargo build --timings --release --workspace | |
| - uses: aws-actions/configure-aws-credentials@v6.2.3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| role-to-assume: arn:aws:iam::024603541914:role/GitHubOIDCRole | |
| role-session-name: S2nQuicGHAS3Session | |
| aws-region: us-west-2 | |
| - name: Upload to S3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| id: s3 | |
| run: | | |
| TARGET_SHA="${{ github.sha }}/timing/index.html" | |
| aws s3 cp examples/echo/target/cargo-timings/cargo-timing.html "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" --acl private --follow-symlinks | |
| URL="$CDN/$TARGET_SHA" | |
| echo "URL=$URL" >> $GITHUB_OUTPUT | |
| # Only upload to latest if the event is push to main | |
| if [ "${{ github.event_name }}" == "push" ]; then | |
| TARGET_LATEST="latest/timing/index.html" | |
| aws s3 cp "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_LATEST" | |
| fi | |
| - uses: ouzi-dev/commit-status-updater@v2.0.2 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| name: "timing / report" | |
| status: "success" | |
| url: "${{ steps.s3.outputs.URL }}" | |
| typos: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal | |
| rustup override set stable | |
| - uses: camshaft/install@v1 | |
| with: | |
| crate: typos-cli | |
| bins: typos | |
| - name: Run typos | |
| run: | | |
| ./scripts/typos --format json | tee /tmp/typos.json | jq -rs '.[] | "::error file=\(.path),line=\(.line_num),col=\(.byte_offset)::\(.typo) should be \"" + (.corrections // [] | join("\" or \"") + "\"")' | |
| cat /tmp/typos.json | |
| ! grep -q '[^[:space:]]' /tmp/typos.json | |
| kani: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| crate: [common/s2n-codec, quic/s2n-quic-core, quic/s2n-quic-platform] | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Kani run | |
| uses: model-checking/kani-github-action@v1.1 | |
| with: | |
| working-directory: ${{ matrix.crate }} | |
| dhat: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal | |
| rustup override set stable | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Run cargo build | |
| working-directory: tools/memory-report | |
| run: cargo build --release --workspace | |
| - name: Run server | |
| working-directory: tools/memory-report | |
| run: ./target/release/memory-report server & | |
| - name: Run client | |
| id: run-client | |
| working-directory: tools/memory-report | |
| continue-on-error: true | |
| run: ./target/release/memory-report client > report.tsv | |
| - name: Prepare artifacts | |
| working-directory: tools/memory-report | |
| run: | | |
| mkdir -p target/report | |
| mv report.tsv target/report/ | |
| mv dhat-heap.json target/report/ | |
| - uses: aws-actions/configure-aws-credentials@v6.2.3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| role-to-assume: arn:aws:iam::024603541914:role/GitHubOIDCRole | |
| role-session-name: S2nQuicGHAS3Session | |
| aws-region: us-west-2 | |
| - name: Upload to S3 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| id: s3 | |
| working-directory: tools/memory-report | |
| run: | | |
| TARGET_SHA="${{ github.sha }}/dhat" | |
| aws s3 sync target/report "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" --acl private --follow-symlinks | |
| URL="$CDN/dhat/dh_view.html?url=/$TARGET_SHA/dhat-heap.json" | |
| echo "URL=$URL" >> $GITHUB_OUTPUT | |
| # Only upload to latest if the event is push to main | |
| if [ "${{ github.event_name }}" == "push" ]; then | |
| TARGET_LATEST="latest/dhat" | |
| aws s3 cp "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_SHA" "s3://${{ env.CI_ARTIFACTS_BUCKET }}/$TARGET_LATEST" --recursive | |
| fi | |
| - uses: ouzi-dev/commit-status-updater@v2.0.2 | |
| if: github.event_name == 'push' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| name: "dhat / report" | |
| status: "success" | |
| url: "${{ steps.s3.outputs.URL }}" | |
| - name: Check run client status | |
| if: steps.run-client.outcome != 'success' | |
| run: | | |
| echo "Run client step failed" | |
| exit 1 | |
| loom: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| crate: [quic/s2n-quic-core] | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| submodules: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal | |
| rustup override set stable | |
| - uses: camshaft/rust-cache@v1 | |
| with: | |
| key: ${{ matrix.crate }} | |
| - name: ${{ matrix.crate }} | |
| # run the tests with release mode since some of the loom models can be expensive | |
| run: cd ${{ matrix.crate }} && cargo test --release loom | |
| env: | |
| RUSTFLAGS: --cfg loom -Cdebug-assertions | |
| xdp: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| lfs: true | |
| - name: Install rust toolchain | |
| id: toolchain | |
| run: | | |
| rustup toolchain install stable --profile minimal --component rustfmt | |
| rustup override set stable | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Install bpf-linker | |
| run: cargo install bpf-linker@0.10.4 | |
| - name: Build ebpf | |
| working-directory: tools/xdp | |
| env: | |
| RUST_LOG: trace | |
| run: cargo +stable xtask ci | |
| dc-wireshark: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macOS-latest] | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| lfs: true | |
| - name: Install rust toolchain | |
| working-directory: dc/wireshark | |
| run: | | |
| rustup toolchain install stable --profile minimal --component rustfmt | |
| rustup override set stable | |
| - uses: camshaft/install@v1 | |
| with: | |
| crate: bindgen-cli | |
| bins: bindgen | |
| - uses: camshaft/rust-cache@v1 | |
| - name: Generate bindings | |
| working-directory: dc/wireshark | |
| run: cargo xtask bindings | |
| - name: Run cargo fmt | |
| working-directory: dc/wireshark | |
| run: cargo fmt --all -- --check | |
| - name: Run tests | |
| working-directory: dc/wireshark | |
| run: cargo xtask test | |
| - name: Run build | |
| working-directory: dc/wireshark | |
| run: cargo xtask build | |
| ci-status-report: | |
| runs-on: ubuntu-latest | |
| if: ${{ always() }} | |
| needs: [env, rustfmt, clippy, udeps, doc, test, test-windows-gnu, asan, fips, miri, no_std, compliance, coverage, crates, examples, recovery-simulations, sims, copyright, s2n-events, generate-events, snapshots, timing, typos, kani, dhat, loom, xdp, dc-wireshark] | |
| steps: | |
| - uses: aws-actions/configure-aws-credentials@v6.2.3 | |
| if: github.event_name == 'push' || github.event_name == 'schedule' || github.repository == github.event.pull_request.head.repo.full_name | |
| with: | |
| role-to-assume: arn:aws:iam::003495580562:role/GitHubOIDCRole | |
| role-session-name: S2nQuicGHASession | |
| aws-region: us-west-2 | |
| - name: Report daily CI run to CloudWatch | |
| if: github.event_name == 'push' || github.event_name == 'schedule' || github.repository == github.event.pull_request.head.repo.full_name | |
| run: | | |
| METRIC_VALUE=${{ contains(needs.*.result, 'failure') && '1' || '0' }} | |
| aws cloudwatch put-metric-data --namespace "Github" --metric-name "ActionCIFailure" \ | |
| --value $METRIC_VALUE --dimensions Initiator=${{github.event_name}} --timestamp $(date +%s) | |
| - name: Calculate workflow duration | |
| run: | | |
| START_TIME=${{ needs.env.outputs.start-time }} | |
| END_TIME=$(date +%s) | |
| DURATION_SECONDS=$((END_TIME - START_TIME)) | |
| DURATION_MINUTES=$(echo "scale=2; $DURATION_SECONDS / 60" | bc) | |
| CI_STATUS="${{ contains(needs.*.result, 'failure') && 'failure' || 'success' }}" | |
| echo "Workflow duration: $DURATION_MINUTES minutes" | |
| echo "CI Status: $CI_STATUS" | |
| echo "Event type: ${{ github.event_name }}" | |
| # Save for next step | |
| echo "DURATION_MINUTES=$DURATION_MINUTES" >> $GITHUB_ENV | |
| echo "CI_STATUS=$CI_STATUS" >> $GITHUB_ENV | |
| echo "END_TIME=$END_TIME" >> $GITHUB_ENV | |
| - name: Report workflow duration to CloudWatch | |
| if: github.event_name == 'push' || github.event_name == 'schedule' || github.repository == github.event.pull_request.head.repo.full_name | |
| run: | | |
| aws cloudwatch put-metric-data \ | |
| --namespace "Github" \ | |
| --metric-name "ActionCIDuration" \ | |
| --value $DURATION_MINUTES \ | |
| --dimensions Status=$CI_STATUS \ | |
| --timestamp $END_TIME | |
| echo "Successfully reported workflow duration to CloudWatch" |