From 2595b4cb36184bdd40f8f396811688734ab593cf Mon Sep 17 00:00:00 2001 From: Kaan Kacar Date: Mon, 29 Jun 2026 17:50:36 +0300 Subject: [PATCH 1/2] Prepare v1.2.0 for agent-skills discovery - plugin.json + marketplace.json: 1.1.1 -> 1.2.0 (first pinnable release) - smart-contracts: fix frontmatter name (soroban -> smart-contracts); the directory was renamed in #32 but the name field was missed - add release workflow: on a vX.Y.Z tag, bundle multi-file skills as .tar.gz release assets and emit per-skill sha256 digests, so the Agent Skills discovery index (stellar-docs#2440) can pin stable hashes. Archives are release-only assets, never committed to the tree. --- .claude-plugin/marketplace.json | 3 +- .claude-plugin/plugin.json | 2 +- .github/workflows/release.yml | 68 +++++++++++++++++++++++++++++++++ skills/smart-contracts/SKILL.md | 2 +- 4 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index bc7cf7f..a1b5613 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -9,7 +9,8 @@ { "name": "stellar-dev", "source": "./", - "description": "Skills for modern Stellar development" + "description": "Skills for modern Stellar development", + "version": "1.2.0" } ] } diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 76c412b..afa3ed9 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "stellar-dev", "description": "End-to-end Stellar development: smart contracts (Rust, soroban-sdk), stellar-sdk (JS/Python/Go), RPC/Horizon APIs, Stellar Assets, wallet integration, testing, security, and ecosystem", - "version": "1.1.1", + "version": "1.2.0", "author": { "name": "Stellar Development Foundation" }, diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6df94e0 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,68 @@ +name: Release skill archives + +# On a version tag (e.g. v1.2.0), bundle every multi-file skill as a +# `.tar.gz` and attach it to the GitHub Release as an asset. The +# tarballs are NOT committed to the repo — they exist only as release +# assets, so the source tree stays clean. Their stable download URLs and +# SHA-256 digests feed the Agent Skills discovery index (RFC v0.2.0), +# published from stellar-docs (PR #2440). +# +# A skill is bundled iff its directory holds files beyond SKILL.md: the +# RFC requires multi-file skills be distributed as `type: archive`, while +# single-file skills are referenced directly as `type: skill-md`. + +on: + push: + tags: + - "v*" + workflow_dispatch: + inputs: + tag: + description: "Existing tag to (re)build archives for, e.g. v1.2.0" + required: true + +permissions: + contents: write + +jobs: + archives: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.tag || github.ref_name }} + + - name: Bundle multi-file skills and compute digests + run: | + set -euo pipefail + mkdir -p dist + : > dist/skills-digests.txt + for d in skills/*/; do + slug=$(basename "$d") + [ -f "${d}SKILL.md" ] || continue + companions=$(find "$d" -type f ! -name SKILL.md | wc -l | tr -d ' ') + if [ "$companions" -gt 0 ]; then + # SKILL.md at the archive root, no wrapper directory (RFC requirement). + tar -czf "dist/$slug.tar.gz" -C "$d" . + digest=$(sha256sum "dist/$slug.tar.gz" | awk '{print $1}') + printf '%s\tarchive\tsha256:%s\n' "$slug" "$digest" >> dist/skills-digests.txt + else + digest=$(sha256sum "${d}SKILL.md" | awk '{print $1}') + printf '%s\tskill-md\tsha256:%s\n' "$slug" "$digest" >> dist/skills-digests.txt + fi + done + echo "Per-skill artifact digests:" + cat dist/skills-digests.txt + + - name: Attach archives + digest manifest to the release + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + TAG="${{ github.event.inputs.tag || github.ref_name }}" + gh release view "$TAG" >/dev/null 2>&1 || \ + gh release create "$TAG" --title "$TAG" \ + --notes "Skill archives for Agent Skills discovery (RFC v0.2.0). Multi-file skills are bundled as .tar.gz; skills-digests.txt lists the sha256 of each skill artifact (tarball for archives, SKILL.md for single-file skills)." + # --clobber so re-runs replace assets in place. + archives=$(ls dist/*.tar.gz 2>/dev/null || true) + gh release upload "$TAG" $archives dist/skills-digests.txt --clobber diff --git a/skills/smart-contracts/SKILL.md b/skills/smart-contracts/SKILL.md index b7038d2..8b94146 100644 --- a/skills/smart-contracts/SKILL.md +++ b/skills/smart-contracts/SKILL.md @@ -1,5 +1,5 @@ --- -name: soroban +name: smart-contracts description: Stellar smart contract development (Rust, soroban-sdk). Entry point with project setup, contract anatomy, and build/deploy workflow, routing to three companion files in this directory — development.md (storage, auth, cross-contract calls, events, errors, upgrades, factories, troubleshooting), testing.md (unit, fuzz, property, fork, mutation, integration), and security.md (vulnerability classes, checklists, tooling, audits). Use when writing, testing, securing, or shipping Stellar smart contracts (formerly branded Soroban). user-invocable: true argument-hint: "[contract task]" From 011ae7064cccc066d29d1fcdd56a84486ac77d50 Mon Sep 17 00:00:00 2001 From: Kaan Kacar Date: Mon, 29 Jun 2026 18:01:57 +0300 Subject: [PATCH 2/2] release workflow: build reproducible skill archives Address PR review: tar -czf embeds per-entry mtime/uid/gid and gzip embeds a timestamp, so re-running the release for a tag would yield a different digest and could clobber an already-published asset's hash. Build with fixed mtime/ownership, sorted entries, and gzip -n so re-runs are byte-identical and the digest is verifiable by rebuilding from the tag. --- .github/workflows/release.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6df94e0..faa57a0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,11 @@ jobs: companions=$(find "$d" -type f ! -name SKILL.md | wc -l | tr -d ' ') if [ "$companions" -gt 0 ]; then # SKILL.md at the archive root, no wrapper directory (RFC requirement). - tar -czf "dist/$slug.tar.gz" -C "$d" . + # Reproducible bytes (fixed mtime/ownership, sorted entries, gzip -n) + # so re-runs are idempotent and the digest is verifiable from the tag. + tar --sort=name --format=gnu --mtime='@0' \ + --owner=0 --group=0 --numeric-owner \ + -C "$d" -cf - . | gzip -n -9 > "dist/$slug.tar.gz" digest=$(sha256sum "dist/$slug.tar.gz" | awk '{print $1}') printf '%s\tarchive\tsha256:%s\n' "$slug" "$digest" >> dist/skills-digests.txt else