diff --git a/.cursor/skills/astvcs-add-tree-sitter-language/SKILL.md b/.cursor/skills/astvcs-add-tree-sitter-language/SKILL.md index 0f8cf47..64a1745 100644 --- a/.cursor/skills/astvcs-add-tree-sitter-language/SKILL.md +++ b/.cursor/skills/astvcs-add-tree-sitter-language/SKILL.md @@ -14,7 +14,7 @@ metadata: ## Gather 1. Confirm the extension is not already listed in [docs/architecture.md](../../../docs/architecture.md). -2. Find a maintained `tree-sitter-*` crate on crates.io compatible with `tree-sitter = "0.26.12"`. +2. Find a maintained `tree-sitter-*` crate on crates.io compatible with `tree-sitter = "0.27.0"`. 3. Read `src/frontend/languages.rs`, `src/frontend/treesitter.rs`, and `supported_extensions()` in `src/lib.rs`. ## Act diff --git a/.cursor/skills/astvcs-develop/SKILL.md b/.cursor/skills/astvcs-develop/SKILL.md index ee58c27..0c5b530 100644 --- a/.cursor/skills/astvcs-develop/SKILL.md +++ b/.cursor/skills/astvcs-develop/SKILL.md @@ -48,7 +48,7 @@ cargo build --release - Push a tag matching `v*` (for example `v0.1.4`) to trigger `.github/workflows/release.yml`. - The workflow matrix builds on `ubuntu-latest` and `windows-latest` with `cargo build --release --locked`, runs smoke tests (`astvcs --version`, `astvcs init` creating `.astvcs`, all three release binaries present via `Test-Path`), packages `astvcs-linux-x86_64.tar.gz` and `astvcs-windows-x86_64.zip` containing `astvcs`, `astvcs-merge-driver`, and `astvcs-diff-driver`, and attaches them to a GitHub Release via `softprops/action-gh-release`. - Windows jobs enable symlink creation (same registry step as `ci.yml`) so smoke tests can create symlinks if needed. -- Draft release notes from [`docs/RELEASE.md`](../../../docs/RELEASE.md). Do not publish to crates.io. +- Keep the current release section in [`docs/RELEASE.md`](../../../docs/RELEASE.md). The release workflow publishes Requirements, Install, and that version's changelog as the GitHub Release body, plus a compare link. Do not publish to crates.io. - Git driver setup lives in [`docs/git-integration.md`](../../../docs/git-integration.md). `v0.1.0` archives shipped only the main CLI binary. From `v0.1.2`, structural merge-driver conflicts write `<<<<<<<` markers into `%A` for text/AST paths. ### Code change rules diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b520ac..a16abe6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -90,11 +90,38 @@ jobs: permissions: contents: write steps: + - uses: actions/checkout@v7 - uses: actions/download-artifact@v8 with: path: dist merge-multiple: true + - name: Write release notes + shell: pwsh + run: | + $md = Get-Content -Raw -Path docs/RELEASE.md + $start = $md.IndexOf("## Requirements") + $changelogAt = $md.IndexOf("## Changelog") + if ($start -lt 0 -or $changelogAt -lt 0) { throw "docs/RELEASE.md is missing Requirements or Changelog" } + $front = $md.Substring($start, $changelogAt - $start).TrimEnd() + $versions = [regex]::Matches($md, '(?m)^### (v\d+\.\d+\.\d+)') | ForEach-Object { $_.Groups[1].Value } + if ($versions.Count -lt 2) { throw "docs/RELEASE.md needs the current and previous changelog sections" } + $current = $versions[0] + $previous = $versions[1] + $pattern = "(?s)### " + [regex]::Escape($current) + "\r?\n(.*?)(?=\r?\n### v|\z)" + $section = [regex]::Match($md, $pattern) + if (-not $section.Success) { throw "missing changelog section for $current" } + $bullets = $section.Groups[1].Value.Trim() + $compare = "https://github.com/$env:GITHUB_REPOSITORY/compare/${previous}...${current}" + @( + $front + "" + "## Changelog" + "" + $bullets + "" + "**Full Changelog**: $compare" + ) -join "`n" | Set-Content -Path release-notes.md -Encoding utf8NoBOM - uses: softprops/action-gh-release@v3 with: files: dist/* - generate_release_notes: true + body_path: release-notes.md diff --git a/Cargo.lock b/Cargo.lock index cda408c..4241a76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,7 +47,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -58,7 +58,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -108,14 +108,14 @@ dependencies = [ [[package]] name = "astvcs" -version = "0.1.7" +version = "0.1.8" dependencies = [ "base64 0.23.1", "clap", "hex", "ignore", "proptest", - "rand 0.10.2", + "rand 0.10.3", "rcgen", "regex", "reqwest", @@ -306,9 +306,9 @@ checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" [[package]] name = "clap" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" dependencies = [ "clap_builder", "clap_derive", @@ -316,9 +316,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" dependencies = [ "anstream", "anstyle", @@ -328,9 +328,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.6.4" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061" +checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0" dependencies = [ "heck", "proc-macro2", @@ -520,7 +520,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -1337,9 +1337,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" dependencies = [ "chacha20", "getrandom 0.4.3", @@ -1528,7 +1528,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -1606,7 +1606,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -1807,7 +1807,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -1910,10 +1910,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.3", + "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -2109,13 +2109,12 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.26.12" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c567a8e18ae93f20982c90370b16fd24023aeaf52f6052b96957ab253a0fec" +checksum = "2038684e0058edba0d17302619f62eabce4a8e11c6ac59506996a8d79848851d" dependencies = [ "cc", "regex", - "regex-syntax", "serde_json", "streaming-iterator", "tree-sitter-language", @@ -2243,9 +2242,9 @@ dependencies = [ [[package]] name = "tree-sitter-language" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782" +checksum = "ca0d1bf6fdd806e43ae5198f82f527056d359def39e54e67a0f478ac09dac081" [[package]] name = "tree-sitter-python" @@ -2546,7 +2545,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7b851be..b03d858 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "astvcs" -version = "0.1.7" +version = "0.1.8" edition = "2024" license = "MIT" @@ -33,7 +33,7 @@ sha2 = "0.11.0" similar = "3.2.0" subtle = "2.6.1" tiny_http = { version = "0.12.0", features = ["ssl-rustls"] } -tree-sitter = "0.26.12" +tree-sitter = "0.27.0" tree-sitter-bash = "0.25.1" tree-sitter-c = "0.24.2" tree-sitter-c-sharp = "0.23.5" diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 2f8dd13..a952fba 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -4,7 +4,7 @@ Copy this outline when drafting a GitHub Release for a new tag. Project overview ## Version -`v0.1.7` (matches `Cargo.toml` `version` and `astvcs --version`) +`v0.1.8` (matches `Cargo.toml` `version` and `astvcs --version`) ## Requirements @@ -22,10 +22,17 @@ Download the platform archive from [GitHub Releases](https://github.com/Cod-e-Co Each archive contains three binaries: `astvcs`, `astvcs-merge-driver`, and `astvcs-diff-driver` (`.exe` on Windows). The `v0.1.0` archives shipped only the main `astvcs` binary. -Verify: `astvcs --version` should print `0.1.7`. +Verify: `astvcs --version` should print `0.1.8`. ## Changelog +### v0.1.8 + +- Bump direct crate tree-sitter to 0.27.0 +- Bump lockfile crates clap to 4.6.7 and rand to 0.10.3 +- Skip parent diffs in the history driver when HEAD is the root commit so the long history test can finish +- Publish GitHub Release notes from the current section of this file + ### v0.1.7 - Bump direct crates: reqwest, similar, tree-sitter, zstd diff --git a/tests/history_smoke.rs b/tests/history_smoke.rs index 20ff74e..85839aa 100644 --- a/tests/history_smoke.rs +++ b/tests/history_smoke.rs @@ -185,30 +185,31 @@ impl HistoryModel { fn diff_head(&mut self) -> Result<(), String> { let head = self.repo.head_state().map_err(|e| e.to_string())?; - let parent = self + if let Some(parent) = self .repo .load_timeline_entry(&head) .map_err(|e| e.to_string())? .parent - .ok_or_else(|| "head has no parent".to_string())?; - let head_files = self - .repo - .load_state_files(&head) - .map_err(|e| e.to_string())?; - let parent_files = self - .repo - .load_state_files(&parent) - .map_err(|e| e.to_string())?; - for path in head_files - .keys() - .chain(parent_files.keys()) - .collect::>() { - if let (Some(old), Some(new)) = (parent_files.get(path), head_files.get(path)) - && let (astvcs::FileContent::Ast(old_g), astvcs::FileContent::Ast(new_g)) = - (&old.content, &new.content) + let head_files = self + .repo + .load_state_files(&head) + .map_err(|e| e.to_string())?; + let parent_files = self + .repo + .load_state_files(&parent) + .map_err(|e| e.to_string())?; + for path in head_files + .keys() + .chain(parent_files.keys()) + .collect::>() { - let _diff = diff_graphs(old_g, new_g); + if let (Some(old), Some(new)) = (parent_files.get(path), head_files.get(path)) + && let (astvcs::FileContent::Ast(old_g), astvcs::FileContent::Ast(new_g)) = + (&old.content, &new.content) + { + let _diff = diff_graphs(old_g, new_g); + } } } std::fs::read_to_string(self.root.join(RUST_CALC_PATH))