docs/RELEASING.md
Steps to publish a new Karate release. Replace X.Y.Z with the version being released.
TODO (before/with the next release that ships an ext): ext distribution + CLI v2-only. An ext has two delivery forms for two audiences: the Maven Central
io.karatelabs:karate-imagethin jar is for Java teams (declare it as a Maven/Gradle test dependency;karate-coreisprovided, engines come transitively) — this path already ships and is verified. Thekarate-image-X.Y.Z.jardrop-in fatjar (engines bundled) is for non-Java teams driving Karate via the Rust CLI. The deferred work below is only the CLI / non-Java side.For 2.0.10 we shipped core artifacts only and kept the
karate-image-X.Y.Z.jardrop-in local. (Drop-in jars are named per-ext:karate-image-X.Y.Z.jar,karate-max-X.Y.Z.jar, etc.) To ship the drop-in path properly we still need to:
- Switch the Rust CLI (
../karate-cli) to v2io.karatelabs.Mainonly — drop thecom.intuit.karate.Mainv1 shim support indelegate.rs.- Teach the CLI to load exts from the manifest (managed ext install), instead of the current manual
~/.karate/ext/drop-in only.- Likely a matching change in
../karate-vscode-v2.- Then per-release: attach
karate-ext-image-X.Y.Z.jarto the GitHub release, add akarate.shmanifest ext entry, and add a CI fatjar-build job (mvn package -pl karate-image -am -Pfatjar -DskipTests).
main is green on CIpom.xml (remove any -SNAPSHOT or .RC* suffix):
mvn versions:set -DnewVersion=X.Y.Z -DgenerateBackupPoms=false
[no ci] — main is already green and the Maven release job runs the full test suite). The vX.Y.Z tag is created later via the GitHub release UI, not from the CLI:
git add -A && git commit -m "release X.Y.Z [no ci]"
git push
The scan lives in its own workflow (.github/workflows/cve.yml), separate from the release. It is
deliberately not on the release path — an NVD scan can take hours and a release should not wait
on one, so the release does not block on CVEs. cve.yml is the gate: it fails on CVSS >= 9.0.
Trigger CVE & SBOM manually (workflow_dispatch) on main with version: X.Y.Z. The
input rewrites the pom inside the runner before the scan (nothing is pushed), so the report
header, the SBOM's own io.karatelabs:* component entries and the artifact name all agree on
X.Y.Z. Leave it blank — as the weekly schedule does — to scan the pom as-is. Can run in
parallel with step 3.
Expect minutes on a warm NVD cache, but 2+ hours on a cold one (the cache is keyed
nvd-db- and only a completed run saves it). If the wait is unacceptable, use the local
fallback below.
Download the cve-sbom-report-X.Y.Z artifact from the run — you want cve-sbom-report.html
Confirm the CVE Summary shows no active Critical (>= 9) rows. Criticals under
Suppressed are fine — those are declared false positives, see etc/cve-suppressions.xml
Local fallback — produces the identical report without waiting on CI:
mvn -B -ntp org.owasp:dependency-check-maven:13.0.0:check \
-DossIndexAnalyzerEnabled=false -DskipProvidedScope=true -DskipTestScope=true \
-DsuppressionFiles=etc/cve-suppressions.xml -Dformat=JSON
python3 etc/generate-cve-report.py --version X.Y.Z
The report lands at target/cve-sbom-report.html. Pass --version explicitly — unlike CI it does
not read the pom, and an omitted flag drops the version from the header entirely. Note it stamps
only the header: the SBOM's own io.karatelabs:* entries come from the jars on disk, so build
from a pom already at X.Y.Z if you need the two to agree.
If dep-check flags a false positive (a CVE for a same-named library in another ecosystem is
the usual culprit), add a rule to etc/cve-suppressions.xml rather than waving the release
through — the suppression is what makes the gate meaningful on the next run.
workflow_dispatch)X.Y.Z (must match the tag exactly), maven: enabled, tests: enabledkarate-release-X.Y.Z artifact — it holds karate-X.Y.Z.zip, which unzips to the
karate-X.Y.Z.jar fat jar you attach in step 4 Go to https://github.com/karatelabs/karate/releases/new and create tag vX.Y.Z on the release form (target: main) — this creates the tag as part of publishing the release
Set the release title to vX.Y.Z explicitly (must match the tag) — if left blank, the GitHub UI defaults the title to the most recent commit message
Write release notes following the template below — one-line bullets, issue refs at the end (e.g. #2843), milestone link, compare link, 2.0.0 migration note, then ### Artifacts. See v2.0.8 / v2.0.9 for reference renderings.
## ⚠️ Breaking Changes
* <one-line description of the behavior change AND the migration needed to keep old behavior, ending with the issue ref> #NNNN
* ...
## Important Fixes
* <one-line description of the fix, ending with the issue ref> #NNNN
* ...
## New Features & Enhancements
* <one-line description — issue ref optional, only when there's a tracking issue>
* ...
View the complete list of [all issues fixed in this release](https://github.com/karatelabs/karate/milestone/NN?closed=1).
**Full Changelog**: https://github.com/karatelabs/karate/compare/vPREVIOUS...vX.Y.Z
**Important**: refer [2.0.0 release notes](https://github.com/karatelabs/karate/releases/tag/v2.0.0) for those upgrading from 1.X
### Artifacts
* [Maven artifacts](https://central.sonatype.com/artifact/io.karatelabs/karate-core/X.Y.Z)
* [Standalone JAR](https://docs.karatelabs.io/getting-started/standalone-execution) (download below)
* CVE / SBOM report (download below)
Style notes:
Upload release assets (attach to the GitHub release):
karate-X.Y.Z.jar (fat jar — unzipped from the step 3 karate-release-X.Y.Z artifact)cve-sbom-report.html (from step 2 — if the scan is still running on a cold NVD cache,
publish the release without it and attach it when the run completes; the CVE report does
not block the release)X.Y.Z milestone, leaving a vX.Y.Z released comment on each (always — including issues already labeled fixed):
gh issue close <NUM> -R karatelabs/karate -c "vX.Y.Z released"
X.Y.ZThis is critical — the CLI installer pulls versions from this manifest.
karate-sh repo (sibling directory ../karate-sh)public/manifest.json:
karate artifacturl to the fat jar download URL on GitHub Releasessha256 from the release asset or compute locally:
shasum -a 256 karate-X.Y.Z.jar
stable channel from the previous version to the new onechannel_defaults.stable to point to X.Y.Zgenerated_at timestamp1.5.2 legacy anchor for v1 users. Drop everything else. The JARs stay on GitHub Releases either way; the manifest is just the installer's lookup index, so this only affects what karate.sh can resolve by version name.main (Netlify auto-deploys)curl -s https://karate.sh/manifest.json | jq '.channel_defaults.stable'../karate-sh/README.md for full manifest schema details../karate-template to use version X.Y.Z../karate-todo to use version X.Y.Z../karate-docs: bump the KARATE_VERSION constant in docusaurus.config.ts to
X.Y.Z — it is the single source for every @karate.version@ token in the .mdx content
(a markdown preprocessor stamps it into prose and code blocks at build time). Run
npm run build to verify, then commit and push to main (Netlify auto-deploys). Note the
v1→v2 migration snippets (migration-from-v1.mdx, the Nashorn answer in faq.mdx) are
deliberately anchored at 2.0.0 / 1.5.2 — leave those alone.TODO: Automate this step with CI/CD — a workflow that bumps the Karate version across all example projects and runs their tests.
../karate-examples — bump Karate version to X.Y.Z in all example pom.xml / build.gradle filespom.xml to the next RC version:
mvn versions:set -DnewVersion=X.Y.Z+1.RC1 -DgenerateBackupPoms=false
[no ci] to skip the CI build for this bump):
git add -A && git commit -m "prepare for next development iteration [no ci]"
git push