From 347ae6fbf8d710f78b239cbf0e1c936552694dec Mon Sep 17 00:00:00 2001
From: "Daniele E. Domenichelli" <daniele.domenichelli@gmail.com>
Date: Wed, 12 Feb 2020 20:51:01 +0100
Subject: [PATCH] Support rebasing PR from forks and allow only selected users
 to rebase (#17)

* Support rebasing PR from forks

This works only if the "Allow edit from maintainers" option is checked
and the `GITHUB_TOKEN` variable is set using a developer token, i.e.

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_OAUTH_TOKEN }}

* Use the user name and email for committer name

Instead of using a generic name and address, fetch these information
from using the GitHub API.

* Allow user based tokens

If an environment variable `<user_login>_TOKEN` exists, that variable is
used instead of `GITHUB_TOKEN`.

This makes it possible to allow only some users to rebase the PRs by
setting

  env:
    <user1>_TOKEN: ${{ secrets.<user1>_TOKEN }}
    <user2>_TOKEN: ${{ secrets.<user2>_TOKEN }}
---
 entrypoint.sh | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/entrypoint.sh b/entrypoint.sh
index cb0d1f2..591423e 100755
--- a/entrypoint.sh
+++ b/entrypoint.sh
@@ -20,6 +20,22 @@ pr_resp=$(curl -X GET -s -H "${AUTH_HEADER}" -H "${API_HEADER}" \
 BASE_REPO=$(echo "$pr_resp" | jq -r .base.repo.full_name)
 BASE_BRANCH=$(echo "$pr_resp" | jq -r .base.ref)
 
+USER_LOGIN=$(jq -r ".comment.user.login" "$GITHUB_EVENT_PATH")
+
+user_resp=$(curl -X GET -s -H "${AUTH_HEADER}" -H "${API_HEADER}" \
+            "${URI}/users/${USER_LOGIN}")
+
+USER_NAME=$(echo "$user_resp" | jq -r ".name")
+if [[ "$USER_NAME" == "null" ]]; then
+	USER_NAME=$USER_LOGIN
+fi
+USER_NAME="${USER_NAME} (Rebase PR Action)"
+
+USER_EMAIL=$(echo "$user_resp" | jq -r ".email")
+if [[ "$USER_EMAIL" == "null" ]]; then
+	USER_EMAIL="$USER_LOGIN@users.noreply.github.com"
+fi
+
 if [[ "$(echo "$pr_resp" | jq -r .rebaseable)" != "true" ]]; then
 	echo "GitHub doesn't think that the PR is rebaseable!"
 	exit 1
@@ -36,24 +52,24 @@ HEAD_BRANCH=$(echo "$pr_resp" | jq -r .head.ref)
 
 echo "Base branch for PR #$PR_NUMBER is $BASE_BRANCH"
 
-if [[ "$BASE_REPO" != "$HEAD_REPO" ]]; then
-	echo "PRs from forks are not supported at the moment."
-	exit 1
-fi
+USER_TOKEN=${USER_LOGIN}_TOKEN
+COMMITTER_TOKEN=${!USER_TOKEN:-$GITHUB_TOKEN}
+
+git remote set-url origin https://x-access-token:$COMMITTER_TOKEN@github.com/$GITHUB_REPOSITORY.git
+git config --global user.email "$USER_EMAIL"
+git config --global user.name "$USER_NAME"
 
-git remote set-url origin https://x-access-token:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY.git
-git config --global user.email "action@github.com"
-git config --global user.name "GitHub Action"
+git remote add fork https://x-access-token:$COMMITTER_TOKEN@github.com/$HEAD_REPO.git
 
 set -o xtrace
 
 # make sure branches are up-to-date
 git fetch origin $BASE_BRANCH
-git fetch origin $HEAD_BRANCH
+git fetch fork $HEAD_BRANCH
 
 # do the rebase
-git checkout -b $HEAD_BRANCH origin/$HEAD_BRANCH
+git checkout -b $HEAD_BRANCH fork/$HEAD_BRANCH
 git rebase origin/$BASE_BRANCH
 
 # push back
-git push --force-with-lease
+git push --force-with-lease fork $HEAD_BRANCH