Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 0 additions & 65 deletions .releaserc.json

This file was deleted.

170 changes: 170 additions & 0 deletions .releaserc.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
// SPDX-License-Identifier: Apache-2.0
//
// semantic-release configuration.
//
// This is an ESM (.mjs) config rather than .releaserc.json because the
// release-notes-generator needs a `writerOpts.transform` function to strip git
// trailers (e.g. `Signed-off-by:`) that the conventional-commits parser folds
// into `BREAKING CHANGE` notes. JSON cannot carry functions.
//
// This config defaults to a dry run as a fail-safe: the publishing plugins
// (@semantic-release/github, @semantic-release/git) and the exec verify/publish
// commands are only included when RELEASE_DRY_RUN=false. ci/release/run.sh opts
// in to a real release that way; every other invocation -- including a typo'd or
// forgotten env var -- stays harmless.
//
// The env var is needed on top of --dry-run because --dry-run alone is not
// enough: semantic-release still runs every plugin's verifyConditions step in
// dry-run mode (it skips only prepare, publish, addChannel, success and fail).
// @semantic-release/github's verifyConditions fails without a GITHUB_TOKEN, so
// the side-effecting plugins must be omitted entirely, not merely guarded by
// --dry-run, to allow a credential-free dry run.

import { createRequire } from "node:module";
import { pathToFileURL } from "node:url";

// Load the conventionalcommits preset. The release scripts run semantic-release
// via `npx -p ...`, which installs the preset alongside semantic-release in a
// temporary node_modules. A bare `import` here would resolve relative to this
// config file's directory (the repo, which has no node_modules) and fail, so
// fall back to resolving the preset relative to the running semantic-release
// binary (process.argv[1]). The plain import still covers local dev where the
// preset is installed alongside the project.
const loadPreset = async () => {
try {
return (await import("conventional-changelog-conventionalcommits")).default;
} catch {
const require = createRequire(pathToFileURL(process.argv[1]));
const resolved = pathToFileURL(
require.resolve("conventional-changelog-conventionalcommits")
).href;
return (await import(resolved)).default;
}
};
const conventionalcommits = await loadPreset();
Comment on lines +23 to +44

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure why the import handling is so complicated here. The examples in the documentation are much simpler, using static rather than dynamic imports, and more what I would expect for ESM imports.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dynamic import + fallback is unfortunately load-bearing given how we invoke the tool. The release scripts run semantic-release via npx -p …, which installs conventional-changelog-conventionalcommits into a temporary node_modules alongside the semantic-release binary. A bare static import from this config resolves relative to the config file's own directory (the repo root, which has no node_modules) and fails with ERR_MODULE_NOT_FOUND — so the catch re-resolves the preset relative to the running semantic-release binary (process.argv[1]). The static-import example in the docs assumes the preset is installed as a local devDependency, which isn't the case here.

This was ported from the spec repo but the explanatory comment got dropped in the port — I've restored it so the "why" lives next to the code.


// Git trailers that should never appear in the changelog or release notes.
const TRAILER_KEYS = [
"Signed-off-by",
"Co-authored-by",
"Co-developed-by",
"Reviewed-by",
"Acked-by",
"Tested-by",
"Reported-by",
"Suggested-by",
"Helped-by",
"Cc",
];
const TRAILER = new RegExp(`^(?:${TRAILER_KEYS.join("|")}):\\s`, "i");

// The conventional-commits parser ends a BREAKING CHANGE note only at a
// recognized reference (closes #..., fixes #...) or another note keyword, not
// at a git trailer -- so a trailing `Signed-off-by:` gets absorbed into the
// note text. Strip such trailing trailer lines.
const stripTrailers = (text) => {
if (!text) {
return text;
}

const lines = text.split("\n");
while (lines.length) {
const last = lines[lines.length - 1].trim();
if (last === "" || TRAILER.test(last)) {
lines.pop();
} else {
break;
}
}
return lines.join("\n");
};

const preset = await conventionalcommits();
const presetTransform = preset.writer.transform;
const dryRun = process.env.RELEASE_DRY_RUN !== "false";

export default {
branches: [
{ name: "+([0-9])?(.{+([0-9]),x}).x" },
{ name: "main" },
{ name: "next" },
{ name: "next-major" },
{ name: "beta", prerelease: true },
{ name: "alpha", prerelease: true },
],
preset: "conventionalcommits",
dryRun,
plugins: [
[
"@semantic-release/release-notes-generator",
{
// Only `transform` is overridden; the generator merges this over the
// preset's writer options, so templates/grouping/sorting are kept.
writerOpts: {
transform(commit, context) {
const out = presetTransform(commit, context);
if (out && Array.isArray(out.notes)) {
out.notes = out.notes.map((note) => ({
...note,
text: stripTrailers(note.text),
}));
}
return out;
},
},
},
],
[
"@semantic-release/commit-analyzer",
{
releaseRules: [{ breaking: true, release: "minor" }],
},
],
[
"@semantic-release/exec",
dryRun
? {}
: {
verifyConditionsCmd: "ci/release/verify.sh",
prepareCmd: "ci/release/prepare.sh ${nextRelease.version}",
publishCmd: "ci/release/publish.sh",
},
],
[
"@semantic-release/changelog",
{
changelogTitle: "Release Notes\n---",
changelogFile: "CHANGELOG.md",
},
],
...(dryRun
? []
: [
[
"@semantic-release/github",
{
assets: [
{
path: "native/libs/isthmus-macOS-latest",
name: "isthmus-macOS-${nextRelease.version}",
label: "Isthmus Native Image - macOS",
},
{
path: "native/libs/isthmus-ubuntu-latest",
name: "isthmus-ubuntu-${nextRelease.version}",
label: "Isthmus Native Image - Linux",
},
],
successComment: false,
},
],
[
"@semantic-release/git",
{
assets: ["gradle.properties", "CHANGELOG.md"],
message: "chore(release): ${nextRelease.version}",
},
],
]),
],
};
57 changes: 57 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,63 @@ Release Notes

## [0.95.0](https://github.com/substrait-io/substrait-java/compare/v0.94.0...v0.95.0) (2026-07-05)

### ⚠ BREAKING CHANGES

* **core:** remove deprecated Time, Timestamp, TimestampTZ types and literals (#950)
* **deps:** Protobuf bindings are now generated using the v4
protobuf libraries, released in March 2024. Ensure that dependent
projects also use the v4 protobuf-java libraries, and be aware of the
breaking changes within the protobuf-java APIs documented at
https://protobuf.dev/news/v26/#java-breaking-changes

### Features

* **core:** add Substrait dialect support ([#861](https://github.com/substrait-io/substrait-java/issues/861)) ([ff76c77](https://github.com/substrait-io/substrait-java/commit/ff76c771d37f644ee57c77c7db0eb061804126f5))
* **core:** remove deprecated Time, Timestamp, TimestampTZ types and literals ([#950](https://github.com/substrait-io/substrait-java/issues/950)) ([71b940f](https://github.com/substrait-io/substrait-java/commit/71b940f94fcd711603d1cfbafb9a2002ea5fd0f5))
* **isthmus:** map execution context variables to/from Calcite ([#976](https://github.com/substrait-io/substrait-java/issues/976)) ([08c2889](https://github.com/substrait-io/substrait-java/commit/08c2889e675bb51ef6b5d39b8c9ed1e3811a474b))

### Bug Fixes

* **core:** add compiled output to javadocImmutable classpath ([#953](https://github.com/substrait-io/substrait-java/issues/953)) ([1d3ea51](https://github.com/substrait-io/substrait-java/commit/1d3ea51537ee6b3e944ae6db96d014ef15e37c41))
* **core:** validate Plan.Root output name count ([#812](https://github.com/substrait-io/substrait-java/issues/812)) ([4bd6b69](https://github.com/substrait-io/substrait-java/commit/4bd6b69ce535098da82d1ae33d6e2cfd78c62e78))
* **isthmus:** avoid NPE from dangling correlations left by partial decorrelation ([fbf2930](https://github.com/substrait-io/substrait-java/commit/fbf2930ce575a47a643940f3f5bcd89474dab3cc))
* **isthmus:** handle LITERAL_AGG in aggregate conversion ([52a32ba](https://github.com/substrait-io/substrait-java/commit/52a32bad575da67031ddd4e44caddeef641b9ed5))
* **isthmus:** use reachability-metadata.json for native image build ([#979](https://github.com/substrait-io/substrait-java/issues/979)) ([a1e48c6](https://github.com/substrait-io/substrait-java/commit/a1e48c6b4d38b5ec8750b1918263c35bc1a83dc0))
* **isthmus:** use Substrait type system when building Calcite RelBuilder ([#973](https://github.com/substrait-io/substrait-java/issues/973)) ([b370df5](https://github.com/substrait-io/substrait-java/commit/b370df50b8f35e802be3e78d3e5f87303b2e7517)), closes [#954](https://github.com/substrait-io/substrait-java/issues/954) [#955](https://github.com/substrait-io/substrait-java/issues/955)

### Build System

* **deps:** update protobuf from v3 to v4 ([#962](https://github.com/substrait-io/substrait-java/issues/962)) ([1516209](https://github.com/substrait-io/substrait-java/commit/1516209dd1c6801082a4a04649b5da79af4e0a1b))

### ⚠ BREAKING CHANGES

* **core:** remove deprecated Time, Timestamp, TimestampTZ types and literals (#950)
* **deps:** Protobuf bindings are now generated using the v4
protobuf libraries, released in March 2024. Ensure that dependent
projects also use the v4 protobuf-java libraries, and be aware of the
breaking changes within the protobuf-java APIs documented at
https://protobuf.dev/news/v26/#java-breaking-changes

### Features

* **core:** add Substrait dialect support ([#861](https://github.com/substrait-io/substrait-java/issues/861)) ([ff76c77](https://github.com/substrait-io/substrait-java/commit/ff76c771d37f644ee57c77c7db0eb061804126f5))
* **core:** remove deprecated Time, Timestamp, TimestampTZ types and literals ([#950](https://github.com/substrait-io/substrait-java/issues/950)) ([71b940f](https://github.com/substrait-io/substrait-java/commit/71b940f94fcd711603d1cfbafb9a2002ea5fd0f5))
* **isthmus:** map execution context variables to/from Calcite ([#976](https://github.com/substrait-io/substrait-java/issues/976)) ([08c2889](https://github.com/substrait-io/substrait-java/commit/08c2889e675bb51ef6b5d39b8c9ed1e3811a474b))

### Bug Fixes

* **core:** add compiled output to javadocImmutable classpath ([#953](https://github.com/substrait-io/substrait-java/issues/953)) ([1d3ea51](https://github.com/substrait-io/substrait-java/commit/1d3ea51537ee6b3e944ae6db96d014ef15e37c41))
* **core:** validate Plan.Root output name count ([#812](https://github.com/substrait-io/substrait-java/issues/812)) ([4bd6b69](https://github.com/substrait-io/substrait-java/commit/4bd6b69ce535098da82d1ae33d6e2cfd78c62e78))
* **isthmus:** avoid NPE from dangling correlations left by partial decorrelation ([fbf2930](https://github.com/substrait-io/substrait-java/commit/fbf2930ce575a47a643940f3f5bcd89474dab3cc))
* **isthmus:** handle LITERAL_AGG in aggregate conversion ([52a32ba](https://github.com/substrait-io/substrait-java/commit/52a32bad575da67031ddd4e44caddeef641b9ed5))
* **isthmus:** use reachability-metadata.json for native image build ([#979](https://github.com/substrait-io/substrait-java/issues/979)) ([a1e48c6](https://github.com/substrait-io/substrait-java/commit/a1e48c6b4d38b5ec8750b1918263c35bc1a83dc0))
* **isthmus:** use Substrait type system when building Calcite RelBuilder ([#973](https://github.com/substrait-io/substrait-java/issues/973)) ([b370df5](https://github.com/substrait-io/substrait-java/commit/b370df50b8f35e802be3e78d3e5f87303b2e7517)), closes [#954](https://github.com/substrait-io/substrait-java/issues/954) [#955](https://github.com/substrait-io/substrait-java/issues/955)

### Build System

* **deps:** update protobuf from v3 to v4 ([#962](https://github.com/substrait-io/substrait-java/issues/962)) ([1516209](https://github.com/substrait-io/substrait-java/commit/1516209dd1c6801082a4a04649b5da79af4e0a1b))


## [0.94.0](https://github.com/substrait-io/substrait-java/compare/v0.93.0...v0.94.0) (2026-06-21)

### Features
Expand Down
22 changes: 9 additions & 13 deletions ci/release/dry_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,19 @@ trap cleanup EXIT ERR
cd "$worktree" || exit 1

export GITHUB_REF="$branch"
export RELEASE_DRY_RUN=true

npx --yes \
-p semantic-release \
-p "@semantic-release/commit-analyzer" \
-p "@semantic-release/release-notes-generator" \
-p "@semantic-release/changelog" \
-p "@semantic-release/exec" \
-p "@semantic-release/git" \
-p "conventional-changelog-conventionalcommits" \
-p "semantic-release@25.0.5" \
-p "@semantic-release/commit-analyzer@13.0.1" \
-p "@semantic-release/release-notes-generator@14.1.1" \
-p "@semantic-release/changelog@6.0.3" \
-p "@semantic-release/github@12.0.8" \
-p "@semantic-release/exec@7.1.0" \
-p "@semantic-release/git@10.0.1" \
-p "conventional-changelog-conventionalcommits@9.3.1" \
semantic-release \
--ci false \
--dry-run \
--preset conventionalcommits \
--plugins \
--analyze-commits "@semantic-release/commit-analyzer" \
--generate-notes "@semantic-release/release-notes-generator" \
--verify-conditions "@semantic-release/changelog,@semantic-release/exec,@semantic-release/git" \
--prepare "@semantic-release/changelog,@semantic-release/exec" \
--branches "$branch" \
--repository-url "file://$PWD"
18 changes: 9 additions & 9 deletions ci/release/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

set -euo pipefail

npx --yes \
-p semantic-release \
-p "@semantic-release/commit-analyzer" \
-p "@semantic-release/release-notes-generator" \
-p "@semantic-release/changelog" \
-p "@semantic-release/github" \
-p "@semantic-release/exec" \
-p "@semantic-release/git" \
-p "conventional-changelog-conventionalcommits" \
RELEASE_DRY_RUN=false npx --yes \
-p "semantic-release@25.0.5" \
-p "@semantic-release/commit-analyzer@13.0.1" \
-p "@semantic-release/release-notes-generator@14.1.1" \
-p "@semantic-release/changelog@6.0.3" \
-p "@semantic-release/github@12.0.8" \
-p "@semantic-release/exec@7.1.0" \
-p "@semantic-release/git@10.0.1" \
-p "conventional-changelog-conventionalcommits@9.3.1" \
semantic-release --ci
Loading