mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-10 22:43:40 +00:00
* ci(security): add CodeQL SAST workflow for JS/TS and Python
CodeQL analyzes both languages on PR, main push, and weekly schedule.
Findings upload to the Security tab as SARIF. Advisory only on
introduction; promote to required check after baseline triage.
Plan: docs/plans/2026-05-03-001-feat-automated-security-scans-plan.md (U1)
* ci(security): add Dependency Review PR gate
Blocks PRs introducing high+ severity dependency vulnerabilities.
Posts inline summary comment on failure. Required-check candidate
after one week of clean runs.
Plan: docs/plans/2026-05-03-001-feat-automated-security-scans-plan.md (U2)
* ci(security): add Gitleaks secret scanning
PR runs scan the diff; main pushes scan full history.
Defense-in-depth on top of GitHub native push protection
(documented as a recommended Settings toggle in SECURITY.md).
Plan: docs/plans/2026-05-03-001-feat-automated-security-scans-plan.md (U3)
* ci(security): add OpenSSF Scorecard workflow
Weekly + on main push. SARIF uploads to Security tab; public
badge URL resolves after first scheduled run lands.
Plan: docs/plans/2026-05-03-001-feat-automated-security-scans-plan.md (U4)
* ci(security): add zizmor workflow lint
Lints .github/workflows/** for known Actions security misconfigurations
(unpinned actions, dangerous interpolation, missing permissions).
Triggered only on PRs touching .github/**.
Plan: docs/plans/2026-05-03-001-feat-automated-security-scans-plan.md (U5)
* ci(security): add Trivy container image scanning
Builds Dockerfile.cli and Dockerfile.web, then scans images for
HIGH/CRITICAL CVEs. Findings record-only on Security tab; not
PR-blocking. Weekly schedule + main push for freshness.
Plan: docs/plans/2026-05-03-001-feat-automated-security-scans-plan.md (U6)
* docs(security): add SECURITY.md policy and Scorecard badge
Vulnerability disclosure policy points to GitHub Private Vulnerability
Reporting. Documents in-CI scans landed in this branch and recommended
admin actions for forks.
Plan: docs/plans/2026-05-03-001-feat-automated-security-scans-plan.md (U7)
* fix(review): apply autofix feedback
- CodeQL paths-ignore: replace brace expansion (parser.{c,js}) with two
explicit entries — CodeQL uses .gitignore-style globs that do NOT support
brace expansion, so the original pattern matched no files.
- Trivy: pin aquasecurity/trivy-action from @master to @0.28.0 — mutable
refs are a supply-chain risk and are exactly what zizmor (added in this
same plan) is meant to flag.
ce-code-review run: /tmp/compound-engineering/ce-code-review/20260503-104259-279c3bc4/
* docs(review): record residual review findings
ce-code-review autofix run flagged three downstream-resolver items
that are not blockers but should land before promoting any of the new
security workflows to required PR checks.
Source: /tmp/compound-engineering/ce-code-review/20260503-104259-279c3bc4/
* fix(ci-security): address all zizmor + dependency-review violations
Resolves all GitHub Advanced Security findings on PR #1297:
- Add 'persist-credentials: false' to actions/checkout in 5 workflows
(codeql, dependency-review, gitleaks, trivy, workflow-lint). Prevents
the GITHUB_TOKEN from persisting in .git/config for downstream steps
to read. Scorecard already had it.
- Pin every net-new third-party Action to a commit SHA (was: major-tag
refs flagged by zizmor as 'unpinned action reference'):
github/codeql-action -> v3.35.3 (0daab03)
actions/dependency-review-action -> v4.9.0 (2031cfc)
gitleaks/gitleaks-action -> v2.3.9 (ff98106)
ossf/scorecard-action -> v2.4.3 (4eaacf0)
docker/build-push-action -> v6.19.2 (10e90e3)
- Bump aquasecurity/trivy-action 0.28.0 -> 0.36.0 (ed142fd). Versions
< 0.35.0 are flagged by GHSA-69fq-xp46-6x23 (briefly compromised
supply chain). Caught by Dependency Review on the introducing PR.
- Pin pipx-installed zizmor to 1.24.1 (was unpinned 'pipx install
zizmor' resolving to latest at run time).
Removes the now-stale residual-findings doc since every item it
recorded is resolved on this branch.
* fix(ci-security): clear remaining zizmor findings
After landing the new security workflows, zizmor reported 5 high+
findings against pre-existing workflows (none introduced by this PR's
new files, all introduced by zizmor's wider scope). Resolved per
research at docs.zizmor.sh and PyO3/maturin issue #2425:
Real fixes (cache-poisoning):
- publish.yml + release-candidate.yml: add 'package-manager-cache:
false' to actions/setup-node. setup-node v5+ enables caching by
default when a packageManager field is present in package.json;
explicit opt-out keeps release installs hermetic and clears the
audit. Cost: ~30s slower per release run.
Documented exemptions (dangerous-triggers, .github/zizmor.yml):
- ci-report.yml: workflow_run is REQUIRED to post sticky comments
on fork PRs (forks have read-only GITHUB_TOKEN on pull_request).
- claude.yml: pull_request_target is required by claude-code-action
to access secrets and post fork-PR review comments. PR checkouts
pin fork HEAD SHA to mitigate TOCTOU.
- pr-labeler.yml: pull_request_target on the autolabel job needs
pull-requests:write. release-drafter runs with dry-run:true and
reads config from the BASE ref only.
Each exemption carries the documented mitigation in zizmor.yml.
workflow-lint.yml now passes --config to both the SARIF and the
gate invocations.
Local 'zizmor --config .github/zizmor.yml --min-severity high .'
reports: No findings to report. Good job!
101 lines
3.7 KiB
YAML
101 lines
3.7 KiB
YAML
name: Publish to npm
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
|
|
# No workflow-level permissions — scoped per job below.
|
|
|
|
# Concurrency convention: see CONTRIBUTING.md → "GitHub Actions — Concurrency Convention".
|
|
# Tag refs are unique per release, so distinct tags run in parallel. Re-pushes of the
|
|
# same tag serialize. cancel-in-progress: false — never cancel a publish mid-flight.
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
ci:
|
|
uses: ./.github/workflows/ci.yml
|
|
permissions:
|
|
contents: read
|
|
actions: read
|
|
# No pull-requests:write — `ci.yml`'s save-pr-meta job is gated on
|
|
# `github.event_name == 'pull_request'`, so it never runs during a
|
|
# tag-triggered publish. Least-privilege for release-critical paths.
|
|
|
|
publish:
|
|
needs: ci
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
permissions:
|
|
contents: write
|
|
id-token: write
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
with:
|
|
node-version: 20
|
|
registry-url: https://registry.npmjs.org
|
|
# Hermetic install for the published artifact — no cache carry-over
|
|
# from non-tag contexts. setup-node v5+ caches by default when a
|
|
# packageManager field is present in package.json, so the explicit
|
|
# opt-out is required to clear the zizmor cache-poisoning audit.
|
|
# ~30s slower per release; runs rarely.
|
|
package-manager-cache: false
|
|
- name: Build gitnexus-shared
|
|
run: npm install && npm run build
|
|
working-directory: gitnexus-shared
|
|
|
|
- run: npm ci
|
|
working-directory: gitnexus
|
|
|
|
- name: Verify version consistency
|
|
shell: bash
|
|
run: |
|
|
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
|
|
if ! [[ "$TAG_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
|
|
echo "::error::Tag does not follow semver: v$TAG_VERSION"
|
|
exit 1
|
|
fi
|
|
PKG_VERSION=$(node -p "require('./package.json').version")
|
|
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
|
|
echo "::error::Tag version (v$TAG_VERSION) does not match package.json version ($PKG_VERSION)"
|
|
exit 1
|
|
fi
|
|
echo "Version verified: $PKG_VERSION"
|
|
working-directory: gitnexus
|
|
|
|
- name: Build
|
|
run: npm run build
|
|
working-directory: gitnexus
|
|
|
|
- name: Dry-run publish
|
|
run: npm publish --dry-run
|
|
working-directory: gitnexus
|
|
|
|
- name: Publish to npm
|
|
run: npm publish --provenance --access public
|
|
working-directory: gitnexus
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
|
|
- name: Extract release notes from CHANGELOG
|
|
id: changelog
|
|
shell: bash
|
|
run: |
|
|
VERSION="${GITHUB_REF#refs/tags/v}"
|
|
NOTES=$(awk "/^## \\[$VERSION\\]/{found=1; next} /^## \\[/{if(found) exit} found" gitnexus/CHANGELOG.md)
|
|
if [ -z "$NOTES" ]; then
|
|
echo "::warning::No CHANGELOG entry found for v$VERSION, falling back to auto-generated notes"
|
|
echo "fallback=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "$NOTES" > /tmp/release-notes.md
|
|
echo "fallback=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Create GitHub Release
|
|
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v2
|
|
with:
|
|
body_path: ${{ steps.changelog.outputs.fallback == 'false' && '/tmp/release-notes.md' || '' }}
|
|
generate_release_notes: ${{ steps.changelog.outputs.fallback == 'true' }}
|