Skip to content

Commit 3e11534

Browse files
committed
add push listeners
1 parent 5fd16f3 commit 3e11534

File tree

2 files changed

+264
-20
lines changed

2 files changed

+264
-20
lines changed

.github/workflows/external-pr-trigger.yml

Lines changed: 109 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ name: External PR Trigger
22

33
on:
44
pull_request:
5-
types: [opened, reopened]
5+
types: [opened, synchronize, reopened]
6+
push:
7+
branches:
8+
- "**"
9+
- "!main"
610

711
jobs:
812
trigger-external-pr:
913
runs-on: ubuntu-latest
1014
# Only run if the source branch does not have a PMM- prefix
1115
if: |
12-
!startsWith(github.event.pull_request.head.ref, 'PMM-')
16+
(github.event_name == 'pull_request' && !startsWith(github.event.pull_request.head.ref, 'PMM-')) ||
17+
(github.event_name == 'push' && !startsWith(github.ref_name, 'PMM-'))
1318
1419
steps:
1520
- name: Checkout repository
@@ -20,19 +25,39 @@ jobs:
2025
git config --global user.name "github-actions[bot]"
2126
git config --global user.email "github-actions[bot]@users.noreply.github.com"
2227
28+
- name: Set variables based on event type
29+
id: set-vars
30+
run: |
31+
if [ "${{ github.event_name }}" == "pull_request" ]; then
32+
echo "source_branch=${{ github.event.pull_request.head.ref }}" >> $GITHUB_OUTPUT
33+
echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
34+
echo "pr_author=${{ github.event.pull_request.user.login }}" >> $GITHUB_OUTPUT
35+
echo "pr_title=${{ github.event.pull_request.title }}" >> $GITHUB_OUTPUT
36+
echo "pr_url=${{ github.event.pull_request.html_url }}" >> $GITHUB_OUTPUT
37+
echo "pr_body=${{ github.event.pull_request.body }}" >> $GITHUB_OUTPUT
38+
else
39+
echo "source_branch=${{ github.ref_name }}" >> $GITHUB_OUTPUT
40+
echo "pr_number=N/A" >> $GITHUB_OUTPUT
41+
echo "pr_author=${{ github.actor }}" >> $GITHUB_OUTPUT
42+
echo "pr_title=Push to ${{ github.ref_name }}" >> $GITHUB_OUTPUT
43+
echo "pr_url=${{ github.server_url }}/${{ github.repository }}/tree/${{ github.ref_name }}" >> $GITHUB_OUTPUT
44+
echo "pr_body=Automated PR for push to branch ${{ github.ref_name }}" >> $GITHUB_OUTPUT
45+
fi
46+
2347
- name: Create branch in target repository
2448
env:
2549
GITHUB_TOKEN: ${{ secrets.TARGET_REPO_TOKEN }}
2650
TARGET_REPO: ${{ vars.TARGET_REPO_OWNER }}/${{ vars.TARGET_REPO_NAME }}
27-
SOURCE_BRANCH: ${{ github.event.pull_request.head.ref }}
28-
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
51+
SOURCE_BRANCH: ${{ steps.set-vars.outputs.source_branch }}
52+
PR_NUMBER: ${{ steps.set-vars.outputs.pr_number }}
53+
PR_AUTHOR: ${{ steps.set-vars.outputs.pr_author }}
2954
run: |
3055
# Clone the target repository
3156
git clone https://x-access-token:${GITHUB_TOKEN}@github.com/${TARGET_REPO}.git target-repo
3257
cd target-repo
3358
3459
# Create a new branch based on the PR branch name
35-
git checkout -b "mongodb-exporter-external-pr-${SOURCE_BRANCH}"
60+
git checkout -b "external-pr-${SOURCE_BRANCH}"
3661
3762
# Check if ci.yml exists
3863
if [ ! -f "ci.yml" ]; then
@@ -44,36 +69,100 @@ jobs:
4469
# Modify ci.yml file with PR information
4570
cat > ci.yml << EOF
4671
# Auto-generated from external PR
47-
deps:
48-
-name: mongodb_exporter
49-
url: https://github.com/${GITHUB_REPOSITORY}
50-
branch: ${SOURCE_BRANCH}
72+
external_pr:
73+
source_repo: ${{ github.repository }}
74+
pr_number: ${PR_NUMBER}
75+
pr_author: ${PR_AUTHOR}
76+
pr_branch: ${SOURCE_BRANCH}
77+
pr_title: ${{ steps.set-vars.outputs.pr_title }}
78+
pr_url: ${{ steps.set-vars.outputs.pr_url }}
79+
triggered_at: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
80+
event_type: ${{ github.event_name }}
81+
commit_sha: ${{ github.sha }}
5182
EOF
5283
5384
# Commit changes
5485
git add ci.yml
55-
git commit -m "Update ci.yml for external PR #${PR_NUMBER} from ${PR_AUTHOR}"
86+
if [ "${{ github.event_name }}" == "pull_request" ]; then
87+
git commit -m "Update ci.yml for external PR #${PR_NUMBER} from ${PR_AUTHOR}"
88+
else
89+
git commit -m "Update ci.yml for push to ${SOURCE_BRANCH} by ${PR_AUTHOR}"
90+
fi
5691
5792
# Push the new branch
58-
git push origin "mongodb-exporter-external-pr-${SOURCE_BRANCH}"
93+
git push origin "external-pr-${SOURCE_BRANCH}"
94+
95+
- name: Check if PR already exists in target repository
96+
id: check-pr
97+
env:
98+
GITHUB_TOKEN: ${{ secrets.TARGET_REPO_TOKEN }}
99+
TARGET_REPO: ${{ vars.TARGET_REPO_OWNER }}/${{ vars.TARGET_REPO_NAME }}
100+
SOURCE_BRANCH: ${{ steps.set-vars.outputs.source_branch }}
101+
run: |
102+
# Check if a PR already exists for this branch
103+
EXISTING_PR=$(gh pr list --repo "${TARGET_REPO}" --head "external-pr-${SOURCE_BRANCH}" --json number --jq '.[0].number' || echo "")
104+
105+
if [ -n "$EXISTING_PR" ]; then
106+
echo "PR already exists: #${EXISTING_PR}"
107+
echo "pr_exists=true" >> $GITHUB_OUTPUT
108+
echo "existing_pr_number=${EXISTING_PR}" >> $GITHUB_OUTPUT
109+
else
110+
echo "No existing PR found"
111+
echo "pr_exists=false" >> $GITHUB_OUTPUT
112+
fi
59113
60114
- name: Create Pull Request in target repository
115+
if: steps.check-pr.outputs.pr_exists == 'false'
61116
env:
62117
GITHUB_TOKEN: ${{ secrets.TARGET_REPO_TOKEN }}
63118
TARGET_REPO: ${{ vars.TARGET_REPO_OWNER }}/${{ vars.TARGET_REPO_NAME }}
64-
SOURCE_BRANCH: ${{ github.event.pull_request.head.ref }}
65-
PR_NUMBER: ${{ github.event.pull_request.number }}
66-
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
119+
SOURCE_BRANCH: ${{ steps.set-vars.outputs.source_branch }}
120+
PR_NUMBER: ${{ steps.set-vars.outputs.pr_number }}
121+
PR_AUTHOR: ${{ steps.set-vars.outputs.pr_author }}
122+
PR_TITLE: ${{ steps.set-vars.outputs.pr_title }}
123+
PR_URL: ${{ steps.set-vars.outputs.pr_url }}
124+
PR_BODY: ${{ steps.set-vars.outputs.pr_body }}
67125
run: |
68126
# Create PR using GitHub CLI
69-
gh pr create \
70-
--repo "${TARGET_REPO}" \
71-
--title "External PR: ${{ github.event.pull_request.title }}" \
72-
--body "This PR was automatically generated from external pull request #${PR_NUMBER} by @${PR_AUTHOR} in ${{ github.repository }} (branch: ${SOURCE_BRANCH}).
127+
if [ "${{ github.event_name }}" == "pull_request" ]; then
128+
TITLE="External PR: ${PR_TITLE}"
129+
BODY="This PR was automatically generated from external pull request #${PR_NUMBER} by @${PR_AUTHOR} in ${{ github.repository }} (branch: ${SOURCE_BRANCH}).
73130
74-
Original PR: ${{ github.event.pull_request.html_url }}
131+
Original PR: ${PR_URL}
75132
76133
## Original PR Description
77-
${{ github.event.pull_request.body }}" \
134+
${PR_BODY}"
135+
else
136+
TITLE="External Push: ${SOURCE_BRANCH}"
137+
BODY="This PR was automatically generated from a push to branch ${SOURCE_BRANCH} by @${PR_AUTHOR} in ${{ github.repository }}.
138+
139+
Branch: ${PR_URL}
140+
141+
## Push Details
142+
- Pusher: @${PR_AUTHOR}
143+
- Commit: ${{ github.sha }}
144+
- Timestamp: $(date -u +"%Y-%m-%dT%H:%M:%SZ")"
145+
fi
146+
147+
gh pr create \
148+
--repo "${TARGET_REPO}" \
149+
--title "${TITLE}" \
150+
--body "${BODY}" \
78151
--base main \
79152
--head "external-pr-${SOURCE_BRANCH}"
153+
154+
- name: Update existing PR in target repository
155+
if: steps.check-pr.outputs.pr_exists == 'true'
156+
env:
157+
GITHUB_TOKEN: ${{ secrets.TARGET_REPO_TOKEN }}
158+
TARGET_REPO: ${{ vars.TARGET_REPO_OWNER }}/${{ vars.TARGET_REPO_NAME }}
159+
EXISTING_PR: ${{ steps.check-pr.outputs.existing_pr_number }}
160+
SOURCE_BRANCH: ${{ steps.set-vars.outputs.source_branch }}
161+
run: |
162+
echo "PR #${EXISTING_PR} already exists in ${TARGET_REPO} for branch external-pr-${SOURCE_BRANCH}"
163+
echo "The branch has been updated with the latest changes."
164+
165+
# Optionally, add a comment to the existing PR
166+
gh pr comment ${EXISTING_PR} \
167+
--repo "${TARGET_REPO}" \
168+
--body "Branch updated with new changes from ${{ github.event_name }} event at $(date -u +"%Y-%m-%dT%H:%M:%SZ")"

EXTERNAL_PR_ACTION.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# External PR Trigger GitHub Action
2+
3+
This GitHub Action automatically triggers actions in a target repository when a pull request is created or when commits are pushed to branches that don't have a `PMM-` prefix.
4+
5+
## Overview
6+
7+
When a pull request is opened, synchronized, or reopened, OR when commits are pushed to a branch that does NOT have a `PMM-` prefix, this action will:
8+
1. Create a new branch in a specified target repository
9+
2. Modify a `ci.yml` file in that repository with PR/push information
10+
3. Create a pull request in the target repository (or update if one already exists)
11+
12+
## Trigger Events
13+
14+
The action triggers on:
15+
- **Pull Request events**: opened, synchronized, reopened
16+
- **Push events**: to any branch except `main` and `master`
17+
18+
In both cases, the action only runs if the branch does NOT have a `PMM-` prefix.
19+
20+
## Setup Instructions
21+
22+
### 1. Understanding the Branch Prefix Check
23+
24+
The workflow checks the source branch name:
25+
26+
```yaml
27+
if: |
28+
(github.event_name == 'pull_request' && !startsWith(github.event.pull_request.head.ref, 'PMM-')) ||
29+
(github.event_name == 'push' && !startsWith(github.ref_name, 'PMM-'))
30+
```
31+
32+
This means:
33+
- Branches WITH the `PMM-` prefix will NOT trigger this action
34+
- Branches WITHOUT the `PMM-` prefix WILL trigger this action
35+
36+
### 2. Create a Personal Access Token
37+
38+
You need a Personal Access Token (PAT) with permissions to create branches and pull requests in the target repository:
39+
40+
1. Go to GitHub Settings → Developer settings → Personal access tokens
41+
2. Generate a new token with the following scopes:
42+
- `repo` (full control of private repositories)
43+
- `workflow` (if the target repo has GitHub Actions)
44+
3. Copy the generated token
45+
46+
### 3. Configure Repository Secrets
47+
48+
In your repository settings, go to Secrets and variables → Actions, and add:
49+
50+
- **SECRET**: `TARGET_REPO_TOKEN` - The Personal Access Token you created
51+
52+
### 4. Configure Repository Variables
53+
54+
In your repository settings, go to Secrets and variables → Actions → Variables tab, and add:
55+
56+
- **VARIABLE**: `TARGET_REPO_OWNER` - The owner/organization of the target repository
57+
- **VARIABLE**: `TARGET_REPO_NAME` - The name of the target repository
58+
59+
Example:
60+
- `TARGET_REPO_OWNER`: `myorg`
61+
- `TARGET_REPO_NAME`: `ci-configs`
62+
63+
### 5. Customize the ci.yml Content (Optional)
64+
65+
The action creates/updates a `ci.yml` file in the target repository. The content includes:
66+
67+
```yaml
68+
# Auto-generated from external PR
69+
external_pr:
70+
source_repo: <repository>
71+
pr_number: <PR number or N/A for pushes>
72+
pr_author: <author>
73+
pr_branch: <branch name>
74+
pr_title: <PR title or push description>
75+
pr_url: <PR URL or branch URL>
76+
triggered_at: <timestamp>
77+
event_type: <pull_request or push>
78+
commit_sha: <commit SHA>
79+
```
80+
81+
## How It Works
82+
83+
### For Pull Requests
84+
85+
1. **Trigger**: PR is opened, synchronized, or reopened
86+
2. **Branch Check**: Verifies the PR branch doesn't have `PMM-` prefix
87+
3. **Target Branch**: Creates/updates branch `external-pr-{source-branch-name}`
88+
4. **PR Creation**: Creates a PR titled "External PR: {original PR title}"
89+
90+
### For Push Events
91+
92+
1. **Trigger**: Commits are pushed to a branch (not main/master)
93+
2. **Branch Check**: Verifies the branch doesn't have `PMM-` prefix
94+
3. **Target Branch**: Creates/updates branch `external-pr-{source-branch-name}`
95+
4. **PR Handling**:
96+
- If no PR exists: Creates one titled "External Push: {branch name}"
97+
- If PR exists: Updates the branch and adds a comment to the existing PR
98+
99+
## Key Features
100+
101+
### Duplicate PR Prevention
102+
The action checks if a PR already exists for the branch in the target repository:
103+
- If no PR exists: Creates a new one
104+
- If PR exists: Updates the branch and comments on the existing PR
105+
106+
### Event-Specific Information
107+
The `ci.yml` file includes different metadata based on the triggering event:
108+
- **Pull Request**: Includes PR number, title, and description
109+
- **Push**: Includes branch name, pusher, and commit SHA
110+
111+
## Security Considerations
112+
113+
1. **Token Security**: The PAT is stored as a secret and never exposed in logs
114+
2. **Limited Scope**: The action only modifies the specified `ci.yml` file
115+
3. **Branch Filtering**: Only branches without the `PMM-` prefix trigger the action
116+
4. **Protected Branches**: Pushes to `main` and `master` are excluded
117+
118+
## Troubleshooting
119+
120+
### Action Not Triggering
121+
- Verify the branch does NOT have a `PMM-` prefix
122+
- Check that the workflow file is in `.github/workflows/` directory
123+
- Ensure the event (PR or push) matches the configured triggers
124+
- For pushes, verify the branch is not `main` or `master`
125+
126+
### Permission Errors
127+
- Verify the PAT has the correct scopes
128+
- Check that the token hasn't expired
129+
- Ensure the target repository allows the token's access
130+
131+
### Branch/PR Creation Fails
132+
- Check that the target repository exists
133+
- Verify the `TARGET_REPO_OWNER` and `TARGET_REPO_NAME` variables are correct
134+
- Check for existing branches with conflicting names
135+
136+
## Example Scenarios
137+
138+
### Scenario 1: New PR from non-PMM branch
139+
1. User creates PR #123 from branch `fix-bug`
140+
2. Action creates branch `external-pr-fix-bug` in target repo
141+
3. Creates PR titled "External PR: Fix bug title"
142+
143+
### Scenario 2: Push to existing branch with PR
144+
1. User pushes to branch `feature-xyz` (PR already exists in target)
145+
2. Action updates branch `external-pr-feature-xyz`
146+
3. Adds comment to existing PR about the update
147+
148+
### Scenario 3: Push to new branch without PR
149+
1. User pushes to new branch `hotfix-123`
150+
2. Action creates branch `external-pr-hotfix-123` in target repo
151+
3. Creates PR titled "External Push: hotfix-123"
152+
153+
### Scenario 4: PMM branch (Action does NOT trigger)
154+
1. User creates PR or pushes to branch `PMM-1234-fix-issue`
155+
2. Action does NOT trigger due to `PMM-` prefix

0 commit comments

Comments
 (0)