Skip to content
Open
64 changes: 64 additions & 0 deletions .github/actions/create-github-issue/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: "Create Vulnerability Issue"
description: "Creates a GitHub issue if CRITICAL/HIGH vulnerabilities are found in the scan report"

inputs:
report_path:
description: "Path to the vulnerability report file"
required: true
package_name:
description: "Name of the package being released"
required: true
package_version:
description: "Version of the package being released"
required: true
release_branch:
description: "Release branch name"
required: true
labels:
description: "Labels to apply to the created issue"
required: false
default: "security"
vuln_art_url:
description: "URL to the vulnerability report artifact"
required: false

runs:
using: "composite"
steps:
- name: Check vulnerabilities in report
id: check_vulns
shell: bash
run: |
set -euo pipefail
REPORT="${{ inputs.report_path }}"

if grep -qE "CRITICAL|HIGH" "$REPORT"; then
echo "found=true" >> "$GITHUB_OUTPUT"
else
echo "found=false" >> "$GITHUB_OUTPUT"
fi

- name: Create GitHub Issue
if: steps.check_vulns.outputs.found == 'true'
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
TITLE="🔒 Security vulnerabilities in ${{ inputs.package_name }}@${{ inputs.package_version }}"
BODY=$(cat <<EOF
The vulnerability scan for \`${{ inputs.package_name }}@${{ inputs.package_version }}\` on branch \`${{ inputs.release_branch }}\` has detected **CRITICAL/HIGH** vulnerabilities.

**Release Branch:** \`${{ inputs.release_branch }}\`
**Package Version:** \`${{ inputs.package_version }}\`

Please review the attached vulnerability report and take necessary action. URL of the vulnerability report ${{ inputs.vuln_art_url }}.

---
_This issue was automatically generated by the Release Pipeline._
EOF
)

gh issue create \
--title "$TITLE" \
--body "$BODY" \
--label "${{ inputs.labels }}"
19 changes: 19 additions & 0 deletions .github/actions/create-vuln-issue.b/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Create Vulnerability Issue (local composite action)

Creates a GitHub Issue **iff** the given vulnerability report file is **non-empty**.

## Inputs
- `report_path` (required): Path to the vulnerability report, e.g. `vuln-report.txt`.
- `package_name` (required)
- `package_version` (required)
- `release_branch` (required)
- `title_prefix` (optional, default: "Security vulnerabilities detected")
- `labels` (optional, comma-separated, default: "security,automated")
- `artifact_name` (optional): If provided, the action will link to the matching run artifact.

## Permissions
Job must grant:
```yaml
permissions:
contents: read
issues: write
105 changes: 105 additions & 0 deletions .github/actions/create-vuln-issue.b/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: "Create Vulnerability Issue (Inline)"
description: "Creates a GitHub issue only if vuln-report.txt contains CRITICAL/HIGH findings, inlining the report."
branding:
icon: alert-triangle
color: red

inputs:
report_path:
description: "Path to vulnerability report (e.g., vuln-report.txt)"
required: true
package_name:
description: "Package name for context"
required: false
default: ""
package_version:
description: "Package version for context"
required: false
default: ""
release_branch:
description: "Release branch for context"
required: false
default: ""
title_prefix:
description: "Issue title prefix"
required: false
default: "Security vulnerabilities detected"
labels:
description: "Comma-separated labels to apply to the issue"
required: false
default: "security,automated,trivy"

runs:
using: "composite"
steps:
- name: Inspect report for CRITICAL/HIGH
id: scan
shell: bash
run: |
set -euo pipefail
FILE="${{ inputs.report_path }}"

if [[ ! -f "$FILE" ]]; then
echo "has_findings=false" >> "$GITHUB_OUTPUT"
echo "❎ Report not found at $FILE. Skipping issue creation."
exit 0
fi

if ! [[ -s "$FILE" ]]; then
echo "has_findings=false" >> "$GITHUB_OUTPUT"
echo "✅ Report exists but is empty. Skipping issue creation."
exit 0
fi

# Look for CRITICAL or HIGH (case-insensitive, whole word)
if grep -Eqi '\b(CRITICAL|HIGH)\b' "$FILE"; then
echo "has_findings=true" >> "$GITHUB_OUTPUT"

# Escape backticks so the code block renders correctly in Markdown
REPORT_ESCAPED=$(sed 's/`/\\`/g' "$FILE")

{
echo "VULN_BODY<<'EOF_VULN'"
echo "$REPORT_ESCAPED"
echo "EOF_VULN"
} >> "$GITHUB_ENV"
else
echo "has_findings=false" >> "$GITHUB_OUTPUT"
echo "✅ No CRITICAL/HIGH findings in $FILE. Skipping issue creation."
fi

- name: Create GitHub issue with inline report
if: steps.scan.outputs.has_findings == 'true'
uses: actions/github-script@v7
with:
github-token: ${{ github.token }}
script: |
const labelsCsv = `${{ inputs.labels }}`.trim();
const labels = labelsCsv ? labelsCsv.split(',').map(s => s.trim()).filter(Boolean) : [];

const pkg = `${{ inputs.package_name }}` || '(unknown package)';
const version = `${{ inputs.package_version }}` || '(unknown version)';
const branch = `${{ inputs.release_branch }}` || '(unknown branch)';
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${process.env.GITHUB_RUN_ID}`;
const report = process.env.VULN_BODY || '(no report content)';

const title = `${{ inputs.title_prefix }} in ${pkg}@${ver}`;
const body =
`Automated scan detected **CRITICAL/HIGH** vulnerabilities.\n\n` +
`**Package:** ${pkg}\n` +
`**Version:** ${version}\n` +
`**Release branch:** ${branch}\n` +
`**Workflow run:** ${runUrl}\n\n` +
`<details><summary>Trivy Report (table)</summary>\n\n` +
'```\n' + report + '\n```\n\n' +
`</details>\n`;

const { data: issue } = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title,
body,
labels
});

core.info(`✅ Issue created: ${issue.html_url}`);
Loading