diff --git a/.github/workflows/delete-test-mirror-pr.yml b/.github/workflows/delete-test-mirror-pr.yml new file mode 100644 index 0000000..72a88a2 --- /dev/null +++ b/.github/workflows/delete-test-mirror-pr.yml @@ -0,0 +1,89 @@ +name: Delete test image mirror PR + +on: + workflow_dispatch: + inputs: + pr_number: + description: "PR number in dd-trace-java-docker-build (e.g. 123)" + required: true + +jobs: + delete-test-mirror-pr: + runs-on: ubuntu-latest + permissions: + id-token: write # Required for OIDC token federation + contents: read + steps: + - uses: DataDog/dd-octo-sts-action@acaa02eee7e3bb0839e4272dacb37b8f3b58ba80 # v1.0.3 + id: octo-sts + with: + scope: DataDog/images + policy: dd-trace-java-docker-build.update-mirror + + - name: Checkout DataDog/dd-trace-java-docker-build + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + path: dd-trace-java-docker-build + + - name: Checkout DataDog/images + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: DataDog/images + token: ${{ steps.octo-sts.outputs.token }} + path: images + + - name: Capture images HEAD SHA + id: images-head + run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + working-directory: images + + - name: Remove test mirror entries + env: + PR_NUMBER: ${{ github.event.inputs.pr_number }} + run: bash "${GITHUB_WORKSPACE}/dd-trace-java-docker-build/scripts/delete-test-mirror-entries.sh" + working-directory: images + + - name: Define branch name + id: define-branch + run: echo "branch=ci/delete-dd-trace-java-docker-build-test-images-pr${{ github.event.inputs.pr_number }}" >> "$GITHUB_OUTPUT" + + - name: Commit changes + id: create-commit + env: + PR_NUMBER: ${{ github.event.inputs.pr_number }} + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add mirror.yaml mirror.lock.yaml + if git diff --cached --quiet; then + echo "::error::Expected mirror file deletions but found no changes." + exit 1 + fi + git commit -m "chore: Remove dd-trace-java-docker-build test images for PR #${PR_NUMBER}" + echo "commit=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + working-directory: images + + - name: Push changes + uses: DataDog/commit-headless@05d7b7ee023e2c7d01c47832d420c2503cd416f3 # action/v2.0.3 + with: + target: DataDog/images + token: "${{ steps.octo-sts.outputs.token }}" + branch: "${{ steps.define-branch.outputs.branch }}" + head-sha: "${{ steps.images-head.outputs.sha }}" + create-branch: true + command: push + commits: "${{ steps.create-commit.outputs.commit }}" + working-directory: images + + - name: Create pull request + env: + GH_TOKEN: ${{ steps.octo-sts.outputs.token }} + PR_NUMBER: ${{ github.event.inputs.pr_number }} + run: | + gh pr create \ + --repo DataDog/images \ + --draft \ + --title "Remove dd-trace-java-docker-build test images for PR #${PR_NUMBER}" \ + --base master \ + --head "${{ steps.define-branch.outputs.branch }}" \ + --body "Removes mirror.yaml and mirror.lock.yaml entries for \`${PR_NUMBER}_merge-*\` test images from DataDog/dd-trace-java-docker-build#${PR_NUMBER}." diff --git a/README.md b/README.md index b856c10..2b78684 100644 --- a/README.md +++ b/README.md @@ -37,5 +37,7 @@ To test these images in `dd-trace-java` CI: 2. After the PR images are built in the [GitHub Container Registry](https://github.com/DataDog/dd-trace-java-docker-build/pkgs/container/dd-trace-java-docker-build), run the [Create test image mirror PR](https://github.com/DataDog/dd-trace-java-docker-build/actions/workflows/create-test-mirror-pr.yml) workflow with the corresponding PR number: `N`. This automatically opens a PR in [DataDog/images](https://github.com/DataDog/images) that adds mirror entries for the `N_merge-*` test images. Merge the PR that should be automatically approved by the `dd-prapprover` bot. 3. Open a PR in [DataDog/dd-trace-java](https://github.com/DataDog/dd-trace-java) that sets `BUILDER_IMAGE_VERSION_PREFIX: "N_merge-"` in `.gitlab-ci.yml`. Here, you can check your test images with `DataDog/dd-trace-java` CI. 4. Every time you want to test changes made in PR #N, ensure the test image SHAs in `DataDog/images` are updated by running the [Create test image mirror PR](https://github.com/DataDog/dd-trace-java-docker-build/actions/workflows/create-test-mirror-pr.yml) workflow with `N`. Confirm that these PRs are approved and merged by the `dd-prapprover` bot. -5. When the test images look good and `DataDog/dd-trace-java` CI is green, merge your `DataDog/dd-trace-java-docker-build` PR #N, close the test `DataDog/dd-trace-java` PR, and **remove the `N_merge-*` images from the `DataDog/images` repo**. -6. Finally, run the [Tag new images version](https://github.com/DataDog/dd-trace-java-docker-build/actions/workflows/docker-tag.yml) workflow. The [Update mirror digests for ci-* images](https://github.com/DataDog/dd-trace-java-docker-build/actions/workflows/update-mirror-digests.yml) workflow will automatically open a PR in `DataDog/images`, updating the pinned `ci-*` digests. `dd-trace-java` CI should automatically pick up these updated images a few minutes after the PR is merged. +5. When the test images look good and `DataDog/dd-trace-java` CI is green, merge your `DataDog/dd-trace-java-docker-build` PR #N. +6. Close the test `DataDog/dd-trace-java` PR. +7. Run the [Delete test image mirror PR](https://github.com/DataDog/dd-trace-java-docker-build/actions/workflows/delete-test-mirror-pr.yml) workflow with `N` to remove the `N_merge-*` images from `DataDog/images`. Confirm that this PR is approved and merged by the `dd-prapprover` bot. +8. Finally, run the [Tag new images version](https://github.com/DataDog/dd-trace-java-docker-build/actions/workflows/docker-tag.yml) workflow. The [Update mirror digests for ci-* images](https://github.com/DataDog/dd-trace-java-docker-build/actions/workflows/update-mirror-digests.yml) workflow will automatically open a PR in `DataDog/images`, updating the pinned `ci-*` digests. `dd-trace-java` CI should automatically pick up these updated images a few minutes after the PR is merged. diff --git a/scripts/delete-test-mirror-entries.sh b/scripts/delete-test-mirror-entries.sh new file mode 100644 index 0000000..18a31f0 --- /dev/null +++ b/scripts/delete-test-mirror-entries.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +# delete-test-mirror-entries.sh — remove {PR_NUMBER}_merge-* test image entries +# from mirror.yaml and mirror.lock.yaml in the DataDog/images repo. +# +# This script is called in the delete-test-mirror-pr GitHub workflow. +# It must be run from the root of DataDog/images. +# +# Required env var: +# PR_NUMBER — pull request number in dd-trace-java-docker-build (numeric) + +set -euo pipefail + +readonly SOURCE_REPO="ghcr.io/datadog/dd-trace-java-docker-build" +readonly CI_VARIANTS=(base 7 8 11 17 21 25 tip zulu8 zulu11 oracle8 ibm8 semeru8 semeru11 semeru17 graalvm17 graalvm21 graalvm25) + +if ! [[ "${PR_NUMBER}" =~ ^[0-9]+$ ]]; then + echo "::error::PR_NUMBER must be numeric (got: '${PR_NUMBER}')" >&2 + exit 1 +fi + +readonly PREFIX="${PR_NUMBER}_merge-" + +require_entry_exists() { + local tag="$1" + if ! grep -qF "${SOURCE_REPO}:${tag}\"" mirror.yaml; then + echo "::error::Missing mirror.yaml entry for ${SOURCE_REPO}:${tag}" >&2 + exit 1 + fi + if ! grep -qF "${SOURCE_REPO}:${tag}" mirror.lock.yaml; then + echo "::error::Missing mirror.lock.yaml entry for ${SOURCE_REPO}:${tag}" >&2 + exit 1 + fi +} + +remove_from_mirror_yaml() { + local tag="$1" + local src=" - source: \"${SOURCE_REPO}:${tag}\"" + local file="mirror.yaml" + awk -v src="${src}" ' + $0 == src { skip=1; removed=1; next } + skip && /^ - source: / { skip=0 } + !skip { print } + END { + if (!removed) { + exit 44 + } + } + ' "${file}" > "${file}.tmp" && mv "${file}.tmp" "${file}" +} + +remove_from_mirror_lock() { + local tag="$1" + local src=" - source: ${SOURCE_REPO}:${tag}" + local file="mirror.lock.yaml" + awk -v src="${src}" ' + $0 == src { skip_digest=1; removed=1; next } + skip_digest && /^ digest: / { skip_digest=0; next } + { print } + END { + if (!removed) { + exit 45 + } + } + ' "${file}" > "${file}.tmp" && mv "${file}.tmp" "${file}" +} + +echo "Validating test mirror entries for prefix '${PREFIX}'..." +for variant in "${CI_VARIANTS[@]}"; do + require_entry_exists "${PREFIX}${variant}" +done + +echo "Removing test mirror entries for prefix '${PREFIX}'..." +for variant in "${CI_VARIANTS[@]}"; do + tag="${PREFIX}${variant}" + remove_from_mirror_yaml "${tag}" + remove_from_mirror_lock "${tag}" +done + +echo "Removed ${#CI_VARIANTS[@]} entries from mirror.yaml and mirror.lock.yaml"