Skip to content

Prepare the 0.1.0 release and API compatibility gate - #43

Merged
juherr merged 2 commits into
mainfrom
juherr/finir-milestone-5
Jul 25, 2026
Merged

Prepare the 0.1.0 release and API compatibility gate#43
juherr merged 2 commits into
mainfrom
juherr/finir-milestone-5

Conversation

@juherr

@juherr juherr commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • define and document the supported API boundary for the 0.x series
  • enforce source and binary compatibility with Revapi after the first baseline becomes available
  • prepare all public modules and human-facing notes for the 0.1.0 release
  • add a protected, resumable Maven Central publication workflow with signed tag finalization

Release behavior

The manually dispatched workflow only runs from main and uses the protected maven-central
environment. It validates the requested version, changelog, signing key, release bundle, artifact
inventory, and an isolated Maven consumer before publishing with autoPublish=true. After Maven
Central reports the deployment as published and all public GAVs resolve, a separate job creates or
verifies the signed tag and GitHub Release.

The workflow is intentionally safe to resume: an existing tag or release is accepted only when it
matches the published commit.

API compatibility

Revapi compares every module with the latest final release and tolerates the missing baseline only
before 0.1.0 exists. Internal packages, generated provider implementations, OCPI support code, and
SecureXmlSource are excluded from the compatibility commitment. Compatibility exceptions require
an exact difference, a Migration: justification, and the same migration in CHANGELOG.md.

Validation

  • ./scripts/verify.sh
  • ./mvnw revapi:validate-configuration
  • ./mvnw -Prelease -Dgpg.skip=true -DskipTests package
  • local GPG-signed Central bundle: 28 public artifacts verified with POMs, main artifacts, sources,
    Javadocs, signatures, and MD5/SHA-1/SHA-256/SHA-512 checksums
  • isolated Maven consumer against the extracted bundle
  • actionlint, zizmor, mdbook-lint, and offline Lychee checks
  • temporary-baseline tests proving supported API breaks fail, internal changes are ignored, and an
    explicitly justified exception is accepted

Follow-up

This PR tracks #12 and #14 but must not close them yet. After merge, run the release workflow from
main, verify Maven Central, the signed tag, and the GitHub Release, then open the separate
0.2.0-SNAPSHOT post-release PR with an empty Unreleased section.

Summary by CodeRabbit

  • New Features

    • Released datex4j 0.1.0, a modular Java 21 SDK for reading, writing, validating, and converting DATEX II publications.
    • Delivered generated DATEX II and OCPI models, version-neutral XML/JSON support, validation facades, plus domain builders/helpers.
    • Published Maven Central artifacts for supported modules.
  • Documentation

    • Added comprehensive API compatibility guidance, supported API boundaries, upgrade expectations, and known limitations.
  • Release Process

    • Improved the Maven Central release workflow with automated API-compatibility checks and post-publication smoke validation.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1a8ac36a-7f47-497e-be1c-c6f5ab551046

📥 Commits

Reviewing files that changed from the base of the PR and between 853289a and ecee683.

📒 Files selected for processing (2)
  • .github/workflows/release.yml
  • scripts/build-central-bundle.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/build-central-bundle.sh
  • .github/workflows/release.yml

📝 Walkthrough

Walkthrough

The PR prepares the 0.1.0 release by defining API compatibility enforcement, aligning Maven modules to the release version, adding Central bundle tooling and signed publication automation, and updating release documentation, notes, and consumer smoke tests.

Changes

API Compatibility and Release Governance

Layer / File(s) Summary
Revapi compatibility enforcement
pom.xml, config/revapi/revapi.json, config/revapi/accepted-differences.json, scripts/verify-revapi-allowlist.sh, scripts/verify.sh, docs/api-compatibility.md, CONTRIBUTING.md
Revapi configuration runs during verify against a RELEASE baseline with filter/transform rules; the empty allowlist enforces that any accepted differences must include Migration: justifications tracked in CHANGELOG.md; public API surface (facades, builders, model generations, mapping APIs) versus implementation details (internal packages, SPI providers, SecureXmlSource) are documented.
API surface markers and documentation
datex4j-json/src/main/java/.../internal/*.java, datex4j-model/src/main/java/..., datex4j-ocpi/src/main/java/..., datex4j-xml/src/main/java/DatexXmlSource.java
Internal JSON classes (DatexEnumJson, DatexPrefixes, GAttributes, MultilingualStringJson, SubstitutionJson) transition from public to package-private; all model SPI packages (v2.0 through v3.7) receive package-info documentation directing consumers to the high-level DatexModelProvider; an AggregateMarker and root package-info document the model aggregate's role; OCPI mapping/support and XML implementation-detail packages are formally marked unsupported.
Release documentation and guidance
docs/api-compatibility.md, docs/README.md, README.md, CONTRIBUTING.md
New API compatibility policy page and updated contribution/README guidance direct users and contributors to the documented API boundary and release procedures.

Release Artifact Alignment and Publishing Infrastructure

Layer / File(s) Summary
0.1.0 Maven coordinates
pom.xml, datex4j-*/pom.xml, examples/pom.xml
All module POM parent versions and direct versions transition from 0.1.0-SNAPSHOT to 0.1.0; build properties add RevAPI and Central publishing configuration.
Maven Central bundle assembly and verification
config/release/public-artifacts.txt, scripts/build-central-bundle.sh, scripts/verify-central-bundle.sh, scripts/git-gpg-wrapper.sh
A manifest file enumerates 29 public artifacts (POM, model, core, domain, JSON, validation, OCPI, XML, location modules plus BOM and builders); build-central-bundle.sh stages each artifact's .pom, conditionally stages .jar/-sources.jar/-javadoc.jar, copies GPG signatures, generates MD5/SHA1/SHA256/SHA512 checksums, and packages into a ZIP; verify-central-bundle.sh extracts, validates payload/signature presence, verifies signatures via GPG, checks checksums against computed digests, and compares actual versus expected artifact inventory; a GPG wrapper script enforces passphrase file environment setup.
Manual Maven Central release workflow
.github/workflows/release.yml, config/release-smoke/pom.xml, config/release-smoke/src/test/java/dev/juherr/datex4j/release/PublishedConsumerTest.java
A manually dispatched GitHub workflow accepts a version input and runs only on main; the publish job validates release inputs (version format, changelog/release-notes presence, Revapi allowlist consistency, Central/GPG credentials), verifies local signing capability via a create/verify/delete cycle, checks that any existing remote tag matches the current commit, builds a local Central bundle, validates the bundle, runs an isolated consumer smoke test against the staged bundle, publishes to Maven Central (skipping deployment if artifacts already exist), waits for published POMs to resolve, and runs a final consumer test; the finalize job creates or verifies the signed annotated tag and creates or verifies the GitHub Release; an isolated PublishedConsumerTest uses ServiceLoader to verify only DatexVersion.V3_7 is exposed and constructs a DatexXml.builder() without throwing.
Release metadata and notes
.github/release-notes/0.1.0.md, CHANGELOG.md, README.md
Release notes introduce the initial modular SDK scope, list delivered DATEX II and OCPI model artifacts, provide Maven dependency instructions, and note known limitations; changelog adds a 0.1.0 section dated 2026-07-25 with entries for the API compatibility boundary and publication workflow; README updates the project status version and BOM example to 0.1.0, and adds an API compatibility documentation link.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseOperator
  participant PublishJob
  participant LocalBundle
  participant MavenCentral
  participant FinalizeJob
  participant GitHubRelease
  ReleaseOperator->>PublishJob: dispatch workflow with version=0.1.0
  PublishJob->>PublishJob: validate inputs, changelog, Revapi allowlist
  PublishJob->>PublishJob: verify signing capability (create/verify/delete tag)
  PublishJob->>LocalBundle: build and verify Central bundle
  PublishJob->>LocalBundle: run isolated consumer smoke test
  PublishJob->>MavenCentral: check for existing artifacts (HEAD *.pom)
  PublishJob->>MavenCentral: deploy with autoPublish=true, waitUntil=published
  PublishJob->>MavenCentral: poll for published POMs (retry loop)
  PublishJob->>LocalBundle: final consumer test against Maven Central
  FinalizeJob->>GitHubRelease: create or verify signed annotated tag
  FinalizeJob->>GitHubRelease: create or verify GitHub Release with notes
Loading

Poem

A rabbit packed the jars with care,
Signed each bundle, checked each pair.
Revapi watched the API gate,
While Central learned to publish straight.
"Hop hop!" said Bunny, "0.1.0 is great!" 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: preparing the 0.1.0 release and adding the API compatibility gate.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch juherr/finir-milestone-5

Comment @coderabbitai help to get the list of available commands.

@juherr
juherr marked this pull request as ready for review July 25, 2026 14:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/release.yml (1)

135-156: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add a timeout to the Central-resolution curl probe.

curl --fail --silent --show-error --head has no --max-time/--connect-timeout; a hung connection could stall well past the intended ~10-minute retry budget instead of failing fast into the next attempt.

⏱️ Proposed fix
-              if ! curl --fail --silent --show-error --head "${pom_url}" >/dev/null; then
+              if ! curl --fail --silent --show-error --max-time 15 --head "${pom_url}" >/dev/null; then
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 135 - 156, Add a per-request
timeout to the Maven Central probe in the release workflow’s “Wait for Maven
Central resolution” loop by configuring curl with an appropriate --max-time
and/or --connect-timeout. Keep the existing retry and failure behavior unchanged
so hung requests fail quickly and allow the approximately 10-minute retry budget
to proceed.
scripts/build-central-bundle.sh (1)

76-79: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Zip is not truncated before writing.

zip -r merges into an existing archive rather than replacing it. If ${output} already exists from a stale/prior invocation, the bundle can end up with leftover entries. Add a rm -f "${output}" before the zip step for a clean, reproducible bundle.

🧹 Proposed fix
+rm -f "${output}"
 (
   cd "${staging}"
   zip -q -r "${output}" dev
 )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/build-central-bundle.sh` around lines 76 - 79, Remove any existing
output archive before creating the bundle: in the staging/zip block, add rm -f
"${output}" immediately before the zip invocation so
scripts/build-central-bundle.sh always produces a clean archive without stale
entries.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 130-134: Update the “Publish to Maven Central” workflow step to
probe Maven Central for the current version before running the auto-publishing
deploy, reusing the existing curl-based resolution check from the later wait
loop. If the artifacts are already resolvable, skip deploy and continue to the
wait/finalize stage; otherwise preserve the existing deploy command.

---

Nitpick comments:
In @.github/workflows/release.yml:
- Around line 135-156: Add a per-request timeout to the Maven Central probe in
the release workflow’s “Wait for Maven Central resolution” loop by configuring
curl with an appropriate --max-time and/or --connect-timeout. Keep the existing
retry and failure behavior unchanged so hung requests fail quickly and allow the
approximately 10-minute retry budget to proceed.

In `@scripts/build-central-bundle.sh`:
- Around line 76-79: Remove any existing output archive before creating the
bundle: in the staging/zip block, add rm -f "${output}" immediately before the
zip invocation so scripts/build-central-bundle.sh always produces a clean
archive without stale entries.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1f20ab7c-5ef4-4c94-b3cc-2d173b06d17d

📥 Commits

Reviewing files that changed from the base of the PR and between 68561e5 and 853289a.

📒 Files selected for processing (70)
  • .github/release-notes/0.1.0.md
  • .github/workflows/release.yml
  • CHANGELOG.md
  • CONTRIBUTING.md
  • README.md
  • config/release-smoke/pom.xml
  • config/release-smoke/src/test/java/dev/juherr/datex4j/release/PublishedConsumerTest.java
  • config/release/public-artifacts.txt
  • config/revapi/accepted-differences.json
  • config/revapi/revapi.json
  • datex4j-bom/pom.xml
  • datex4j-builders/pom.xml
  • datex4j-consumer-tests/pom.xml
  • datex4j-core/pom.xml
  • datex4j-domain-evcharging/pom.xml
  • datex4j-domain-parking/pom.xml
  • datex4j-domain-srti/pom.xml
  • datex4j-domain-traffic/pom.xml
  • datex4j-domain-uvar/pom.xml
  • datex4j-integration-tests/pom.xml
  • datex4j-json/pom.xml
  • datex4j-json/src/main/java/dev/juherr/datex4j/json/internal/DatexEnumJson.java
  • datex4j-json/src/main/java/dev/juherr/datex4j/json/internal/DatexPrefixes.java
  • datex4j-json/src/main/java/dev/juherr/datex4j/json/internal/GAttributes.java
  • datex4j-json/src/main/java/dev/juherr/datex4j/json/internal/MultilingualStringJson.java
  • datex4j-json/src/main/java/dev/juherr/datex4j/json/internal/SubstitutionJson.java
  • datex4j-location/pom.xml
  • datex4j-model-spi/pom.xml
  • datex4j-model-v2_0/pom.xml
  • datex4j-model-v2_0/src/main/java/dev/juherr/datex4j/model/v2_0/spi/package-info.java
  • datex4j-model-v2_1/pom.xml
  • datex4j-model-v2_1/src/main/java/dev/juherr/datex4j/model/v2_1/spi/package-info.java
  • datex4j-model-v2_2/pom.xml
  • datex4j-model-v2_2/src/main/java/dev/juherr/datex4j/model/v2_2/spi/package-info.java
  • datex4j-model-v2_3/pom.xml
  • datex4j-model-v2_3/src/main/java/dev/juherr/datex4j/model/v2_3/spi/package-info.java
  • datex4j-model-v3_0/pom.xml
  • datex4j-model-v3_0/src/main/java/dev/juherr/datex4j/model/v3_0/spi/package-info.java
  • datex4j-model-v3_1/pom.xml
  • datex4j-model-v3_1/src/main/java/dev/juherr/datex4j/model/v3_1/spi/package-info.java
  • datex4j-model-v3_2/pom.xml
  • datex4j-model-v3_2/src/main/java/dev/juherr/datex4j/model/v3_2/spi/package-info.java
  • datex4j-model-v3_3/pom.xml
  • datex4j-model-v3_3/src/main/java/dev/juherr/datex4j/model/v3_3/spi/package-info.java
  • datex4j-model-v3_4/pom.xml
  • datex4j-model-v3_4/src/main/java/dev/juherr/datex4j/model/v3_4/spi/package-info.java
  • datex4j-model-v3_5/pom.xml
  • datex4j-model-v3_5/src/main/java/dev/juherr/datex4j/model/v3_5/spi/package-info.java
  • datex4j-model-v3_6/pom.xml
  • datex4j-model-v3_6/src/main/java/dev/juherr/datex4j/model/v3_6/spi/package-info.java
  • datex4j-model-v3_7/pom.xml
  • datex4j-model-v3_7/src/main/java/dev/juherr/datex4j/model/v3_7/spi/package-info.java
  • datex4j-model/pom.xml
  • datex4j-model/src/main/java/dev/juherr/datex4j/model/AggregateMarker.java
  • datex4j-model/src/main/java/dev/juherr/datex4j/model/package-info.java
  • datex4j-ocpi/pom.xml
  • datex4j-ocpi/src/main/java/dev/juherr/datex4j/ocpi/mapping/internal/package-info.java
  • datex4j-ocpi/src/main/java/dev/juherr/datex4j/ocpi/support/package-info.java
  • datex4j-validation/pom.xml
  • datex4j-xml/pom.xml
  • datex4j-xml/src/main/java/dev/juherr/datex4j/xml/SecureXmlSource.java
  • docs/README.md
  • docs/api-compatibility.md
  • examples/pom.xml
  • pom.xml
  • scripts/build-central-bundle.sh
  • scripts/git-gpg-wrapper.sh
  • scripts/verify-central-bundle.sh
  • scripts/verify-revapi-allowlist.sh
  • scripts/verify.sh

Comment thread .github/workflows/release.yml
@juherr
juherr merged commit 4aa373d into main Jul 25, 2026
8 checks passed
@juherr
juherr deleted the juherr/finir-milestone-5 branch July 25, 2026 14:44
juherr added a commit that referenced this pull request Jul 25, 2026
Prepare the 0.1.0 release and API compatibility gate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant