Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions .github/workflows/lint-and-unit-tests.yml
Original file line number Diff line number Diff line change
@@ -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