Skip to content

feat(design): redesign - part 2 (#1136) #2263

feat(design): redesign - part 2 (#1136)

feat(design): redesign - part 2 (#1136) #2263

Workflow file for this run

name: Security
on:
pull_request:
types: [opened, reopened, synchronize, ready_for_review]
branches: ['**']
push:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
semgrep:
name: Semgrep SAST
runs-on: ubuntu-latest
container:
image: semgrep/semgrep@sha256:a3d49dc967b8534a6a76628e50c51cbfe33eb7195dc2feab1fdc0f100852c8ef
permissions:
contents: read
pull-requests: write
security-events: write
if: github.actor != 'dependabot[bot]'
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Run Semgrep (full scan)
if: github.event_name != 'pull_request'
run: |
semgrep scan \
--config p/typescript \
--config p/react \
--config p/nodejs \
--config p/owasp-top-ten \
--config p/security-audit \
--config p/secrets \
--config p/jwt \
--sarif-output semgrep.sarif \
--json-output semgrep.json
- name: Run Semgrep (diff-aware)
if: github.event_name == 'pull_request'
run: |
semgrep scan \
--config p/typescript \
--config p/react \
--config p/nodejs \
--config p/owasp-top-ten \
--config p/security-audit \
--config p/secrets \
--config p/jwt \
--baseline-commit ${{ github.event.pull_request.base.sha }} \
--sarif-output semgrep.sarif \
--json-output semgrep.json
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0
if: always() && hashFiles('semgrep.sarif') != ''
continue-on-error: true
with:
sarif_file: semgrep.sarif
# Post findings as a PR comment using curl + jq (no Node.js needed in Alpine).
# Security: semgrep output is read from files and escaped by jq — never
# interpolated through ${{ }} or shell expansion — preventing injection.
- name: Post Semgrep results as PR comment
if: always() && github.event_name == 'pull_request' && hashFiles('semgrep.json') != ''
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
shell: sh
run: |
apk add --no-cache curl jq > /dev/null 2>&1 || true
MARKER="<!-- semgrep-scan-results -->"
FINDING_COUNT=$(jq '.results | length' semgrep.json)
# Build the comment body in a file (never in a shell variable)
{
echo "$MARKER"
echo "## Semgrep Security Scan"
echo ""
if [ "$FINDING_COUNT" -eq 0 ]; then
echo "No security issues found."
else
echo "**Found $FINDING_COUNT issue(s).**"
echo ""
echo "| # | Severity | Rule | File | Line |"
echo "|---|----------|------|------|------|"
# Use jq to produce pre-escaped table rows from the JSON file.
# jq --raw-output safely handles any characters in the fields.
jq -r '
.results | to_entries[] |
"\(.key + 1) | " +
"`\(.value.extra.severity // "UNKNOWN")` | " +
"`\(.value.check_id | split(".")[-1])` | " +
"`\(.value.path)` | " +
"L\(.value.start.line)"
' semgrep.json | while IFS= read -r row; do
echo "| $row |"
done
echo ""
echo "<details>"
echo "<summary>Finding details</summary>"
echo ""
jq -r '
.results[] |
"### `\(.check_id | split(".")[-1])` — \(.path):\(.start.line)\n" +
"**Severity:** \(.extra.severity // "UNKNOWN") \n" +
"**Message:** \(.extra.message)\n" +
"```\n\(.extra.lines)\n```\n"
' semgrep.json
echo "</details>"
fi
} > comment_body.md
# Use jq to build the JSON payload from the file — jq handles all escaping.
PAYLOAD=$(jq -n --rawfile body comment_body.md '{ body: $body }')
# Find existing comment by marker
COMMENT_ID=$(
curl -sf \
-H "Authorization: Bearer $GH_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/$REPO/issues/$PR_NUMBER/comments?per_page=100" \
| jq ".[] | select(.body | startswith(\"$MARKER\")) | .id" \
| head -1
)
if [ -n "$COMMENT_ID" ]; then
# Update existing comment
curl -sf -X PATCH \
-H "Authorization: Bearer $GH_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/$REPO/issues/comments/$COMMENT_ID" \
-d "$PAYLOAD" > /dev/null
echo "Updated existing comment $COMMENT_ID"
else
# Create new comment
curl -sf -X POST \
-H "Authorization: Bearer $GH_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/$REPO/issues/$PR_NUMBER/comments" \
-d "$PAYLOAD" > /dev/null
echo "Created new comment"
fi