Skip to content

fix(release): exclude relay symlink chains from source archive + guard it in prek#845

Merged
potiuk merged 2 commits into
apache:mainfrom
potiuk:feature/release-exclude-relay-symlinks
Jul 12, 2026
Merged

fix(release): exclude relay symlink chains from source archive + guard it in prek#845
potiuk merged 2 commits into
apache:mainfrom
potiuk:feature/release-exclude-relay-symlinks

Conversation

@potiuk

@potiuk potiuk commented Jul 12, 2026

Copy link
Copy Markdown
Member

Why

The 0.1.0-rc1 source archive was -1'd (binding) and the rc2 upload was
rejected by ATR with:

Extraction failed: symlink target outside extraction directory:
apache-magpie-0.1.0/.claude/skills/magpie-audit-finding-fix

Root cause: the committed agent-view relay dirs (.claude/skills/,
.github/skills/, .kiro/skills/) are symlink chains — each
magpie-<skill> link points at ../../.agents/skills/magpie-<skill>, which
is itself a symlink. A safe extractor (ATR's upload validator) refuses to
follow a symlink whose target is another symlink and reads it as escaping the
extraction dir, failing the whole upload.

What

  • .gitattributesexport-ignore the three relay dirs. Only the
    single-hop .agents/skills/* view (which points straight at real
    skills/* dirs) ships; it resolves cleanly for any extractor. .agents/
    stays in the release so the shipped links still resolve.
  • Repoint shipped references off the now-excluded relay view:
    projects/_template/*.md links and tools/spec-loop/specs/* test -f
    paths now use .agents/skills/*.
  • New symlink-lint --archive rule + symlink-lint-archive prek hook
    builds the source archive exactly as the release does (git archive --worktree-attributes of the staged tree, honouring export-ignore) and
    fails the commit on any symlink chain or dangling link. This is what breaks
    an RC upload; the hook now catches it before an RC is cut. release-verify-rc
    already re-checks the same property against the unpacked tarball.

Verification

Built the archive from this branch:

  • 69 symlinks, all .agents/skills/* single-hop → real dirs
  • 0 chains, 0 dangling, 0 .pyc/__pycache__
  • symlink-lint, skill-and-tool-validate, spec-validate all pass

New pytest cases lock rule 3 (chain flagged, export-ignored chain clean,
dangling flagged, --archive exit codes).

Tester added 2 commits July 12, 2026 22:18
…rchive

ATR's upload validator rejects the .claude/skills / .github/skills /
.kiro/skills relay symlinks (they chain through .agents/skills/*, which a
safe extractor reads as a target outside the entry). Export-ignore the
relay dirs, keep the single-hop .agents/skills/* view (resolves to real
skills/*), and repoint the template + spec references from .claude/skills
to .agents/skills so they resolve in the archive.
…symlinks

The 0.1.0-rc1/rc2 uploads were -1'd / rejected because the source archive
carried symlink *chains*: the .claude/.github/.kiro relay dirs point at
.agents/skills/*, which are themselves symlinks. ATR's upload validator
refuses a symlink whose target is itself a symlink ("target outside
extraction directory"), so the whole upload failed.

Add a third symlink-lint rule (`--archive`) that builds the source archive
exactly as the release does (git archive --worktree-attributes of the
staged tree, honouring .gitattributes export-ignore) and rejects any
symlink a safe extractor refuses:

  - chain    — target is itself a symlink (the ATR rejection)
  - dangling — target got export-ignored, orphaning the link

Wire it as the `symlink-lint-archive` prek hook, fired whenever
.gitattributes, an agent-view skills/ tree, skills/, or
projects/_template/ changes — the inputs that shape the archive — so a
regression fails the commit before an RC is ever cut. release-verify-rc
still re-checks the same property against the unpacked tarball.
@potiuk potiuk merged commit 3892332 into apache:main Jul 12, 2026
9 checks passed
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.

1 participant