-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ci: Check that the fast-forward check and /fast-forward work.
- Check that the actions work by opening a pull request in a test repository, and then fast forwarding it.
- Loading branch information
Showing
3 changed files
with
352 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,54 @@ | ||
# This action is run from the sequoia-pgp/fast-forward repository and | ||
# modifies a different repository, sequoia-pgp/fast-forward-unit-test. | ||
# We can create a fine-grained acess token that allows just modifying | ||
# that repository by going to: | ||
# | ||
# https://github.com/settings/personal-access-tokens/new | ||
# | ||
# And entering: | ||
# | ||
# - Name: fast-forward-unit-tests | ||
# - Expiration: Far in the future | ||
# - Resource owner: sequoia-pgp | ||
# - Only select repositories - sequoia-pgp/fast-forward-unit-tests | ||
# - Permissions - select read and write permission for contents, issues, | ||
# and pull requests. | ||
# | ||
# Add the secret to the fast-forward repository by going to: | ||
# | ||
# https://github.com/sequoia-pgp/fast-forward/settings/secrets/actions | ||
# | ||
# or: | ||
# | ||
# Repository, Secrets and variables, Actions, New repository secret | ||
# | ||
# And enter: | ||
# | ||
# - Name: FAST_FORWARD_UNIT_TESTS_TOKEN | ||
# - Secret: The token | ||
# | ||
# Note: the name is meaningful and is used by the | ||
# tests/fast-forward.sh script. | ||
|
||
name: ci | ||
on: | ||
push: | ||
|
||
permissions: | ||
contents: write | ||
pull-requests: write | ||
issues: write | ||
|
||
jobs: | ||
compile: | ||
name: Fast forward | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
|
||
- name: Check that /fast-forward fast forwards. | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
FAST_FORWARD_UNIT_TESTS_TOKEN: ${{ secrets.FAST_FORWARD_UNIT_TESTS_TOKEN }} | ||
run: tests/fast-forward.sh |
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 |
---|---|---|
@@ -1 +1,2 @@ | ||
*~ | ||
tests/run.sh |
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,297 @@ | ||
#! /bin/bash | ||
|
||
# This script can be run locally or via GitHub actions. If you want | ||
# to run it locally, just run the script and it will tell you what | ||
# variables you need to set. | ||
|
||
# Where to run the test. | ||
OWNER=${OWNER:-sequoia-pgp} | ||
REPO=${REPO:-fast-forward-unit-tests} | ||
|
||
# To generate a personal access token, go to your profile and then: | ||
# | ||
# - Top-Right Menu | ||
# - Settings | ||
# - Developer Settings | ||
# - Personal access tokens | ||
# - Tokens (classic) | ||
# - Generate a personal access token | ||
# | ||
# Create a token with "repo" permission. | ||
if test "x$GITHUB_TOKEN" = x -a "x$FAST_FORWARD_UNIT_TESTS_TOKEN" = x | ||
then | ||
echo "Either the GITHUB_TOKEN or the FAST_FORWARD_UNIT_TESTS_TOKEN environment variable needs to be set." | ||
exit 1 | ||
fi | ||
|
||
# Prefer FAST_FORWARD_UNIT_TESTS_TOKEN (which is a secret known to the | ||
# fast-forward repository), but when that is not set try GITHUB_TOKEN, | ||
# which works with personal access tokens, and when the action is run | ||
# from the same repository. | ||
TOKEN="${FAST_FORWARD_UNIT_TESTS_TOKEN:-$GITHUB_TOKEN}" | ||
|
||
if test x$GITHUB_ACTOR = x | ||
then | ||
echo "GITHUB_ACTOR environment variable (your GitHub user name) is not set, but is required." | ||
exit 1 | ||
fi | ||
|
||
TEMPFILES=$(mktemp) | ||
echo -n "$TEMPFILES" >> "$TEMPFILES" | ||
function maketemp { | ||
F=$(mktemp $*) | ||
echo -n " $F" >> $TEMPFILES | ||
echo "$F" | ||
} | ||
function maketemp_exit { | ||
TEMPFILES=$(cat $TEMPFILES) | ||
if test x"$TEMPFILES" != x | ||
then | ||
echo -e "Clean up temporary files by running:\n $ rm -rf $TEMPFILES" | ||
fi | ||
} | ||
trap maketemp_exit EXIT | ||
|
||
set -ex | ||
|
||
# Files from the fast-forward repository that we copy over. | ||
FILES=".github/workflows/fast-forward.yml | ||
.github/workflows/pull_request.yml" | ||
|
||
FAST_FORWARD_REPO=$(git rev-parse --show-toplevel) | ||
for f in $FILES | ||
do | ||
if ! test -e "$FAST_FORWARD_REPO/$f" | ||
then | ||
echo "Missing \"$f\". Are you really in the fast-forward repo?" | ||
exit 1 | ||
fi | ||
done | ||
|
||
echo "::group::Initializing scratch repository" | ||
|
||
D=$(maketemp -d) | ||
echo "Scratch directory: $D" | ||
cd $D | ||
|
||
git init --initial-branch main . | ||
git config user.name "Fast Forward Unit Test" | ||
git config user.email "[email protected]" | ||
|
||
git config credential.helper store | ||
{ | ||
echo "url=https://$GITHUB_ACTOR@github.com/$OWNER/$REPO.git" | ||
echo "username=$GITHUB_ACTOR" | ||
echo "password=$TOKEN" | ||
} | git credential approve | ||
|
||
git remote add origin "https://$GITHUB_ACTOR@github.com/$OWNER/$REPO.git" | ||
|
||
echo "::endgroup::" | ||
|
||
echo "::group::Add commit #1" | ||
|
||
# Add the workflow files. | ||
for f in $FILES | ||
do | ||
mkdir -p $(dirname $f) | ||
cp "$FAST_FORWARD_REPO/$f" "$f" | ||
git add "$f" | ||
done | ||
|
||
git commit -m 'Initial commit' --no-gpg-sign | ||
|
||
BASE=fast-forward-test-0$RANDOM | ||
git push origin main:$BASE | ||
|
||
echo "::endgroup::" | ||
|
||
# Create a new commit, push it to a different branch. | ||
echo "::group::Add commit #2" | ||
|
||
echo $RANDOM > hello | ||
git add hello | ||
git commit -m 'Hello' --no-gpg-sign | ||
|
||
PR=$BASE-pr | ||
git push origin main:$PR | ||
|
||
echo "::endgroup::" | ||
|
||
echo "::group::Open pull request" | ||
|
||
# Create a pull request. | ||
OPEN_PR_RESULT=$(maketemp) | ||
curl --silent --show-error --output $OPEN_PR_RESULT -L \ | ||
-X POST \ | ||
-H "Accept: application/vnd.github+json" \ | ||
-H "Authorization: Bearer $TOKEN" \ | ||
-H "X-GitHub-Api-Version: 2022-11-28" \ | ||
https://api.github.com/repos/$OWNER/$REPO/pulls \ | ||
-d '{ | ||
"title":"/fast-forward unit test", | ||
"body":"This is a test, this is only a test!", | ||
"head":"'"$PR"'", | ||
"base":"'"$BASE"'" | ||
}' | ||
|
||
PR_URL=$(jq -r ".url" < $OPEN_PR_RESULT) | ||
if test "x$PR_URL" = xnull | ||
then | ||
echo "Couldn't get PR's URL" | ||
echo "Server's response:" | ||
cat "$OPEN_PR_RESULT" | ||
exit 1 | ||
fi | ||
PR_NUMBER=$(jq -r ".number" < $OPEN_PR_RESULT) | ||
if test "x$PR_NUMBER" = xnull | ||
then | ||
echo "Couldn't get PR's number" | ||
echo "Server's response:" | ||
cat "$OPEN_PR_RESULT" | ||
exit 1 | ||
fi | ||
|
||
echo "::endgroup::" | ||
|
||
echo "Pull request: https://github.com/$OWNER/$REPO/pull/$PR_NUMBER" | ||
|
||
# Wait for the check-fast-forward job to finish and check the results. | ||
echo "::group::Check that the check-fast-forward action ran, and said yes" | ||
|
||
COMMENTS_RESULT=$(maketemp) | ||
echo "Waiting for job to finish..." | ||
for i in $(seq 20 -1 0) | ||
do | ||
if test $i -eq 0 | ||
then | ||
echo "Timeout waiting for check-fast-forward job" | ||
cat "$COMMENTS_RESULT" | ||
exit 1 | ||
fi | ||
sleep 3 | ||
|
||
curl --silent --show-error --output "$COMMENTS_RESULT" -L \ | ||
-H "Accept: application/vnd.github+json" \ | ||
-H "Authorization: Bearer $TOKEN" \ | ||
-H "X-GitHub-Api-Version: 2022-11-28" \ | ||
https://api.github.com/repos/$OWNER/$REPO/issues/$PR_NUMBER/comments | ||
|
||
COMMENT=$(jq -r .[0].body <"$COMMENTS_RESULT") | ||
if test "x$COMMENT" = xnull | ||
then | ||
# The job hasn't completed yet. | ||
continue | ||
else | ||
if echo $COMMENT | grep -q 'you can add a comment with `/fast-forward` to fast forward' | ||
then | ||
echo check-fast-forward worked. | ||
else | ||
echo "Unexpected comment in response to push, did check-fast-forward change?" | ||
cat $COMMENTS_RESULT | ||
exit 1 | ||
fi | ||
fi | ||
|
||
break | ||
done | ||
|
||
echo "::endgroup::" | ||
|
||
echo "::group::Post a /fast-forward comment to fast forward the pull request" | ||
|
||
curl --silent --show-error -L \ | ||
-X POST \ | ||
-H "Accept: application/vnd.github+json" \ | ||
-H "Authorization: Bearer $TOKEN" \ | ||
-H "X-GitHub-Api-Version: 2022-11-28" \ | ||
https://api.github.com/repos/$OWNER/$REPO/issues/$PR_NUMBER/comments \ | ||
-d '{ "body":"We should /fast-forward this..." }' | ||
|
||
# Wait for the fast-forward job to finish and then check the results. | ||
echo "Waiting for job to finish..." | ||
for i in $(seq 20 -1 0) | ||
do | ||
if test $i -eq 0 | ||
then | ||
echo "Timeout waiting for fast-forward job" | ||
cat "$COMMENTS_RESULT" | ||
exit 1 | ||
fi | ||
sleep 3 | ||
|
||
curl --silent --show-error --output "$COMMENTS_RESULT" -L \ | ||
-H "Accept: application/vnd.github+json" \ | ||
-H "Authorization: Bearer $TOKEN" \ | ||
-H "X-GitHub-Api-Version: 2022-11-28" \ | ||
https://api.github.com/repos/$OWNER/$REPO/issues/$PR_NUMBER/comments | ||
|
||
# Comment 0 is from check-fast-forward, 1 is our /fast-forward, | ||
# and 2 will be from fast-forward. | ||
COMMENT=$(jq -r .[2].body <"$COMMENTS_RESULT") | ||
if test "x$COMMENT" = xnull | ||
then | ||
# The job hasn't completed yet. | ||
continue | ||
else | ||
if echo $COMMENT | grep -q 'Fast forwarding `'"$BASE"'`' | ||
then | ||
echo fast-forward worked. | ||
else | ||
echo "Unexpected comment in response to /fast-forward, did fast-forward change?" | ||
cat "$COMMENTS_RESULT" | ||
exit 1 | ||
fi | ||
fi | ||
|
||
break | ||
done | ||
|
||
echo "::endgroup::" | ||
|
||
# Make sure the base was fast forwarded by checking that it's sha is | ||
# now identical to HEAD. | ||
echo "::group::Check that the remote branch was fast forwarded" | ||
|
||
git fetch -a origin $BASE | ||
|
||
BASE_SHA=$(git rev-parse origin/$BASE) | ||
if test x$BASE_SHA = x | ||
then | ||
echo "Base branch disappeared?!?" | ||
exit 1 | ||
fi | ||
HEAD_SHA=$(git rev-parse HEAD) | ||
if test "x$BASE_SHA" != "x$HEAD_SHA" | ||
then | ||
echo "Base was not fast forwarded to HEAD: $BASE_SHA != $HEAD_SHA!" | ||
exit 1 | ||
fi | ||
|
||
echo "Pull request was fast forwarded!" | ||
|
||
echo "::endgroup::" | ||
|
||
# Make sure the base was fast forwarded by checking that it's sha is | ||
# now identical to HEAD. | ||
echo "::group::Check that the PR is closed" | ||
|
||
MERGED_PR_RESULT=$(maketemp) | ||
curl --silent --show-error --output $MERGED_PR_RESULT -L \ | ||
-H "Accept: application/vnd.github+json" \ | ||
-H "Authorization: Bearer $TOKEN" \ | ||
-H "X-GitHub-Api-Version: 2022-11-28" \ | ||
https://api.github.com/repos/$OWNER/$REPO/issues/$PR_NUMBER | ||
cat $MERGED_PR_RESULT | ||
|
||
STATE=$(jq -r .state <"$MERGED_PR_RESULT") | ||
if test "x$STATE" != xclosed | ||
then | ||
echo "PR was not closed (state: '$STATE')" | ||
exit 1 | ||
fi | ||
|
||
echo "::endgroup::" | ||
|
||
# Clean up on success. | ||
rm -rf $D |