From 730881225274315ea2b00a8d5cb0dafec64caee0 Mon Sep 17 00:00:00 2001 From: Louis Parkin Date: Fri, 10 Jul 2026 17:20:47 +0200 Subject: [PATCH] STAC-25142 Add GitHub Actions lint + unit-test workflow (agent CI migration phase 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ports filename_linting + unbranded/branded unit_tests from .gitlab-ci-agent.yml to GitHub Actions, tracking the active stackstate-7.78.2 pipeline. - filename-linting on `docker` (cheap gate; only needs `git ls-files`). - unbranded/branded unit tests on `xlarge` inside the datadog_build image (tag 7af9194f), pulled via the read-only quay proxy. - 7.78.2 deltas vs 7.71.2: `--major-version` dropped from agent.build/inv test (removed upstream in DD 7.78), and branded runs scripts/verify_branding_literals.sh after fix_branding.sh. Test-execution policy (architect directive — minimize redundant runs): each suite runs once. filename-lint on every PR; the two heavy ~2h suites on pull_request, deduped via concurrency cancel-in-progress. They move to merge_group (run once at land) at phase 6; master/version-branch pushes then build+publish without re-running tests. Security: minimal contents: read, SHA-pinned checkout, persist-credentials false, no PATs, registry-proxy secret only via container.credentials, fork PRs skipped. Zizmor clean; actionlint clean apart from self-hosted labels. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/lint-and-unit-tests.yml | 156 ++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 .github/workflows/lint-and-unit-tests.yml diff --git a/.github/workflows/lint-and-unit-tests.yml b/.github/workflows/lint-and-unit-tests.yml new file mode 100644 index 000000000000..e889595f3979 --- /dev/null +++ b/.github/workflows/lint-and-unit-tests.yml @@ -0,0 +1,156 @@ +name: Lint and unit tests + +# Ported from .gitlab-ci-agent.yml (filename_linting, unbranded_unit_tests, +# branded_unit_tests) as part of the GitLab -> GitHub migration (STAC-25142), +# phase 1: lint + unit tests. Tracks the stackstate-7.78.2 pipeline. +# +# Test-execution policy (architect directive — minimize redundant runs): +# * filename-linting is a cheap gate and runs on every PR. +# * The two unit suites are heavy (each does a full `inv agent.build` + full +# `inv test`, ~2h on an XL runner). They run ONCE per change here, deduped +# via `concurrency: cancel-in-progress`. When the merge queue is enabled +# (phase 6) they move to `merge_group` (run once at land) and drop from +# `pull_request`; master/version-branch pushes then build+publish WITHOUT +# re-running tests. Follow-ups tracked in the migration scope doc: +# - path-filter the heavy suites (skip when no Go/build inputs changed) +# - open question for architects: do we need BOTH unbranded and branded +# on every path, or branded-as-gate + unbranded on the queue only? +# +# Prerequisites for a GREEN run (see scope doc): +# * The GitLab push mirror to this repo must be disabled (done 2026-07-10), +# otherwise a mirror sync overwrites anything pushed to GitHub. +# * This is a PUBLIC repo. The read-only registry-proxy credentials must be +# available to it (org-inherited or provisioned via pulumi-infra): +# vars REGISTRY_HOST, REGISTRY_USER + secret REGISTRY_PASSWORD. Org secrets +# are never exposed to fork PRs, so external-fork PRs skip these jobs. + +on: + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + # conda env baked into the datadog_build image. + CONDA_ENV: ddpy3 + +jobs: + filename-linting: + name: Filename linting + # Same-repo PRs only: the registry-proxy secret is not exposed to fork PRs. + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + runs-on: docker + timeout-minutes: 20 + container: + # datadog_build image (built by datadog-agent-buildimages), pulled via the + # read-only quay proxy — mirrors BUILD_IMAGE in .gitlab-ci.yml (7.78.2 tag). + image: ${{ vars.REGISTRY_HOST }}/quay/stackstate/datadog_build_linux_x64:7af9194f + credentials: + username: ${{ vars.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + steps: + - name: Check out repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: inv linter.filenames + run: | + set -eo pipefail + # linter.filenames only shells out to `git ls-files` + path checks, so + # it needs no Go deps/vendoring (the GitLab job carried that as boilerplate). + . /root/miniforge3/etc/profile.d/conda.sh + conda activate "${CONDA_ENV}" + inv -e linter.filenames + + unbranded-unit-tests: + name: Unit tests (unbranded / DataDog) + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + runs-on: xlarge + timeout-minutes: 150 + container: + image: ${{ vars.REGISTRY_HOST }}/quay/stackstate/datadog_build_linux_x64:7af9194f + credentials: + username: ${{ vars.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + steps: + - name: Check out repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Build agent and run unit tests + run: | + set -eo pipefail + export PATH="$PATH:/usr/local/go/bin" + . /root/miniforge3/etc/profile.d/conda.sh + conda activate "${CONDA_ENV}" + go clean -modcache + go work sync + go work vendor + inv -e deps --verbose + # /go/bin is not cached on ephemeral runners; re-run deps to get tool + # binaries (golint, misspell, ...). + inv deps + export AGENT_GITHUB_ORG=DataDog + export GITHUB_ORG=DataDog + export BRANDED=false + export AGENT_REPO_NAME=datadog-agent + inv -e agent.build --race + gofmt -l -w -s ./pkg ./cmd + inv -e rtloader.test + invoke install-tools + # Go 1.25+ no longer ships prebuilt tool binaries; build covdata into + # GOTOOLDIR so `go test -cover` resolves it (golang/go#75031). + go build -o "$(go env GOTOOLDIR)/covdata" cmd/covdata + # Drop build tags for features StackState does not ship in its images. + export STS_UT_BUILD_EXCLUDE="oracle,trivy,trivy_no_javadb,nvml,jetson,bundle_installer,systemd" + inv -e test --coverage --race --profile --cpus 4 --build-exclude="${STS_UT_BUILD_EXCLUDE}" --timeout=600 + + branded-unit-tests: + name: Unit tests (branded / StackState) + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + runs-on: xlarge + timeout-minutes: 150 + container: + image: ${{ vars.REGISTRY_HOST }}/quay/stackstate/datadog_build_linux_x64:7af9194f + credentials: + username: ${{ vars.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + steps: + - name: Check out repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Build agent and run unit tests + run: | + set -eo pipefail + export PATH="$PATH:/usr/local/go/bin" + . /root/miniforge3/etc/profile.d/conda.sh + conda activate "${CONDA_ENV}" + go clean -modcache + go work sync + go work vendor + inv -e deps --verbose + inv deps + export AGENT_GITHUB_ORG=DataDog + export GITHUB_ORG=DataDog + export BRANDED=true + export AGENT_REPO_NAME=datadog-agent + export OMNIBUS_FORCE_PACKAGES=true + # Rebrand DataDog -> StackState, then verify no unbranded literals remain. + ./fix_branding.sh + ./scripts/verify_branding_literals.sh + inv -e agent.build --race + gofmt -l -w -s ./pkg ./cmd + inv -e rtloader.test + invoke install-tools + go build -o "$(go env GOTOOLDIR)/covdata" cmd/covdata + export STS_UT_BUILD_EXCLUDE="oracle,trivy,trivy_no_javadb,nvml,jetson,bundle_installer,systemd" + inv -e test --coverage --race --profile --cpus 4 --build-exclude="${STS_UT_BUILD_EXCLUDE}" --timeout=600