From 17ed3d119b144221a0d3f911bb51ac6d0c1a6203 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Sun, 17 Mar 2024 16:59:56 +0900 Subject: [PATCH] Implement staging container action (#53) * Implement staging container action Import https://github.com/kachick/dotfiles/pull/473 and following commits in that repo --- .../workflows/cleanup-staging-packages.yml | 83 ++++++++++++++ .github/workflows/containers.yml | 103 +++++++++++++++++- 2 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/cleanup-staging-packages.yml diff --git a/.github/workflows/cleanup-staging-packages.yml b/.github/workflows/cleanup-staging-packages.yml new file mode 100644 index 0000000..97bcd6a --- /dev/null +++ b/.github/workflows/cleanup-staging-packages.yml @@ -0,0 +1,83 @@ +name: 👋 staging ⬢🗑️ +on: + pull_request: + types: + - closed + workflow_dispatch: + inputs: + pr-number: + description: 'Target PR number' + required: true + type: number + +defaults: + run: + # https://pubs.opengroup.org/onlinepubs/009695399/utilities/set.html + shell: bash -Ceuxo pipefail {0} + +jobs: + ghcr: + runs-on: ubuntu-22.04 + if: (github.event_name != 'pull_request') || (github.event.pull_request.merged == true) + timeout-minutes: 15 + steps: + - name: Install gh-action-escape + run: curl -fsSL https://raw.githubusercontent.com/kachick/gh-action-escape/main/scripts/install-in-github-action.sh | sh -s v0.2.0 + - name: Get metadata + id: get-meta + run: | + if [ '${{ github.event_name }}' == 'pull_request' ]; then + echo -n '${{ github.event.pull_request.number }}' | gh-action-escape -name=pr_number | tee -a "$GITHUB_OUTPUT" + else + echo -n '${{ inputs.pr-number }}' | gh-action-escape -name=pr_number | tee -a "$GITHUB_OUTPUT" + fi + - name: Inspect the PR published package + id: inspect-package + run: | + gh api --paginate \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /users/kachick/packages/container/ubuntu-nix-systemd/versions \ + --jq '.[] | select(.metadata.container.tags[] | match("^pr-${{ steps.get-meta.outputs.pr_number }}-")).id' | \ + ruby -e 'puts STDIN.each_line.map(&:chomp).join(",")' | \ + gh-action-escape -name=ubuntu-nix-systemd-package-version-ids | tee -a "$GITHUB_OUTPUT" + + gh api --paginate \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /users/kachick/packages/container/ubuntu-nix-sudoer/versions \ + --jq '.[] | select(.metadata.container.tags[] | match("^pr-${{ steps.get-meta.outputs.pr_number }}-")).id' | \ + ruby -e 'puts STDIN.each_line.map(&:chomp).join(",")' | \ + gh-action-escape -name=ubuntu-nix-sudoer-package-version-ids | tee -a "$GITHUB_OUTPUT" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0 + with: + owner: ${{ github.repository_owner }} + package-name: 'ubuntu-nix-systemd' + package-type: 'container' + token: ${{ github.token }} + package-version-ids: ${{ steps.inspect-package.outputs.ubuntu-nix-systemd-package-version-ids }} + - uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0 + with: + owner: ${{ github.repository_owner }} + package-name: 'ubuntu-nix-sudoer' + package-type: 'container' + token: ${{ github.token }} + package-version-ids: ${{ steps.inspect-package.outputs.ubuntu-nix-sudoer-package-version-ids }} + - name: Prepare git to run gh commands + uses: actions/checkout@v4 + - name: Post comments to the PR + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + ( + cat <<'EOF' + 🤖 removed 🗑️ staging ⬢ from ghcr.io + + ```plaintext + ${{ steps.inspect-package.outputs.ubuntu-nix-systemd-package-version-ids }} + ${{ steps.inspect-package.outputs.ubuntu-nix-sudoer-package-version-ids }} + ``` + EOF + ) | gh pr comment '${{ steps.get-meta.outputs.pr_number }}' --body-file - diff --git a/.github/workflows/containers.yml b/.github/workflows/containers.yml index df98899..8a98e59 100644 --- a/.github/workflows/containers.yml +++ b/.github/workflows/containers.yml @@ -16,37 +16,68 @@ on: workflow_dispatch: jobs: + # podman can handle lowercase. So normalize the outputs get-meta: runs-on: ubuntu-22.04 timeout-minutes: 5 outputs: started_at: ${{ steps.timestamp.outputs.started_at }} + ref_tag: ${{ steps.tags.outputs.ref }} + special_tag: ${{ steps.tags.outputs.special }} + timestamp_tag: ${{ steps.tags.outputs.timestamp }} steps: - name: Get started timestamp id: timestamp run: | # Do not use ":" delimiter as iso-8601/rfc-3339, it cannot be used in container tag - echo "started_at=$(date --utc '+%Y%m%d-%H%M%S-%Z')" >> "$GITHUB_OUTPUT" + echo started_at="$(date --utc '+%Y%m%d-%H%M%S-%Z')" | ruby -pe '$_.downcase!' | tee -a "$GITHUB_OUTPUT" + - name: Generate tags for the image + id: tags + # https://github.com/orgs/community/discussions/26557#discussioncomment-3252327 + run: | + echo "timestamp=${{ steps.timestamp.outputs.started_at }}" | tee -a "$GITHUB_OUTPUT" + + special='' + ref='' + + if [ '${{ github.event_name }}' = 'pull_request' ]; then + special='pr-${{ github.event.number }}-${{ github.event.pull_request.head.sha }}' + ref='${{ github.event.pull_request.head.sha }}' + elif [ '${{ github.event_name }}' = 'push' ] && [ '${{ github.ref_name }}' = '${{ github.event.repository.default_branch }}' ]; then + special='latest' + ref='${{ github.sha }}' + else + exit 1 + fi + + echo "special=${special}" | tee -a "$GITHUB_OUTPUT" + echo "ref=${ref}" | tee -a "$GITHUB_OUTPUT" ubuntu-nix-sudoer: needs: [get-meta] runs-on: ubuntu-22.04 timeout-minutes: 30 + outputs: + package-json: ${{ steps.inspect-package.outputs.json }} steps: - uses: actions/checkout@v4 + - name: Install gh-action-escape + run: curl -fsSL https://raw.githubusercontent.com/kachick/gh-action-escape/main/scripts/install-in-github-action.sh | sh -s v0.2.0 - name: Build Image id: build-image uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 #v2.13 with: image: ubuntu-nix-sudoer - tags: latest ${{ github.sha }} ${{ needs.get-meta.outputs.started_at }} + tags: ${{ needs.get-meta.outputs.special_tag }}-sudoer ${{ needs.get-meta.outputs.ref_tag }}-sudoer ${{ needs.get-meta.outputs.timestamp_tag }}-sudoer containerfiles: | ./images/ubuntu-nix-sudoer/Containerfile build-args: | username=user oci: true + - name: Inspect the created image + run: 'podman inspect ${{ steps.build-image.outputs.image }}' - name: Push To ghcr.io id: push-to-ghcr - if: ${{ github.event_name != 'pull_request' }} + if: ${{ github.actor == github.repository_owner }} uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c #v2.8 with: image: ${{ steps.build-image.outputs.image }} @@ -57,24 +88,46 @@ jobs: - name: Log outputs if: ${{ github.event_name != 'pull_request' }} run: echo "${{ toJSON(steps.push-to-ghcr.outputs) }}" + - name: Inspect the package + id: inspect-package + if: ${{ github.actor == github.repository_owner }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euxo pipefail + + echo "${{ toJSON(steps.push-to-ghcr.outputs) }}" + + gh api --paginate \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /users/${{ github.repository_owner }}/packages/container/ubuntu-nix-sudoer/versions \ + --jq '.[] | select(.name == "${{ steps.push-to-ghcr.outputs.digest }}")' | \ + jq | gh-action-escape -name=json | tee -a "$GITHUB_OUTPUT" ubuntu-nix-systemd: needs: [get-meta] runs-on: ubuntu-22.04 timeout-minutes: 30 + outputs: + package-json: ${{ steps.inspect-package.outputs.json }} steps: - uses: actions/checkout@v4 + - name: Install gh-action-escape + run: curl -fsSL https://raw.githubusercontent.com/kachick/gh-action-escape/main/scripts/install-in-github-action.sh | sh -s v0.2.0 - name: Build Image id: build-image uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 #v2.13 with: image: ubuntu-nix-systemd - tags: latest ${{ github.sha }} ${{ needs.get-meta.outputs.started_at }} + tags: ${{ needs.get-meta.outputs.special_tag }}-systemd ${{ needs.get-meta.outputs.ref_tag }}-systemd ${{ needs.get-meta.outputs.timestamp_tag }}-systemd containerfiles: | ./images/ubuntu-nix-systemd/Containerfile oci: true + - name: Inspect the created image + run: 'podman inspect ${{ steps.build-image.outputs.image }}' - name: Push To ghcr.io id: push-to-ghcr - if: ${{ github.event_name != 'pull_request' }} + if: ${{ github.actor == github.repository_owner }} uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c #v2.8 with: image: ${{ steps.build-image.outputs.image }} @@ -85,3 +138,43 @@ jobs: - name: Log outputs if: ${{ github.event_name != 'pull_request' }} run: echo "${{ toJSON(steps.push-to-ghcr.outputs) }}" + - name: Inspect the package + id: inspect-package + if: ${{ github.actor == github.repository_owner }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euxo pipefail + + echo "${{ toJSON(steps.push-to-ghcr.outputs) }}" + + gh api --paginate \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /users/${{ github.repository_owner }}/packages/container/ubuntu-nix-systemd/versions \ + --jq '.[] | select(.name == "${{ steps.push-to-ghcr.outputs.digest }}")' | \ + jq | gh-action-escape -name=json | tee -a "$GITHUB_OUTPUT" + + announce-staging: + needs: [get-meta, ubuntu-nix-systemd, ubuntu-nix-sudoer] + runs-on: ubuntu-22.04 + timeout-minutes: 10 + steps: + - name: Prepare git to run gh commands + uses: actions/checkout@v4 + - name: Post comments + if: ${{ (github.actor == github.repository_owner) && (github.event_name == 'pull_request') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + ( + cat <<'EOF' + ⬢🦭 Staging container-image has been deployed 🚀\ + You can check in package URL + + * systemd: https://github.com/${{ github.repository }}/pkgs/container/ubuntu-nix-systemd/${{ fromJson(needs.ubuntu-nix-systemd.outputs.package-json).id }}?tag=${{ needs.get-meta.outputs.special_tag }}-systemd + * sudoer: https://github.com/${{ github.repository }}/pkgs/container/ubuntu-nix-sudoer/${{ fromJson(needs.ubuntu-nix-sudoer.outputs.package-json).id }}?tag=${{ needs.get-meta.outputs.special_tag }}-sudoer + + This image will be automatically 🤖 removed from ghcr.io 🗑️ if you merged/closed this PR 😌 + EOF + ) | gh pr comment ${{ github.event.number }} --body-file -