From 1cc5cf50d324cdb74847787a151b52c157c55b91 Mon Sep 17 00:00:00 2001 From: Milan Garnier Date: Thu, 30 Jul 2026 11:43:48 +0200 Subject: [PATCH 1/3] fix(ci): publish system-tests image via GH Actions dispatch Standalone workflow that pulls per-branch build artifacts from S3 and pushes a multi-arch dd-library-php image so system-tests can pull it by branch slug. Lands first, before GitLab CI is wired to dispatch it, since workflow_dispatch resolves the workflow by filename against the default branch's registered workflows regardless of target ref. --- .../workflows/publish-system-tests-image.yml | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 .github/workflows/publish-system-tests-image.yml diff --git a/.github/workflows/publish-system-tests-image.yml b/.github/workflows/publish-system-tests-image.yml new file mode 100644 index 0000000000..0d7ee2428c --- /dev/null +++ b/.github/workflows/publish-system-tests-image.yml @@ -0,0 +1,80 @@ +name: "Publish system-tests image" + +# Pushes the per-branch dd-library-php image that DataDog/system-tests pulls +# (LIBRARY_TARGET_BRANCH), tagged with the GitLab CI_COMMIT_REF_SLUG. +on: + workflow_dispatch: + inputs: + ref_slug: + description: "Sanitised branch name (GitLab CI_COMMIT_REF_SLUG); used as the image tag and the S3 prefix." + required: true + +concurrency: + group: "publish-system-tests-image-${{ github.event.inputs.ref_slug }}" + cancel-in-progress: true + +env: + IMAGE: "ghcr.io/datadog/dd-trace-php/dd-library-php" + PACKAGE_PATH: "orgs/DataDog/packages/container/dd-trace-php%2Fdd-library-php" + S3_BASE: "https://dd-trace-php-builds.s3.us-east-1.amazonaws.com/ci" + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - name: Download build artifacts from S3 + env: + REF_SLUG: ${{ github.event.inputs.ref_slug }} + run: | + set -euo pipefail + base="${S3_BASE}/${REF_SLUG}" + mkdir -p packages/amd64 packages/arm64 + curl -fSL --retry 3 "${base}/dd-library-php-x86_64-linux-gnu.tar.gz" -o packages/amd64/dd-library-php-x86_64-linux-gnu.tar.gz + curl -fSL --retry 3 "${base}/dd-library-php-aarch64-linux-gnu.tar.gz" -o packages/arm64/dd-library-php-aarch64-linux-gnu.tar.gz + curl -fSL --retry 3 "${base}/datadog-setup.php" -o packages/amd64/datadog-setup.php + cp packages/amd64/datadog-setup.php packages/arm64/datadog-setup.php + + - name: Log in to GHCR + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ACTOR: ${{ github.actor }} + run: echo "$GH_TOKEN" | docker login ghcr.io -u "$ACTOR" --password-stdin + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 + + - name: Build and push image + env: + REF_SLUG: ${{ github.event.inputs.ref_slug }} + run: | + set -euo pipefail + printf 'FROM scratch\nARG TARGETARCH\nCOPY packages/${TARGETARCH}/dd-library-php-*-linux-gnu.tar.gz /\nCOPY packages/${TARGETARCH}/datadog-setup.php /\n' > Dockerfile.system-tests + # Label links the image to this repo, which is what makes GHCR grant this repo's + # GITHUB_TOKEN manage rights on the package (needed for the cleanup step below). + docker buildx build --platform linux/amd64,linux/arm64 \ + --label org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} \ + -f Dockerfile.system-tests -t "${IMAGE}:${REF_SLUG}" --push . + echo "Pushed ${IMAGE}:${REF_SLUG}" + + - name: Clean up superseded untagged versions + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REF_SLUG: ${{ github.event.inputs.ref_slug }} + continue-on-error: true + run: | # re-pushing a tag above just retargets it, leaving the old version untagged; + # the just-pushed multi-arch index's own child manifests are untagged too, so + # keep whatever digest the current tag still references. + set -euo pipefail + keep_digests=$(docker buildx imagetools inspect "${IMAGE}:${REF_SLUG}" --raw | jq -r '.manifests[].digest') + gh api "${PACKAGE_PATH}/versions" \ + --jq '.[] | select(.metadata.container.tags == []) | "\(.id) \(.name)"' \ + | while read -r id digest; do + if grep -qxF "$digest" <<< "$keep_digests"; then + continue + fi + gh api "${PACKAGE_PATH}/versions/${id}" -X DELETE + done + echo "Untagged-version cleanup complete" From dc1b2acdfb56a850fd13094933502a4d88cde307 Mon Sep 17 00:00:00 2001 From: Milan Garnier Date: Mon, 3 Aug 2026 11:09:47 +0200 Subject: [PATCH 2/3] fix(ci): scope system-tests image cleanup to digests this run superseded --- .../workflows/publish-system-tests-image.yml | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/.github/workflows/publish-system-tests-image.yml b/.github/workflows/publish-system-tests-image.yml index 0d7ee2428c..a0c6ec80a5 100644 --- a/.github/workflows/publish-system-tests-image.yml +++ b/.github/workflows/publish-system-tests-image.yml @@ -32,8 +32,8 @@ jobs: set -euo pipefail base="${S3_BASE}/${REF_SLUG}" mkdir -p packages/amd64 packages/arm64 - curl -fSL --retry 3 "${base}/dd-library-php-x86_64-linux-gnu.tar.gz" -o packages/amd64/dd-library-php-x86_64-linux-gnu.tar.gz - curl -fSL --retry 3 "${base}/dd-library-php-aarch64-linux-gnu.tar.gz" -o packages/arm64/dd-library-php-aarch64-linux-gnu.tar.gz + curl -fSL --retry 3 "${base}/dd-library-php-x86_64-linux-gnu.tar.gz" -o "packages/amd64/dd-library-php-${REF_SLUG}-x86_64-linux-gnu.tar.gz" + curl -fSL --retry 3 "${base}/dd-library-php-aarch64-linux-gnu.tar.gz" -o "packages/arm64/dd-library-php-${REF_SLUG}-aarch64-linux-gnu.tar.gz" curl -fSL --retry 3 "${base}/datadog-setup.php" -o packages/amd64/datadog-setup.php cp packages/amd64/datadog-setup.php packages/arm64/datadog-setup.php @@ -46,6 +46,16 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 + - name: Record digests about to be superseded + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REF_SLUG: ${{ github.event.inputs.ref_slug }} + run: | + set -euo pipefail + old_index=$(gh api "${PACKAGE_PATH}/versions" --jq '.[] | select(.metadata.container.tags[]? == "'"${REF_SLUG}"'") | .name') + old_children=$(docker buildx imagetools inspect "${IMAGE}:${REF_SLUG}" --raw 2>/dev/null | jq -r '.manifests[].digest' || true) + printf '%s\n' "$old_index" $old_children | sed '/^$/d' > old_digests.txt + - name: Build and push image env: REF_SLUG: ${{ github.event.inputs.ref_slug }} @@ -59,22 +69,14 @@ jobs: -f Dockerfile.system-tests -t "${IMAGE}:${REF_SLUG}" --push . echo "Pushed ${IMAGE}:${REF_SLUG}" - - name: Clean up superseded untagged versions + - name: Delete the digests this run superseded env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - REF_SLUG: ${{ github.event.inputs.ref_slug }} continue-on-error: true - run: | # re-pushing a tag above just retargets it, leaving the old version untagged; - # the just-pushed multi-arch index's own child manifests are untagged too, so - # keep whatever digest the current tag still references. + run: | set -euo pipefail - keep_digests=$(docker buildx imagetools inspect "${IMAGE}:${REF_SLUG}" --raw | jq -r '.manifests[].digest') - gh api "${PACKAGE_PATH}/versions" \ - --jq '.[] | select(.metadata.container.tags == []) | "\(.id) \(.name)"' \ - | while read -r id digest; do - if grep -qxF "$digest" <<< "$keep_digests"; then - continue - fi - gh api "${PACKAGE_PATH}/versions/${id}" -X DELETE - done - echo "Untagged-version cleanup complete" + while read -r digest; do + id=$(gh api "${PACKAGE_PATH}/versions" --jq '.[] | select(.name=="'"$digest"'" and .metadata.container.tags==[]) | .id') + [ -n "$id" ] && gh api "${PACKAGE_PATH}/versions/${id}" -X DELETE + done < old_digests.txt + echo "Superseded-digest cleanup complete" From e14d7f9198c27fc0732f2f0fec58e07d1e57da92 Mon Sep 17 00:00:00 2001 From: Milan Garnier Date: Mon, 3 Aug 2026 11:22:15 +0200 Subject: [PATCH 3/3] fix(ci): scope gitlab-ci-publish-packages octo-sts policy to actions:write --- .github/chainguard/gitlab-ci-publish-packages.sts.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/chainguard/gitlab-ci-publish-packages.sts.yaml b/.github/chainguard/gitlab-ci-publish-packages.sts.yaml index ede956febc..4f9c1efd7f 100644 --- a/.github/chainguard/gitlab-ci-publish-packages.sts.yaml +++ b/.github/chainguard/gitlab-ci-publish-packages.sts.yaml @@ -3,5 +3,5 @@ issuer: https://gitlab.ddbuild.io subject_pattern: "project_path:DataDog/apm-reliability/dd-trace-php:ref_type:(branch|tag):ref:.*" permissions: - packages: write + actions: write pull_requests: read