From 0bce5b8ff8bbd95026b6110674bc0b85b002894f Mon Sep 17 00:00:00 2001 From: Freaks Date: Sun, 12 Jul 2026 19:43:14 +0200 Subject: [PATCH] feat(chatops): add /command for build test pr in PR --- .github/PULL_REQUEST_TEMPLATE.md | 2 + .github/workflows/build-image-pr.yml | 61 ++++++++++++++++ .github/workflows/cleanup-pr-image.yml | 98 ++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 .github/workflows/build-image-pr.yml create mode 100644 .github/workflows/cleanup-pr-image.yml diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a39fb2509..77a07a88f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,6 +3,8 @@ Fixes # + + ## What changed diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml new file mode 100644 index 000000000..9dfcddfff --- /dev/null +++ b/.github/workflows/build-image-pr.yml @@ -0,0 +1,61 @@ +name: Build a test image from a PR code + +on: + issue_comment: + types: [created] + +jobs: + build-images: + if: | + github.event.issue.pull_request && contains(github.event.comment.body, '/create-test-image') && + ( + github.event.comment.author_association == 'OWNER' || + github.event.comment.author_association == 'CONTRIBUTOR' || + github.event.comment.author_association == 'COLLABORATOR' || + github.event.comment.author_association == 'FIRST_TIME_CONTRIBUTOR' + ) + runs-on: + ubuntu-latest + + permissions: + contents: read + pull-requests: write + + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 + + - name: Get Pull Requests Informations + id: pr + uses: actions/github-script@v7 + with: + script: | + const pr = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + + core.setOutput('sha', pr.data.head.sha); + core.setOutput('ref', pr.data.head.ref); + + - name: Checkout Last Commits + uses: actions/checkout@v4 + with: + ref: ${{ steps.pr.outputs.sha}} + + - name: Log in to GitHub Container Registry + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GHCR_GITHUB_TOKEN }} + + - name: Build & Push Docker image + run: | + VERSION=${pr-${{ github.event.issue.number }}-${{ steps.pr.outputs.sha }}} + echo "Building Multi-Arch Docker image with version $VERSION" + make docker-build-publish VERSION=$VERSION REPO_OWNER=${{ github.repository_owner }} + + + diff --git a/.github/workflows/cleanup-pr-image.yml b/.github/workflows/cleanup-pr-image.yml new file mode 100644 index 000000000..eabecae89 --- /dev/null +++ b/.github/workflows/cleanup-pr-image.yml @@ -0,0 +1,98 @@ +name: Cleanup PR test images + +on: + pull_request: + types: [closed] + + schedule: + - cron: "0 3 1 * *" # Tous les 1er du mois à 03:00 UTC + +permissions: + packages: write + +jobs: + cleanup-closed-pr: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + + steps: + - name: Delete closed PR images + uses: actions/github-script@v7 + with: + script: | + const owner = context.repo.owner; + const packageName = context.repo.repo.toLowerCase(); + const prefix = `pr-${context.payload.pull_request.number}-`; + + const versions = await github.paginate( + github.rest.packages.getAllPackageVersionsForPackageOwnedByOrg, + { + org: owner, + package_type: "container", + package_name: packageName, + per_page: 100, + } + ); + + for (const version of versions) { + const tags = version.metadata?.container?.tags ?? []; + + if (!tags.some(tag => tag.startsWith(prefix))) { + continue; + } + + core.info(`Deleting ${tags.join(", ")}`); + + await github.rest.packages.deletePackageVersionForOrg({ + org: owner, + package_type: "container", + package_name: packageName, + package_version_id: version.id, + }); + } + + cleanup-old-images: + if: github.event_name == 'schedule' + runs-on: ubuntu-latest + + steps: + - name: Delete old PR images + uses: actions/github-script@v7 + with: + script: | + const owner = context.repo.owner; + const packageName = context.repo.repo.toLowerCase(); + const retentionDays = 30; + + const cutoff = new Date(); + cutoff.setDate(cutoff.getDate() - retentionDays); + + const versions = await github.paginate( + github.rest.packages.getAllPackageVersionsForPackageOwnedByOrg, + { + org: owner, + package_type: "container", + package_name: packageName, + per_page: 100, + } + ); + + for (const version of versions) { + const tags = version.metadata?.container?.tags ?? []; + + const isPrImage = tags.some(tag => tag.startsWith("pr-")); + const createdAt = new Date(version.created_at); + + if (!isPrImage || createdAt > cutoff) { + continue; + } + + core.info(`Deleting old image ${tags.join(", ")}`); + + await github.rest.packages.deletePackageVersionForOrg({ + org: owner, + package_type: "container", + package_name: packageName, + package_version_id: version.id, + }); + } \ No newline at end of file