Skip to content

Commit 54151f7

Browse files
chmouelpipelines-as-code[bot]
authored andcommitted
feat: Implement script to mirror external PRs for E2E tests
* Added `hack/mirror-pr.sh` script. * Added documentation to `docs/content/docs/dev/_index.md`. * Script allows maintainers to mirror external contributor pull requests to their fork. * This enables running E2E tests which may be blocked by security restrictions on external PRs. * Creates a draft pull request in the upstream repository with a `do-not-merge` label. * Adds a comment to the original pull request linking to the mirrored version. Signed-off-by: Chmouel Boudjnah <[email protected]>
1 parent 6484b59 commit 54151f7

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

docs/content/docs/dev/_index.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,43 @@ for arm64.
432432
- A GitHub action is using [ko](https://ko.build/) to build the amd64 and arm64 images whenever there is
433433
a push to a branch or for a release.
434434

435+
## Testing External contributor Pull Requests for E2E Testing
436+
437+
When an external contributor submits a pull request (PR), E2E tests may not run
438+
automatically due to security restrictions. To work around this, maintainers
439+
can use a script to mirror the external PR to their own fork, allowing E2E
440+
tests to run safely.
441+
442+
### Usage
443+
444+
1. Ensure you have the [GitHub CLI (`gh`)](https://cli.github.com/) installed and authenticated and fzf installed.
445+
2. Fork the repository and configure your fork as a git remote.
446+
3. Run the script:
447+
448+
```bash
449+
./hack/mirror-pr.sh <PR_NUMBER> <YOUR_FORK_REMOTE>
450+
```
451+
452+
If you omit the PR number, you'll be prompted to select one interactively.
453+
Same for the fork remote, if you omit it, it will get asked with fzf.
454+
455+
### What the Script Does
456+
457+
- Checks out the external PR locally.
458+
- Pushes the branch to your fork with a unique name.
459+
- Creates a draft pull request on the upstream repository with a `[MIRRORED] DO NOT MERGE` title and a `do-not-merge` label.
460+
- Comments on the original PR with a link to the mirrored PR.
461+
462+
This process allows E2E tests to run on the mirrored PR, while preventing accidental merges. Once the original PR is merged, the mirrored PR can be closed.
463+
464+
See the script (`./hack/mirror-pr.sh`) in the repository for details.
465+
466+
### When all is green in the mirrored PR pull request
467+
468+
- You can merge the external contributor original PR.
469+
- Close the mirrored PR.
470+
- Cleanup the branches on your fork or on your local repo
471+
435472
# Links
436473

437474
- [Jira Backlog](https://issues.redhat.com/browse/SRVKP-2144?jql=component%20%3D%20%22Pipeline%20as%20Code%22%20%20AND%20status%20!%3D%20Done)

hack/mirror-pr.sh

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/env bash
2+
# A script to mirror an external contributor's pull request to a maintainer's fork
3+
# for the purpose of running E2E tests.
4+
#
5+
# Prerequisites:
6+
# 1. GitHub CLI (`gh`) must be installed and authenticated (`gh auth login`).
7+
# 2. You must have a fork of the repository.
8+
# 3. You must have a git remote configured for the upstream repository (e.g., "upstream").
9+
#
10+
# Usage:
11+
# ./mirror-pr.sh <PR_NUMBER> <FORK_REMOTE>
12+
#
13+
# Example:
14+
# ./mirror-pr.sh 1234 my-github-user
15+
#
16+
# if no PR number is provided, it will prompt you to select one using `fzf`.
17+
18+
set -eo pipefail
19+
20+
# --- Prerequisite Check ---
21+
22+
if ! command -v gh &>/dev/null; then
23+
echo "Error: GitHub CLI ('gh') is not installed. Please install it to continue."
24+
echo "See: https://cli.github.com/"
25+
exit 1
26+
fi
27+
28+
echo "✅ GitHub CLI is installed."
29+
# --- Configuration and Argument Parsing ---
30+
31+
PR_NUMBER=$1
32+
FORK_REMOTE=${GH_FORK_REMOTE:-$2}
33+
UPSTREAM_REPO=${GH_UPSTREAM_REPO:-openshift-pipelines/pipelines-as-code}
34+
35+
if [[ -z ${PR_NUMBER} ]]; then
36+
PR_SELECTION=$(gh pr list --repo "$UPSTREAM_REPO" --json number,title,author --template '{{range .}}{{.number}}: {{.title}} (by {{.author.login}})
37+
{{end}}' | fzf --prompt="Select PR: ")
38+
PR_NUMBER=$(echo "$PR_SELECTION" | awk -F: '{print $1}' | xargs)
39+
fi
40+
41+
if [[ -z $FORK_REMOTE ]]; then
42+
FORK_REMOTE=$(git remote | awk '{print $1}' | grep -v origin | sort -u | fzf -1 --prompt="Select fork remote: ")
43+
fi
44+
45+
if [[ -z "$PR_NUMBER" || -z "$FORK_REMOTE" ]]; then
46+
echo "Usage: $0 <PR_NUMBER> <YOUR_REMOTE_FORK>"
47+
echo "Example: $0 1234 openshift-pipelines/pipelines-as-code my-github-user"
48+
exit 1
49+
fi
50+
51+
# --- Main Logic ---
52+
53+
echo "🔄 Fetching details for PR #${PR_NUMBER} from ${UPSTREAM_REPO}..."
54+
55+
# Fetch PR title and author using GitHub CLI
56+
PR_TITLE=$(gh pr view "$PR_NUMBER" --repo "$UPSTREAM_REPO" --json title -q .title)
57+
PR_AUTHOR=$(gh pr view "$PR_NUMBER" --repo "$UPSTREAM_REPO" --json author -q .author.login)
58+
PR_URL="https://github.com/${UPSTREAM_REPO}/pull/${PR_NUMBER}"
59+
60+
if [[ -z "$PR_TITLE" ]]; then
61+
echo "❌ Error: Could not fetch details for PR #${PR_NUMBER}. Please check the PR number and repository."
62+
exit 1
63+
fi
64+
65+
echo " - Title: $PR_TITLE"
66+
echo " - Author: $PR_AUTHOR"
67+
68+
# 1. Checkout the PR locally
69+
echo "🔄 Checking out PR #${PR_NUMBER} locally..."
70+
gh pr checkout "$PR_NUMBER" --repo "$UPSTREAM_REPO"
71+
72+
# 2. Push the branch to your fork
73+
NEW_BRANCH_NAME="test-pr-${PR_NUMBER}-${PR_AUTHOR}"
74+
75+
echo "🔄 Pushing changes to a new branch '${NEW_BRANCH_NAME}' on your fork (${FORK_REMOTE})..."
76+
# Force push in case the branch already exists from a previous test run
77+
git push "$FORK_REMOTE" "HEAD:${NEW_BRANCH_NAME}" -f
78+
79+
# 3. Create a new Pull Request from the fork to the upstream repo
80+
MIRRORED_PR_TITLE="[MIRRORED] DO NOT MERGE: ${PR_TITLE}"
81+
MIRRORED_PR_BODY="Mirrors ${PR_URL} to run E2E tests. Original author: @${PR_AUTHOR}"
82+
DO_NOT_MERGE_LABEL="do-not-merge" # You might need to create this label in your repo if it doesn't exist
83+
84+
echo "🔄 Creating a new mirrored pull request on ${UPSTREAM_REPO}..."
85+
86+
# Create the PR as a draft to prevent accidental merges before tests run.
87+
# The --head flag specifies the branch in your fork.
88+
CREATED_PR_URL=$(gh pr create \
89+
--repo "$UPSTREAM_REPO" \
90+
--title "$MIRRORED_PR_TITLE" \
91+
--body "$MIRRORED_PR_BODY" \
92+
--head "${FORK_REMOTE}:${NEW_BRANCH_NAME}" \
93+
--label "$DO_NOT_MERGE_LABEL" \
94+
--draft) # Using --draft is safer
95+
96+
# Check if the PR was created successfully
97+
if [[ -z "$CREATED_PR_URL" ]]; then
98+
echo "❌ Error: Failed to create the mirrored pull request."
99+
exit 1
100+
fi
101+
102+
gh pr comment "$PR_NUMBER" --repo "$UPSTREAM_REPO" --body "A mirrored PR has been created for E2E testing: ${CREATED_PR_URL}"
103+
104+
echo "✅ Successfully created mirrored pull request!"
105+
echo " ${CREATED_PR_URL}"
106+
107+
echo "🚀 Done."

0 commit comments

Comments
 (0)