Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 242 additions & 2 deletions .github/actions/fossa-guard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ The `fossa-guard` GitHub Action integrates with the FOSSA API to fetch and proce
| `github_run_id` | No | GitHub Actions run ID for build links (optional). |
| `github_server_url` | No | GitHub server URL (default: https://github.com) (optional). |

### PR Integration Inputs (Optional)

| Input | Default | Description |
|-------|---------|-------------|
| `github_token` | `${{ github.token }}` | GitHub token for PR comments and status checks |
| `enable_pr_comment` | `false` | Enable PR commenting (`true`/`false`) |
| `enable_status_check` | `false` | Enable GitHub status checks (`true`/`false`) |
| `status_check_name` | `FOSSA Guard` | Custom name for status checks |
| `pr_comment_max_violations` | `5` | Max violations shown in PR comment |
| `enable_diff_mode` | `false` | Enable diff mode to show only new issues (`true`/`false`) |
| `diff_base_revision_sha` | (auto-detect) | Base revision SHA to compare against (optional - auto-detects default branch) |
| `enable_license_enrichment` | `true` | Show declared/discovered license indicators (`true`/`false`) |

### Issue Types Explained
- **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.
- **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.
Expand All @@ -52,10 +65,18 @@ The `fossa-guard` GitHub Action integrates with the FOSSA API to fetch and proce

| Mode | Description |
|--------|-----------------------------------------------------------------------------------------------|
| BLOCK | Fails the build if violations matching `block_on` are found. Prints a Markdown/HTML summary. |
| 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. |
| 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. |
| 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. |
| 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. |

### Mode Behavior Clarification

**Important**: PR comments and status checks work identically in both BLOCK and REPORT modes. The only difference is:
- **REPORT mode**: Shows violations in status check (failure), but build passes (exit 0)
- **BLOCK mode**: Shows violations in status check (failure), and build fails (exit 2)

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.

---

## Business Logic
Expand Down Expand Up @@ -101,6 +122,179 @@ jobs:

---

## Pull Request Workflow Examples

### Basic PR Integration

```yaml
name: FOSSA PR Check

on:
pull_request:
branches: [main]

permissions:
pull-requests: write # For PR comments
checks: write # For status checks
issues: write # For PR comments

jobs:
fossa-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: FOSSA Guard with PR Integration
uses: SolaceDev/solace-public-workflows/.github/actions/fossa-guard@main
with:
fossa_api_key: ${{ secrets.FOSSA_API_KEY }}
fossa_project_id: ${{ secrets.FOSSA_PROJECT_ID }}
fossa_category: licensing
fossa_mode: BLOCK
fossa_branch: ${{ github.event.pull_request.number && 'PR' || github.event.repository.default_branch }}
fossa_revision: ${{ github.event.pull_request.head.ref || github.sha }}
block_on: policy_conflict,policy_flag
# PR features (auto-enabled)
github_token: ${{ github.token }}
enable_pr_comment: true
enable_status_check: true
```

### With Diff Mode (Recommended for PRs)

Diff mode shows only newly introduced issues, making PR reviews more focused:

```yaml
name: FOSSA PR Check with Diff Mode

on:
pull_request:
branches: [main, master]

permissions:
pull-requests: write # For PR comments
checks: write # For status checks
issues: write # For PR comments

jobs:
fossa-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: FOSSA Guard - Licensing (Diff Mode)
uses: SolaceDev/solace-public-workflows/.github/actions/fossa-guard@main
with:
fossa_api_key: ${{ secrets.FOSSA_API_KEY }}
fossa_project_id: ${{ secrets.FOSSA_PROJECT_ID }}
fossa_category: licensing
fossa_mode: BLOCK
fossa_branch: PR
fossa_revision: ${{ github.event.pull_request.head.ref }}
block_on: policy_conflict
# Diff mode - auto-detects base branch
enable_diff_mode: true
# PR Integration
github_token: ${{ github.token }}
enable_pr_comment: true
enable_status_check: true

- name: FOSSA Guard - Vulnerabilities (Diff Mode)
uses: SolaceDev/solace-public-workflows/.github/actions/fossa-guard@main
with:
fossa_api_key: ${{ secrets.FOSSA_API_KEY }}
fossa_project_id: ${{ secrets.FOSSA_PROJECT_ID }}
fossa_category: vulnerability
fossa_mode: BLOCK
fossa_branch: PR
fossa_revision: ${{ github.event.pull_request.head.ref }}
block_on: critical,high
# Diff mode
enable_diff_mode: true
# PR Integration
github_token: ${{ github.token }}
enable_pr_comment: true
enable_status_check: true
```

### REPORT Mode Example (Non-Blocking)

Use REPORT mode for gradual rollout - violations are shown but don't fail the build:

```yaml
- name: FOSSA Guard (Report Mode - Non-Blocking)
uses: SolaceDev/solace-public-workflows/.github/actions/fossa-guard@main
with:
fossa_api_key: ${{ secrets.FOSSA_API_KEY }}
fossa_project_id: ${{ secrets.FOSSA_PROJECT_ID }}
fossa_category: licensing
fossa_mode: REPORT # Show violations but don't fail build
block_on: policy_conflict,policy_flag
enable_diff_mode: true
github_token: ${{ github.token }}
enable_pr_comment: true
enable_status_check: true # Status shows failure but build passes
```

### Branch Protection Setup

To enforce FOSSA checks before merging:

1. Repository Settings → Branches → Add protection rule
2. Enable "Require status checks to pass before merging"
3. Add required checks:
- `FOSSA Guard (licensing)`
- `FOSSA Guard (vulnerability)` (if applicable)

---

## Diff Mode

Diff mode compares the PR branch against the base branch to show only newly introduced issues, making PR reviews more focused.

### How It Works

- Compares current scan results against base branch scan results
- Shows "X new, Y total (Z in base)" in PR comments for clarity
- Auto-detects default branch (main/master) if `diff_base_revision_sha` not provided
- Uses three-tier matching strategy for accurate comparison

### Requirements

- Base branch must have been scanned by FOSSA for comparison to work
- Best used with PR workflows to focus on newly introduced issues

### Usage

```yaml
with:
enable_diff_mode: true
# Optional - will auto-detect if not provided
diff_base_revision_sha: ${{ github.event.pull_request.base.sha }}
```

---

## PR Comment Features

- **Smart deduplication**: One comment per category (licensing/vulnerability) - updates existing, doesn't duplicate
- **Top N violations**: Shows top N violations (default: 5, configurable via `pr_comment_max_violations`)
- **Clear explanations**: Shows what's blocking vs what needs review
- **Direct links**: Links to full scan report and FOSSA dashboard
- **Blocking status**: For vulnerabilities, shows actual blocking status (e.g., "✅ No blocking issues found (configured to block on: HIGH)")
- **Diff mode support**: Shows "X new, Y total (Z in base)" when diff mode is enabled

---

## Status Check Behavior

- Status checks show **failure** when violations exist matching `block_on` rules (regardless of mode)
- Status checks show **success** when no violations found or all issues are non-blocking
- Can be used with branch protection rules to enforce compliance
- Works in both BLOCK and REPORT modes (only exit code differs)

---

## Notes
- The action prints a Markdown summary to the GitHub Actions log.
- If the `GITHUB_STEP_SUMMARY` environment variable is set, the summary is also written to the step summary for rich UI display.
Expand All @@ -109,3 +303,49 @@ jobs:
- Slack integration parameters (`slack_token`, `slack_channel`, `slack_thread_ts`) allow posting formatted reports to Slack channels or threads.
- GitHub context parameters (`github_repository`, `github_run_id`, `github_server_url`) allow linking reports to specific repositories and builds.
- For more details, see the script source and comments.

---

## Troubleshooting

### PR Comment Not Appearing

**Check:**
- `github_token` input is set (defaults to `${{ github.token }}`)
- Workflow has `pull-requests: write` and `issues: write` permissions
- Running in `pull_request` event (not `push`)
- `enable_pr_comment` is not set to `false`

### Status Check Not Appearing

**Check:**
- Workflow has `checks: write` permission
- Using PR head SHA: `fossa_revision: ${{ github.event.pull_request.head.ref || github.sha }}`
- `enable_status_check` is not set to `false`

### Diff Mode Not Working

**Check:**
- The PR branch revision has been scanned by FOSSA (ensure FOSSA scan runs before FOSSA Guard)
- The base branch revision exists in FOSSA scan history
- `enable_diff_mode` is set to `true`
- FOSSA project exists and has scan data for both revisions

### Token Permission Errors

Add to workflow:
```yaml
permissions:
pull-requests: write
checks: write
issues: write
```

---


## Reference Links

- **Implementation PR**: https://github.com/SolaceDev/maas-build-actions/pull/581
- **Live Example**: https://github.com/SolaceDev/solace-agent-mesh-enterprise/pull/458
- **Full Documentation**: See maas-build-actions repository `scripts/fossa-guard/fossa-guard-usage.md`
54 changes: 53 additions & 1 deletion .github/actions/fossa-guard/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,41 @@ inputs:
github_server_url:
description: "GitHub server URL (default: https://github.com) (optional)"
required: false
github_token:
description: "GitHub token for PR comments and status checks"
required: false
default: ${{ github.token }}
enable_pr_comment:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is off by default.

description: "Enable PR commenting (true/false)"
required: false
default: "false"
enable_status_check:
description: "Enable GitHub status checks (true/false)"
required: false
default: "false"
status_check_name:
description: "Custom name for GitHub status check"
required: false
default: "FOSSA Guard"
pr_comment_max_violations:
description: "Maximum violations to show in PR comment"
required: false
default: "5"
enable_diff_mode:
description: "Enable diff mode to show only new issues (true/false)"
required: false
default: "false"
diff_base_revision_sha:
description: "Base revision SHA to compare against (optional - auto-detects default branch)"
required: false
enable_license_enrichment:
description: "Show declared/discovered license indicators (true/false)"
required: false
default: "true"

runs:
using: docker
image: docker://ghcr.io/solacedev/maas-build-actions:master
image: docker://ghcr.io/solacedev/maas-build-actions:latest
entrypoint: /bin/sh
args:
- -c
Expand All @@ -73,6 +104,14 @@ runs:
if [ -n "$INPUT_GITHUB_REPOSITORY" ]; then export GITHUB_REPOSITORY="$INPUT_GITHUB_REPOSITORY"; fi
if [ -n "$INPUT_GITHUB_RUN_ID" ]; then export GITHUB_RUN_ID="$INPUT_GITHUB_RUN_ID"; fi
if [ -n "$INPUT_GITHUB_SERVER_URL" ]; then export GITHUB_SERVER_URL="$INPUT_GITHUB_SERVER_URL"; fi
if [ -n "$INPUT_GITHUB_TOKEN" ]; then export GITHUB_TOKEN="$INPUT_GITHUB_TOKEN"; fi
if [ -n "$INPUT_ENABLE_PR_COMMENT" ]; then export ENABLE_PR_COMMENT="$INPUT_ENABLE_PR_COMMENT"; fi
if [ -n "$INPUT_ENABLE_STATUS_CHECK" ]; then export ENABLE_STATUS_CHECK="$INPUT_ENABLE_STATUS_CHECK"; fi
if [ -n "$INPUT_STATUS_CHECK_NAME" ]; then export STATUS_CHECK_NAME="$INPUT_STATUS_CHECK_NAME"; fi
if [ -n "$INPUT_PR_COMMENT_MAX_VIOLATIONS" ]; then export PR_COMMENT_MAX_VIOLATIONS="$INPUT_PR_COMMENT_MAX_VIOLATIONS"; fi
if [ -n "$INPUT_ENABLE_DIFF_MODE" ]; then export ENABLE_DIFF_MODE="$INPUT_ENABLE_DIFF_MODE"; fi
if [ -n "$INPUT_DIFF_BASE_REVISION_SHA" ]; then export DIFF_BASE_REVISION_SHA="$INPUT_DIFF_BASE_REVISION_SHA"; fi
if [ -n "$INPUT_ENABLE_LICENSE_ENRICHMENT" ]; then export ENABLE_LICENSE_ENRICHMENT="$INPUT_ENABLE_LICENSE_ENRICHMENT"; fi
echo "Debug: Inputs:"
echo "FOSSA_API_KEY: [REDACTED]"
echo "FOSSA_PROJECT_ID: $FOSSA_PROJECT_ID"
Expand All @@ -90,5 +129,18 @@ runs:
echo "GITHUB_REPOSITORY: $GITHUB_REPOSITORY"
echo "GITHUB_RUN_ID: $GITHUB_RUN_ID"
echo "GITHUB_SERVER_URL: $GITHUB_SERVER_URL"
echo "GITHUB_TOKEN: [REDACTED]"
echo "ENABLE_PR_COMMENT: $ENABLE_PR_COMMENT"
echo "ENABLE_STATUS_CHECK: $ENABLE_STATUS_CHECK"
echo "STATUS_CHECK_NAME: $STATUS_CHECK_NAME"
echo "PR_COMMENT_MAX_VIOLATIONS: $PR_COMMENT_MAX_VIOLATIONS"
echo "ENABLE_DIFF_MODE: $ENABLE_DIFF_MODE"
echo "DIFF_BASE_REVISION_SHA: $DIFF_BASE_REVISION_SHA"
echo "ENABLE_LICENSE_ENRICHMENT: $ENABLE_LICENSE_ENRICHMENT"
echo "GITHUB_EVENT_NAME: $GITHUB_EVENT_NAME"
echo "GITHUB_REF: $GITHUB_REF"
echo "GITHUB_SHA: $GITHUB_SHA"
echo "GITHUB_HEAD_REF: $GITHUB_HEAD_REF"
echo "GITHUB_BASE_REF: $GITHUB_BASE_REF"
source /maas-build-actions/venv/bin/activate
python3 /maas-build-actions/scripts/fossa-guard/fossa_guard.py