-
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
349 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,51 @@ | ||
# This action is run from sequoia-pgp/fast-forward. It needs to | ||
# access the sequoia-pgp/fast-forward-unit-test repository. We can't | ||
# use a GitHub Token: its permissions are limited to the repository in | ||
# which the action is run. Instead, we can use a deploy key: | ||
# | ||
# https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys#deploy-keys | ||
# | ||
# Deploy keys with write access can perform the same actions as an | ||
# organization member with admin access, or a collaborator on a | ||
# personal repository. For more information, see "Repository roles | ||
# for an organization" and "Permission levels for a personal account | ||
# repository." | ||
# | ||
# To add a deply key to fast-forward-unit-tests, go to: | ||
# | ||
# https://github.com/sequoia-pgp/fast-forward-unit-tests | ||
# | ||
# Then go to settings, deploy keys, add deploy key. | ||
# | ||
# Generate a new ssh key pair in fast-forward/secrets (don't add it to | ||
# the repository). | ||
# | ||
# $ ssh-keygen -t ed25519 | ||
# | ||
# In the fast-forward repository, navigate to Settings, Secrets and | ||
# variables, Actions, New repository secret. Name the environment | ||
# variable `FAST_FORWARD_UNIT_TESTS_SSH_KEY`. This is automatically | ||
# used by the fast-forward 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_SSH_KEY: ${{ secrets.FAST_FORWARD_UNIT_TESTS_SSH_KEY }} | ||
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,3 @@ | ||
*~ | ||
tests/run.sh | ||
secrets |
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,296 @@ | ||
#! /bin/bash | ||
|
||
# Go to: | ||
# - 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 | ||
then | ||
echo "GITHUB_TOKEN environment variable is not set, but is required." | ||
exit 1 | ||
fi | ||
|
||
if test x$GITHUB_ACTOR = x | ||
then | ||
echo "GITHUB_ACTOR environment variable is not set, but is required." | ||
exit 1 | ||
fi | ||
|
||
if test "x$FAST_FORWARD_UNIT_TESTS_SSH_KEY" != x | ||
then | ||
echo "Adding deploy key for fast-forward-unit-tests repository." | ||
# XXX: It would be better to use an ssh-agent. | ||
SSH_ID=$(mktemp) | ||
echo "$FAST_FORWARD_UNIT_TESTS_SSH_KEY" > "$SSH_ID" | ||
else | ||
echo "No deploy key for target repository. Hoping for the best." | ||
fi | ||
echo SSH_ID: $SSH_ID | ||
|
||
# Where to run the test. | ||
OWNER=${OWNER:-sequoia-pgp} | ||
REPO=${REPO:-fast-forward-unit-tests} | ||
|
||
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 "Cleanup 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]" | ||
if test "x$SSH_ID" != x | ||
then | ||
git config core.sshCommand "ssh -i $SSH_ID" | ||
fi | ||
|
||
CLONE_URL="github.com/$OWNER/$REPO.git" | ||
git remote add origin "https://$GITHUB_ACTOR@$CLONE_URL" | ||
|
||
# When running on a GitHub runner, we need to use the github token to | ||
# interaction with the git repository. | ||
git config credential.helper store | ||
{ | ||
echo "url=https://$GITHUB_ACTOR@$CLONE_URL" | ||
echo "username=$GITHUB_ACTOR" | ||
echo "password=$GITHUB_TOKEN" | ||
} | git credential approve | ||
|
||
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 $GITHUB_TOKEN" \ | ||
-H "X-GitHub-Api-Version: 2022-11-28" \ | ||
https://api.github.com/repos/$OWNER/$REPO/pulls \ | ||
-d '{ | ||
"title":"Test", | ||
"body":"This is a test, 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" | ||
exit 1 | ||
fi | ||
PR_NUMBER=$(jq -r ".number" < $OPEN_PR_RESULT) | ||
if test "x$PR_NUMBER" = xnull | ||
then | ||
echo "Couldn't get PR's URL" | ||
exit 1 | ||
fi | ||
|
||
echo "::endgroup::" | ||
|
||
# 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) | ||
for i in $(seq 1 10) | ||
do | ||
if test $i -eq 10 | ||
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 $GITHUB_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 -L \ | ||
-X POST \ | ||
-H "Accept: application/vnd.github+json" \ | ||
-H "Authorization: Bearer $GITHUB_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. | ||
for i in $(seq 1 10) | ||
do | ||
if test $i -eq 10 | ||
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 $GITHUB_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 $GITHUB_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 |