diff --git a/docs/contributing/ci.md b/docs/contributing/ci.md new file mode 100644 index 000000000..8055fe095 --- /dev/null +++ b/docs/contributing/ci.md @@ -0,0 +1,48 @@ +--- +name: Running Tests on Untrusted Forks +sidebar_position: 99 +--- + +# Running CI Scripts on Untrusted Forks + +Untrusted forks could contain malicious code to mine cryptocurrency, steal secrets, or otherwise harm the CI server. + +For PRs from untrusted forks, to run the CI scripts, we need to: + +1. Review the code to ensure that it is safe to run on the CI server. +2. If the code is safe, run the `ci:trust` script to push the commits to a branch on the main repository, where the CI scripts can be run. +3. Once the tests have run, the status of the PR will be updated automatically (because the commits are the same). + + +## How to run the CI scripts on untrusted forks: + +1. Copy the name of the branch from the PR. + ci-copy-fork-branch +2. From your local clone of the main repository, run the `ci:trust` script. + ```bash + yarn ci:trust + ``` +3. The branch will be pushed and the tests will run + ci-tests-running + + +## What does ci:trust do? + +The `ci:trust` script does the following: + +1. Adds and fetches the untrusted fork as a temporary remote in your local repository. +2. Pushes the specific branch from the untrusted fork to a designated temporary branch in your original repository. +3. Pushing to a local branch triggers the continuous integration (CI) tests on the commits of the branch. +4. Because the commits are the same, the status of the PR will be updated automatically. + + +### Notes +1. The ci:trust script will only work if you have write access to the main repository. This prevents malicious users from running the script on the main repository. +2. The ci:trust script pushes the commits to a branch called `temp-branch-to-test-fork`. + +::: warning + +The `temp-branch-to-test-fork` branch will be deleted and recreated if it already exists. This allows the script to +clean up its own temporary branches. + +::: diff --git a/docs/contributing/images/ci-copy-fork-branch.png b/docs/contributing/images/ci-copy-fork-branch.png new file mode 100644 index 000000000..8d401229a Binary files /dev/null and b/docs/contributing/images/ci-copy-fork-branch.png differ diff --git a/docs/contributing/images/ci-tests-running.png b/docs/contributing/images/ci-tests-running.png new file mode 100644 index 000000000..25e465fd0 Binary files /dev/null and b/docs/contributing/images/ci-tests-running.png differ diff --git a/scripts/git-push-fork-to-upstream-repo.sh b/scripts/git-push-fork-to-upstream-repo.sh new file mode 100755 index 000000000..662a4182f --- /dev/null +++ b/scripts/git-push-fork-to-upstream-repo.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +set -eo pipefail + +: "${GPF_REACTOTRON_BRANCH:=build-trusted-commits}" + +REACTOTRON_REPO="git@github.com:infinitered/reactotron.git" +BRANCH_SPEC=$1 +NUM_COLONS=$(echo "$BRANCH_SPEC" | awk -F: '{print NF-1}') + +if [ "$#" -ne 1 ] || [ "$NUM_COLONS" -ne 1 ] ; then + echo "Usage: :" + exit 1 +fi + +SOURCE_GH_USER=$(echo "$BRANCH_SPEC" | awk -F: '{print $1}') +SOURCE_BRANCH=$(echo "$BRANCH_SPEC" | awk -F: '{print $2}') +REPO_NAME=$(git remote get-url --push origin | awk -F/ '{print $NF}' | sed 's/\.git$//') + +# Check if 'temp-branch-to-test-fork' remote exists and then remove it +if git config --get "remote.temp-branch-to-test-fork.url" > /dev/null; then + git remote remove temp-branch-to-test-fork + echo "Removed remote temp-branch-to-test-fork" +else + echo "Remote temp-branch-to-test-fork does not exist, no need to remove it" +fi + +git remote add temp-branch-to-test-fork "git@github.com:$SOURCE_GH_USER/$REPO_NAME.git" + +git fetch --all +git push --force "$REACTOTRON_REPO" "refs/remotes/temp-branch-to-test-fork/$SOURCE_BRANCH:refs/heads/$GPF_REACTOTRON_BRANCH" +git remote remove temp-branch-to-test-fork || echo "Removed new remote temp-branch-to-test-fork" + +cat <