Skip to content
98 changes: 79 additions & 19 deletions .github/workflows/gotip-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
workflow_dispatch: { } # manually

env:
TEST_RESULTS: /tmp/tip-results # path to where test results will be saved
TEST_RESULTS: ${{ github.workspace }}/tip-results # path to where test results will be saved

permissions:
id-token: write
Expand Down Expand Up @@ -43,28 +43,88 @@ jobs:
ref: ${{ github.ref }}
repository: DataDog/dd-trace-go

- name: Get Gotip
run: |-
go install golang.org/dl/gotip@latest
echo "$HOME/go/bin" >> "$GITHUB_PATH"
echo "${{ github.workspace }}/bin" >> "$GITHUB_PATH"
- name: Setup Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version: stable
cache-dependency-path: '**/go.sum'

- name: Capture trusted commit SHA
# Pinned before any sandboxed step so we can re-checkout this exact
# commit after the sandbox runs. Anything that escapes the sandbox
# could otherwise rewrite .git/HEAD or refs and trick the host into
# running attacker-controlled code via local actions.
id: trusted
run: echo "sha=$(git rev-parse HEAD)" >> "${GITHUB_OUTPUT}"

- name: Run tests with gotip (sandboxed)
# gotip pulls and runs the latest Go toolchain. Keep that toolchain and
# the test process inside gVisor, persisting only reports/coverage.
uses: geomys/sandboxed-step@7d75eb49d17fdeeb3656b3a57d35932d205bcfb9 # v1.2.1
with:
persist-workspace-changes: 'true'
env: |
DD_APPSEC_WAF_TIMEOUT=1h
GO_CMD=gotip
TEST_RESULTS=${{ env.TEST_RESULTS }}
run: |-
mkdir -p "${GITHUB_WORKSPACE}/bin"
GOBIN="${GITHUB_WORKSPACE}/bin" go install golang.org/dl/gotip@latest
export PATH="${GITHUB_WORKSPACE}/bin:${PATH}"
./scripts/install_tools.sh --bin-dir "${GITHUB_WORKSPACE}/bin"
gotip download
./scripts/ci_test_core.sh

- name: Download dependencies
env:
GO_CMD: gotip
- name: Stage sandbox artifacts outside workspace
# Move the test results and coverage files to RUNNER_TEMP so the
# next checkout (which wipes the workspace) does not delete them.
# Only regular files are staged, to avoid following any symlinks
# that may have been planted inside the sandbox.
id: stage
if: always()
run: |-
./scripts/install_tools.sh --bin-dir ${{ github.workspace }}/bin
gotip download
set -euo pipefail
SAFE="${RUNNER_TEMP}/sandbox-artifacts"
rm -rf "${SAFE}"
mkdir -p "${SAFE}"
if [ -d "${TEST_RESULTS}" ]; then
( cd "${TEST_RESULTS}" && find . -type f -print0 \
| tar --null --no-recursion -T - -cf "${SAFE}/test-results.tar" )
fi
( cd "${GITHUB_WORKSPACE}" \
&& find . -type f \( -name 'coverage*.txt' -o -name 'profile.cov' \) -print0 \
| tar --null --no-recursion -T - -cf "${SAFE}/coverage.tar" ) || true

- name: Run tests
env:
DD_APPSEC_WAF_TIMEOUT: 1h
TEST_RESULTS: ${{ env.TEST_RESULTS }}
GO_CMD: gotip
run: ./scripts/ci_test_core.sh
- name: Re-checkout trusted commit after sandbox
# Wipe the (potentially tampered) workspace and check out the SHA we
# captured before the sandbox ran. This restores .git, tracked files,
# and any local actions to a known-good state before any credentialed
# local action is invoked.
id: recheckout
if: always()
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
ref: ${{ steps.trusted.outputs.sha }}
repository: DataDog/dd-trace-go
clean: true

- name: Restore sandbox artifacts
id: restore
if: always() && steps.recheckout.outcome == 'success'
run: |-
set -euo pipefail
SAFE="${RUNNER_TEMP}/sandbox-artifacts"
mkdir -p "${TEST_RESULTS}"
if [ -f "${SAFE}/test-results.tar" ]; then
tar -C "${TEST_RESULTS}" -xf "${SAFE}/test-results.tar"
fi
if [ -f "${SAFE}/coverage.tar" ]; then
tar -C "${GITHUB_WORKSPACE}" -xf "${SAFE}/coverage.tar"
fi

- name: Upload the results to Datadog CI App
if: always()
if: always() && steps.restore.outcome == 'success'
continue-on-error: true
uses: ./.github/actions/dd-ci-upload
with:
Expand All @@ -73,7 +133,7 @@ jobs:
tags: go:gotip,arch:${{ runner.arch }},os:${{ runner.os }}

- name: Upload Coverage
if: always()
if: always() && steps.restore.outcome == 'success'
continue-on-error: true
uses: ./.github/actions/codecov-upload
with:
Expand Down
47 changes: 33 additions & 14 deletions .github/workflows/govulncheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ permissions:
jobs:
# Non-blocking: generates SARIF and uploads to GitHub Code Scanning.
# Replaces Dependabot Security Alerts with reachability-aware findings.
# Uses the official golang/govulncheck-action — see PR description for
# Uses the official golang/govulncheck-action — see PR #4599 for
# the enterprise allowlist request context.
# NOTE: Only core packages are scanned here. Contrib modules are scanned
# separately in govulncheck-contribs-analysis (SARIF, non-blocking) and
# in govulncheck-tests (blocking, sandboxed).
# separately in govulncheck-contribs-analysis (SARIF, non-blocking,
# sandboxed) and in govulncheck-tests (blocking, sandboxed).
govulncheck-analysis:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -114,22 +114,36 @@ jobs:
with:
go-version: stable
cache-dependency-path: '**/go.sum'
- name: Run govulncheck on contrib modules (SARIF)
- name: Run govulncheck on contrib modules (SARIF, sandboxed)
# geomys/sandboxed-step uses gVisor to confine execution, preventing
# supply chain attacks from exfiltrating tokens or making network calls.
# Installs govulncheck and runs govulncheck-contribs-sarif.sh, which
# scans each contrib module and merges results into one SARIF file.
# -format sarif exits 0 even when vulnerabilities are found.
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
./.github/workflows/apps/govulncheck-contribs-sarif.sh govulncheck-contribs.sarif
- name: Upload contrib SARIF to GitHub Code Scanning
uses: geomys/sandboxed-step@7d75eb49d17fdeeb3656b3a57d35932d205bcfb9 # v1.2.1
with:
persist-workspace-changes: 'true'
run: |-
mkdir -p "${GITHUB_WORKSPACE}/bin"
GOBIN="${GITHUB_WORKSPACE}/bin" go install golang.org/x/vuln/cmd/govulncheck@latest
export PATH="${GITHUB_WORKSPACE}/bin:${PATH}"
./.github/workflows/apps/govulncheck-contribs-sarif.sh govulncheck-contribs.sarif
- name: Restore workspace after sandbox
id: restore
if: always()
run: |-
git reset --hard HEAD
git clean -fdx -e govulncheck-contribs.sarif
- name: Upload contrib SARIF to GitHub Code Scanning
if: always() && steps.restore.outcome == 'success' && hashFiles('govulncheck-contribs.sarif') != ''
uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1
with:
sarif_file: govulncheck-contribs.sarif
category: govulncheck-contribs

# Blocking: fails the build if any reachable vulnerability is found.
# Scans both core packages and all contrib modules (each with its own go.mod).
# govulncheck execution is sandboxed via geomys/sandboxed-step (gVisor).
govulncheck-tests:
runs-on: ubuntu-latest
steps:
Expand All @@ -142,9 +156,14 @@ jobs:
with:
go-version: stable
cache-dependency-path: '**/go.sum'
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Run govulncheck (core)
run: govulncheck ./ddtrace/... ./appsec/... ./profiler/... ./internal/... ./instrumentation/...
- name: Run govulncheck (contrib)
run: ./.github/workflows/apps/govulncheck-contribs-v2.sh
- name: Run govulncheck (sandboxed)
# geomys/sandboxed-step uses gVisor to confine execution, preventing
# supply chain attacks from exfiltrating tokens or making network calls.
uses: geomys/sandboxed-step@7d75eb49d17fdeeb3656b3a57d35932d205bcfb9 # v1.2.1
with:
run: |
mkdir -p "${GITHUB_WORKSPACE}/bin"
GOBIN="${GITHUB_WORKSPACE}/bin" go install golang.org/x/vuln/cmd/govulncheck@latest
export PATH="${GITHUB_WORKSPACE}/bin:${PATH}"
govulncheck ./ddtrace/... ./appsec/... ./profiler/... ./internal/... ./instrumentation/...
./.github/workflows/apps/govulncheck-contribs-v2.sh
114 changes: 91 additions & 23 deletions .github/workflows/smoke-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,29 @@ jobs:
tools-dir: ${{ github.workspace }}/_tools
tools-bin: ${{ github.workspace }}/bin

- name: go get -u
run: |-
mkdir -p "$TEST_RESULTS"
# shellcheck disable=SC2086
go get -u -t $PACKAGES
go mod tidy
find . -iname go.mod -exec dirname {} \; | while read -r d; do pushd "$d" && go mod tidy && popd; done

- name: Install requested go-libddwaf version
if: github.event_name == 'workflow_call' && inputs.go-libddwaf-ref != ''
run: |-
go get -u -t github.com/DataDog/go-libddwaf/v4@${{ inputs.go-libddwaf-ref }}
go mod tidy

- name: Compile dd-trace-go
run: |
# shellcheck disable=SC2086
go build $PACKAGES
- name: Compile dd-trace-go with updated dependencies (sandboxed)
# go get -u executes dependency code from the network. Keep those
# changes inside the gVisor sandbox; this setup job only needs to prove
# the updated dependency graph still compiles.
uses: geomys/sandboxed-step@7d75eb49d17fdeeb3656b3a57d35932d205bcfb9 # v1.2.1
with:
env: |
GOPROXY=${{ env.GOPROXY }}
GO_LIBDDWAF_REF=${{ inputs.go-libddwaf-ref }}
PACKAGES=${{ env.PACKAGES }}
TEST_RESULTS=${{ env.TEST_RESULTS }}
run: |-
mkdir -p "$TEST_RESULTS"
# shellcheck disable=SC2086
go get -u -t $PACKAGES
go mod tidy
find . -iname go.mod -exec dirname {} \; | while read -r d; do pushd "$d" && go mod tidy && popd; done
if [ -n "${GO_LIBDDWAF_REF:-}" ]; then
go get -u -t "github.com/DataDog/go-libddwaf/v4@${GO_LIBDDWAF_REF}"
go mod tidy
fi
# shellcheck disable=SC2086
go build $PACKAGES

- name: Compute Matrix
id: matrix
Expand All @@ -92,6 +97,8 @@ jobs:
chunk: ${{ fromJson(needs.setup-env.outputs.matrix) }}
runs-on: ubuntu-latest
if: github.repository_owner == 'DataDog' # only run on DataDog's repository, not in forks
env:
TEST_RESULTS: ${{ github.workspace }}/test-results
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Expand All @@ -108,27 +115,88 @@ jobs:
go-version: stable
tools-dir: ${{ github.workspace }}/_tools
tools-bin: ${{ github.workspace }}/bin
- name: Test contribs
- name: Capture trusted commit SHA
# Pinned before any sandboxed step so we can re-checkout this exact
# commit after the sandbox runs. Anything that escapes the sandbox
# could otherwise rewrite .git/HEAD or refs and trick the host into
# running attacker-controlled code via local actions.
id: trusted
run: echo "sha=$(git rev-parse HEAD)" >> "${GITHUB_OUTPUT}"
- name: Test contribs (sandboxed)
# It needs to run before "Test dd-trace-go" to avoid TestTelemetryEnabled tests to fail.
# The smoke script runs go get -u inside each contrib module, so run it
# in gVisor and persist only the generated reports/coverage for uploads.
uses: geomys/sandboxed-step@7d75eb49d17fdeeb3656b3a57d35932d205bcfb9 # v1.2.1
with:
persist-workspace-changes: 'true'
env: |
GOPROXY=${{ env.GOPROXY }}
TEST_RESULTS=${{ env.TEST_RESULTS }}
run: |-
export PATH="${GITHUB_WORKSPACE}/bin:${PATH}"
./scripts/ci_test_contrib.sh smoke ${{ toJson(matrix.chunk) }}
- name: Stage sandbox artifacts outside workspace
# Move the test results and coverage files to RUNNER_TEMP so the
# next checkout (which wipes the workspace) does not delete them.
# Only regular files are staged, to avoid following any symlinks
# that may have been planted inside the sandbox.
id: stage
if: always()
run: |-
export PATH="${{ github.workspace }}/bin:${PATH}"
./scripts/ci_test_contrib.sh smoke ${{ toJson(matrix.chunk) }}
set -euo pipefail
SAFE="${RUNNER_TEMP}/sandbox-artifacts"
rm -rf "${SAFE}"
mkdir -p "${SAFE}"
if [ -d "${TEST_RESULTS}" ]; then
( cd "${TEST_RESULTS}" && find . -type f -print0 \
| tar --null --no-recursion -T - -cf "${SAFE}/test-results.tar" )
fi
( cd "${GITHUB_WORKSPACE}" \
&& find . -type f \( -name 'coverage*.txt' -o -name 'profile.cov' \) -print0 \
| tar --null --no-recursion -T - -cf "${SAFE}/coverage.tar" ) || true
- name: Re-checkout trusted commit after sandbox
# Wipe the (potentially tampered) workspace and check out the SHA we
# captured before the sandbox ran. This restores .git, tracked files,
# and any local actions to a known-good state before any credentialed
# local action is invoked.
id: recheckout
if: always()
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
ref: ${{ steps.trusted.outputs.sha }}
repository: DataDog/dd-trace-go
clean: true
- name: Restore sandbox artifacts
id: restore
if: always() && steps.recheckout.outcome == 'success'
run: |-
set -euo pipefail
SAFE="${RUNNER_TEMP}/sandbox-artifacts"
mkdir -p "${TEST_RESULTS}"
if [ -f "${SAFE}/test-results.tar" ]; then
tar -C "${TEST_RESULTS}" -xf "${SAFE}/test-results.tar"
fi
if [ -f "${SAFE}/coverage.tar" ]; then
tar -C "${GITHUB_WORKSPACE}" -xf "${SAFE}/coverage.tar"
fi
- name: Get Datadog credentials
id: dd-sts
if: always() && steps.restore.outcome == 'success'
continue-on-error: true
uses: DataDog/dd-sts-action@2e8187910199bd93129520183c093e19aa585c75
with:
policy: dd-trace-go
- name: Upload the results to Datadog CI App
if: always()
if: always() && steps.restore.outcome == 'success'
continue-on-error: true
uses: ./.github/actions/dd-ci-upload
with:
dd-api-key: ${{ steps.dd-sts.outputs.api_key }}
path: ${{ env.TEST_RESULTS }}
tags: go:stable,arch:${{ runner.arch }},os:${{ runner.os }}
- name: Upload Coverage
if: always()
if: always() && steps.restore.outcome == 'success'
continue-on-error: true
uses: ./.github/actions/codecov-upload
with:
Expand Down
Loading