| name | ship |
| description | Use when releasing a new version of the RIDDL IntelliJ IDEA plugin, or when the user says "ship", "cut a release", or "publish to the marketplace" in this repository. |
Ship Skill
Executes a full release cycle for the RIDDL IntelliJ IDEA plugin.
Follow each step in order. STOP immediately if any assertion
fails and report the problem.
This plugin differs from the ossuminc library /ship skills in two
ways that matter:
- The version lives in
resources/META-INF/plugin.xml, not in
the git tag. sbt-dynver names the zip, but the Marketplace
reads <version> from the descriptor. Nothing patches it
automatically — if you only tag, the Marketplace publishes a
version labelled with the old number.
- The artifact is a plugin zip on JetBrains Marketplace, not a
jar on GitHub Packages. There is no
sbt publish here.
Arguments
The user should provide a version number (e.g. 0.11.0). If not
provided:
- Find the latest tag (not just what is reachable from HEAD):
git tag --sort=-v:refname | head -5
- See what changed:
git log --oneline <latest-tag>..HEAD
- Analyse per semver and recommend a version — present your
recommendation and let the user confirm or override. Do not ask
them to pick from a list.
First-Time Setup (once per plugin, by a human)
Skip this section if the plugin is already on the Marketplace.
Check with:
curl -s -o /dev/null -w "%{http_code}\n" \
https://plugins.jetbrains.com/api/plugins/intellij/com.ossuminc.riddl.plugins.idea
404 means it is not published yet and the steps below are required.
200 means setup is done — go to Pre-Flight Checks.
The first publication cannot be automated. JetBrains states
plainly: "The first plugin publication must always be uploaded
manually." Only after that can sbt publishPlugin target this
plugin ID.
- Sign in at https://plugins.jetbrains.com with a JetBrains
Account.
- Account menu -> Upload plugin. On first upload you must
accept the JetBrains Marketplace Developer Agreement and
create a vendor profile (use
ossuminc, matching
<vendor> in plugin.xml).
- Build the artifact and upload
target/RIDDL4IDEA-<VERSION>.zip.
Set licence to Apache-2.0 and add tags people would actually
search for. The 400 MB Marketplace limit is not a concern here —
the zip is around 20 MB.
- Wait for review. Every new plugin gets automated and manual
review, and it only becomes publicly visible after it passes.
JetBrains does not guarantee a timeframe; if there is no word
after 3–4 working days, email marketplace@jetbrains.com.
- Create the API token: Marketplace profile -> My Tokens tab ->
generate a permanent token. It looks like
perm:xxxxxxxx.
- Store it where sbt-idea-plugin looks — a file is preferable to an
env var since it is not exposed to every subprocess:
echo 'perm:YOUR_TOKEN' > ~/.ij-plugin-repo-token
chmod 600 ~/.ij-plugin-repo-token
Alternatively set IJ_PLUGIN_REPO_TOKEN. Without one,
sbt publishPlugin fails with "Plugin repo authorisation token
not set".
Common rejection causes worth pre-empting: a default/placeholder
logo, a vague name, a description with broken links or grammar
errors, missing licence disclosure, or collecting telemetry without
consent.
Pre-Flight Checks
-
Always ship from main. Confirm:
git branch --show-current
git pull origin main
-
Assert the working tree is clean:
git status --porcelain
If dirty, list the files and ask how to proceed. sbt-dynver
appends a -N-<hash>-<timestamp> suffix for a dirty tree, which
would end up in the zip filename.
-
Verify the tag does not already exist:
git tag -l <VERSION>
-
Confirm the Marketplace token is available (see First-Time
Setup) — otherwise the release will fail at the last step, after
the tag is already pushed:
ls ~/.ij-plugin-repo-token || echo "${IJ_PLUGIN_REPO_TOKEN:+set}"
Ship Steps
-
Update the plugin descriptor. This is the step that has no
analogue in the library ship skills, and skipping it silently
publishes a mislabelled release. In
resources/META-INF/plugin.xml:
- Set
<version> to <VERSION>.
- Prepend a
<h3><VERSION></h3> section to <change-notes>,
written for users — what they can now do, not commit
subjects. Trim the oldest entries so only the last few
versions remain.
- Check
<idea-version since-build="..."> is still right. Use
the branch number (e.g. 253), never a full build number,
or users on earlier builds of the same release cannot
install.
-
Verify formatting, tests and packaging all pass:
sbt clean scalafmtCheck Test/scalafmtCheck test packageArtifactZip
clean matters — a stale target/ can serve an old resolved
classpath to Test scope and produce a green run against the
wrong riddl version. See NOTEBOOK.md "Trap: stale target/".
-
Run the plugin verifier and report the findings to the user
before continuing:
sbt runPluginVerifier
cat target/verifier/reports/*/plugins/*/<VERSION>/verification-verdict.txt
The verdict line is what matters — it should start with
Compatible. build.sbt narrows failureLevels to genuine
blockers, so the task passing means no compatibility problems,
not that the report is empty. Read the counts of internal,
experimental, deprecated and scheduled-for-removal API usage out
of the verdict and report them: they are review material for the
Marketplace, and a rising count is a warning sign. As of 0.10.0
the baseline is 8 internal, 13 experimental, 8 deprecated and 12
scheduled-for-removal.
This does NOT prove the plugin runs on IDEA Community. The
verifier checks against the SDK the build targets, which is now
ideaIU. Since the move to the unified distribution, nothing in
the build or this check fails on an Ultimate-only API. To
actually verify Community, point pluginVerifierOptions'
overrideIDEs at an IC installation. Until that is wired up,
treat Community compatibility as unverified and review new
platform API use by hand.
-
Confirm the packaged descriptor carries the right version. The
zip filename comes from dynver and the descriptor does not, so
they can disagree:
Post-Release Verification
-
Confirm the GitHub release exists:
gh release view <VERSION>
-
Confirm the Marketplace accepted the upload — the new version
should appear (possibly pending review):
curl -s https://plugins.jetbrains.com/api/plugins/intellij/com.ossuminc.riddl.plugins.idea | head -c 400
-
git status to confirm a clean tree.
-
Update NOTEBOOK.md: move the shipped items out of "Changes
Since " and reset it for the next cycle.
-
Report a summary: version, commit SHA, release URL, verifier
findings, and Marketplace status.
If Something Fails
- Tests, formatting or packaging fail in step 6 — fix before
tagging. Nothing has been published yet.
- Verifier reports new problems in step 7 — report and let the
user decide. Do not silently proceed.
- Descriptor version is wrong in step 8 — redo step 5. Catching
it here is the entire point of that check.
- Tag pushed but publish fails in step 12 — do NOT delete the
pushed tag. Fix the token or network problem and re-run
sbt publishPlugin; it is idempotent for a given version.
- Marketplace rejects the upload — read the rejection email,
fix, bump to the next patch version and ship again. A rejected
version number cannot be reused.