Skip to content

Commit 1f08173

Browse files
feat(DATAGO-121121): Add PR diff feature and PR comment and status check with fossa-guard. (#60)
Integrate PR integration enhancements from maas-build-actions #581: - Add enable_diff_mode input to show only newly introduced issues - Add diff_base_revision_sha input for base branch comparison - Add enable_license_enrichment input for license indicators - Pass GitHub context variables (EVENT_NAME, REF, SHA, HEAD_REF, BASE_REF) - Update README with comprehensive examples and documentation New Features: - Diff mode compares PR against base branch (auto-detects default branch) - License enrichment shows declared/discovered indicators - Enhanced PR workflow examples (basic, diff mode, REPORT mode) - Mode behavior clarification (BLOCK vs REPORT) - Migration path for gradual adoption All features are opt-in and backwards compatible. Related: SolaceDev/maas-build-actions#581 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent ac2e5dd commit 1f08173

File tree

2 files changed

+295
-3
lines changed

2 files changed

+295
-3
lines changed

.github/actions/fossa-guard/README.md

Lines changed: 242 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ The `fossa-guard` GitHub Action integrates with the FOSSA API to fetch and proce
3939
| `github_run_id` | No | GitHub Actions run ID for build links (optional). |
4040
| `github_server_url` | No | GitHub server URL (default: https://github.com) (optional). |
4141

42+
### PR Integration Inputs (Optional)
43+
44+
| Input | Default | Description |
45+
|-------|---------|-------------|
46+
| `github_token` | `${{ github.token }}` | GitHub token for PR comments and status checks |
47+
| `enable_pr_comment` | `false` | Enable PR commenting (`true`/`false`) |
48+
| `enable_status_check` | `false` | Enable GitHub status checks (`true`/`false`) |
49+
| `status_check_name` | `FOSSA Guard` | Custom name for status checks |
50+
| `pr_comment_max_violations` | `5` | Max violations shown in PR comment |
51+
| `enable_diff_mode` | `false` | Enable diff mode to show only new issues (`true`/`false`) |
52+
| `diff_base_revision_sha` | (auto-detect) | Base revision SHA to compare against (optional - auto-detects default branch) |
53+
| `enable_license_enrichment` | `true` | Show declared/discovered license indicators (`true`/`false`) |
54+
4255
### Issue Types Explained
4356
- **policy_conflict**: There is a known explicit policy violation (FOSSA terminology). This means the license or dependency is denied in your FOSSA policy and should block the build.
4457
- **policy_flag**: The license needs to be reviewed or is unknown (FOSSA terminology). This means the license or dependency is flagged for review or is uncategorized in your FOSSA policy and may require manual attention.
@@ -52,10 +65,18 @@ The `fossa-guard` GitHub Action integrates with the FOSSA API to fetch and proce
5265

5366
| Mode | Description |
5467
|--------|-----------------------------------------------------------------------------------------------|
55-
| BLOCK | Fails the build if violations matching `block_on` are found. Prints a Markdown/HTML summary. |
56-
| REPORT | Generates and sends Slack reports (requires `slack_token` and `slack_channel`). Prints a Markdown/HTML summary. Intended for reporting only. Exit code 1 if Slack reporting fails and REPORT is the only action. |
68+
| BLOCK | Fails the build if violations matching `block_on` are found (exit code 2). PR comments show violations. Status checks fail. Prints a Markdown/HTML summary. |
69+
| REPORT | Shows violations in PR comments and status checks (marked as failed), but build passes (exit code 0). Useful for gradual rollout. Also sends Slack reports if configured. |
5770
| BLOCK,REPORT | Combines both actions - blocks on violations AND sends Slack reports. Exit code 2 if blocking violations found (Slack failure won't affect exit code). Exit code 0 if no blocking violations. |
5871

72+
### Mode Behavior Clarification
73+
74+
**Important**: PR comments and status checks work identically in both BLOCK and REPORT modes. The only difference is:
75+
- **REPORT mode**: Shows violations in status check (failure), but build passes (exit 0)
76+
- **BLOCK mode**: Shows violations in status check (failure), and build fails (exit 2)
77+
78+
This allows you to enable PR integration in REPORT mode first for visibility without blocking builds, then switch to BLOCK mode when ready to enforce compliance.
79+
5980
---
6081

6182
## Business Logic
@@ -101,6 +122,179 @@ jobs:
101122

102123
---
103124

125+
## Pull Request Workflow Examples
126+
127+
### Basic PR Integration
128+
129+
```yaml
130+
name: FOSSA PR Check
131+
132+
on:
133+
pull_request:
134+
branches: [main]
135+
136+
permissions:
137+
pull-requests: write # For PR comments
138+
checks: write # For status checks
139+
issues: write # For PR comments
140+
141+
jobs:
142+
fossa-check:
143+
runs-on: ubuntu-latest
144+
steps:
145+
- uses: actions/checkout@v4
146+
147+
- name: FOSSA Guard with PR Integration
148+
uses: SolaceDev/solace-public-workflows/.github/actions/fossa-guard@main
149+
with:
150+
fossa_api_key: ${{ secrets.FOSSA_API_KEY }}
151+
fossa_project_id: ${{ secrets.FOSSA_PROJECT_ID }}
152+
fossa_category: licensing
153+
fossa_mode: BLOCK
154+
fossa_branch: ${{ github.event.pull_request.number && 'PR' || github.event.repository.default_branch }}
155+
fossa_revision: ${{ github.event.pull_request.head.ref || github.sha }}
156+
block_on: policy_conflict,policy_flag
157+
# PR features (auto-enabled)
158+
github_token: ${{ github.token }}
159+
enable_pr_comment: true
160+
enable_status_check: true
161+
```
162+
163+
### With Diff Mode (Recommended for PRs)
164+
165+
Diff mode shows only newly introduced issues, making PR reviews more focused:
166+
167+
```yaml
168+
name: FOSSA PR Check with Diff Mode
169+
170+
on:
171+
pull_request:
172+
branches: [main, master]
173+
174+
permissions:
175+
pull-requests: write # For PR comments
176+
checks: write # For status checks
177+
issues: write # For PR comments
178+
179+
jobs:
180+
fossa-check:
181+
runs-on: ubuntu-latest
182+
steps:
183+
- uses: actions/checkout@v4
184+
185+
- name: FOSSA Guard - Licensing (Diff Mode)
186+
uses: SolaceDev/solace-public-workflows/.github/actions/fossa-guard@main
187+
with:
188+
fossa_api_key: ${{ secrets.FOSSA_API_KEY }}
189+
fossa_project_id: ${{ secrets.FOSSA_PROJECT_ID }}
190+
fossa_category: licensing
191+
fossa_mode: BLOCK
192+
fossa_branch: PR
193+
fossa_revision: ${{ github.event.pull_request.head.ref }}
194+
block_on: policy_conflict
195+
# Diff mode - auto-detects base branch
196+
enable_diff_mode: true
197+
# PR Integration
198+
github_token: ${{ github.token }}
199+
enable_pr_comment: true
200+
enable_status_check: true
201+
202+
- name: FOSSA Guard - Vulnerabilities (Diff Mode)
203+
uses: SolaceDev/solace-public-workflows/.github/actions/fossa-guard@main
204+
with:
205+
fossa_api_key: ${{ secrets.FOSSA_API_KEY }}
206+
fossa_project_id: ${{ secrets.FOSSA_PROJECT_ID }}
207+
fossa_category: vulnerability
208+
fossa_mode: BLOCK
209+
fossa_branch: PR
210+
fossa_revision: ${{ github.event.pull_request.head.ref }}
211+
block_on: critical,high
212+
# Diff mode
213+
enable_diff_mode: true
214+
# PR Integration
215+
github_token: ${{ github.token }}
216+
enable_pr_comment: true
217+
enable_status_check: true
218+
```
219+
220+
### REPORT Mode Example (Non-Blocking)
221+
222+
Use REPORT mode for gradual rollout - violations are shown but don't fail the build:
223+
224+
```yaml
225+
- name: FOSSA Guard (Report Mode - Non-Blocking)
226+
uses: SolaceDev/solace-public-workflows/.github/actions/fossa-guard@main
227+
with:
228+
fossa_api_key: ${{ secrets.FOSSA_API_KEY }}
229+
fossa_project_id: ${{ secrets.FOSSA_PROJECT_ID }}
230+
fossa_category: licensing
231+
fossa_mode: REPORT # Show violations but don't fail build
232+
block_on: policy_conflict,policy_flag
233+
enable_diff_mode: true
234+
github_token: ${{ github.token }}
235+
enable_pr_comment: true
236+
enable_status_check: true # Status shows failure but build passes
237+
```
238+
239+
### Branch Protection Setup
240+
241+
To enforce FOSSA checks before merging:
242+
243+
1. Repository Settings → Branches → Add protection rule
244+
2. Enable "Require status checks to pass before merging"
245+
3. Add required checks:
246+
- `FOSSA Guard (licensing)`
247+
- `FOSSA Guard (vulnerability)` (if applicable)
248+
249+
---
250+
251+
## Diff Mode
252+
253+
Diff mode compares the PR branch against the base branch to show only newly introduced issues, making PR reviews more focused.
254+
255+
### How It Works
256+
257+
- Compares current scan results against base branch scan results
258+
- Shows "X new, Y total (Z in base)" in PR comments for clarity
259+
- Auto-detects default branch (main/master) if `diff_base_revision_sha` not provided
260+
- Uses three-tier matching strategy for accurate comparison
261+
262+
### Requirements
263+
264+
- Base branch must have been scanned by FOSSA for comparison to work
265+
- Best used with PR workflows to focus on newly introduced issues
266+
267+
### Usage
268+
269+
```yaml
270+
with:
271+
enable_diff_mode: true
272+
# Optional - will auto-detect if not provided
273+
diff_base_revision_sha: ${{ github.event.pull_request.base.sha }}
274+
```
275+
276+
---
277+
278+
## PR Comment Features
279+
280+
- **Smart deduplication**: One comment per category (licensing/vulnerability) - updates existing, doesn't duplicate
281+
- **Top N violations**: Shows top N violations (default: 5, configurable via `pr_comment_max_violations`)
282+
- **Clear explanations**: Shows what's blocking vs what needs review
283+
- **Direct links**: Links to full scan report and FOSSA dashboard
284+
- **Blocking status**: For vulnerabilities, shows actual blocking status (e.g., "✅ No blocking issues found (configured to block on: HIGH)")
285+
- **Diff mode support**: Shows "X new, Y total (Z in base)" when diff mode is enabled
286+
287+
---
288+
289+
## Status Check Behavior
290+
291+
- Status checks show **failure** when violations exist matching `block_on` rules (regardless of mode)
292+
- Status checks show **success** when no violations found or all issues are non-blocking
293+
- Can be used with branch protection rules to enforce compliance
294+
- Works in both BLOCK and REPORT modes (only exit code differs)
295+
296+
---
297+
104298
## Notes
105299
- The action prints a Markdown summary to the GitHub Actions log.
106300
- If the `GITHUB_STEP_SUMMARY` environment variable is set, the summary is also written to the step summary for rich UI display.
@@ -109,3 +303,49 @@ jobs:
109303
- Slack integration parameters (`slack_token`, `slack_channel`, `slack_thread_ts`) allow posting formatted reports to Slack channels or threads.
110304
- GitHub context parameters (`github_repository`, `github_run_id`, `github_server_url`) allow linking reports to specific repositories and builds.
111305
- For more details, see the script source and comments.
306+
307+
---
308+
309+
## Troubleshooting
310+
311+
### PR Comment Not Appearing
312+
313+
**Check:**
314+
- `github_token` input is set (defaults to `${{ github.token }}`)
315+
- Workflow has `pull-requests: write` and `issues: write` permissions
316+
- Running in `pull_request` event (not `push`)
317+
- `enable_pr_comment` is not set to `false`
318+
319+
### Status Check Not Appearing
320+
321+
**Check:**
322+
- Workflow has `checks: write` permission
323+
- Using PR head SHA: `fossa_revision: ${{ github.event.pull_request.head.ref || github.sha }}`
324+
- `enable_status_check` is not set to `false`
325+
326+
### Diff Mode Not Working
327+
328+
**Check:**
329+
- The PR branch revision has been scanned by FOSSA (ensure FOSSA scan runs before FOSSA Guard)
330+
- The base branch revision exists in FOSSA scan history
331+
- `enable_diff_mode` is set to `true`
332+
- FOSSA project exists and has scan data for both revisions
333+
334+
### Token Permission Errors
335+
336+
Add to workflow:
337+
```yaml
338+
permissions:
339+
pull-requests: write
340+
checks: write
341+
issues: write
342+
```
343+
344+
---
345+
346+
347+
## Reference Links
348+
349+
- **Implementation PR**: https://github.com/SolaceDev/maas-build-actions/pull/581
350+
- **Live Example**: https://github.com/SolaceDev/solace-agent-mesh-enterprise/pull/458
351+
- **Full Documentation**: See maas-build-actions repository `scripts/fossa-guard/fossa-guard-usage.md`

.github/actions/fossa-guard/action.yaml

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,41 @@ inputs:
4949
github_server_url:
5050
description: "GitHub server URL (default: https://github.com) (optional)"
5151
required: false
52+
github_token:
53+
description: "GitHub token for PR comments and status checks"
54+
required: false
55+
default: ${{ github.token }}
56+
enable_pr_comment:
57+
description: "Enable PR commenting (true/false)"
58+
required: false
59+
default: "false"
60+
enable_status_check:
61+
description: "Enable GitHub status checks (true/false)"
62+
required: false
63+
default: "false"
64+
status_check_name:
65+
description: "Custom name for GitHub status check"
66+
required: false
67+
default: "FOSSA Guard"
68+
pr_comment_max_violations:
69+
description: "Maximum violations to show in PR comment"
70+
required: false
71+
default: "5"
72+
enable_diff_mode:
73+
description: "Enable diff mode to show only new issues (true/false)"
74+
required: false
75+
default: "false"
76+
diff_base_revision_sha:
77+
description: "Base revision SHA to compare against (optional - auto-detects default branch)"
78+
required: false
79+
enable_license_enrichment:
80+
description: "Show declared/discovered license indicators (true/false)"
81+
required: false
82+
default: "true"
5283

5384
runs:
5485
using: docker
55-
image: docker://ghcr.io/solacedev/maas-build-actions:master
86+
image: docker://ghcr.io/solacedev/maas-build-actions:latest
5687
entrypoint: /bin/sh
5788
args:
5889
- -c
@@ -73,6 +104,14 @@ runs:
73104
if [ -n "$INPUT_GITHUB_REPOSITORY" ]; then export GITHUB_REPOSITORY="$INPUT_GITHUB_REPOSITORY"; fi
74105
if [ -n "$INPUT_GITHUB_RUN_ID" ]; then export GITHUB_RUN_ID="$INPUT_GITHUB_RUN_ID"; fi
75106
if [ -n "$INPUT_GITHUB_SERVER_URL" ]; then export GITHUB_SERVER_URL="$INPUT_GITHUB_SERVER_URL"; fi
107+
if [ -n "$INPUT_GITHUB_TOKEN" ]; then export GITHUB_TOKEN="$INPUT_GITHUB_TOKEN"; fi
108+
if [ -n "$INPUT_ENABLE_PR_COMMENT" ]; then export ENABLE_PR_COMMENT="$INPUT_ENABLE_PR_COMMENT"; fi
109+
if [ -n "$INPUT_ENABLE_STATUS_CHECK" ]; then export ENABLE_STATUS_CHECK="$INPUT_ENABLE_STATUS_CHECK"; fi
110+
if [ -n "$INPUT_STATUS_CHECK_NAME" ]; then export STATUS_CHECK_NAME="$INPUT_STATUS_CHECK_NAME"; fi
111+
if [ -n "$INPUT_PR_COMMENT_MAX_VIOLATIONS" ]; then export PR_COMMENT_MAX_VIOLATIONS="$INPUT_PR_COMMENT_MAX_VIOLATIONS"; fi
112+
if [ -n "$INPUT_ENABLE_DIFF_MODE" ]; then export ENABLE_DIFF_MODE="$INPUT_ENABLE_DIFF_MODE"; fi
113+
if [ -n "$INPUT_DIFF_BASE_REVISION_SHA" ]; then export DIFF_BASE_REVISION_SHA="$INPUT_DIFF_BASE_REVISION_SHA"; fi
114+
if [ -n "$INPUT_ENABLE_LICENSE_ENRICHMENT" ]; then export ENABLE_LICENSE_ENRICHMENT="$INPUT_ENABLE_LICENSE_ENRICHMENT"; fi
76115
echo "Debug: Inputs:"
77116
echo "FOSSA_API_KEY: [REDACTED]"
78117
echo "FOSSA_PROJECT_ID: $FOSSA_PROJECT_ID"
@@ -90,5 +129,18 @@ runs:
90129
echo "GITHUB_REPOSITORY: $GITHUB_REPOSITORY"
91130
echo "GITHUB_RUN_ID: $GITHUB_RUN_ID"
92131
echo "GITHUB_SERVER_URL: $GITHUB_SERVER_URL"
132+
echo "GITHUB_TOKEN: [REDACTED]"
133+
echo "ENABLE_PR_COMMENT: $ENABLE_PR_COMMENT"
134+
echo "ENABLE_STATUS_CHECK: $ENABLE_STATUS_CHECK"
135+
echo "STATUS_CHECK_NAME: $STATUS_CHECK_NAME"
136+
echo "PR_COMMENT_MAX_VIOLATIONS: $PR_COMMENT_MAX_VIOLATIONS"
137+
echo "ENABLE_DIFF_MODE: $ENABLE_DIFF_MODE"
138+
echo "DIFF_BASE_REVISION_SHA: $DIFF_BASE_REVISION_SHA"
139+
echo "ENABLE_LICENSE_ENRICHMENT: $ENABLE_LICENSE_ENRICHMENT"
140+
echo "GITHUB_EVENT_NAME: $GITHUB_EVENT_NAME"
141+
echo "GITHUB_REF: $GITHUB_REF"
142+
echo "GITHUB_SHA: $GITHUB_SHA"
143+
echo "GITHUB_HEAD_REF: $GITHUB_HEAD_REF"
144+
echo "GITHUB_BASE_REF: $GITHUB_BASE_REF"
93145
source /maas-build-actions/venv/bin/activate
94146
python3 /maas-build-actions/scripts/fossa-guard/fossa_guard.py

0 commit comments

Comments
 (0)