Skip to content

Commit 350c86b

Browse files
authored
Merge pull request #61 from adobe/skill-release-workflow
feat: add per-skill semantic-release workflow
2 parents fccf6a7 + 33598bb commit 350c86b

72 files changed

Lines changed: 7749 additions & 21 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release.yml

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
name: Release Skills
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: write
9+
issues: write
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
# Skip release commits to avoid infinite loops
15+
if: "!contains(github.event.head_commit.message, '[skip ci]')"
16+
steps:
17+
- uses: actions/checkout@v6
18+
with:
19+
fetch-depth: 0
20+
# Use a token with push access so commits from semantic-release trigger CI
21+
token: ${{ secrets.GITHUB_TOKEN }}
22+
23+
- uses: actions/setup-node@v4
24+
with:
25+
node-version: 20
26+
cache: npm
27+
28+
- name: Install dependencies
29+
run: npm ci
30+
31+
- uses: tesslio/setup-tessl@v2
32+
with:
33+
token: ${{ secrets.TESSL_TOKEN }}
34+
35+
- name: Detect changed skills
36+
id: detect
37+
run: |
38+
# Compare HEAD with its parent to find what changed in this push
39+
CHANGED_FILES=$(git diff --name-only ${{ github.event.before }}..${{ github.sha }} 2>/dev/null || git diff --name-only HEAD)
40+
41+
# Build list of all skill directories (parents of SKILL.md)
42+
ALL_SKILL_DIRS=$(find skills -name SKILL.md -exec dirname {} \; | sort)
43+
44+
# For each changed file, find which skill directory it belongs to
45+
DIRS=""
46+
for changed_file in $CHANGED_FILES; do
47+
for skill_dir in $ALL_SKILL_DIRS; do
48+
case "$changed_file" in
49+
"$skill_dir"/*)
50+
# Check not already added
51+
case " $DIRS " in
52+
*" $skill_dir "*) ;;
53+
*) DIRS="$DIRS $skill_dir" ;;
54+
esac
55+
break
56+
;;
57+
esac
58+
done
59+
done
60+
61+
DIRS=$(echo "$DIRS" | xargs) # trim whitespace
62+
63+
if [ -z "$DIRS" ]; then
64+
echo "skip=true" >> "$GITHUB_OUTPUT"
65+
echo "No skill directories changed."
66+
else
67+
echo "skip=false" >> "$GITHUB_OUTPUT"
68+
echo "dirs=$DIRS" >> "$GITHUB_OUTPUT"
69+
echo "Changed skills: $DIRS"
70+
fi
71+
72+
- name: Release changed skills
73+
if: steps.detect.outputs.skip != 'true'
74+
env:
75+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76+
TESSL_TOKEN: ${{ secrets.TESSL_TOKEN }}
77+
run: |
78+
PASS=0
79+
FAIL=0
80+
SKIP=0
81+
SUMMARY_ROWS=""
82+
83+
for skill_dir in ${{ steps.detect.outputs.dirs }}; do
84+
SKILL_NAME=$(basename "$skill_dir")
85+
86+
# Each skill needs a package.json for semantic-release-monorepo
87+
if [ ! -f "$skill_dir/package.json" ]; then
88+
echo "::warning::$skill_dir has no package.json — skipping release"
89+
SKIP=$((SKIP + 1))
90+
SUMMARY_ROWS="${SUMMARY_ROWS}| ${SKILL_NAME} | skipped (no package.json) | ⏭️ |\n"
91+
continue
92+
fi
93+
94+
echo "::group::Releasing $SKILL_NAME"
95+
96+
EXIT_CODE=0
97+
(cd "$skill_dir" && npx semantic-release -e semantic-release-monorepo) || EXIT_CODE=$?
98+
99+
echo "::endgroup::"
100+
101+
if [ "$EXIT_CODE" -ne 0 ]; then
102+
echo "::error::Release failed for $SKILL_NAME (exit code $EXIT_CODE)"
103+
FAIL=$((FAIL + 1))
104+
SUMMARY_ROWS="${SUMMARY_ROWS}| ${SKILL_NAME} | failed | ❌ |\n"
105+
else
106+
PASS=$((PASS + 1))
107+
SUMMARY_ROWS="${SUMMARY_ROWS}| ${SKILL_NAME} | released | ✅ |\n"
108+
fi
109+
done
110+
111+
TOTAL=$((PASS + FAIL + SKIP))
112+
113+
{
114+
echo "## Skill Releases"
115+
echo ""
116+
echo "| Skill | Result | Status |"
117+
echo "|-------|--------|--------|"
118+
echo -e "$SUMMARY_ROWS"
119+
echo "| **Total** | **$PASS released, $SKIP skipped, $FAIL failed** | $([ "$FAIL" -eq 0 ] && echo '✅' || echo '❌') |"
120+
} >> "$GITHUB_STEP_SUMMARY"
121+
122+
echo ""
123+
echo "============================="
124+
echo " Skill Release Summary"
125+
echo "============================="
126+
echo " Released: $PASS"
127+
echo " Skipped: $SKIP"
128+
echo " Failed: $FAIL"
129+
echo "============================="
130+
131+
if [ "$FAIL" -gt 0 ]; then
132+
echo "::error::$FAIL skill(s) failed to release"
133+
exit 1
134+
fi
135+

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ node_modules/
1111

1212
# Temporary files
1313
drafts/tmp/
14+
15+
# Release artifacts
16+
*.skill
17+
dist/

.releaserc.base.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"branches": ["main"],
3+
"plugins": [
4+
"@semantic-release/commit-analyzer",
5+
"@semantic-release/release-notes-generator",
6+
[
7+
"@semantic-release/changelog",
8+
{
9+
"changelogFile": "CHANGELOG.md"
10+
}
11+
],
12+
[
13+
"@semantic-release/exec",
14+
{
15+
"prepareCmd": "bash \"${GITHUB_WORKSPACE:-$(git rev-parse --show-toplevel)}/scripts/prepare-release.sh\" \"$PWD\" \"${nextRelease.version}\""
16+
}
17+
],
18+
[
19+
"@semantic-release/github",
20+
{
21+
"assets": [
22+
{
23+
"path": "*.skill",
24+
"label": "Skill package"
25+
}
26+
]
27+
}
28+
],
29+
[
30+
"@semantic-release/exec",
31+
{
32+
"publishCmd": "if [ -f tile.json ]; then tessl skill publish . --workspace adobe; fi"
33+
}
34+
],
35+
[
36+
"@semantic-release/git",
37+
{
38+
"assets": ["CHANGELOG.md", "SKILL.md"],
39+
"message": "chore(release): ${nextRelease.gitTag} [skip ci]"
40+
}
41+
]
42+
]
43+
}
44+

0 commit comments

Comments
 (0)