* chore(deps): bump actions/checkout from 6.0.3 to 7.0.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](df4cb1c069...9c091bb21b)
---
updated-dependencies:
- dependency-name: actions/checkout
dependency-version: 7.0.0
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* ci: set persist-credentials: false on read-only checkouts (zizmor artipacked)
Adds `persist-credentials: false` to the 9 checkout steps flagged by
zizmor's credential-persistence (artipacked) rule on PR #2292. All are
read-only CI/test/quality jobs that never use the git token afterward, so
not persisting it removes the leak surface. Checkouts that push (publish,
pr-autofix, commit-fork-prebuilds, etc.) keep credentials and are untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Gergo Magyar <gergomagyar@icloud.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude Code defaults to prompting for Bash approval. In GitHub Actions there
is no human to approve, so gh pr comment and similar commands fail and the
PR receives no review comment. Pass --dangerously-skip-permissions for the
code-review step only (headless CI; token and checkout are already scoped).
Co-authored-by: Cursor <cursoragent@cursor.com>
The Run Claude Code Review step passed an invalid PR ref
(owner/repo/pull/N) which gh interprets as a branch name, causing
early gh pr view failures. More importantly, the prompt omitted
--comment, so the code-review plugin only displayed findings in
terminal output and never invoked gh pr comment to post to the PR.
Switch to a full PR URL and add --comment so the plugin posts the
review during the session, which also routes around upstream bugs
anthropics/claude-code-action#1061 and #1087 where the action's
post-step capture can silently drop output on issue_comment triggers.
* Initial plan
* chore(security): harden workflow permissions and pin Docker base image digests
Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/2ddc8f2b-7355-48cf-9a0b-c06df66c3f47
* fix(security): restore permissions: {} on publish + release-candidate workflows
These two release-publishing workflows had permissions: {} (the strictest valid form) before PR #1454, which replaced it with permissions: read-all. Every job in both files already declares its own permissions block, so the workflow-level default is only the safety net for future jobs added without one — read-all weakens that net for no benefit. Restore {} and the explanatory comment.
Scorecard's TokenPermissions check accepts both forms, so this preserves U9 compliance.
* fix(security): narrow permissions: read-all to contents: read on 13 workflows
PR #1454 added permissions: read-all to 13 workflows that previously had no top-level permissions block. read-all is Scorecard-compliant but unnecessarily broad — every job in scope only needs contents:read at the workflow level (job-level blocks already grant the writes that any job actually performs).
Snapshot of every job in the 13 workflows confirms contents:read is sufficient:
- ci.yml: quality/tests/scope-parity have explicit contents:read job blocks; save-pr-meta uses upload-artifact only (no token scopes needed); ci-status is pure shell.
- ci-e2e.yml, ci-quality.yml, ci-scope-parity.yml, ci-tests.yml: all jobs do checkout + npm + tsc/vitest/playwright/upload-artifact only; no API token scopes required.
- claude.yml, codeql.yml, dependency-review.yml, docker.yml, gitleaks.yml, pr-labeler.yml, trivy.yml, workflow-lint.yml: all jobs already declare their own job-level blocks (security-events:write, pull-requests:write, packages:write, etc.) so the workflow-level default does not gate them.
zizmor (--min-severity high) is clean on the resulting tree. Pre-existing medium findings (secrets-inherit, artipacked) are in unrelated workflows and untouched by this commit.
scorecard.yml also uses read-all but pre-existed PR #1454 and is deferred to a follow-up PR per the plan's scope boundary.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
* ci: standardize workflow concurrency and automate release-note labeling
Concurrency — prevent racing CI jobs
- Every top-level workflow now declares an explicit concurrency block.
- PR runs cancel-in-progress on supersede; main/push/workflow_call/publish
runs queue instead of cancelling so every commit and every release is
validated end-to-end.
- ci.yml uses a literal `CI-` prefix (not `${{ github.workflow }}`) and a
per-run nested group for workflow_call invocations, avoiding a potential
deadlock with publish.yml and release-candidate.yml callers whose own
concurrency groups could otherwise collide with the called workflow.
- ci-report.yml falls back to `<head-repo>/<head-branch>` for fork PRs
(stable across reruns) instead of the per-run-unique workflow_run.id
which did not actually serialize anything.
- ci-quality.yml enforces the convention: fails CI if any non-reusable
workflow lacks a concurrency block or a reusable workflow declares one.
Release-note automation
- New pr-labeler.yml: amannn/action-semantic-pull-request enforces
conventional-commit PR titles on pull_request (fork-safe, read-only);
release-drafter/release-drafter with disable-releaser: true applies the
matching label under pull_request_target (write-scoped). sync-labels in
.github/release-drafter.yml removes managed autolabels that no longer
match (e.g. when `!` or `BREAKING CHANGE:` is dropped from a PR).
- .github/release.yml (unchanged) continues to map labels to categorized
release-notes sections.
- dependabot.yml added for the github-actions ecosystem so pinned SHAs
auto-refresh on a weekly cadence.
Docs
- CONTRIBUTING.md documents the concurrency convention, the
conventional-commit PR-title rules, and the reusable-workflow exception.
Follow-up to verify before relying on the labeler in anger
- gh api repos/amannn/action-semantic-pull-request/git/refs/tags/v5.5.3
- gh api repos/release-drafter/release-drafter/git/refs/tags/v6.0.0
- Confirm release-drafter reads its config from the base ref (not fork
head) when invoked via pull_request_target.
* ci: address PR review feedback on concurrency and labeler workflows
Two blocking fixes
- pr-labeler.yml: separate concurrency slots for pull_request and
pull_request_target. Previously both triggers shared a single group
with cancel-in-progress: true, so the privileged autolabel run could
cancel the title-validation check mid-run and leave a required status
in a permanent cancelled state.
- pr-labeler.yml autolabel job: add contents: read. release-drafter's
context.config() reads .github/release-drafter.yml from the default
branch via the repo-contents API and 403s without the scope. Job-level
permissions nullify all unlisted scopes so an explicit grant is needed.
Two non-blocking improvements
- Replace the hardcoded reusable-workflow allowlist in ci-quality.yml
with dynamic on:-block parsing. New workflow_call-only workflows no
longer produce false-positive convention failures.
- Implement actual group-key validation. The check now also asserts that
every concurrency.group expression references either ${{ github.workflow }}
or the literal CI- prefix (the documented ci.yml exception).
- Script extracted to .github/scripts/check-workflow-concurrency.py so
it is runnable locally and independently testable.
* feat: configure prettier with pre-commit hook integration
Add prettier, lint-staged, and prettier-plugin-tailwindcss at the repo
root with husky pre-commit hook integration. Moves husky from
gitnexus/ to root package.json for reliable hook installation.
- Root package.json with prepare/format/format:check scripts
- .prettierrc with endOfLine:lf and tailwindStylesheet for TW v4
- .prettierignore excluding fixtures, vendor, generated, *.d.ts, *.md
- .gitattributes enforcing LF line endings for Windows consistency
- Pre-commit hook uses direct node_modules/.bin/ paths (no npx)
* style: apply prettier formatting to entire codebase
One-time bulk format. No logic changes.
Use .git-blame-ignore-revs to skip this commit in git blame.
* chore: add .git-blame-ignore-revs for prettier format commit
* perf: pre-commit hook runs only tests related to staged files
Use vitest --related to scope test execution to tests that import
the changed files, instead of running the full suite on every commit.
* perf: remove vitest from pre-commit hook, keep in CI only
Pre-commit now runs lint-staged + tsc only. Tests run in CI
(ci-tests.yml) where they belong — keeps commits fast.
* ci: add prettier format check to quality workflow
PRs will now fail if code isn't formatted with prettier.
* feat(ingestion): respect .gitignore and .gitnexusignore during file discovery
Add support for excluding files from indexing based on .gitignore and
.gitnexusignore patterns. Previously, GitNexus used only a hardcoded
ignore list, causing significant index pollution in repositories with
git-ignored directories containing code (e.g., Docker-mounted volumes).
Changes:
- Add `ignore` package for gitignore-spec pattern matching
- Add `loadIgnoreRules()` to parse .gitignore + .gitnexusignore
- Add `createIgnoreFilter()` returning glob-compatible IgnoreLike object
- Integrate filter into glob's `ignore` option for directory-level pruning
- Remove post-glob `.filter()` call (now handled during traversal)
The hardcoded DEFAULT_IGNORE_LIST remains as fallback for non-git repos.
Closes#228
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(ingestion): address review feedback on ignore filtering
- Distinguish ENOENT vs EACCES in loadIgnoreRules (warn on permission errors)
- Add GITNEXUS_NO_GITIGNORE env var to bypass .gitignore parsing
- Fix bare-name pattern matching in childrenIgnored (check both with/without trailing slash)
- Rename isIgnoredDirectory to isHardcodedIgnoredDirectory for clarity
- Add clarifying comments for design decisions (D2 negation, D3 dot:false redundancy)
- Add tests for bare-name patterns, file-glob patterns, EACCES handling, env var
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(ingestion): address second round of review feedback
- G1: Document GITNEXUS_NO_GITIGNORE in `analyze --help` and log when active
- G2: Add comment clarifying path-scurry POSIX normalization contract
- G3: Add IgnoreOptions interface — env var now falls back, callers can
pass `noGitignore` explicitly for testability and future CLI flag
- G4: Add integration test verifying walkRepositoryPaths respects the env var
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(ingestion): gracefully skip files with unavailable tree-sitter grammars
Port unsupported language resilience from PR #301 by @jecanore.
- Make Kotlin import optional (like Swift) in parser-loader and parse-worker
- Add worker-local isLanguageAvailable() with filePath param for tsx distinction
- Track and log skipped files per language in both sequential and worker paths
- Add skippedLanguages to ParseWorkerResult for worker→main aggregation
- Add isLanguageAvailable unit tests
Refs: #301, #155, #228
Co-Authored-By: jecanore <juan@housingbase.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(e2e): add ignore + language-skip end-to-end test with fixture repo
Add a fixture repo (test/fixtures/ignore-and-skip-repo/) with .gitignore,
.gitnexusignore, TypeScript source files, and a Swift file to exercise
all three features end-to-end:
- File discovery: verifies .gitignore excludes data/ and *.log,
.gitnexusignore excludes vendor/, source files are discovered
- Parsing: verifies TypeScript files produce Function nodes and DEFINES
relationships, Swift files are skipped gracefully when grammar is
unavailable
Add the test to the standalone group in ci-integration.yml and coverage job.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(ci): move ignore-and-skip-e2e test to e2e group per review feedback
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(test): use temp directory instead of fixture for e2e ignore test
The fixture's .gitignore prevented data/seed.json and debug.log from
being committed — these files would be missing after checkout in CI.
Switch to creating the entire test structure in a temp directory via
beforeAll (matching filesystem-walker.test.ts pattern). This ensures
all files exist regardless of git ignore rules.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(test): correct graph API usage in e2e ignore test
Use graph.nodes property getter instead of graph.getNodes(), and check
Function node filePath instead of non-existent File nodes (File nodes
are created by processStructure, not processParsing).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ci: add workflows permission to ci-integration.yml
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ci: change workflows permission to write per review
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ci: move workflows permission from ci-integration.yml to ci.yml caller
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(ci): fix Claude workflows for fork PRs, remove misplaced workflows perm
Three issues prevented Claude from running on fork PRs:
1. claude-code-review.yml lacked workflows:write — push failed when
fork PRs modify .github/workflows/ files
2. claude.yml had no fork PR support — checked out main and couldn't
fetch the fork's branch from origin
3. Cleanup step unconditionally deleted branches even when push failed,
breaking the concurrent claude.yml workflow
Also removes workflows:write from ci.yml's integration job — CI tests
don't need that permission. The permission belongs on the claude
workflows that push fork branches.
Changes:
- Add workflows:write to both claude workflow permissions blocks
- Add fork PR detection + branch push/cleanup to claude.yml
- Add step id to push-fork; cleanup only runs if push succeeded
- Pass branch names via env vars to prevent shell injection (security)
- Add concurrency groups to prevent race conditions between workflows
- Remove misplaced workflows:write from ci.yml integration job
* fix(ci): use GitHub API for fork branch refs instead of git push
GITHUB_TOKEN cannot have 'workflows' permission — it's only valid for
PATs and GitHub Apps. This means git push fails whenever a fork PR
modifies .github/workflows/ files.
Replace git push with the GitHub REST API (POST/PATCH /git/refs) to
create temporary branch refs. The API creates a pointer to the
already-existing PR head commit without triggering the workflow file
push protection. Similarly, cleanup uses DELETE /git/refs instead of
git push --delete.
Also removes the invalid 'workflows: write' from permissions blocks.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: jecanore <juan@housingbase.io>
Co-authored-by: Gergo Magyar <gergomagyar@icloud.com>
* Initial plan
* fix: add pull-requests write permissions to GitHub Actions workflows
Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>
* fix(ci): remove ineffective job-level permissions from reusable workflow
* fix(ci): pass PR write permission from caller to reusable unit-tests workflow
* fix(ci): harden CI/CD workflows with security fixes and reliability improvements
- Pin all actions to commit SHAs to prevent supply-chain attacks
- Fix shell injection in ci-integration.yml by using env vars instead of direct interpolation
- Scope permissions per-job in publish.yml (was granting pull-requests:write to publish job)
- Restrict claude-code-review to trusted contributors only (OWNER/MEMBER/COLLABORATOR)
- Switch claude-code-review to pull_request_target for fork PR support
- Fix fail-fast: false in ci-unit-tests.yml cross-platform matrix
- Remove duplicate ubuntu-latest from unit test matrix
- Add timeouts to all workflow jobs
- Improve kuzu-db test loop to continue on failure and report per-file errors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(ci): read thresholds from `vitest.config.ts`
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>