Skip to content

fix(ci): harden release-proposal-dispatch against untrusted main_start_ref #17551

fix(ci): harden release-proposal-dispatch against untrusted main_start_ref

fix(ci): harden release-proposal-dispatch against untrusted main_start_ref #17551

Workflow file for this run

name: Test
on:
pull_request:
types: ['opened', 'edited', 'reopened', 'synchronize']
branches-ignore:
- "v[0-9]+.[0-9]+.[0-9]+.[0-9]+"
- release
push:
branches:
- main
- mq-working-branch-*
schedule:
- cron: '0 6 * * *'
env:
CARGO_TERM_COLOR: always
jobs:
setup:
runs-on: ubuntu-latest
outputs:
packages-count: ${{ steps.set-packages.outputs.packages-count }}
packages: ${{ steps.set-packages.outputs.packages }}
crashtracker-feature: ${{ steps.set-packages.outputs.crashtracker-feature }}
run-test-spawn: ${{ steps.set-packages.outputs.run-test-spawn }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
with:
fetch-depth: 0
- name: Get crates report
id: changed-crates
uses: ./.github/actions/crates-reporter
- name: Set unit test packages
id: set-packages
env:
CHANGED_CRATES_STATUS: ${{ steps.changed-crates.outputs.status }}
CHANGED_CRATES_COUNT: ${{ steps.changed-crates.outputs.crates_count }}
AFFECTED_CRATES: ${{ steps.changed-crates.outputs.affected_crates }}
run: |
if [[ "$CHANGED_CRATES_STATUS" == "skipped" ]]; then
COUNT="1"
PACKAGES=""
CRASHTRACKER_FEATURE="--features libdd-crashtracker/generate-unit-test-files"
RUN_TEST_SPAWN="true"
elif [[ "$CHANGED_CRATES_COUNT" == "0" ]]; then
COUNT="0"
PACKAGES=""
CRASHTRACKER_FEATURE=""
RUN_TEST_SPAWN="false"
else
COUNT=$(echo "$AFFECTED_CRATES" | jq 'length')
PACKAGES=$(echo "$AFFECTED_CRATES" | jq -r 'map("-p " + .) | join(" ")')
if echo "$AFFECTED_CRATES" | jq -e 'any(. == "libdd-crashtracker")' > /dev/null; then
CRASHTRACKER_FEATURE="--features libdd-crashtracker/generate-unit-test-files"
else
CRASHTRACKER_FEATURE=""
fi
if echo "$AFFECTED_CRATES" | jq -e 'any(. == "test_spawn_from_lib")' > /dev/null; then
RUN_TEST_SPAWN="true"
else
RUN_TEST_SPAWN="false"
fi
fi
{
echo "packages-count=$COUNT"
echo "packages=$PACKAGES"
echo "crashtracker-feature=$CRASHTRACKER_FEATURE"
echo "run-test-spawn=$RUN_TEST_SPAWN"
} >> $GITHUB_OUTPUT
test:
name: "cargo test #${{ matrix.platform }}"
needs: setup
if: needs.setup.outputs.packages-count != '0'
# Ubuntu jobs run on the larger APM runner pool — the default GitHub-hosted
# ubuntu-latest disk fills up partway through the workspace build.
runs-on: ${{ (matrix.platform == 'ubuntu-latest' && fromJSON('{"labels":"ubuntu-latest-16-cores","group":"APM Larger Runners"}')) || matrix.platform }}
permissions:
checks: write
contents: read
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
PACKAGES: ${{ needs.setup.outputs.packages }}
CRASHTRACKER_FEATURE: ${{ needs.setup.outputs.crashtracker-feature }}
TRACING_CRATES: "libdd-data-pipeline libdd-trace-utils libdd-tracer-flare"
strategy:
matrix:
platform: [windows-latest, ubuntu-latest, macos-15]
fail-fast: false
steps:
- name: Free Disk Space (Ubuntu only)
if: runner.os == 'Linux' && matrix.platform == 'ubuntu-latest'
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # 1.3.1
with:
tool-cache: true
android: true
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: true
- name: Checkout sources
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
with:
submodules: recursive
- id: rust-version
# rustup auto-installs the version pinned in rust-toolchain.toml on first invocation.
# On Windows run happens in a PowerShell, so start bash explicitly.
run: bash -c 'echo "version=$(rustc --version | cut -d" " -f2)" >> $GITHUB_OUTPUT'
- name: Install cargo nextest
uses: taiki-e/install-action@2c41309d51ede152b6f2ee6bf3b71e6dc9a8b7df # 2.49.27
with:
tool: nextest@0.9.96
- name: Install Go (macOS and Linux)
if: runner.os == 'macOS' || runner.os == 'Linux'
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: 'stable'
cache: false
- name: Cache [rust]
uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # 2.8.1
with:
cache-targets: true # cache build artifacts
cache-bin: true # cache the ~/.cargo/bin directory
- name: "Remove nextest CI report"
shell: bash
run: rm -rf target/nextest/ci/junit.xml
- name: "[${{ steps.rust-version.outputs.version}}] cargo build"
shell: bash
run: |
if [[ -z "$PACKAGES" ]]; then
cargo build --workspace --exclude builder --verbose
else
# word splitting on $PACKAGES is intentional
# shellcheck disable=SC2086
cargo build $PACKAGES --verbose
fi
- name: "[${{ steps.rust-version.outputs.version}}] cargo test (doc) and cargo nextest run"
shell: bash
# Run doc tests with cargo test and run tests with nextest and generate junit.xml
run: |
if [[ -z "$PACKAGES" ]]; then
# shellcheck disable=SC2086
cargo test --workspace $CRASHTRACKER_FEATURE --exclude builder --doc --verbose
# shellcheck disable=SC2086
cargo nextest run --workspace $CRASHTRACKER_FEATURE --profile ci --verbose --no-tests=pass -E '!test(tracing_integration_tests::)'
cargo nextest run -p libdd-http-client --no-default-features --features hyper-backend,https --profile ci --verbose
else
# shellcheck disable=SC2086
cargo test $PACKAGES $CRASHTRACKER_FEATURE --doc --verbose
# shellcheck disable=SC2086
cargo nextest run $PACKAGES $CRASHTRACKER_FEATURE --profile ci --verbose --no-tests=pass -E '!test(tracing_integration_tests::)'
if echo "$PACKAGES" | grep -q "libdd-http-client"; then
cargo nextest run -p libdd-http-client --no-default-features --features hyper-backend,https --profile ci --verbose
fi
fi
env:
RUST_BACKTRACE: full
- name: "[${{ steps.rust-version.outputs.version}}] cargo nextest run --all-features"
shell: bash
run: |
if [[ -z "$PACKAGES" ]]; then
cargo nextest run --workspace --all-features --exclude test_spawn_from_lib --verbose --no-tests=pass -E '!test(tracing_integration_tests::)'
else
# shellcheck disable=SC2086
cargo nextest run $PACKAGES --all-features --verbose --no-tests=pass -E '!test(tracing_integration_tests::) & !package(test_spawn_from_lib)'
fi
env:
RUST_BACKTRACE: full
- name: "[${{ steps.rust-version.outputs.version}}] Tracing integration tests"
if: runner.os == 'Linux'
shell: bash
run: |
if [[ -z "$PACKAGES" ]]; then
# shellcheck disable=SC2086
for crate in $TRACING_CRATES; do
PACKAGES="$PACKAGES -p $crate"
done
cargo nextest run $PACKAGES --profile ci --test-threads=1 --verbose --no-tests=pass -E 'test(tracing_integration_tests::)'
else
TRACING_PACKAGES=""
for crate in $TRACING_CRATES; do
if echo "$PACKAGES" | grep -qw -- "-p $crate"; then
TRACING_PACKAGES="$TRACING_PACKAGES -p $crate"
fi
done
if [[ -z "$TRACING_PACKAGES" ]]; then
echo "No tracing integration test crates found in PACKAGES, skipping."
else
# shellcheck disable=SC2086
cargo nextest run $TRACING_PACKAGES --profile ci --test-threads=1 --verbose --no-tests=pass -E 'test(tracing_integration_tests::)'
fi
fi
env:
RUST_BACKTRACE: full
- name: "[${{ steps.rust-version.outputs.version}}] RUSTFLAGS=\"-C prefer-dynamic\" cargo nextest run --package test_spawn_from_lib --features prefer-dynamic -E '!test(tracing_integration_tests::)'"
shell: bash
run: cargo nextest run --package test_spawn_from_lib --features prefer-dynamic -E '!test(tracing_integration_tests::)'
env:
RUSTFLAGS: "-C prefer-dynamic"
RUST_BACKTRACE: full
- name: Add file attributes to JUnit XML
if: success() || failure()
shell: bash
run: cargo run --bin add_junit_file_attributes -- target/nextest/ci/junit.xml
- name: Report Test Results
if: success() || failure()
uses: mikepenz/action-junit-report@db71d41eb79864e25ab0337e395c352e84523afe # 4.3.1
with:
report_paths: "target/nextest/ci/junit.xml"
check_name: "[${{ matrix.platform }}:${{ steps.rust-version.outputs.version }}] test report"
include_passed: true
- name: Upload test results to Datadog
if: success() || failure()
shell: bash
run: |
# Download datadog-ci binary
if [ "${{ runner.os }}" == "Linux" ]; then
URL="https://github.com/DataDog/datadog-ci/releases/download/v4.2.2/datadog-ci_linux-x64"
OUTPUT="datadog-ci"
CHECKSUM_CMD="sha256sum"
EXPECTED_CHECKSUM="3e1e9649d15d3feacced89ec90de66151046a58c7844217e4112362ad8dbf8d1"
elif [ "${{ runner.os }}" == "Windows" ]; then
URL="https://github.com/DataDog/datadog-ci/releases/download/v4.2.2/datadog-ci_win-x64"
OUTPUT="datadog-ci.exe"
CHECKSUM_CMD="sha256sum"
EXPECTED_CHECKSUM="13313279cb884fe098e2f80ca21d23e67b78a090a12e891e8e35be653ee2bbd0"
elif [ "${{ runner.os }}" == "macOS" ]; then
URL="https://github.com/DataDog/datadog-ci/releases/download/v4.2.2/datadog-ci_darwin-x64"
OUTPUT="datadog-ci"
CHECKSUM_CMD="shasum -a 256"
EXPECTED_CHECKSUM="071a6140b17438b3f9dd6c65da48b48ea03fc310034fa624ce874fdb6c325da4"
fi
echo "Downloading datadog-ci from $URL"
curl -L --fail --retry 3 -o "$OUTPUT" "$URL"
chmod +x "$OUTPUT"
# Verify checksum
ACTUAL_CHECKSUM=$($CHECKSUM_CMD "$OUTPUT" | cut -d' ' -f1)
echo "Expected checksum: $EXPECTED_CHECKSUM"
echo "Actual checksum: $ACTUAL_CHECKSUM"
if [ "$ACTUAL_CHECKSUM" != "$EXPECTED_CHECKSUM" ]; then
echo "Checksum verification failed!"
exit 1
fi
echo "Checksum verification passed"
# Upload test results
./"$OUTPUT" junit upload \
--service libdatadog \
--env ci \
--logs \
--tags rustc:${{ steps.rust-version.outputs.version }},arch:${{ runner.arch }},os:${{ runner.os }},platform:${{ matrix.platform }} \
target/nextest/ci/junit.xml
env:
DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }}
cross-centos7:
name: Test x86_64-unknown-linux-gnu on centOS7 docker image
needs: setup
if: needs.setup.outputs.packages-count != '0'
runs-on: ubuntu-latest
env:
PACKAGES: ${{ needs.setup.outputs.packages }}
CRASHTRACKER_FEATURE: ${{ needs.setup.outputs.crashtracker-feature }}
concurrency:
group: ci-${{ github.ref == 'refs/heads/main' && github.run_id || github.ref }}-cross-centos7
cancel-in-progress: true
steps:
- name: Free Disk Space
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # 1.3.1
with:
tool-cache: true
android: true
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: true
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
with:
submodules: recursive
- name: Cache [rust]
uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # 2.8.1
with:
cache-targets: true # cache build artifacts
cache-bin: true # cache the ~/.cargo/bin directory
- name: Build CentOS 7 Docker image
run: docker build -t libdatadog-centos7 -f tools/docker/Dockerfile.centos .
- name: "cargo nextest run (centos7)"
# Run docker as a user, not the default root
# Mount and use the runner's toolchain as it's the same arch
# exclude tracing integration tests since they require docker in docker to run a test-agent
shell: bash
run: |
if [[ -z "$PACKAGES" ]]; then
# shellcheck disable=SC2086
NEXTEST_CMD="cargo nextest run --workspace $CRASHTRACKER_FEATURE --profile ci --no-tests=pass -E '!test(tracing_integration_tests::)'"
else
# shellcheck disable=SC2086
NEXTEST_CMD="cargo nextest run $PACKAGES $CRASHTRACKER_FEATURE --profile ci --no-tests=pass -E '!test(tracing_integration_tests::)'"
fi
docker run --rm \
--user "$(id -u):$(id -g)" \
-v "${{ github.workspace }}:/workspace" \
-v "${CARGO_HOME:-$HOME/.cargo}:/usr/local/cargo" \
-v "${RUSTUP_HOME:-$HOME/.rustup}:/usr/local/rustup" \
-e CARGO_HOME=/usr/local/cargo \
-e RUSTUP_HOME=/usr/local/rustup \
-e PATH=/usr/local/cargo/bin:/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin:/opt/rh/devtoolset-11/root/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
-w /workspace \
libdatadog-centos7 \
sh -c "$NEXTEST_CMD"
- name: Add file attributes to JUnit XML
if: success() || failure()
run: cargo run --bin add_junit_file_attributes -- target/nextest/ci/junit.xml
- name: Report Test Results
if: success() || failure()
uses: mikepenz/action-junit-report@db71d41eb79864e25ab0337e395c352e84523afe # 4.3.1
with:
report_paths: "target/nextest/ci/junit.xml"
check_name: "[centos7] test report"
include_passed: true
- name: Upload test results to Datadog
if: success() || failure()
run: |
URL="https://github.com/DataDog/datadog-ci/releases/download/v4.2.2/datadog-ci_linux-x64"
OUTPUT="datadog-ci"
EXPECTED_CHECKSUM="3e1e9649d15d3feacced89ec90de66151046a58c7844217e4112362ad8dbf8d1"
echo "Downloading datadog-ci from $URL"
curl -L --fail --retry 3 -o "$OUTPUT" "$URL"
chmod +x "$OUTPUT"
ACTUAL_CHECKSUM=$(sha256sum "$OUTPUT" | cut -d' ' -f1)
echo "Expected checksum: $EXPECTED_CHECKSUM"
echo "Actual checksum: $ACTUAL_CHECKSUM"
if [ "$ACTUAL_CHECKSUM" != "$EXPECTED_CHECKSUM" ]; then
echo "Checksum verification failed!"
exit 1
fi
echo "Checksum verification passed"
./"$OUTPUT" junit upload \
--service libdatadog \
--env ci \
--logs \
--tags arch:${{ runner.arch }},os:Linux,platform:centos7 \
target/nextest/ci/junit.xml
env:
DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }}
no-certs-exporter:
name: "exporter_e2e tests (no CA certificates)"
runs-on: ubuntu-latest
concurrency:
group: ci-${{ github.ref == 'refs/heads/main' && github.run_id || github.ref }}-no-certs-exporter
cancel-in-progress: true
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
with:
submodules: recursive
- name: Cache [rust]
uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # 2.8.1
with:
cache-targets: true
cache-bin: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # 3.10.0
- name: Pre-fetch dependencies (requires network/certs on the runner)
run: cargo fetch
- name: Build no-certs Docker image
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
file: tools/docker/Dockerfile.no-certs
tags: libdatadog-no-certs
load: true
cache-from: type=gha,scope=no-certs-docker
cache-to: type=gha,scope=no-certs-docker,mode=max
- name: "cargo test exporter_e2e (no CA certificates)"
# Mount the runner's Rust toolchain and cargo cache — no network needed inside.
# The container has no CA certificates, reproducing minimal environments like
# bare ubuntu:20.04. Regression test for 9a61cae82 which unconditionally loaded
# the system cert store even for plain HTTP/unix endpoints.
run: >-
docker run --rm
--user "$(id -u):$(id -g)"
-v "${{ github.workspace }}:/workspace"
-v "${CARGO_HOME:-$HOME/.cargo}:/usr/local/cargo"
-v "${RUSTUP_HOME:-$HOME/.rustup}:/usr/local/rustup"
-e CARGO_HOME=/usr/local/cargo
-e RUSTUP_HOME=/usr/local/rustup
-e PATH=/usr/local/cargo/bin:/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
-w /workspace
libdatadog-no-certs
cargo test -p libdd-profiling --test exporter_e2e
wasm:
name: "cargo check --target wasm32-unknown-unknown"
runs-on: ubuntu-latest
concurrency:
group: ci-${{ github.ref == 'refs/heads/main' && github.run_id || github.ref }}-wasm
cancel-in-progress: true
steps:
- name: Checkout sources
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2
with:
submodules: recursive
- name: Install wasm32 target
run: rustup target add wasm32-unknown-unknown
- name: Cache [rust]
uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # 2.8.1
with:
cache-targets: true
cache-bin: true
- name: "cargo check -p libdd-data-pipeline --target wasm32-unknown-unknown --no-default-features"
run: cargo check -p libdd-data-pipeline --target wasm32-unknown-unknown --no-default-features
env:
RUSTFLAGS: "-D warnings -A unused-imports -A dead-code -A unused-variables"