Skip to content

Add codemap-full release and blast radius bundle#70

Merged
JordanCoin merged 2 commits intomainfrom
codex/codemap-full-blast-radius
Apr 8, 2026
Merged

Add codemap-full release and blast radius bundle#70
JordanCoin merged 2 commits intomainfrom
codex/codemap-full-blast-radius

Conversation

@JordanCoin
Copy link
Copy Markdown
Owner

Summary

  • add a codemap-full release archive that bundles codemap, ast-grep, and sg
  • make ast-grep resolution prefer bundled sibling binaries before falling back to PATH
  • add JSON output for codemap --importers
  • add a bounded scripts/codemap-blast-radius.sh wrapper for diff/deps/importers review context
  • document tarball CI install paths for both standard and self-contained archives

Why

This makes the direct tarball/CI install path work for --deps without relying on Homebrew or a separate runtime install, and it gives PR-review workflows a compact blast-radius bundle that adds impact context without sending the whole repo to an LLM.

Verification

  • go test ./...
  • bash -n scripts/codemap-blast-radius.sh
  • bash -n scripts/download-bundled-astgrep.sh
  • goreleaser check
  • goreleaser release --snapshot --clean --skip=publish
  • smoke test: build codemap, place bundled ast-grep siblings next to it, clear PATH of ast-grep, confirm codemap --deps still works on a temp repo

Notes

  • package manager outputs remain pinned to the standard archive; codemap-full is an additional release asset
  • go mod tidy promoted gopkg.in/yaml.v3 to a direct dependency because it is already imported by skills/loader.go

Copilot AI review requested due to automatic review settings April 8, 2026 17:43
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new “full” release artifact that bundles codemap with sibling ast-grep/sg binaries, updates dependency scanning to prefer those bundled binaries, and introduces JSON output + a “blast radius” wrapper script to generate compact PR-review context.

Changes:

  • Add a codemap-full GoReleaser archive and a pre-build download step to fetch pinned ast-grep release assets.
  • Prefer bundled sibling ast-grep/sg binaries before falling back to PATH, and standardize the “not found” error handling.
  • Add JSON output for codemap --importers, plus a bounded scripts/codemap-blast-radius.sh wrapper and README documentation.

Reviewed changes

Copilot reviewed 11 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
scripts/download-bundled-astgrep.sh New downloader/extractor for pinned ast-grep release zips into bundled-tools/.
scripts/codemap-blast-radius.sh New wrapper to emit bounded diff/deps/importers context in Markdown/Text/JSON.
scanner/walker.go Switch missing-ast-grep error to shared sentinel error.
scanner/types.go Add ImportersReport struct for --importers JSON output.
scanner/astgrep.go Add bundled-sibling lookup + verification of sg/ast-grep candidates; define ErrAstGrepNotFound.
scanner/astgrep_test.go Add tests for rejecting non-ast-grep sg and bundled candidate behavior.
README.md Document tarball vs codemap-full install paths and the blast-radius workflow.
main.go Add JSON output path for importers mode; improve deps-mode guidance when ast-grep is missing.
main_more_test.go Update importers test call signature and add coverage for --json --importers.
go.mod Promote gopkg.in/yaml.v3 to a direct dependency.
go.sum Update sums for module graph changes.
.goreleaser.yml Add “full” archive and download hook; ensure package-manager outputs stay on default archive.
.gitignore Ignore generated bundled-tools/ directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

"linux arm64 app-aarch64-unknown-linux-gnu.zip"
"windows amd64 app-x86_64-pc-windows-msvc.zip"
)

Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm -rf "$output_dir" can be dangerously destructive if --output-dir is set to /, ., or an empty string (e.g., via CI env/arg mistakes). Add a safety guard that rejects empty///. paths (and ideally requires the output directory to be within the repo) before deleting, or delete only the expected per-target subdirectories.

Suggested change
case "$output_dir" in
""|"/"|".")
echo "Refusing to delete unsafe output directory: $output_dir" >&2
exit 1
;;
esac
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "$script_dir/.." && pwd)"
repo_root_abs="$(python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$repo_root")"
output_dir_abs="$(python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$output_dir")"
if [[ "$output_dir_abs" == "$repo_root_abs" ]]; then
echo "Refusing to delete repository root: $output_dir" >&2
exit 1
fi
case "$output_dir_abs" in
"$repo_root_abs"/*)
;;
*)
echo "Refusing to delete output directory outside repository: $output_dir" >&2
exit 1
;;
esac

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9de3a07. The downloader no longer deletes the whole output root; it now rejects unsafe base paths ("", /, .) and only removes the expected per-target subdirectories before recreating them.

Comment on lines +67 to +75
import urllib.request
import zipfile

version, asset, dest = sys.argv[1:]
url = f"https://github.com/ast-grep/ast-grep/releases/download/{version}/{asset}"
print(f"Downloading {url}", file=sys.stderr)

with urllib.request.urlopen(url) as response:
data = response.read()
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Python downloader uses urllib.request.urlopen(url) without a timeout, which can hang a release build indefinitely on network issues. Pass an explicit timeout (and optionally add a simple retry/backoff) so CI/release runs fail fast and predictably.

Suggested change
import urllib.request
import zipfile
version, asset, dest = sys.argv[1:]
url = f"https://github.com/ast-grep/ast-grep/releases/download/{version}/{asset}"
print(f"Downloading {url}", file=sys.stderr)
with urllib.request.urlopen(url) as response:
data = response.read()
import time
import urllib.error
import urllib.request
import zipfile
DOWNLOAD_TIMEOUT_SECONDS = 30
DOWNLOAD_RETRIES = 3
RETRY_BACKOFF_SECONDS = 2
version, asset, dest = sys.argv[1:]
url = f"https://github.com/ast-grep/ast-grep/releases/download/{version}/{asset}"
print(f"Downloading {url}", file=sys.stderr)
last_error = None
for attempt in range(1, DOWNLOAD_RETRIES + 1):
try:
with urllib.request.urlopen(url, timeout=DOWNLOAD_TIMEOUT_SECONDS) as response:
data = response.read()
break
except (TimeoutError, urllib.error.URLError, OSError) as exc:
last_error = exc
if attempt == DOWNLOAD_RETRIES:
raise
print(
f"Download attempt {attempt} failed for {url}: {exc}. "
f"Retrying in {RETRY_BACKOFF_SECONDS}s...",
file=sys.stderr,
)
time.sleep(RETRY_BACKOFF_SECONDS)
else:
raise last_error

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9de3a07. The embedded Python downloader now uses an explicit timeout, retries with backoff, and fails with a clear error after the retry budget is exhausted.

.goreleaser.yml Outdated
before:
hooks:
- go mod tidy
- ./scripts/download-bundled-astgrep.sh
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding ./scripts/download-bundled-astgrep.sh to before.hooks makes goreleaser runs depend on Python + outbound network access. Consider making this hook conditional (e.g., env-gated) or moving the download step into a dedicated CI job that prepares artifacts, so local/offline goreleaser runs remain reproducible and don't unexpectedly fail.

Suggested change
- ./scripts/download-bundled-astgrep.sh
- sh -c 'if [ "${DOWNLOAD_BUNDLED_ASTGREP:-0}" = "1" ]; then ./scripts/download-bundled-astgrep.sh; else echo "Skipping bundled ast-grep download (set DOWNLOAD_BUNDLED_ASTGREP=1 to enable)"; fi'

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9de3a07, but with a slightly different shape. The networked codemap-full path now lives in a dedicated release-only config (.goreleaser.full.yml) and the GitHub Actions release workflow explicitly uses that config. The default .goreleaser.yml is back to the standard offline/local release path, so local goreleaser runs no longer require Python or outbound network access.

.goreleaser.yml Outdated
Comment on lines +44 to +58
- id: full
ids:
- codemap
name_template: '{{ .ProjectName }}-full_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}'
formats:
- tar.gz
format_overrides:
- goos: windows
formats:
- zip
files:
- src: bundled-tools/{{ .Os }}_{{ .Arch }}/ast-grep{{ if eq .Os "windows" }}.exe{{ end }}
strip_parent: true
- src: bundled-tools/{{ .Os }}_{{ .Arch }}/sg{{ if eq .Os "windows" }}.exe{{ end }}
strip_parent: true
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The full archive currently only adds ast-grep/sg to the bundle; it does not include README.md or LICENSE* like the default archive does. If these files are intentionally included in release artifacts (and for license distribution consistency), add them to the full archive files: list as well.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9de3a07. The codemap-full archive now includes README.md, LICENSE*, and the bundled sg-rules alongside codemap, ast-grep, and sg for consistency with the standard archive.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 61882742eb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +74 to +75
with urllib.request.urlopen(url) as response:
data = response.read()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Validate ast-grep downloads before bundling

The release hook downloads executable archives and immediately repackages them into codemap-full without any checksum or signature verification. If GitHub traffic is intercepted, a mirror/proxy is compromised, or the upstream asset is replaced, this pipeline will ship a tampered ast-grep/sg binary to users. Please verify each downloaded asset against pinned expected hashes (or signed checksums) before extraction.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9de3a07. The downloader now verifies each ast-grep asset against a pinned SHA-256 before extraction, so the codemap-full pipeline no longer republishes unverified downloaded executables.

@JordanCoin JordanCoin merged commit 95a8468 into main Apr 8, 2026
12 checks passed
@JordanCoin JordanCoin deleted the codex/codemap-full-blast-radius branch April 8, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants