From 6fef393ae5c4634ec21fa4c0583dd20fc950bebb Mon Sep 17 00:00:00 2001 From: "pandoscope-release-bot[bot]" <310396883+pandoscope-release-bot[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2026 20:54:24 +0000 Subject: [PATCH] chore: update agentic template v3.16.0 -> v3.16.1 --- .copier-answers.agentic.yml | 2 +- .github/workflows/template-update.yml | 10 ++++++++++ .pre-commit-config.yaml | 8 +++++++- scripts/ci/check_gate.py | 22 +++++++++++++++++++--- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/.copier-answers.agentic.yml b/.copier-answers.agentic.yml index 0c0e2a1..155a819 100644 --- a/.copier-answers.agentic.yml +++ b/.copier-answers.agentic.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY -_commit: v3.16.0 +_commit: v3.16.1 _src_path: https://github.com/pandoscope/agentic-engineering-template agentic_disambiguate_roots: '' agentic_disambiguate_version: 0.3.0 diff --git a/.github/workflows/template-update.yml b/.github/workflows/template-update.yml index c3b5500..9e0fd37 100644 --- a/.github/workflows/template-update.yml +++ b/.github/workflows/template-update.yml @@ -254,6 +254,16 @@ jobs: --json body --jq .body \ || echo "_No release notes found for $NEW_REF in $template_repo._")" + # The changelog is quoted material from another repo, and it + # must not act on this one (#149). Release notes render every + # reference as `closes owner/repo#n`, GitHub reads closing + # keywords in a PR BODY, and `owner/repo#n` reaches across + # repositories — so merging an update PR here closed an + # upstream ticket whose work was not done. The verb is + # defused and the link kept: `closes [x#1]` -> `ref [x#1]`. + changelog="$(printf '%s' "$changelog" | sed -E \ + 's/(close[sd]?|fix(e[sd])?|resolve[sd]?)([[:space:]]+\[?[A-Za-z0-9._\/-]*#[0-9]+)/ref\3/Ig')" + { echo "Automated \`copier update\` of the agentic template: \`$OLD_REF\` -> \`$NEW_REF\`." echo diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 434a68b..43ecdc7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,11 @@ # See https://pre-commit.com for more information -exclude: "CHANGELOG.md|.copier-answers.agentic.yml|.all-contributorsrc|\\.agents/skills|\\.claude/skills" +# +# Vendored paths are excluded: they are template output, byte-pinned +# upstream, and a fix applied here would be overwritten by the next +# update. `scripts/ci/` joins the skills directories for that reason — +# a consumer with stricter lint rules than the template's own would +# otherwise fail on code it cannot change. +exclude: "CHANGELOG.md|.copier-answers.agentic.yml|.all-contributorsrc|\\.agents/skills|\\.claude/skills|scripts/ci/" default_stages: [pre-commit] default_install_hook_types: [pre-commit, commit-msg] diff --git a/scripts/ci/check_gate.py b/scripts/ci/check_gate.py index 89eab22..a17b943 100644 --- a/scripts/ci/check_gate.py +++ b/scripts/ci/check_gate.py @@ -28,17 +28,33 @@ API = os.environ.get("GITHUB_API_URL", "https://api.github.com") SERVER = os.environ.get("GITHUB_SERVER_URL", "https://github.com") +def api_url(path): + """The absolute URL for an API path, refusing any non-HTTP scheme. + + `API` comes from the environment, so a hostile or fat-fingered + `GITHUB_API_URL` could otherwise steer the gate's own reads at + `file:` and have it judge a PR on whatever it found on disk. The + scheme is checked here, once, because this is the only place a URL + is built. + """ + url = API + path + if not url.startswith(("https://", "http://")): + scheme = url.split(":", 1)[0] if ":" in url else url + raise ValueError(f"GITHUB_API_URL must be http(s) — refusing scheme {scheme!r}") + return url + + def fetch(path, token): """GET one API path, parsed. The only network call in this file.""" - req = urllib.request.Request( - API + path, + req = urllib.request.Request( # noqa: S310 — api_url rejects every other scheme + api_url(path), headers={ "Authorization": f"Bearer {token}", "Accept": "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28", }, ) - with urllib.request.urlopen(req) as response: + with urllib.request.urlopen(req) as response: # noqa: S310 — checked above return json.load(response)