mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-04 16:39:35 +08:00
227 lines
7.5 KiB
YAML
227 lines
7.5 KiB
YAML
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
name: Workflow Security Reports
|
|
|
|
on:
|
|
pull_request:
|
|
merge_group:
|
|
types: [checks_requested]
|
|
push:
|
|
branches: [main]
|
|
schedule:
|
|
- cron: "17 6 * * 1"
|
|
workflow_dispatch:
|
|
workflow_call:
|
|
inputs:
|
|
candidate_ref:
|
|
description: Optional pre-release tag to scan instead of the triggering revision
|
|
default: ""
|
|
type: string
|
|
fail-on-findings:
|
|
description: Fail on Zizmor HIGH findings; Actionlint remains informational
|
|
default: false
|
|
type: boolean
|
|
secrets:
|
|
CACHIX_AUTH_TOKEN:
|
|
required: false
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
defaults:
|
|
run:
|
|
shell: nix develop --command bash -euo pipefail {0}
|
|
|
|
concurrency:
|
|
group: workflow-security-${{ github.workflow }}-${{ inputs.candidate_ref || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
actionlint:
|
|
name: Actionlint (informational)
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
security-events: write
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
id: checkout
|
|
with:
|
|
ref: ${{ inputs.candidate_ref && format('refs/tags/{0}', inputs.candidate_ref) || '' }}
|
|
persist-credentials: false
|
|
|
|
- name: Set up Nix
|
|
uses: ./.github/actions/setup-nix
|
|
with:
|
|
cachix-auth-token: ${{ github.event_name != 'pull_request' && secrets.CACHIX_AUTH_TOKEN || '' }}
|
|
|
|
- name: Run Actionlint
|
|
run: |
|
|
set -uo pipefail
|
|
mkdir -p reports
|
|
echo "::add-matcher::.github/actionlint-matcher.json"
|
|
|
|
set +e
|
|
actionlint -shellcheck= -pyflakes= 2>&1 | tee reports/actionlint.txt
|
|
status=${PIPESTATUS[0]}
|
|
|
|
echo "::remove-matcher owner=actionlint::"
|
|
actionlint \
|
|
-shellcheck= \
|
|
-pyflakes= \
|
|
-format "$(cat .github/actionlint-sarif-template.txt)" \
|
|
> reports/actionlint.sarif
|
|
sarif_status=$?
|
|
set -e
|
|
|
|
if [ "$status" -le 1 ] && [ "$sarif_status" -ne "$status" ]; then
|
|
echo "::error::Actionlint could not produce SARIF (exit $sarif_status)."
|
|
exit "$sarif_status"
|
|
fi
|
|
|
|
{
|
|
echo "### Actionlint"
|
|
echo
|
|
} >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
case "$status" in
|
|
0)
|
|
echo "No findings." >> "$GITHUB_STEP_SUMMARY"
|
|
;;
|
|
1)
|
|
echo "::warning::Actionlint reported findings; this check is informational."
|
|
echo "Findings were reported as annotations and do not fail CI." >> "$GITHUB_STEP_SUMMARY"
|
|
;;
|
|
2|3)
|
|
echo "::error::Actionlint could not complete (exit $status)."
|
|
echo "Actionlint failed to run correctly (exit $status)." >> "$GITHUB_STEP_SUMMARY"
|
|
exit "$status"
|
|
;;
|
|
*)
|
|
echo "::error::Actionlint returned unexpected exit code $status."
|
|
echo "Actionlint returned unexpected exit code $status." >> "$GITHUB_STEP_SUMMARY"
|
|
exit "$status"
|
|
;;
|
|
esac
|
|
|
|
- name: Upload Actionlint SARIF to Code Scanning
|
|
if: success()
|
|
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
|
|
with:
|
|
sarif_file: reports/actionlint.sarif
|
|
ref: ${{ inputs.candidate_ref && format('refs/tags/{0}', inputs.candidate_ref) || '' }}
|
|
sha: ${{ inputs.candidate_ref && steps.checkout.outputs.commit || '' }}
|
|
category: actionlint
|
|
|
|
- name: Upload Actionlint report
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: actionlint-${{ github.run_id }}
|
|
path: |
|
|
reports/actionlint.txt
|
|
reports/actionlint.sarif
|
|
if-no-files-found: ignore
|
|
retention-days: 14
|
|
|
|
zizmor:
|
|
name: ${{ inputs.fail-on-findings && 'Zizmor High report' || 'Zizmor High report (informational)' }}
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
security-events: write
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
id: checkout
|
|
with:
|
|
ref: ${{ inputs.candidate_ref && format('refs/tags/{0}', inputs.candidate_ref) || '' }}
|
|
persist-credentials: false
|
|
|
|
- name: Set up Nix
|
|
uses: ./.github/actions/setup-nix
|
|
with:
|
|
cachix-auth-token: ${{ github.event_name != 'pull_request' && secrets.CACHIX_AUTH_TOKEN || '' }}
|
|
|
|
- name: Run Zizmor
|
|
id: findings
|
|
env:
|
|
FAIL_ON_FINDINGS: ${{ inputs.fail-on-findings || false }}
|
|
run: |
|
|
set -euo pipefail
|
|
mkdir -p reports
|
|
|
|
zizmor \
|
|
--offline \
|
|
--persona=regular \
|
|
--min-severity=high \
|
|
--no-exit-codes \
|
|
--format=json \
|
|
. > reports/zizmor-high.json
|
|
|
|
zizmor \
|
|
--offline \
|
|
--persona=regular \
|
|
--min-severity=high \
|
|
--no-exit-codes \
|
|
--format=sarif \
|
|
. > reports/zizmor-high.sarif
|
|
|
|
finding_count=$(jq '
|
|
[.[] | select(.ignored != true and .determinations.severity == "High")] | length
|
|
' reports/zizmor-high.json)
|
|
echo "high_count=$finding_count" >> "$GITHUB_OUTPUT"
|
|
{
|
|
echo "### Zizmor high-severity report"
|
|
echo
|
|
echo "Zizmor has no critical severity; high is its maximum level."
|
|
echo
|
|
echo "Findings: $finding_count"
|
|
if [ "$finding_count" -gt 0 ]; then
|
|
echo
|
|
jq -r \
|
|
'group_by(.ident) | .[] | "- `\(.[0].ident)`: \(length)"' \
|
|
reports/zizmor-high.json
|
|
echo
|
|
echo "Fail on HIGH findings: $FAIL_ON_FINDINGS"
|
|
fi
|
|
} >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
if [ "$finding_count" -gt 0 ]; then
|
|
echo "::warning::Zizmor reported $finding_count high-severity findings."
|
|
fi
|
|
|
|
- name: Upload Zizmor SARIF to Code Scanning
|
|
if: success()
|
|
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
|
|
with:
|
|
sarif_file: reports/zizmor-high.sarif
|
|
ref: ${{ inputs.candidate_ref && format('refs/tags/{0}', inputs.candidate_ref) || '' }}
|
|
sha: ${{ inputs.candidate_ref && steps.checkout.outputs.commit || '' }}
|
|
category: zizmor-high
|
|
|
|
- name: Upload Zizmor reports
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: zizmor-high-${{ github.run_id }}
|
|
path: |
|
|
reports/zizmor-high.json
|
|
reports/zizmor-high.sarif
|
|
if-no-files-found: ignore
|
|
retention-days: 14
|
|
|
|
- name: Enforce HIGH/CRITICAL threshold
|
|
if: ${{ !cancelled() && steps.findings.outcome == 'success' }}
|
|
env:
|
|
HIGH_COUNT: ${{ steps.findings.outputs.high_count }}
|
|
FAIL_ON_FINDINGS: ${{ inputs.fail-on-findings || false }}
|
|
run: |
|
|
if [ "$HIGH_COUNT" -gt 0 ]; then
|
|
if [ "$FAIL_ON_FINDINGS" = "true" ]; then
|
|
echo "::error::Zizmor reported $HIGH_COUNT HIGH findings."
|
|
exit 1
|
|
fi
|
|
echo "::warning::Zizmor reported $HIGH_COUNT HIGH findings; enforcement is disabled."
|
|
fi
|