Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add diff comment to help reviewers #592

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions .github/workflows/diff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
name: Generate Diff

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@master
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,
});
}
Loading