Publish Grails skills through SkillsJars - #15805
Conversation
Expose the canonical .agents/skills directory through a root skills symlink so SkillsJars can discover the existing skill definitions without duplicating files. Add a verification task and publishing notes for submitting the skills from skillsjars.com. Assisted-by: Hephaestus:openai/gpt-5.5 codex-review
There was a problem hiding this comment.
Pull request overview
This PR adds build-time verification and documentation to support publishing the repository’s agent skills via SkillsJars, using a root-level skills path intended for SkillsJars discovery.
Changes:
- Add a
verifySkillsJarsSourcesGradle verification task to validate theskillspublication path and presence ofSKILL.mdmarkers. - Exclude the
skillspath from Apache RAT scanning to avoid symlink/discovery-path complications. - Document the skills directory purpose and publishing workflow under
.agents/skills.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
gradle/rat-root-config.gradle |
Excludes skills discovery path from RAT audit inputs. |
build.gradle |
Adds verifySkillsJarsSources task to validate symlink target, git mode, and skill markers. |
.agents/skills/README.md |
Documents the canonical skills location and SkillsJars publishing/verification steps. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 8.0.x #15805 +/- ##
==================================================
- Coverage 49.4820% 49.4809% -0.0011%
+ Complexity 16698 16697 -1
==================================================
Files 1947 1947
Lines 92474 92474
Branches 16152 16152
==================================================
- Hits 45758 45757 -1
+ Misses 39610 39609 -1
- Partials 7106 7108 +2 🚀 New features to boost your workflow:
|
Limit the SkillsJars publication path to Grails skills useful for building or upgrading end-user applications. Keep internal Grails core development skills only under .agents/skills and expose the public skills through real skills directories containing SKILL.md symlinks to the canonical sources. Assisted-by: Hephaestus:openai/gpt-5.5 codex-review
|
Updated this PR to publish only the app-facing Grails skills:
The internal Grails core skills remain under |
✅ All tests passed ✅🏷️ Commit: fa7f03b Learn more about TestLens at testlens.app. |
|
Maintenance pass complete. Copilot generated no inline review comments, there are no review threads to resolve, Codecov/TestLens are green on the existing branch, and I reran ./gradlew.bat --no-daemon --no-parallel --max-workers=1 verifySkillsJarsSources locally. No code changes were needed. |
|
I dug into this more and I don't believe we can use SkillsJars - it's acting a publisher directly to maven central. This goes against the ASF voting rules. Has there been any discussion on the mailing lists about this problem? |
|
Follow-up on the ASF voting concern: this branch is still SkillsJars-based end to end. The changed files add verifySkillsJarsSources in build.gradle, expose skills/grails-developer and skills/grails-8-upgrade solely for SkillsJars discovery, and document com.skillsjars Maven Central coordinates in .agents/skills/README.md; the final search did not find a separate in-repo release path for these skill artifacts. Given that, we should not try to land this as-is. Proposed path: pause or close this PR, take the publish-to-Maven-Central and voting question to the dev list or Infra, and replace it with an ASF-controlled publication mechanism only if the project agrees on release and vote semantics. Until then, keeping the skills as source docs under .agents/skills avoids publishing artifacts outside the normal Apache release process. |
|
I dug into this, and the factual premise is correct for the PR as written - but there's a compliant path that still achieves the goal, so I don't think we have to abandon skill distribution. Why the objection holds for the current approach: the SkillsJars web service clones the repo, generates The compliant alternative (and I think what we actually want): build the skills jar in the So the fix is to swap the distribution mechanism: package + publish the skills through the ASF release pipeline (voted) rather than via the SkillsJars external publisher. I'll rework the PR along those lines. No prior dev@ thread found on this - I'll start one so the packaging/coordinates get consensus before we wire it into the release. |
|
I actually havea side branch that already publishes these as skill jars, i'm happy to push it too - but how do you consume it? |
|
FYI: I pushed my rework branch (this was a start, i didn't finish it once I saw that skilljars couldn't pull other jars): https://github.com/apache/grails-core/tree/rework/publish-grails-skills |
borinquenkid
left a comment
There was a problem hiding this comment.
Review
Overview: Exposes two app-facing skills (grails-developer, grails-8-upgrade) to the third-party SkillsJars discovery service via a new root-level skills/ directory, where each skill folder contains only a SKILL.md symlink back to the canonical .agents/skills/... source. Adds a verifySkillsJarsSources Gradle task to assert the published set and symlink integrity, and excludes the alias paths from RAT.
Code quality / correctness
- Symlink targets (
../../.agents/skills/<name>/SKILL.md) resolve correctly fromskills/<name>/SKILL.md. - The verification task's dual-mode target read (
Files.isSymbolicLinkvs. plain-file fallback) sensibly handles checkouts where symlinks degrade to text files. - Minor fragility:
expectedSkillTarget.substring(6)hardcodes the'../../'prefix length to locate the source file. Works today, but breaks silently (wrong path) if a target's depth ever changes. Resolving the path properly (e.g.Paths.get(...).resolve(target).normalize()) would be more robust than the magic-number substring.
Verification task isn't wired to check/CI
verifySkillsJarsSources is registered but not added as a dependency of check, build, or any GitHub Actions workflow — it's purely a manual, docs-invoked gate. If .agents/skills/grails-developer/SKILL.md is ever moved or renamed, the symlink breaks silently and CI stays green; nobody finds out until someone remembers to run the task by hand (or SkillsJars' scan quietly fails). Wiring this into check (or at least the RAT/CodeAnalysis job) would close that gap cheaply.
Test coverage
No automated test (e.g. Gradle TestKit) proves verifySkillsJarsSources actually fails when a symlink is broken/missing/wrong-target. Combined with the task not running in CI, the verification logic is currently unverified in both directions.
Governance note (not a code defect)
This introduces a new distribution channel: skill content sourced from apache/grails-core gets scanned and republished under com.skillsjars:apache__grails-core__* on Maven Central by a non-ASF third party. Nothing in the build itself talks to skillsjars.com (it's a manual post-merge submission per the new README), so there's no build-time supply-chain exposure — but worth an explicit maintainer/PMC nod that this publishing path is sanctioned, beyond code review (likely already implicit via #15454).
Suggested (non-blocking) actions
- Wire
verifySkillsJarsSourcesintocheckso drift is caught automatically instead of relying on someone remembering to run it. - Replace the
substring(6)prefix assumption with proper path resolution. - Confirm governance sign-off for the third-party publishing workflow.
Nothing here blocks the change — it's small, self-contained, and CI is green — but 1–2 are cheap hardening fixes and 3 is worth a one-line confirmation in the thread.
|
I do not think this should be in RC1. We should discuss this as I don't understand how publishing a skill jar is consumable by skill jars. From what I can tell, they have to publish. We need to discuss this one before going forward. |
|
Following up on the ASF publishing concern — I think there's a compromise that sidesteps it entirely rather than trying to find an ASF-compliant way to route through SkillsJars. The governance problem is coupled to SkillsJars specifically, not to distributing skills at all. Per @jdaugherty's finding on the rework branch, SkillsJars' own discovery/registry only indexes artifacts published through their scan-and-publish pipeline under Proposal: for This repo already has the exact mechanism for this, and it ships zero new files through any third-party service:
Why this is actually a better fit for Where this doesn't help — and I don't think we should pretend it does: Concretely, I'd propose:
Happy to put together the |
The Problem
SkillsJars discovers and publishes agent skills from a root-level
skills/**/SKILL.mdlayout. Grails keeps its canonical skill sources under.agents/skills, which SkillsJars does not scan by default - and that directory also contains framework-contributor-only skills that should not be published to application developers.The Fix
Expose only the app-facing Grails skills through the SkillsJars discovery path, without duplicating any content, while keeping contributor skills internal.
Published via root-level
skills/(real directories whoseSKILL.mdis a symlink to the canonical source):skills/grails-developer/SKILL.md->.agents/skills/grails-developer/SKILL.mdskills/grails-8-upgrade/SKILL.md->.agents/skills/grails-8-upgrade/SKILL.mdKept internal under
.agents/skillsonly:hibernate-developer,test-fixer,violation-fixer, and other core-contributor workflow skills.The change also:
SKILL.mdsymlinks so SkillsJars discovers normal skill folders;verifySkillsJarsSourcesGradle task asserting the exact published skill set, symlink targets, git mode120000, and canonical source markers;.agents/skills);How to publish after merge
Submit the SkillsJars form with GitHub Org
apacheand Repograils-core. SkillsJars shallow-clones the public repo, scansskills/**/SKILL.md, and publishes Maven Central artifacts undercom.skillsjars:com.skillsjars:apache__grails-core__grails-developer:<date>-<commit>com.skillsjars:apache__grails-core__grails-8-upgrade:<date>-<commit>Testing
./gradlew verifySkillsJarsSourcespasses;git diff --cached --checkclean../gradlew ratno longer reports theskills/**or tracked.claude/skills/**symlink aliases.Refs #15454