Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 2 additions & 91 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: ['1.26']
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -33,96 +34,6 @@ jobs:
files: coverage.out
continue-on-error: true

build-windows:
# CGO build smoke-test on native Windows. tree-sitter needs a C/C++
# compiler — the GitHub windows runner ships mingw-w64 on PATH, so no
# extra toolchain setup is required. `go build ./...` compiles every
# production package; the focused agents and sidecar tests also exercise
# Windows-only paths without opting into the unsupported full test suite.
runs-on: windows-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod

- name: Build CLI
run: go build -o gortex.exe ./cmd/gortex/

- name: Build all packages
run: go build ./...

- name: Test Windows agent integrations
run: go test -timeout=5m -count=1 ./internal/agents

# Symlink confinement keeps out-of-repo files out of the index, and it
# reads differently on Windows: a symlink reparse point maps to
# ModeSymlink but a directory junction maps to ModeIrregular, and
# evalSymlinks normalises path case where Unix does not. Verifying it
# only on the linux/macos matrix would leave the platform whose
# semantics differ most as the untested one.
- name: Test symlink confinement
run: go test -timeout=5m -count=1 ./internal/pathguard

# Windows refuses to unlink an open file, so a leaked sidecar handle
# pins its directory and fails the enclosing t.TempDir() cleanup. That
# asymmetry is invisible on the linux/macos matrix, which is why this
# one test runs here rather than only there.
- name: Test sidecar handle release
run: go test -timeout=5m -count=1 -run TestCloseSidecar ./internal/persistence

# Same asymmetry, different holder: the plan-lock fixture opens an
# on-disk Store, so a missing Close pins plan_lock.sqlite and fails
# its t.TempDir() cleanup here while passing everywhere else. Every
# assertion in these tests is platform-neutral — only the cleanup
# distinguishes the runners — so nothing but this step can protect
# the fixture's Close from being dropped again.
- name: Test plan-lock fixture handle release
run: >
go test -timeout=10m -count=1
-run 'PlanLock|PlansLocked|PlansNeverScan'
./internal/graph/store_sqlite

# os.UserHomeDir reads %USERPROFILE% here and $HOME everywhere else, so
# a test that isolates itself with HOME alone keeps resolving the real
# profile on Windows — and writes to it. That is invisible to the
# linux/macos matrix by construction, so the isolation helper and the
# path resolver it protects have to be verified on this runner or not
# at all.
- name: Test user-state isolation
run: go test -timeout=5m -count=1 ./internal/testenv ./internal/platform

# Indexed paths are repoPrefix + '/' + the rest in native separators, so
# on Windows a stored path reads `repo/dir\file.cs`. Every test for that
# shape is a no-op on the linux/macos matrix — POSIX treats '\' as an
# ordinary filename byte, so filepath.Clean and filepath.ToSlash both
# leave the fixture untouched and the assertions pass with or without
# the production fix. This runner is the only one where they can fail.
- name: Test store path separator handling
run: go test -timeout=5m -count=1 ./internal/graphpath

# The same asymmetry reaches the other direction too: a test that spells
# an expected path with '/' passes on POSIX whatever the code does, and
# only this runner can tell whether the value under test is a native
# filesystem path (filepath.Join / filepath.Clean) or a '/'-keyed store
# path. ParseDiffGitPaths, ParseDiffLinesNewSide and FeedbackDir all
# assert on native paths, so they belong here rather than nowhere.
# The path-domain contracts belong here for the same reason. A graph
# key is "<prefix>/" plus a native-separator remainder, so GraphKey,
# JoinFileNodes, the prefix-shadow end-to-end pair and RankFileRisk's
# per-domain normalization only diverge once '/' and the native
# separator differ — every one of them passes on the linux/macos
# matrix whatever the code does. internal/review joins the list
# because the file-risk normalizer lives there.
- name: Test native-separator store path comparisons
run: >
go test -timeout=10m -count=1
-run 'NativeSeparator|MixedSeparator|ImportAdjacency|ParseDiffGitPaths|ParseDiffLinesNewSide|FeedbackDir|ReviewRulepack|PrefixedGraphReportsRulepack|GraphKey|JoinFileNodes|ChangedSymbolsForFiles|PrefixShadow|IdsOnPrefixedGraph|RankFileRisk|PrefixedDeleteAndRename'
./internal/analysis ./internal/graph/store_sqlite
./internal/mcp ./internal/resolver ./internal/persistence
./internal/review

build-linux-static:
# The linux release ships a statically linked binary so it runs on any
# distro (see .goreleaser.yml). That only holds while the code stays
Expand Down
Loading