Skip to content

Commit 5bbfc63

Browse files
Merge pull request #120 from farid-zare/forkPR
Fork pr
2 parents e5877a9 + 95b368f commit 5bbfc63

File tree

3 files changed

+162
-0
lines changed

3 files changed

+162
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ input and providing the issue number ():
211211
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
212212
if: always()
213213
```
214+
**Note:** Special considerations apply to pull requests from forks. See [Fork Pull Requests](docs/fork-pull-requests.md) for details.
214215

215216
### Comment Management Inputs
216217

community-reports/cobra-report/cobra-report.hbs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
### Summary:
12
| **Tests 📝** | **Passed ✅** | **Failed ❌** | **Skipped ⏭️** |
23
| --- | --- | --- | --- |
34
| {{ctrf.summary.tests}} | {{ctrf.summary.passed}} | {{ctrf.summary.failed}} | {{ctrf.summary.skipped}} |
45

6+
### Failed Tests:
57
{{#if (anyFailedTests ctrf.tests)}}
68
<table>
79
<thead>

docs/fork-pull-requests.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# 🚀 GitHub Actions: Securely Commenting Test Results on All PRs
2+
3+
## 📌 Overview
4+
5+
This tutorial explains how to set up a GitHub Actions workflow that runs tests and comments on the results of pull requests (PRs), including those from forks. Using two workflows ensures security while allowing test reports to be posted on all types of PRs.
6+
7+
The setup consists of two workflows:
8+
9+
1. **`workflowA`** - Runs tests and uploads the test results as artifacts.
10+
2. **`workflowB`** - Retrieves test results and comments on the corresponding pull request.
11+
12+
This method is applicable to any project using GitHub Actions for CI/CD, ensuring a secure and efficient way to handle test reporting.
13+
14+
---
15+
16+
## ⚠️ Important Note
17+
18+
These workflows should be implemented on the default branch of the repository (either `master` or `main` in newer repositories) to ensure proper execution and integration. Running workflows on other branches may lead to unexpected behavior, security issues, or failure to post comments on pull requests.
19+
20+
---
21+
22+
## 🔐 Why Use Two Workflows?
23+
24+
GitHub restricts workflows triggered by `pull_request` events from writing to the base repository when PRs originate from forks. This limitation prevents workflows from commenting on pull requests directly.
25+
26+
Using `pull_request_target` instead of `pull_request` allows commenting on forked PRs, but it introduces a significant security risk: the workflow runs with write permissions on the base repository, making it vulnerable to malicious code execution. Attackers could potentially modify workflows to exfiltrate secrets, overwrite critical repository files, or introduce malicious changes that could be merged unnoticed.
27+
28+
To mitigate this, we split the workflow into two:
29+
30+
- **The first workflow (********`workflowA`********)** runs tests and uploads the results as artifacts. This workflow is triggered using `pull_request`, ensuring it runs whenever a new pull request is opened, updated, or reopened.
31+
- **The second workflow (********`workflowB`********)** is triggered by `workflow_run` when the first workflow completes. Since `workflow_run` does not inherit permissions from the pull request, it eliminates security issues while allowing it to post a comment securely.
32+
33+
This method ensures that test results are always accessible while maintaining security.
34+
35+
---
36+
37+
## 🔄 Step-by-Step Workflow Execution
38+
39+
### **1️⃣ workflowA: Running Tests and Uploading Artifacts**
40+
41+
This workflow is triggered when a pull request is opened, synchronized, or reopened on any branch. It performs the following steps:
42+
43+
- **Check out PR code**:
44+
45+
```yaml
46+
- name: Check out PR code
47+
uses: actions/checkout@v4
48+
```
49+
50+
- **Run Tests**:
51+
52+
```yaml
53+
- name: Run Tests
54+
run: |
55+
./run-tests.sh # Replace with your actual test command
56+
```
57+
58+
- **Convert Test Results to a Compatible Format**:
59+
60+
```yaml
61+
- name: Convert Test Results
62+
run: |
63+
npx test-result-converter ./testReport.xml -o ./results/test-report.json # Modify based on your test framework
64+
```
65+
66+
- **Upload Test Report Artifact**:
67+
68+
```yaml
69+
- name: Upload Test Report Artifact
70+
uses: actions/upload-artifact@v4
71+
with:
72+
name: testReport
73+
path: ./results/test-report.json
74+
```
75+
76+
- **Save PR Number and Upload as an Artifact**:
77+
78+
To ensure that `workflowB` can correctly comment on the corresponding pull request, we save the PR number as an artifact in `workflowA`. Since `workflowB` is triggered by `workflowA` using `workflow_run`, it does not have direct access to the PR metadata. Uploading the PR number as an artifact allows `workflowB` to retrieve and use it for posting test results in the correct pull request.
79+
80+
```yaml
81+
- name: Save PR Number
82+
run: echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV
83+
84+
- name: Upload PR Number as Artifact
85+
run: echo $PR_NUMBER > pr_number.txt
86+
shell: bash
87+
88+
- name: Upload PR Number Artifact
89+
uses: actions/upload-artifact@v4
90+
with:
91+
name: pr_number
92+
path: pr_number.txt
93+
```
94+
95+
Since this workflow only requires read permissions, it avoids potential security risks when dealing with external contributions from forked repositories. The second workflow, which has the necessary permissions to write, is responsible for retrieving and posting the results, ensuring a secure and controlled execution process.
96+
97+
---
98+
99+
### **2️⃣ workflowB: Downloading Artifacts and Posting Results**
100+
101+
This workflow is triggered when `workflowA` completes successfully. Since GitHub Actions does not allow direct artifact downloads across workflows using `actions/download-artifact`.
102+
103+
- **Download Test Report Artifact:** Since GitHub Actions does not allow direct artifact downloads across workflows using `actions/download-artifact`, we use [`dawidd6/action-download-artifact@v8`](https://github.com/dawidd6/action-download-artifact) instead. This repository enables downloading artifacts from a previous workflow run by specifying the `run_id`, which is essential when handling artifacts between separate workflows. It follows these steps:
104+
```yaml
105+
- name: Download Test Report Artifact
106+
uses: dawidd6/action-download-artifact@v8
107+
with:
108+
name: testReport
109+
run_id: ${{ github.event.workflow_run.id }}
110+
path: artifacts
111+
```
112+
113+
- **Download PR Number Artifact**:
114+
115+
```yaml
116+
- name: Download PR Number Artifact
117+
uses: dawidd6/action-download-artifact@v8
118+
with:
119+
name: pr_number
120+
run_id: ${{ github.event.workflow_run.id }}
121+
path: pr_number
122+
```
123+
124+
- **Read PR Number**:
125+
126+
```yaml
127+
- name: Read PR Number
128+
id: read_pr_number
129+
run: |
130+
PR_NUMBER=$(cat pr_number/pr_number.txt)
131+
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
132+
```
133+
134+
- **Publish Test Report**:
135+
136+
```yaml
137+
- name: Publish Test Report
138+
uses: test-reporter/[email protected]
139+
with:
140+
report-path: 'artifacts/test-report.json'
141+
issue: ${{ env.PR_NUMBER }}
142+
env:
143+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
144+
```
145+
146+
This final step posts the test report as a comment on the pull request, making it easy for contributors and maintainers to review test results.
147+
148+
---
149+
150+
## ✅ Conclusion
151+
152+
By structuring the workflows this way, we achieve the following:
153+
154+
- **Secure execution** without exposing repository write access to forked pull requests.
155+
- **Successful test execution** and result upload.
156+
- **Seamless commenting** on pull requests with test results while mitigating security risks.
157+
158+
This method ensures that test results are reliably posted while maintaining a secure GitHub Actions setup. Additionally, this approach scales effectively for large repositories with many PRs, as the artifact-based workflow minimizes redundant computations and ensures efficient resource utilization. 🚀
159+

0 commit comments

Comments
 (0)