-
-
Notifications
You must be signed in to change notification settings - Fork 96
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
name: Munge PR | ||
|
||
on: | ||
pull_request_target: | ||
|
||
permissions: | ||
contents: read | ||
pull-requests: write | ||
|
||
defaults: | ||
run: | ||
shell: 'bash -Eeuo pipefail -x {0}' | ||
|
||
env: | ||
# https://github.com/docker-library/bashbrew/issues/10 | ||
GIT_LFS_SKIP_SMUDGE: 1 | ||
|
||
jobs: | ||
|
||
gather: | ||
name: Gather Metadata | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | ||
with: | ||
# ideally this would be "github.event.pull_request.merge_commit_sha" but according to https://docs.github.com/en/free-pro-team@latest/rest/reference/pulls#get-a-pull-request if "mergeable" is null (meaning there's a background job in-progress to check mergeability), that value is undefined... | ||
ref: ${{ github.event.pull_request.head.sha }} | ||
fetch-depth: 0 | ||
- id: gather | ||
name: Affected Images | ||
run: | | ||
(set +x; echo "::stop-commands::$(echo -n ${{ github.token }} | sha256sum | head -c 64)") | ||
git fetch --quiet https://github.com/docker-library/official-images.git master | ||
externalPins="$(git diff --no-renames --name-only FETCH_HEAD...HEAD -- '.external-pins/*/**')" | ||
externalPinTags="$( | ||
if [ -n "$externalPins" ]; then | ||
# doing backflips to run "tag.sh" from master instead of from the PR | ||
git show FETCH_HEAD:.external-pins/tag.sh > ~/master-external-pins-tag.sh | ||
chmod +x ~/master-external-pins-tag.sh | ||
~/master-external-pins-tag.sh $externalPins | ||
fi | ||
)" | ||
images="$(git diff --no-renames --name-only FETCH_HEAD...HEAD -- library/)" | ||
if [ -n "$images" ]; then | ||
new="$(git diff --no-renames --name-only --diff-filter=A FETCH_HEAD...HEAD -- $images)" | ||
deleted="$(git diff --no-renames --name-only --diff-filter=D FETCH_HEAD...HEAD -- $images)" | ||
else | ||
new= | ||
deleted= | ||
fi | ||
export images new deleted externalPins externalPinTags | ||
images="$(jq -cn ' | ||
(env.images | rtrimstr("\n") | split("\n")) as $images | ||
| (env.new | rtrimstr("\n") | split("\n")) as $new | ||
| (env.deleted | rtrimstr("\n") | split("\n")) as $deleted | ||
| (env.externalPins | rtrimstr("\n") | split("\n")) as $externalPins | ||
| (env.externalPinTags | rtrimstr("\n") | split("\n")) as $externalPinTags | ||
| { | ||
images: $images, | ||
count: ($images | length), | ||
new: $new, | ||
deleted: $deleted, | ||
externalPins: $externalPins, | ||
externalPinTags: $externalPinTags, | ||
externalPinsCount: ($externalPins | length), | ||
} | ||
| .imagesAndExternalPinsCount = (.count + .externalPinsCount) # man, I *really* do not love GitHub Actions expressions... | ||
')" | ||
jq . <<<"$images" | ||
set +x | ||
echo "::$(echo -n ${{ github.token }} | sha256sum | head -c 64)::" | ||
echo "images=$images" >> "$GITHUB_OUTPUT" | ||
outputs: | ||
images: '${{ steps.gather.outputs.images }}' | ||
|
||
diff: | ||
name: Diff Comment | ||
runs-on: ubuntu-latest | ||
needs: gather | ||
if: fromJSON(needs.gather.outputs.images).imagesAndExternalPinsCount > 0 | ||
steps: | ||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | ||
with: | ||
# again, this would ideally be "github.event.pull_request.merge_commit_sha" but we might not have that yet when this runs, so we compromise by checkout out the latest code from the target branch (so we get the latest "diff-pr.sh" script to run) | ||
ref: ${{ github.event.pull_request.base.ref }} | ||
fetch-depth: 0 | ||
- uses: docker-library/official-images/.github/workflows/.bashbrew | ||
with: | ||
build: 'docker' | ||
- name: Prepare Environment | ||
run: | | ||
# this avoids running repo-local scripts (to avoid CVE-2020-15228 via the scripts being updated to write nasty things to $GITHUB_ENV) | ||
docker build --tag oisupport/bashbrew:diff-pr . | ||
- name: Gather Maintainers | ||
env: | ||
IMAGES: ${{ needs.gather.outputs.images }} | ||
run: | | ||
files="$(jq <<<"$IMAGES" -r '.images | map(@sh) | join(" ")')" | ||
eval "set -- $files" | ||
for f; do | ||
if [ -s "$f" ]; then | ||
docker run --rm --read-only --tmpfs /tmp oisupport/bashbrew:diff-pr \ | ||
bashbrew cat --format ' - `{{ $.RepoName }}`:{{ range .Manifest.Global.Maintainers }} @{{ .Handle }}{{ end }}' "$f" | ||
fi | ||
done | tee "$GITHUB_WORKSPACE/oi-pr.maint" | ||
- name: Generate Diff | ||
env: | ||
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }} | ||
run: | | ||
docker run --rm --read-only --tmpfs /tmp oisupport/bashbrew:diff-pr ./diff-pr.sh "$GITHUB_PR_NUMBER" | tee "$GITHUB_WORKSPACE/oi-pr.diff" | ||
- name: Comment | ||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
script: | | ||
const commentText = 'Diff for ' + context.payload.pull_request.head.sha + ':'; | ||
const fs = require('fs'); | ||
const diff = fs.readFileSync(process.env.GITHUB_WORKSPACE + '/oi-pr.diff').toString().trimEnd(); | ||
var body = "<details>\n<summary>" + commentText + "</summary>\n\n```diff\n" + diff + "\n```\n\n</details>"; | ||
fs.writeFileSync(process.env.GITHUB_STEP_SUMMARY, body); | ||
// https://docs.github.com/en/graphql/reference/mutations#minimizecomment | ||
const minimizeql = ` | ||
mutation($comment: ID!) { | ||
minimizeComment(input: { classifier: OUTDATED, clientMutationId: "doi-munge-pr", subjectId: $comment }) { | ||
clientMutationId | ||
minimizedComment { | ||
isMinimized | ||
minimizedReason | ||
} | ||
} | ||
} | ||
`; | ||
// https://docs.github.com/en/graphql/reference/mutations#unminimizecomment | ||
const unminimizeql = ` | ||
mutation($comment: ID!) { | ||
unminimizeComment(input: { clientMutationId: "doi-munge-pr", subjectId: $comment }) { | ||
clientMutationId | ||
unminimizedComment { | ||
isMinimized | ||
minimizedReason | ||
} | ||
} | ||
} | ||
`; | ||
needNewComment = true; | ||
console.log('Reviewing existing comments...'); | ||
for await (const { data: comments } of github.paginate.iterator( | ||
github.rest.issues.listComments, | ||
{ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.payload.pull_request.number, | ||
} | ||
)) { | ||
for (const comment of comments) { | ||
if (comment.user.login === 'github-actions[bot]') { | ||
if (needNewComment && comment.body.includes(commentText)) { | ||
needNewComment = false; | ||
console.log('Unhiding comment: ' + comment.id + ' (' + comment.node_id + ')'); | ||
const result = await github.graphql(unminimizeql, { comment: comment.node_id }); | ||
console.log('- result: ' + JSON.stringify(result)); | ||
} else { | ||
console.log('Hiding comment: ' + comment.id + ' (' + comment.node_id + ')'); | ||
const result = await github.graphql(minimizeql, { comment: comment.node_id }); | ||
console.log('- result: ' + JSON.stringify(result)); | ||
} | ||
} | ||
} | ||
} | ||
if (needNewComment) { | ||
console.log('Creating new comment...'); | ||
await github.rest.issues.createComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.payload.pull_request.number, | ||
body: body, | ||
}); | ||
} |