test: new script that detects changes in manifests in a PR

The script runs the gen-manifests command first on the PR head and then
on the merge-base with the PR's base branch (typically 'main') and
checks for any differences.  It creates a review comment on the PR on
GitHub if any changes are detected.

The message is posted as a simple COMMENT type review to inform the
author and reviewers that changes exist.

The script doesn't fail if there's a diff.  CI shouldn't fail if changes
are detected since they can be intentional.  The job fails if something
goes wrong with the script execution (manifest generation, comment
posting, etc).

The script exits immediately if not run from a PR.

The gen-manifests run is silenced with `> /dev/null`.  In the future,
this should be handled by flags to the command itself to control the
output format noisiness.

The gen-manifests command is run 50 workers.  Testing with 100 seemed to
make the execution stall, likely because of the resources on the worker.
We can experiment with this value more in the future.
This commit is contained in:
Achilleas Koutsou 2022-06-14 22:03:37 +02:00 committed by Christian Kellner
parent c38fcb128c
commit 7076f9b8dc

94
test/cases/diff-manifests.sh Executable file
View file

@ -0,0 +1,94 @@
#!/usr/bin/env bash
set -euo pipefail
# Colorful output.
function greenprint {
echo -e "\033[1;32m[$(date -Isecond)] ${1}\033[0m"
}
function redprint {
echo -e "\033[1;31m[$(date -Isecond)] ${1}\033[0m"
}
if [[ "${CI_COMMIT_BRANCH}" != PR-* ]]; then
greenprint "${CI_COMMIT_BRANCH} is not a Pull Request"
greenprint "Skipping"
exit 0
fi
greenprint "Getting PR number"
prnum="${CI_COMMIT_BRANCH#PR-}"
greenprint "Installing jq"
sudo dnf install -y jq
greenprint "Getting base branch name"
basebranch=$(curl \
-u "${SCHUTZBOT_LOGIN}" \
-H 'Accept: application/vnd.github.v3+json' \
"https://api.github.com/repos/osbuild/osbuild-composer/pulls/${prnum}" | jq -r ".base.ref")
greenprint "Fetching origin/${basebranch}"
git fetch origin "${basebranch}"
greenprint "Getting revision IDs for HEAD and merge-base"
head=$(git rev-parse HEAD)
mergebase=$(git merge-base HEAD origin/main)
if [[ "${head}" == "${mergebase}" ]]; then
greenprint "HEAD and merge-base are the same"
greenprint "Test is unnecessary"
exit 0
fi
greenprint "Installing go"
sudo dnf install -y go
manifestdir=$(mktemp -d)
greenprint "Generating all manifests for HEAD (PR #${prnum})"
go run ./cmd/gen-manifests --output "${manifestdir}/PR" --workers 50 > /dev/null
greenprint "Checking out merge-base ${mergebase}"
git checkout "${mergebase}"
greenprint "Generating all manifests for merge-base (${mergebase})"
go run ./cmd/gen-manifests --output "${manifestdir}/${mergebase}" --workers 50 > /dev/null
greenprint "Diff: ${manifestdir}/${mergebase} ${manifestdir}/PR"
diff=$(diff -r "${manifestdir}"/{"${mergebase}",PR})
err=$?
review_data_file="review.json"
if (( err == 0 )); then
greenprint "No changes in manifests"
exit 0
fi
greenprint "Manifests differ"
echo "${diff}"
cat > "${review_data_file}" << EOF
{"body":"⚠️ This PR introduces changes in at least one manifest (when comparing PR HEAD ${head} with the main merge-base ${mergebase}). Please review the changes.","event":"COMMENT"}
EOF
greenprint "Posting review comment"
comment_req_out=$(mktemp)
comment_status=$(curl \
-u "${SCHUTZBOT_LOGIN}" \
-X POST \
-H "Accept: application/vnd.github.v3+json" \
--show-error \
--write-out '%{http_code}' \
--output "${comment_req_out}" \
"https://api.github.com/repos/osbuild/osbuild-composer/pulls/${prnum}/reviews" \
-d @"${review_data_file}")
cat "${comment_req_out}"
if [[ "${comment_status}" != "200" ]]; then
redprint "Comment post failed (${comment_status})"
exit 1
fi
exit 0