Release #19
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| workflow_run: | |
| workflows: ["Validate Skills"] | |
| types: [completed] | |
| branches: [main] | |
| concurrency: ${{ github.workflow }}-${{ github.ref }} | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| id-token: write | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event.workflow_run.conclusion == 'success' }} | |
| outputs: | |
| published: ${{ steps.changesets.outputs.published }} | |
| publishedPackages: ${{ steps.changesets.outputs.publishedPackages }} | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| registry-url: https://registry.npmjs.org | |
| - run: npm ci | |
| - name: Build skills.zip | |
| run: npm run build | |
| - name: Create Release PR or Publish | |
| id: changesets | |
| uses: changesets/action@6a0a831ff30acef54f2c6aa1cbbc1096b066edaf # v1 | |
| with: | |
| publish: npx changeset publish --provenance | |
| title: "chore: version packages" | |
| commit: "chore: version packages" | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| NPM_CONFIG_PROVENANCE: true | |
| - name: Upload skills.zip as release asset | |
| if: steps.changesets.outputs.published == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| TAG="v${VERSION}" | |
| # Create GitHub release with skills.zip if tag exists | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| gh release upload "$TAG" dist/skills.zip --clobber | |
| echo "Uploaded skills.zip to release $TAG ✅" | |
| else | |
| gh release create "$TAG" dist/skills.zip --generate-notes | |
| echo "Created release $TAG with skills.zip ✅" | |
| fi | |
| - name: Register skills on skills.sh | |
| if: steps.changesets.outputs.published == 'true' | |
| run: | | |
| npx -y skills add marcfargas/skills --full-depth --all 2>&1 || echo "⚠️ skills.sh registration failed (non-blocking)" | |
| echo "skills.sh registration done ✅" | |
| verify-publish: | |
| runs-on: ubuntu-latest | |
| needs: release | |
| if: needs.release.outputs.published == 'true' | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: 24 | |
| - name: Wait for npm registry propagation | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "Waiting for @marcfargas/skills@${VERSION} to appear on npm..." | |
| for i in $(seq 1 30); do | |
| if npm view "@marcfargas/skills@${VERSION}" version 2>/dev/null; then | |
| echo "Package available on npm ✅" | |
| exit 0 | |
| fi | |
| echo " Attempt $i/30 — waiting 10s..." | |
| sleep 10 | |
| done | |
| echo "❌ Package not found on npm after 5 minutes" | |
| exit 1 | |
| - name: Verify skills add — default discovery from npm | |
| run: | | |
| set -e | |
| echo "=== Default: npx skills add marcfargas/skills --list ===" | |
| export HOME=$(mktemp -d) | |
| DEFAULT_OUTPUT=$(npx -y skills add marcfargas/skills --list 2>&1) || true | |
| echo "$DEFAULT_OUTPUT" | |
| DEFAULT_COUNT=$(echo "$DEFAULT_OUTPUT" | grep -oP 'Found \K[0-9]+' || echo "0") | |
| echo "Default discovery: $DEFAULT_COUNT skill(s)" | |
| echo "" | |
| echo "=== Full-depth: npx skills add marcfargas/skills --list --full-depth ===" | |
| FULL_OUTPUT=$(npx -y skills add marcfargas/skills --list --full-depth 2>&1) || true | |
| echo "$FULL_OUTPUT" | |
| FULL_COUNT=$(echo "$FULL_OUTPUT" | grep -oP 'Found \K[0-9]+' || echo "0") | |
| echo "Full-depth discovery: $FULL_COUNT skill(s)" | |
| echo "Discovery baseline from npm captured ✅" | |
| - name: Verify skills add — install all from npm | |
| run: | | |
| set -e | |
| export HOME=$(mktemp -d) | |
| OUTPUT=$(npx -y skills add marcfargas/skills --full-depth --all 2>&1) || true | |
| echo "$OUTPUT" | |
| SKILL_NAMES=$(find . -name SKILL.md -not -path './.changeset/*' -not -path '*/node_modules/*' | while read f; do | |
| sed -n '/^---$/,/^---$/p' "$f" | grep '^name:' | head -1 | sed 's/^name:\s*//' | |
| done) | |
| FAILED=0 | |
| for name in $SKILL_NAMES; do | |
| if echo "$OUTPUT" | grep -qi "$name"; then | |
| echo " ✅ $name installed from npm" | |
| else | |
| echo " ❌ $name NOT found" | |
| FAILED=1 | |
| fi | |
| done | |
| if [ "$FAILED" -eq 1 ]; then | |
| echo "⚠️ Some skills not detected in output (may be CLI limitation)" | |
| fi | |
| echo "npm install smoke test done ✅" | |
| - name: Verify skills add — each skill individually from npm | |
| run: | | |
| set -e | |
| SKILL_NAMES=$(find . -name SKILL.md -not -path './.changeset/*' -not -path '*/node_modules/*' | while read f; do | |
| sed -n '/^---$/,/^---$/p' "$f" | grep '^name:' | head -1 | sed 's/^name:\s*//' | |
| done) | |
| FAILED=0 | |
| for name in $SKILL_NAMES; do | |
| export HOME=$(mktemp -d) | |
| OUTPUT=$(npx -y skills add marcfargas/skills --skill "$name" --full-depth --all 2>&1) || true | |
| if echo "$OUTPUT" | grep -qi "$name"; then | |
| echo " ✅ skills add --skill $name (from npm)" | |
| else | |
| echo " ❌ skills add --skill $name FAILED (from npm)" | |
| echo "$OUTPUT" | tail -5 | |
| FAILED=1 | |
| fi | |
| done | |
| if [ "$FAILED" -eq 1 ]; then | |
| echo "❌ Some individual skill installs from npm failed" | |
| exit 1 | |
| fi | |
| echo "All individual skill installs from npm verified ✅" |