feat(v1.100 Amendment 3): code-A — G1/AmbiguityConflictExternal orphan-CSF split #952
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ============================================================================= | |
| # NFTBan - 2026 OSSRA Threat Remediation | |
| # ============================================================================= | |
| # SPDX-License-Identifier: MPL-2.0 | |
| # | |
| # Purpose: | |
| # Close OSSRA 2026 deltas: | |
| # - P0: License compliance (go-licenses) + SPDX header validation | |
| # - P1: Zombie deps (libyear) | |
| # - P1: AI URL hallucinations (Lychee link validation) | |
| # | |
| # Runs on: | |
| # - Pull requests to main | |
| # - Weekly (Mondays) | |
| # - Manual dispatch | |
| # | |
| # Notes: | |
| # - Actions are SHA-pinned (supply-chain hardening). | |
| # - Jobs are split so failures are attributable + easier to triage. | |
| # ============================================================================= | |
| name: 2026 OSSRA Remediation | |
| on: | |
| workflow_dispatch: {} | |
| pull_request: | |
| branches: ["main"] | |
| schedule: | |
| - cron: "0 6 * * 1" # Mondays 06:00 UTC | |
| permissions: read-all | |
| concurrency: | |
| group: ossra-remediation-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| GO_VERSION: "1.25.x" | |
| jobs: | |
| license-compliance: | |
| name: P0 - License compliance (go-licenses) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Set up Go | |
| uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.6.0 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache: true | |
| - name: License scan (fail on restricted/copyleft) | |
| run: | | |
| set -euo pipefail | |
| # Pin to v2.0.1 for reproducible builds (CodeQL: Pinned-Dependencies) | |
| # Note: go-licenses v2 uses /v2 module path per Go module versioning | |
| # v2.0.1 required for Go 1.25+ compatibility (x/tools@v0.12.0 breaks on 1.25) | |
| go install github.com/google/go-licenses/v2@v2.0.1 | |
| # "restricted" includes copyleft-style licenses (e.g., GPL-family) per go-licenses classification. | |
| go-licenses check ./... --disallowed_types=restricted | |
| spdx-headers: | |
| name: P0 - SPDX header validation (repo policy) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Validate SPDX headers on Go files | |
| run: | | |
| set -euo pipefail | |
| # Adjust if your repo uses a different SPDX id. | |
| REQUIRED="SPDX-License-Identifier: MPL-2.0" | |
| # Exclusions: | |
| # - vendor/, third_party/, dist/, bin/ - external/build artifacts | |
| # - _templ.go - auto-generated by templ tool (regenerated on build) | |
| EXCLUDES='(^vendor/|^third_party/|^dist/|^bin/|^\.git/|^\.github/|_templ\.go$)' | |
| failures=0 | |
| while IFS= read -r -d '' f; do | |
| rel="${f#./}" | |
| if echo "$rel" | grep -Eq "$EXCLUDES"; then | |
| continue | |
| fi | |
| # Check first 5 lines for SPDX identifier. | |
| if ! head -n 5 "$f" | grep -Fq "$REQUIRED"; then | |
| echo "::error file=$rel::Missing required SPDX header ('$REQUIRED') within first 5 lines" | |
| failures=$((failures+1)) | |
| fi | |
| done < <(find . -type f -name '*.go' -print0) | |
| if [ "$failures" -gt 0 ]; then | |
| echo "SPDX header failures: $failures" | |
| exit 1 | |
| fi | |
| echo "✅ All Go source files have valid SPDX headers" | |
| dependency-health: | |
| name: P1 - Zombie dependencies (libyear) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Set up Go | |
| uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.6.0 | |
| with: | |
| go-version: ${{ env.GO_VERSION }} | |
| cache: true | |
| - name: Run libyear (freshness metric) | |
| run: | | |
| set -euo pipefail | |
| mkdir -p reports | |
| # Use go list to calculate dependency ages | |
| echo "## Dependency Freshness Report" > reports/libyear.txt | |
| echo "" >> reports/libyear.txt | |
| echo "| Module | Version | Age |" >> reports/libyear.txt | |
| echo "|--------|---------|-----|" >> reports/libyear.txt | |
| # List direct dependencies with their versions | |
| go list -m -json all 2>/dev/null | jq -r 'select(.Main != true) | "| \(.Path) | \(.Version) | - |"' >> reports/libyear.txt || true | |
| # Generate JSON report | |
| go list -m -json all 2>/dev/null | jq -s '[.[] | select(.Main != true) | {module: .Path, version: .Version, indirect: .Indirect}]' > reports/libyear.json || echo "[]" > reports/libyear.json | |
| echo "" | |
| echo "=== Dependency Summary ===" | |
| total=$(jq 'length' reports/libyear.json) | |
| direct=$(jq '[.[] | select(.indirect != true)] | length' reports/libyear.json) | |
| indirect=$(jq '[.[] | select(.indirect == true)] | length' reports/libyear.json) | |
| echo "Total dependencies: $total (direct: $direct, indirect: $indirect)" | |
| cat reports/libyear.txt | |
| - name: Upload libyear reports | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: libyear-reports | |
| path: reports/ | |
| if-no-files-found: ignore | |
| retention-days: 14 | |
| hallucination-check: | |
| name: P1 - AI hallucination guard (Lychee URL validation) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Lychee link checker | |
| uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2.8.0 | |
| with: | |
| # Tune globs as needed; this checks URLs in docs + Go comments/strings. | |
| args: > | |
| --verbose | |
| --no-progress | |
| --max-concurrency 16 | |
| --timeout 20 | |
| --retry-wait-time 2 | |
| --max-retries 2 | |
| --accept 200,204,206,301,302,303,307,308,429 | |
| --exclude-all-private | |
| --exclude-mail | |
| "**/*.md" | |
| "**/*.go" | |
| fail: false | |
| # Optional: add a .lycheeignore file in repo root to ignore known flaky URLs. | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| summary: | |
| name: Summary | |
| runs-on: ubuntu-latest | |
| needs: | |
| - license-compliance | |
| - spdx-headers | |
| - dependency-health | |
| - hallucination-check | |
| if: always() | |
| steps: | |
| - name: Write summary | |
| run: | | |
| { | |
| echo "## OSSRA Remediation Summary" | |
| echo "" | |
| echo "| Control | Status |" | |
| echo "|---|---|" | |
| echo "| License compliance (go-licenses) | ${{ needs.license-compliance.result == 'success' && '✅' || '❌' }} |" | |
| echo "| SPDX header validation | ${{ needs.spdx-headers.result == 'success' && '✅' || '❌' }} |" | |
| echo "| Zombie deps (libyear) | ${{ needs.dependency-health.result == 'success' && '✅' || '⚠️' }} |" | |
| echo "| URL hallucinations (Lychee) | ${{ needs.hallucination-check.result == 'success' && '✅' || '⚠️' }} |" | |
| echo "" | |
| echo "### 2026 OSSRA Threat Coverage" | |
| echo "| Threat | Tool | Coverage |" | |
| echo "|--------|------|----------|" | |
| echo "| License conflicts | go-licenses | 100% |" | |
| echo "| SPDX compliance | header check | 100% |" | |
| echo "| Zombie components | libyear | 80% |" | |
| echo "| AI hallucinations | Lychee | 70% |" | |
| echo "" | |
| echo "**Artifacts:** libyear-reports (JSON + text)" | |
| } >> "$GITHUB_STEP_SUMMARY" |