Skip to content

Process-agent CI

Process-agent CI #91

Workflow file for this run

name: PR278 exact-source image evidence
on:
workflow_dispatch:
permissions: {}
concurrency:
group: process-agent-ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
IMAGE: quay.io/stackstate/stackstate-k8s-process-agent
jobs:
build-and-test:
name: Prebuild, generated-code check, build, and unit tests (${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-24.04
llvm-arch: x86_64
prebuild-image: quay.io/stackstate/datadog_build_system-probe_x64:61b4ad67
builder-image: quay.io/stackstate/datadog_build_deb_x64:61b4ad67
- arch: arm64
runner: ubuntu-24.04-arm
llvm-arch: arm64
prebuild-image: quay.io/stackstate/datadog_build_system-probe_arm64:61b4ad67
builder-image: quay.io/stackstate/datadog_build_deb_arm64:61b4ad67
steps:
- name: Check out source commit
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: c4840469c675351ab1075f8a8469027828635e51
fetch-depth: 0
persist-credentials: false
- name: Generate DataDog eBPF and Go artifacts
env:
LLVM_ARCH: ${{ matrix.llvm-arch }}
PREBUILD_IMAGE: ${{ matrix.prebuild-image }}
run: |
set -euo pipefail
docker run --rm \
--volume "${GITHUB_WORKSPACE}:/workspace" \
--workdir /workspace \
--env LLVM_ARCH="${LLVM_ARCH}" \
--env OUTPUT_USER_ID="$(id -u)" \
--env OUTPUT_GROUP_ID="$(id -g)" \
"${PREBUILD_IMAGE}" \
bash -c '
set -euo pipefail
./prebuild-datadog-agent.sh --generate-no-docker
'
- name: Verify generated code, build, and test
env:
BUILDER_IMAGE: ${{ matrix.builder-image }}
SOURCE_SHA: c4840469c675351ab1075f8a8469027828635e51
run: |
set -euo pipefail
short_sha="$(printf '%s' "${SOURCE_SHA}" | cut -c1-8)"
docker run --rm \
--volume "${GITHUB_WORKSPACE}:/workspace" \
--workdir /workspace \
--env CI=true \
--env GO111MODULE=on \
--env GOPATH=/workspace/.go \
--env PROCESS_AGENT_VERSION="${short_sha}" \
"${BUILDER_IMAGE}" \
bash -c '
source /root/.bashrc
conda activate ddpy3
# The RVM directory hook reads an unset rvm_saved_env variable.
# Keep fail-fast/pipefail without nounset in this legacy builder.
set -eo pipefail
export PATH="${GOPATH}/bin:${PATH}"
go mod verify
gogo_version="$(go list -m -f "{{.Version}}" github.com/gogo/protobuf)"
go install "github.com/gogo/protobuf/protoc-gen-gogofaster@${gogo_version}"
rake protobuf
git diff --exit-code -- model
rake ci
./prebuild-datadog-agent.sh --install-ebpf
git diff --exit-code
'
- name: Upload process-agent image inputs
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: process-agent-${{ matrix.arch }}
path: |
process-agent
ebpf-object-files
if-no-files-found: error
retention-days: 90
image-smoke-and-scan:
name: BCI image smoke test, Trivy secrets/CVEs, and Grype (${{ matrix.arch }})
needs: build-and-test
runs-on: ${{ matrix.runner }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-24.04
long-arch: x86_64
llvm-arch: x86_64
- arch: arm64
runner: ubuntu-24.04-arm
long-arch: aarch64
llvm-arch: arm64
steps:
- name: Check out source commit
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: c4840469c675351ab1075f8a8469027828635e51
persist-credentials: false
- name: Download process-agent image inputs
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: process-agent-${{ matrix.arch }}
path: .
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Resolve image metadata
id: image
env:
SOURCE_SHA: c4840469c675351ab1075f8a8469027828635e51
run: |
set -euo pipefail
short_sha="$(printf '%s' "${SOURCE_SHA}" | cut -c1-8)"
echo "tag=${short_sha}-evidence-${GITHUB_RUN_ID}" >> "${GITHUB_OUTPUT}"
- name: Build local BCI runtime image
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
file: BCI.dockerfile
platforms: linux/${{ matrix.arch }}
load: true
push: false
provenance: false
sbom: false
build-args: |
EBPF_SUBFOLDER=${{ matrix.llvm-arch }}
LONG_ARCH=${{ matrix.long-arch }}
SHORT_ARCH=${{ matrix.arch }}
tags: ${{ env.IMAGE }}:${{ steps.image.outputs.tag }}-${{ matrix.arch }}
- name: Smoke test packaged process-agent binary
env:
ARCH: ${{ matrix.arch }}
TAG: ${{ steps.image.outputs.tag }}
run: |
set -euo pipefail
image="${IMAGE}:${TAG}-${ARCH}"
output="$(docker run --rm \
--entrypoint /opt/stackstate-agent/bin/agent/process-agent \
"${image}" -version)"
printf '%s\n' "${output}"
grep -F "Version: c4840469" <<< "${output}"
healthcheck="$(docker image inspect --format '{{json .Config.Healthcheck.Test}}' "${image}")"
grep -F '/probe.sh' <<< "${healthcheck}"
- name: Scan image with VEX-aware Trivy and Grype
uses: StackVista/image-pipeline/.github/actions/scan-image@6284a6fc006a7cc46a7f00d02c50d5f21b117b63
with:
image: ${{ env.IMAGE }}:${{ steps.image.outputs.tag }}-${{ matrix.arch }}
mode: inform
severity: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
with-grype: true
exceptions-path: exceptions
upload-sarif: false
sarif-category: process-agent-${{ matrix.arch }}
- name: Retain local-image scan reports
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: pr278-local-scan-${{ matrix.arch }}
path: reports/
retention-days: 90
publish-image:
name: Publish and sign commit image (${{ matrix.arch }})
needs: image-smoke-and-scan
if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/evidence/pr278-full-image'
runs-on: ${{ matrix.runner }}
permissions:
contents: read
id-token: write
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-24.04
long-arch: x86_64
llvm-arch: x86_64
- arch: arm64
runner: ubuntu-24.04-arm
long-arch: aarch64
llvm-arch: arm64
steps:
- name: Check out source commit
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: c4840469c675351ab1075f8a8469027828635e51
persist-credentials: false
- name: Download process-agent image inputs
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: process-agent-${{ matrix.arch }}
path: .
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Resolve image tag
id: image
env:
SOURCE_SHA: c4840469c675351ab1075f8a8469027828635e51
run: |
set -euo pipefail
short_sha="$(printf '%s' "${SOURCE_SHA}" | cut -c1-8)"
echo "tag=${short_sha}-evidence-${GITHUB_RUN_ID}" >> "${GITHUB_OUTPUT}"
- name: Resolve canonical OCI labels
id: oci
uses: StackVista/image-pipeline/.github/actions/apply-oci-labels@6284a6fc006a7cc46a7f00d02c50d5f21b117b63
with:
image-name: stackstate-k8s-process-agent
tag: ${{ steps.image.outputs.tag }}
title: SUSE Observability Process Agent
description: Process agent collecting per-process and per-container telemetry for SUSE Observability.
component: stackstate-k8s-process-agent
dockerfile: BCI.dockerfile
base-name: registry.suse.com/bci/bci-micro:15.7
- name: Build, publish, and sign architecture image
uses: StackVista/image-pipeline/.github/actions/push-single-arch@6284a6fc006a7cc46a7f00d02c50d5f21b117b63
with:
image: ${{ env.IMAGE }}
tag: ${{ steps.image.outputs.tag }}
arch: ${{ matrix.arch }}
dockerfile: BCI.dockerfile
labels: |
${{ steps.oci.outputs.labels }}
org.opencontainers.image.revision=c4840469c675351ab1075f8a8469027828635e51
build-args: |
EBPF_SUBFOLDER=${{ matrix.llvm-arch }}
LONG_ARCH=${{ matrix.long-arch }}
SHORT_ARCH=${{ matrix.arch }}
target-registry: quay.io
target-registry-user: ${{ vars.QUAY_USER }}
target-registry-password: ${{ secrets.QUAY_PASSWORD }}
merge-multiarch-manifest:
name: Publish and sign multi-architecture commit image
needs: publish-image
if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/evidence/pr278-full-image'
runs-on: ubuntu-24.04
permissions:
contents: read
id-token: write
steps:
- name: Resolve image tag
id: image
env:
SOURCE_SHA: c4840469c675351ab1075f8a8469027828635e51
run: |
set -euo pipefail
short_sha="$(printf '%s' "${SOURCE_SHA}" | cut -c1-8)"
echo "tag=${short_sha}-evidence-${GITHUB_RUN_ID}" >> "${GITHUB_OUTPUT}"
- name: Merge and sign multi-architecture manifest
uses: StackVista/image-pipeline/.github/actions/merge-multiarch@6284a6fc006a7cc46a7f00d02c50d5f21b117b63
with:
image: ${{ env.IMAGE }}
tag: ${{ steps.image.outputs.tag }}
target-registry: quay.io
target-registry-user: ${{ vars.QUAY_USER }}
target-registry-password: ${{ secrets.QUAY_PASSWORD }}
ci-success:
name: Process-agent CI
needs:
- build-and-test
- image-smoke-and-scan
- publish-image
- merge-multiarch-manifest
- published-image-evidence
if: always()
runs-on: ubuntu-24.04
permissions: {}
steps:
- name: Verify all required jobs succeeded
env:
NEEDS: ${{ toJSON(needs) }}
run: |
set -euo pipefail
failed="$(jq -r '
to_entries[] |
select(.value.result != "success" and .value.result != "skipped") |
.key
' <<< "${NEEDS}")"
if [ -n "${failed}" ]; then
echo "Required process-agent jobs failed:"
printf '%s\n' "${failed}"
exit 1
fi
echo "All required process-agent jobs passed."
published-image-evidence:
name: Published full-image evidence (${{ matrix.arch }})
needs: merge-multiarch-manifest
runs-on: ${{ matrix.runner }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: ubuntu-24.04
- arch: arm64
runner: ubuntu-24.04-arm
steps:
- name: Check out reviewed source and exceptions
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
ref: c4840469c675351ab1075f8a8469027828635e51
persist-credentials: false
- name: Resolve and inspect published architecture image
id: published
env:
ARCH: ${{ matrix.arch }}
run: |
set -euo pipefail
mkdir -p reports
tag="${IMAGE}:c4840469-evidence-${GITHUB_RUN_ID}-${ARCH}"
docker pull --platform "linux/${ARCH}" "${tag}"
digest="$(docker image inspect --format '{{index .RepoDigests 0}}' "${tag}")"
echo "image=${digest}" >> "${GITHUB_OUTPUT}"
docker image inspect "${digest}" > reports/image-inspect.json
printf '%s\n' "${digest}" > reports/image-digest.txt
test "$(docker image inspect --format '{{.Architecture}}' "${digest}")" = "${ARCH}"
test "$(docker image inspect --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' "${digest}")" = c4840469c675351ab1075f8a8469027828635e51
docker run --rm --entrypoint /opt/stackstate-agent/bin/agent/process-agent "${digest}" -version | tee reports/version.txt
grep -F 'Version: c4840469' reports/version.txt
docker run --rm --entrypoint rpm "${digest}" -qa --qf '%{NAME} %{VERSION}-%{RELEASE} %{ARCH}\n' | sort > reports/rpm-inventory.txt
container="$(docker create "${digest}")"
docker cp "${container}:/opt/stackstate-agent/bin/agent/process-agent" /tmp/pr278-process-agent
docker rm "${container}"
sha256sum /tmp/pr278-process-agent > reports/binary-sha256.txt
- name: Scan published digest with current VEX and separate secrets
uses: StackVista/image-pipeline/.github/actions/scan-image@6284a6fc006a7cc46a7f00d02c50d5f21b117b63
with:
image: ${{ steps.published.outputs.image }}
mode: inform
severity: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
with-grype: true
exceptions-path: exceptions
upload-sarif: false
sarif-category: pr278-published-${{ matrix.arch }}
- name: Record inventory, consumed VEX, and evaluator output
env:
SCANNED_IMAGE: ${{ steps.published.outputs.image }}
ARCH: ${{ matrix.arch }}
run: |
set -euo pipefail
go version -m /tmp/pr278-process-agent > reports/binary-modules.txt
trivy image --format cyclonedx --output reports/inventory.cdx.json "${SCANNED_IMAGE}"
cp exceptions/GO-2026-5932.yaml reports/GO-2026-5932.yaml
mkdir reports/consumed-vex
while IFS= read -r document; do
if [[ "${document}" == */pkg/golang/github.com/containerd/containerd/scan.openvex.json ]]; then
cp "${document}" reports/consumed-vex/containerd.openvex.json
fi
done < reports/grype-vex-documents.txt
test -s reports/consumed-vex/containerd.openvex.json
sha256sum reports/consumed-vex/containerd.openvex.json > reports/consumed-vex/SHA256SUMS
image-pipeline-evaluate --image "${SCANNED_IMAGE}" --severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL --mode inform --trivy-json reports/trivy.json --grype-json reports/grype.json --exceptions exceptions --sarif reports/image-pipeline.sarif 2>&1 | tee reports/evaluator.txt
jq -n --arg source c4840469c675351ab1075f8a8469027828635e51 --arg workflow_sha "${GITHUB_SHA}" --arg run "${GITHUB_RUN_ID}" --arg arch "${ARCH}" --arg image "${SCANNED_IMAGE}" '{source:$source,workflow_sha:$workflow_sha,run:$run,arch:$arch,image:$image}' > reports/provenance.json
(cd reports && find . -type f ! -name SHA256SUMS -print0 | sort -z | xargs -0 sha256sum) > reports/SHA256SUMS
- name: Retain published full-image evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: pr278-published-evidence-${{ matrix.arch }}
path: reports/
retention-days: 90
if-no-files-found: error