chore(sync): track caffeinelabs/skills (commit-based) instead of retired caffeinelabs/motoko - #346
chore(sync): track caffeinelabs/skills (commit-based) instead of retired caffeinelabs/motoko#346marc0olo wants to merge 5 commits into
Conversation
…red caffeinelabs/motoko The Motoko skills now sync from caffeinelabs/skills (writing-motoko, migrating-motoko-actors, troubleshooting-motoko-migrations), which publishes no releases. Rework the sync automation and docs from release-based to commit-based for this upstream; mops-cli and static-site stay release-based. - .github/workflows/sync-upstream.yml: replace the check-motoko job (gh release view on caffeinelabs/motoko) with check-caffeinelabs-skills — reads the pinned commit from .claude/upstream.md (writing-motoko section), compares it to the default-branch HEAD, and opens an `upstream-skills`-labelled issue on drift. - scripts/sync-upstream-check.sh: swap the caffeinelabs/motoko case for caffeinelabs/skills (base path skills/, three new skill mappings); clarify the label args are display-only (tag or short SHA). - .claude/CLAUDE.md: document both tracking models (release-tracked vs commit-tracked), update the checklist, the owned-section summary table (frontmatter transform, mops-cli cross-ref, references/ paths; drop the retired motoko-pitfalls row), and the automated-detection section. Tested locally: awk pins 02e5316; same-commit → exit 0; pinned→HEAD → exit 1 with a correct issue body. (Upstream has already advanced to writing-motoko 0.1.5, so a content sync will be due after this lands — separate follow-up.) Part of #327.
There was a problem hiding this comment.
Pull request overview
Updates the upstream sync automation to track the new Motoko upstream (caffeinelabs/skills) by pinned commit SHA (since it has no releases), while keeping the existing release-based tracking for caffeinelabs/mops and dfinity/certified-assets.
Changes:
- Replaces the retired
caffeinelabs/motokorelease check with a commit-basedcaffeinelabs/skillscheck in the sync workflow. - Updates the upstream-diff script’s repo mapping from
caffeinelabs/motoko→caffeinelabs/skills. - Documents the two upstream tracking models (release-tracked vs commit-tracked) and updates the automated detection docs accordingly.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
scripts/sync-upstream-check.sh |
Switches Motoko upstream mapping to caffeinelabs/skills and updates commit-based framing. |
.github/workflows/sync-upstream.yml |
Adds a new commit-based job for caffeinelabs/skills and removes the old caffeinelabs/motoko release-based logic. |
.claude/CLAUDE.md |
Updates upstream-sync documentation to describe commit-tracked vs release-tracked models and the new automation behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
PR review (Copilot): the check enumerated only top-level files via the GitHub Contents API (non-recursive), so nested files like writing-motoko/references/* were never diffed — the automation would miss upstream changes to them. Replace the per-skill Contents API listing with a recursive Git Trees API walk (?recursive=1) filtered to the skill path (paths returned relative to it, so the raw-content fetch and diff headers now include e.g. references/control-flow.md). This also closes the previously-documented "future nested docs/<subdir>/ not covered" caveat for static-site. Warns on stderr if the tree is truncated. Updated the manual list-files snippet in CLAUDE.md and the static-site note in .claude/upstream.md to match (recursive, not top-level-only). Verified locally: 02e5316 -> HEAD now reports a change in writing-motoko/references/control-flow.md that the old top-level-only listing missed.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (1)
scripts/sync-upstream-check.sh:82
list_skill_filescurrently treats GitHub API failures as “no files” (JSON parse errorssys.exit(0)and the trailing|| true) and only warns ontruncatedtrees. That can produce false “no changes” results and prevent the workflow from opening a sync issue when the file listing is incomplete/untrusted. Prefer failing fast when the tree can’t be reliably enumerated (API error, parse error, ortruncated: true).
list_skill_files() {
curl -sf "https://api.github.com/repos/${REPO}/git/trees/$1?recursive=1" \
-H "Authorization: Bearer $GH_TOKEN" | \
python3 -c "
import sys, json
prefix = sys.argv[1].rstrip('/') + '/'
try:
d = json.load(sys.stdin)
except Exception:
sys.exit(0)
if d.get('truncated'):
sys.stderr.write('WARNING: git tree truncated; files under %s may be missed\n' % sys.argv[1])
for e in d.get('tree', []):
if e.get('type') == 'blob' and e['path'].startswith(prefix):
print(e['path'][len(prefix):])
" "$2" || true
}
PR review (Copilot, suppressed): list_skill_files treated API/parse errors as 'no files' (sys.exit(0) + trailing || true) and only warned on truncated trees, so a transient fetch failure or a truncated tree could yield an empty listing → 'no changes' → no sync issue opened (a silent false-negative). Now the helper returns non-zero on a fetch error, unparseable JSON, or truncated: true, and the caller aborts the run with exit 3. The workflow's diff step re-raises any non-0/1 code, so the job fails loudly instead of skipping a real upstream change. Verified: happy path still exit 1 (nested references/ included); a bogus SHA now exits 3 with a clear error instead of exit 0.
|
Re the suppressed comment on |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (1)
scripts/sync-upstream-check.sh:74
list_skill_filesdownloads the full repo tree JSON every time it’s called. Because this function is invoked once per skill (and twice per skill for OLD/NEW), the workflow ends up re-fetching the same large tree multiple times in a single run. Caching the tree per SHA within the run reduces API load and lowers the risk of rate-limit/timeout flakiness.
list_skill_files() {
local tree
# Fail (non-zero) on a fetch error, unparseable response, or a truncated tree — the caller
# aborts rather than treating an incomplete/untrusted listing as "no changes" (a silent miss).
tree=$(curl -sf "https://api.github.com/repos/${REPO}/git/trees/$1?recursive=1" \
…r skill PR review (Copilot, suppressed): list_skill_files downloaded the full recursive repo tree on every call — once per skill x OLD/NEW = 6 fetches for caffeinelabs/ skills, but only 2 unique trees. Split out fetch_tree() which caches each tree to /tmp/upstream-tree-<sha>.json (git trees are immutable per SHA, so caching is safe) and reads from it. Now 2 fetches per run instead of 6 — less API load and fewer transient-failure points (which now abort under the fail-fast change). Verified: happy path exit 1 (nested references/ diffed) with exactly 2 cache files; bogus SHA exit 3; same commit exit 0.
|
Re the suppressed comment on |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (2)
scripts/sync-upstream-check.sh:78
fetch_treecaches the Git Trees API response at a predictable, repo-agnostic path (/tmp/upstream-tree-${sha}.json). This can collide across different upstream repos that happen to share the same commit SHA, and it also risks leaving a partially-written cache file behind (which then won’t be refetched because it is non-empty). Use a per-run/per-repo cache directory (e.g.$RUNNER_TEMP) and write atomically via a temp file +mv.
local cache="/tmp/upstream-tree-${sha}.json"
if [ ! -s "$cache" ]; then
curl -sf "https://api.github.com/repos/${REPO}/git/trees/${sha}?recursive=1" \
-H "Authorization: Bearer $GH_TOKEN" > "$cache" || {
echo "ERROR: could not fetch git tree for ${REPO}@${sha}" >&2
.claude/CLAUDE.md:152
- The example says it “lists all files … in the upstream skill folder”, but the
git/trees/<SHA>?recursive=1request actually returns the full repo tree for that commit and the Python filters by prefix locally. Clarifying this avoids surprising readers about the API response size and potential rate limiting.
# List all files (recursively) in the upstream skill folder at a given commit.
# Recursive matters: some skills nest files (e.g. writing-motoko/references/*).
curl -s "https://api.github.com/repos/<org>/<repo>/git/trees/<SHA>?recursive=1" | \
python3 -c "import sys,json; p='<upstream-skill-path>/'; [print(e['path'][len(p):]) for e in json.load(sys.stdin).get('tree',[]) if e.get('type')=='blob' and e['path'].startswith(p)]"
… docs
PR review (Copilot, suppressed x2):
- fetch_tree cached at a repo-agnostic path and wrote in place, so a partial/
interrupted write could leave a non-empty-but-corrupt cache that [ -s ] then
trusts, and different repos sharing a SHA could collide. Now cache under
${RUNNER_TEMP:-/tmp}, key by repo+SHA, and write to a temp file + mv (atomic:
the cache is only ever complete or absent).
- CLAUDE.md manual snippet: clarify the Git Trees API returns the WHOLE repo
tree and the Python filters to the skill path locally (response-size/rate-limit
awareness).
Verified: happy path exit 1 with repo-scoped cache and no leftover .tmp; bogus
SHA exit 3 leaving no partial cache.
|
Both suppressed comments applied (f3e1204 review):
Both are our own content, so patched directly. |
Skill Validation ReportNo skill files were changed in this PR — validation skipped. |
Wires the upstream sync automation to the new Motoko upstream (
caffeinelabs/skills), which #345 switched us to. That repo publishes no releases, so this reworks the detection + docs from release-based to commit-based for it.mops-cli(caffeinelabs/mops) andstatic-site(dfinity/certified-assets) stay release-based and are untouched.Completes the second half of #327 (the skill migration was #345).
Changes
.github/workflows/sync-upstream.yml— replace thecheck-motokojob (which polledgh release viewon the retiredcaffeinelabs/motoko) withcheck-caffeinelabs-skills: it reads the pinned commit from.claude/upstream.md(thewriting-motokosection — all three skills share one pin), compares it to the upstream default-branch HEAD, and on drift opens an issue labelledupstream-skills(label already created). No tag/release resolution step needed.scripts/sync-upstream-check.sh— swap thecaffeinelabs/motokocase forcaffeinelabs/skills(upstream base pathskills/, three skill mappings:writing-motoko,migrating-motoko-actors,troubleshooting-motoko-migrations). Clarify that the label args are display-only (a release tag, or a short SHA for commit-tracked repos)..claude/CLAUDE.md— document the two tracking models (release-tracked vs commit-tracked), update the sync checklist, rewrite the "What icskills changes vs upstream" summary table (frontmatter transform,mops-clicross-ref,references/paths; drop the obsolete motoko-pitfalls /caffeinelabs/motoko#6156/6157row), and generalise the automated-detection section.Tested locally
No skill content changes;
npm run validategreen.Note
The local test showed upstream has already advanced (
writing-motoko0.1.3 → 0.1.5, plus more). So once this merges, the weekly job (or a manualworkflow_dispatch) will open anupstream-skillssync issue — that content sync is a separate follow-up, not this PR.🤖 Generated with Claude Code