feat(release): darwin/arm64 release workflow #149
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
| name: Security (OSS-CLI) | |
| # OSS-CLI security stack per RAN-46 AC §3 (board ruling, comment fa5ba510). | |
| # Replaces Sonar + CodeQL + OWASP Dependency-Check. | |
| # | |
| # Six independent jobs — fail-fast off so all signals surface on a single run. | |
| # All actions SHA-pinned per Scorecard `Pinned-Dependencies`. Top-level | |
| # `permissions: read-all` per Scorecard `Token-Permissions`; jobs scope up | |
| # only when needed (gitleaks needs full git history; sbom job uploads). | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| schedule: | |
| - cron: '21 4 * * 1' # Mondays 04:21 UTC — catch newly-disclosed CVEs | |
| permissions: read-all | |
| jobs: | |
| osv-scanner: | |
| name: OSV-Scanner (SCA) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| env: | |
| OSV_SCANNER_VERSION: 2.3.5 | |
| GH_TOKEN: ${{ github.token }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2 | |
| # Install osv-scanner from the official GitHub release (binary, not the | |
| # action — google/osv-scanner-action's `action.yml` is composite-only and | |
| # fails when invoked as a job step). Using the preinstalled `gh` CLI | |
| # avoids any external `curl`/`wget` per /home/dev/.claude/CLAUDE.md. | |
| - name: Install osv-scanner | |
| # `gh release download --output` is honoured only when downloading a single asset | |
| # via `--archive` or by exact name; with `--pattern` the asset is written to the | |
| # current dir at its source name. Download then move to a stable name. | |
| run: | | |
| gh release download "v${OSV_SCANNER_VERSION}" \ | |
| --repo google/osv-scanner \ | |
| --pattern 'osv-scanner_linux_amd64' \ | |
| --clobber | |
| mv osv-scanner_linux_amd64 osv-scanner | |
| chmod +x osv-scanner | |
| ./osv-scanner --version | |
| - name: Run osv-scanner (Go module graph) | |
| # Phase 6 cutover: project is Go-only. osv-scanner reads go.mod | |
| # (the entire module graph including transitive deps) and emits | |
| # any matching advisories from OSV.dev / GHSA. govulncheck (in | |
| # go-ci.yml) is the call-graph-aware companion that filters to | |
| # *reachable* vulns — keeping both gives both "have we got it" | |
| # AND "are we exposed". | |
| run: ./osv-scanner --lockfile=go/go.mod | |
| trivy: | |
| name: Trivy (filesystem + container scan) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2 | |
| - uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 | |
| with: | |
| scan-type: fs | |
| scan-ref: . | |
| severity: HIGH,CRITICAL | |
| exit-code: '1' | |
| ignore-unfixed: true | |
| semgrep: | |
| name: Semgrep (SAST) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2 | |
| - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: '3.12' | |
| - name: Install semgrep (pinned for reproducibility) | |
| # Pinned per OpenSSF Scorecard `Pinned-Dependencies` (RAN-46 §5). | |
| # Bump via Dependabot pip ecosystem on a documented cadence; floating | |
| # `semgrep` was previously flagged by Scorecard. pip is left unpinned | |
| # — setup-python@v6 ships a current vendored pip, and the Scorecard | |
| # rule fires only on user-installed packages. | |
| run: python -m pip install --quiet 'semgrep==1.161.0' | |
| - name: Run semgrep (security-audit + owasp-top-ten + golang) | |
| # Phase 6 cutover: project is Go-only. p/java replaced with | |
| # p/golang. p/security-audit + p/owasp-top-ten stay (both | |
| # language-agnostic rule sets). | |
| run: | | |
| semgrep scan \ | |
| --error \ | |
| --config p/security-audit \ | |
| --config p/owasp-top-ten \ | |
| --config p/golang \ | |
| --severity ERROR \ | |
| --metrics off | |
| gitleaks: | |
| name: Gitleaks (secret scan) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| env: | |
| GITLEAKS_VERSION: 8.30.1 | |
| GH_TOKEN: ${{ github.token }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2 | |
| with: | |
| fetch-depth: 0 | |
| # The official `gitleaks/gitleaks-action` requires a paid license for | |
| # GitHub organisations. The underlying gitleaks CLI is MIT-licensed and | |
| # free; install it directly from the upstream release. Using the | |
| # preinstalled `gh` CLI avoids any external `curl`/`wget`. | |
| - name: Install gitleaks | |
| run: | | |
| gh release download "v${GITLEAKS_VERSION}" \ | |
| --repo gitleaks/gitleaks \ | |
| --pattern "gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \ | |
| --output gitleaks.tar.gz | |
| tar -xzf gitleaks.tar.gz gitleaks | |
| chmod +x gitleaks | |
| - name: Run gitleaks (full git history) | |
| run: ./gitleaks detect --source . --redact --no-banner --exit-code 1 | |
| jscpd: | |
| name: jscpd (duplication < 3% on touched code) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: '20' | |
| - run: | | |
| # Scope jscpd to Go production code only: | |
| # - go/cmd — main entry point | |
| # - go/internal — production code (100 detectors + pipeline + MCP) | |
| # Tests share fixture/assertion shape by design (parallelism for | |
| # catching contract regressions, not a refactoring target). | |
| # | |
| # `*language_extractor.go` (one per language under | |
| # intelligence/extractor/{java,typescript,python,golang}) and | |
| # `structures.go` (kotlin/scala/cpp/rust) implement the same | |
| # template-method shape against per-language ASTs by design; | |
| # collapsing into a base would couple unrelated grammars and | |
| # erase per-language readability. Excluded. | |
| # | |
| # --min-tokens 200 calibrated to Go's verbosity floor: each | |
| # detector file's package decl + imports + Type/init/Name/ | |
| # SupportedLanguages/DefaultConfidence/Detect scaffold is | |
| # ~150-180 tokens of identical structural boilerplate across | |
| # 100 detectors. 200 tokens is the floor for "real duplicate | |
| # logic" rather than language scaffolding. | |
| npx --yes jscpd@4 \ | |
| --threshold 3 \ | |
| --min-tokens 200 \ | |
| --reporters consoleFull \ | |
| --format "go" \ | |
| --ignore "**/vendor/**,**/testdata/**,**/grammar/**,**/generated/**,**/dist/**,**/coverage/**,**/intelligence/extractor/**/language_extractor.go,**/detector/**/structures.go" \ | |
| go/cmd go/internal | |
| sbom: | |
| name: SBOM (SPDX + CycloneDX) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2 | |
| - name: Generate SPDX SBOM | |
| uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 | |
| with: | |
| format: spdx-json | |
| output-file: sbom.spdx.json | |
| upload-artifact: false | |
| - name: Generate CycloneDX SBOM | |
| uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 | |
| with: | |
| format: cyclonedx-json | |
| output-file: sbom.cdx.json | |
| upload-artifact: false | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4.6.2 | |
| with: | |
| name: sbom | |
| path: | | |
| sbom.spdx.json | |
| sbom.cdx.json | |
| retention-days: 90 |