Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
107a958
Complete docs/IMPROVEMENT_PLAN.md implementation (Phases 1-8)
bashandbone Sep 11, 2026
b98a13b
chore: deps updates, clippy, formatting
bashandbone Sep 11, 2026
9bbb006
fix: cargo-deny warnings
bashandbone Sep 11, 2026
5341a6a
style: format toml
bashandbone Sep 11, 2026
988c8ed
chore: fix clippy warnings
bashandbone Sep 11, 2026
6d145e5
fix: invalid Cargo.toml formatting
bashandbone Sep 11, 2026
cb3c5ae
style: more reformatting on Cargo.toml
bashandbone Sep 11, 2026
c418777
fix: typos and more Cargo.toml
bashandbone Sep 11, 2026
f48b048
chore: fix intentional typo and formatting
bashandbone Sep 11, 2026
c0fc853
fix: Cargo metadata
bashandbone Sep 11, 2026
e02e184
style: format config.rs
bashandbone Sep 11, 2026
4912be0
style: remove obvious and derivable README from Cargo.toml
bashandbone Sep 11, 2026
de8f099
chore: fix typos check
bashandbone Sep 11, 2026
1e0c7f6
fix(sync): mirror Git 2.51+ URL-first submodule sync remote selection
bashandbone Sep 11, 2026
97865da
test(sync): lock relative-parent remote child URL resolution
bashandbone Sep 11, 2026
a007df2
fix(storage): compare canonical submodule storage paths on Windows
bashandbone Sep 11, 2026
6d05730
fix(lookup): match gitmodules paths across Windows separators
bashandbone Sep 11, 2026
d9d09f8
fix(ci): disable git background maintenance in test harness; reflow m…
bashandbone Sep 11, 2026
90f1bf2
fix(windows): normalize platform path spellings in comparisons and ou…
bashandbone Sep 11, 2026
9e7e514
fix(windows): store manager-planned add paths with Git separators
bashandbone Sep 11, 2026
929ac42
fix(tests): build dotted spelling as string, Path::join drops dot seg…
bashandbone Sep 12, 2026
1b7e1fc
fix(tests): use dot-dot spelling, Path equality skips dot segments
bashandbone Sep 12, 2026
e69b502
fix(windows): fold separators in add record check; canonical git dirs…
bashandbone Sep 12, 2026
41503a2
ci(windows): exclude ephemeral trees from Defender; accelerate fixtur…
bashandbone Sep 12, 2026
d4c2ec6
fix(windows): normalize separators in resolved absolute submodule URLs
bashandbone Sep 12, 2026
988e014
fix(windows): canonicalize file URLs for identity compare, relax perf…
bashandbone Sep 12, 2026
a2c8462
docs(readme): sync project structure, hooks, and test runner with cur…
bashandbone Sep 12, 2026
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
4 changes: 3 additions & 1 deletion .cargo/audit.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# SPDX-FileCopyrightText: 2026 Adam Poulemanos
# SPDX-License-Identifier: LicenseRef-PlainMIT OR MIT

# Canonical advisory policy lives in deny.toml. This file mirrors its empty
# exception list so every audit entry point enforces the same policy.
[advisories]
ignore = ["RUSTSEC-2024-0364"]
ignore = []
8 changes: 6 additions & 2 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
# and shell out to git are serialized among themselves to avoid any residual
# contention on shared git state (e.g. lock files in /tmp).

# Test groups were introduced in cargo-nextest 0.9.48. Older runners silently
# ignore the isolation below and invalidate the retained performance ceilings.
nextest-version = { required = "0.9.55", recommended = "0.9.128" }

[test-groups]
serial-integration = { max-threads = 1 }

Expand All @@ -19,13 +23,13 @@ fail-fast = false
# group. config_tests and command_contract_tests are safe to run in parallel
# with everything (they use isolated temp dirs and per-test gitconfig).
[[profile.default.overrides]]
filter = 'binary_id(submod::integration_tests) | binary_id(submod::sparse_checkout_tests) | binary_id(submod::error_handling_tests) | binary_id(submod::performance_tests)'
filter = 'binary(integration_tests) | binary(sparse_checkout_tests) | binary(error_handling_tests) | binary(performance_tests) | binary(reconciliation_lifecycle_tests) | binary(reconciliation_metadata_tests) | binary(reconciliation_sparse_tests) | binary(phase5_checkout_recovery_tests) | binary(phase5_delete_move_tests) | binary(phase5_reset_batch_tests) | binary(phase6_cli_contract_tests) | binary(phase6_output_tests) | binary(phase6_onboarding_tests)'
test-group = 'serial-integration'

# CI profile: fail fast but still serialize integration tests
[profile.ci]
fail-fast = true

[[profile.ci.overrides]]
filter = 'binary_id(submod::integration_tests) | binary_id(submod::sparse_checkout_tests) | binary_id(submod::error_handling_tests) | binary_id(submod::performance_tests)'
filter = 'binary(integration_tests) | binary(sparse_checkout_tests) | binary(error_handling_tests) | binary(performance_tests) | binary(reconciliation_lifecycle_tests) | binary(reconciliation_metadata_tests) | binary(reconciliation_sparse_tests) | binary(phase5_checkout_recovery_tests) | binary(phase5_delete_move_tests) | binary(phase5_reset_batch_tests) | binary(phase6_cli_contract_tests) | binary(phase6_output_tests) | binary(phase6_onboarding_tests)'
test-group = 'serial-integration'
164 changes: 131 additions & 33 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
#
# SPDX-License-Identifier: LicenseRef-PlainMIT OR MIT

# Third-party actions are pinned to immutable commit SHAs (reviewed
# 2026-09-11; version comments record the moving ref each SHA was taken
# from). To update: resolve the new tag/branch SHA with
# `git ls-remote https://github.com/<owner>/<repo>`, review the upstream
# diff, and update the SHA and comment together. There is no automation
# policy beyond this procedure.

name: CI

on:
Expand All @@ -15,49 +22,43 @@ env:

jobs:
test:
name: Test Suite
runs-on: ubuntu-latest
# beta/nightly are informational: a toolchain regression upstream should not
# gate merges, but we still want to see it.
continue-on-error: ${{ matrix.rust != 'stable' }}
name: Test Suite (stable, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
rust:
- stable
- beta
- nightly
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@master
- name: Install Rust (stable)
uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable
with:
toolchain: ${{ matrix.rust }}
toolchain: stable
components: rustfmt, clippy

- name: Cache cargo registry
uses: actions/cache@v6
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.rust }}
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}-stable

- name: Cache cargo index
uses: actions/cache@v6
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.rust }}
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}-stable

- name: Cache cargo build
uses: actions/cache@v6
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.rust }}
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}-stable

- name: Install cargo-nextest
uses: taiki-e/install-action@v2
uses: taiki-e/install-action@fa23953489c080190314742a9b907f8e97c6767c # v2
with:
tool: cargo-nextest

Expand All @@ -67,19 +68,82 @@ jobs:
git config --global user.email "ci@example.com"
git config --global user.name "CI"

# Fixture repos churn tens of thousands of small files per run and the
# suite shells out to git tens of thousands of times; on Windows both
# costs are an order of magnitude higher without these. The runner is
# ephemeral, so excluding its temp trees from real-time scanning is
# safe. (In-test git performance comes from the harness gitconfig.)
- name: Exclude ephemeral trees from Windows Defender
if: runner.os == 'Windows'
shell: pwsh
run: Add-MpPreference -ExclusionPath $env:GITHUB_WORKSPACE, $env:RUNNER_TEMP, $env:TEMP

- name: Run tests
run: cargo nextest run --all-features --no-fail-fast
run: cargo nextest run --locked --all-features --profile ci --no-fail-fast

- name: Run doctests
run: cargo test --locked --all-features --doc

test-informational:
name: Test Suite (${{ matrix.rust }}, informational)
runs-on: ubuntu-latest
# beta/nightly are informational: a toolchain regression upstream should not
# gate merges, but we still want to see it.
continue-on-error: true
strategy:
fail-fast: false
matrix:
rust:
- beta
- nightly
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable
with:
toolchain: ${{ matrix.rust }}
components: rustfmt, clippy

- name: Install cargo-nextest
uses: taiki-e/install-action@fa23953489c080190314742a9b907f8e97c6767c # v2
with:
tool: cargo-nextest

- name: Setup git
run: |
git config --global user.email "ci@example.com"
git config --global user.name "CI"

- name: Run tests
run: cargo nextest run --locked --all-features --profile ci --no-fail-fast

msrv:
name: MSRV check (Rust 1.89)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Install Rust 1.89
uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable
with:
toolchain: "1.89"

- name: Check MSRV build
run: cargo +1.89 check --locked --all-features

lint:
name: lint
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Install hk with mise
uses: jdx/mise-action@v4
uses: jdx/mise-action@c2a87611a18de5b3828c5652fe268e992400cb5c # v4
env:
HK_MISE: 1
MISE_YES: 1
Expand All @@ -97,7 +161,7 @@ jobs:
hk = { version = "1.48", depends = ["pkl"], postinstall = 'hk install --mise || true'}
pkl = "latest"
typos = { version = "latest", depends = ["rust"] }

# mise installs the toolchain without optional components, so cargo_fmt and
# cargo_clippy have no binary to call.
- name: Add rustfmt and clippy components
Expand All @@ -120,21 +184,55 @@ jobs:
checks: write
contents: read
steps:
- uses: actions/checkout@v7
- uses: rustsec/audit-check@v2
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
# Advisory exceptions live in deny.toml (canonical) and audit.toml; this
# step intentionally carries no inline ignore list so the two files
# cannot drift from what CI enforces. The v2 branch HEAD below was
# reviewed 2026-09-11.
- uses: rustsec/audit-check@69366f33c96575abad1ee0dba8212993eecbe998 # v2
with:
token: ${{ secrets.GITHUB_TOKEN || github.token }}
# Keep in sync with the `ignore` list in deny.toml, which documents why
# each of these is accepted.
ignore: RUSTSEC-2024-0364

package:
name: Package check
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Install Rust (stable)
uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable
with:
toolchain: stable

- name: Verify packaged source builds and tests
run: |
cargo package --locked
pkg=$(ls target/package/submod-*.crate | head -n 1)
rm -rf /tmp/submod-package-check
mkdir -p /tmp/submod-package-check
tar xzf "$pkg" -C /tmp/submod-package-check
cd /tmp/submod-package-check/submod-*
cargo build --locked --all-features
cargo test --locked --all-features --lib

- name: Validate schemas and template generation
run: |
for schema in schemas/v1.0.0/*.json schemas/v1.1.0/*.json schemas/current/*.json schemas/submod.json schemas/latest/*.json; do
python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$schema" \
|| { echo "::error::invalid schema JSON: $schema"; exit 1; }
done
cargo run --locked -- generate-config --template --force --output /tmp/submod-template-check.toml
test -s /tmp/submod-template-check.toml

coverage:
name: Code Coverage
runs-on: ubuntu-latest
permissions:
contents: write
contents: read
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
submodules: recursive

Expand All @@ -148,7 +246,7 @@ jobs:
git config --global user.email "ci@example.com"
git config --global user.name "CI"
- name: install other components
uses: taiki-e/install-action@v2
uses: taiki-e/install-action@fa23953489c080190314742a9b907f8e97c6767c # v2
with:
tool: cargo-nextest,cargo-llvm-cov

Expand All @@ -161,7 +259,7 @@ jobs:
--ignore-filename-regex '\.cargo[/\\]registry|\.cargo[/\\]git|rustup[/\\]toolchains|/rustc/|scripts[/\\]|tests[/\\]|examples[/\\]|benches[/\\]|target[/\\]|.*long_about.rs|.*lib.rs' \
--manifest-path Cargo.toml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v7
uses: codecov/codecov-action@a99c28d3f0da835de33ff2feb2e15691c7b9641f # v7
with:
files: lcov.info
token: ${{ secrets.CODECOV_TOKEN }}
Expand Down
32 changes: 24 additions & 8 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
#
# SPDX-License-Identifier: LicenseRef-PlainMIT OR MIT

# Third-party actions are pinned to immutable commit SHAs (reviewed
# 2026-09-11; version comments record the moving ref each SHA was taken
# from). See .github/workflows/ci.yml for the update procedure.
#
# These jobs validate documentation builds only. API-doc success does not
# prove schema delivery or CLI example behavior; those are covered by the
# package job in ci.yml and the R27 integration tests.

name: Documentation

on:
Expand All @@ -17,45 +25,53 @@ jobs:
docs:
name: Build and Deploy Documentation
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable
with:
toolchain: stable

- name: Cache cargo registry
uses: actions/cache@v6
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}

- name: Cache cargo index
uses: actions/cache@v6
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}

- name: Cache cargo build
uses: actions/cache@v6
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}

- name: Build documentation
run: cargo doc --all-features --no-deps
run: cargo doc --locked --all-features --no-deps

docs_rs_check:
name: Check docs.rs compatibility
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
submodules: recursive

- name: Install Rust nightly
uses: dtolnay/rust-toolchain@nightly
uses: dtolnay/rust-toolchain@be39649afda95dbf70f87cce95f68b8d5797b296 # nightly
with:
toolchain: nightly

- name: Install cargo-docs-rs
run: cargo install cargo-docs-rs
Expand Down
Loading
Loading