CI & Releases
OpenCGMES ships its three products on three independent CI/release trains. Each product has its own -ci workflow (build, test, lint, publish SNAPSHOTs) and its own -release workflow (signed artifacts, triggered by a tag), so a change to one product never forces a release of another. Beyond the six product workflows, two more round out the repository's .github/workflows/: a reusable Docker-image publisher shared by the CIMVocabCheck train, and the docs site's own deploy workflow. This page describes the trains, the versioning scripts that feed them, and the supply-chain gates. See Building for the underlying build commands.
The eight workflows at a glance
| Product | CI workflow | Release workflow | Release tag | Released artifacts |
|---|---|---|---|---|
| CIMXML | cimxml-ci.yml | cimxml-release.yml | cimxml-vX.Y.Z | Maven Central + GitHub Packages JAR; GitHub Release |
| CIMVocabCheck | cimvocabcheck-ci.yml | cimvocabcheck-release.yml | cimvocabcheck-vX.Y.Z | cimvocabcheck-core to Maven Central + GitHub Packages; core/cli/lsp JARs on the GitHub Release; cimvocabcheck-cli image to GHCR |
| CIMNotebook | cimnotebook-ci.yml | cimnotebook-release.yml | cimnotebook-vX.Y.Z | VSIX + IntelliJ zip on the GitHub Release; plugin to JetBrains Marketplace |
Each CI workflow is scoped by path filters, so it only runs when files it owns change (CIMVocabCheck and CIMNotebook CI also trigger on cimxml/** and the shared scripts, because they build against CIMXML).
Two workflows sit outside the three-train table:
docker-publish.yml— a reusable (workflow_call) workflow, not triggered directly, that builds the schema-lesscimvocabcheck-cliimage and pushes it to GHCR.cimvocabcheck-ci.ymlcalls it on every push tomainto publish the:edgetag;cimvocabcheck-release.ymlcalls it on acimvocabcheck-vX.Y.Ztag to publish:X.Y.Zand:latest. See CLI → Docker for the image itself.deploy-docs.yml— builds and deploys this documentation site (Docusaurus) to GitHub Pages. It triggers on pushes tomainthat touchdocs/**(or the workflow file itself), and also builds — but does not deploy — on pull requests touching the same paths, so a docs PR gets a build check without publishing.
How the trains flow
CI trains (push / pull request)
CIMXML CI (cimxml-ci.yml)
- build-test —
mvn -f cimxml/pom.xml clean verifyon Java 21. - publish-snapshot — on push to
main, computes the snapshot version and deploys the-SNAPSHOTJAR to GitHub Packages.
CIMVocabCheck CI (cimvocabcheck-ci.yml)
- lint — compiler-warnings-as-errors, then Spotless/Checkstyle/SpotBugs/PMD (no tests, for fast feedback).
- build-test — checks out submodules recursively and runs
mvn -pl cimvocabcheck/core,cimvocabcheck/cli,cimvocabcheck/lsp -am clean verify(which also builds cimxml). This is the authoritative run, including the ENTSO-E integration tests and coverage gates. - sbom — regenerates the Maven SBOM and enforces the license allow-list + drift check (see below).
- publish-snapshot — on push to
main, installs cimxml locally then deployscimvocabcheck-coreas a-SNAPSHOTto GitHub Packages. (The CLI and LSP are fat-JAR tools and are not deployed to registries.) - publish-edge-image — on push to
main, calls the reusabledocker-publish.ymlto build and pushghcr.io/<owner>/cimvocabcheck-cli:edge, so there is always a fresh schema-less CLI image to test against.
CIMNotebook CI (cimnotebook-ci.yml)
- typecheck-vscode — ESLint, Prettier check, and TypeScript type-check (
npm run lint/format:check/compile). - build-vsix — sets versions, builds the LSP fat JAR from in-repo source, copies it into the extension, then
npm run bundle+vsce package; uploads the VSIX as a build artifact. - build-intellij-plugin — sets versions, builds the LSP fat JAR, runs
gradle spotlessCheck, thengradle buildPlugin; uploads the plugin zip as an artifact. - sbom — regenerates the VS Code + IntelliJ SBOMs and enforces the allow-list + drift check.
Release trains (tag push)
Pushing an annotated tag in the form <product>-vX.Y.Z triggers that product's release workflow. Every release workflow first validates the tag format and derives the release version from it.
- CIMXML release — publishes a GPG-signed JAR to Maven Central (Sonatype Central Portal,
-Pcentral-release), publishes the release to GitHub Packages, and creates a draft GitHub Release with the JAR attached. - CIMVocabCheck release — publishes signed
cimvocabcheck-coreto Maven Central and GitHub Packages, creates a draft GitHub Release with the core, cli, and lsp fat JARs attached, and calls the reusabledocker-publish.ymlto push thecimvocabcheck-cliimage to GHCR tagged:X.Y.Zand:latest. It pins the cimxml dependency to a released version (resolved from the newestcimxml-v*tag) so Maven Central never sees a SNAPSHOT reference. - CIMNotebook release — creates a draft GitHub Release with the VSIX and IntelliJ zip, and publishes the plugin to the JetBrains Marketplace (
gradle publishPlugin). Unlike CI, a release bundles the LSP at the latest released cimvocabcheck version (resolved from the newestcimvocabcheck-v*tag), mirroring how it pins its other dependencies.
CI builds use each component's own in-repo SNAPSHOT version. Releases instead pin cross-product
dependencies to the latest released tag reachable from HEAD (cimvocabcheck → cimxml;
cimnotebook → cimvocabcheck → cimxml), because Maven Central rejects SNAPSHOT references. The cimxml
dependency is required: a cimvocabcheck or cimnotebook release fails if no cimxml-v* tag
exists. The cimnotebook release resolves the bundled cimvocabcheck version with
compute-version.sh cimvocabcheck --released and falls back — with a warning — to the in-repo
0.0.0-SNAPSHOT LSP only until the first cimvocabcheck-v* tag exists.
Versioning
Two scripts under scripts/ derive and apply versions from Git state, so versions are never hand-edited in poms for a release.
compute-version.sh <component> [--released]
Prints the Maven version for cimxml, cimvocabcheck, or cimnotebook:
- On a tagged release push (
<component>-vX.Y.Z) → printsX.Y.Z. - On any other ref → finds the last
<component>-v*tag reachable fromHEAD(git tag --merged HEAD), bumps the patch by one, and appends-SNAPSHOT. Falls back to0.0.0-SNAPSHOTwhen no tag exists. - With
--released→ prints the newest released<component>-v*tag reachable fromHEADas-is (no patch bump, no-SNAPSHOT), again falling back to0.0.0-SNAPSHOT. This is what the cimnotebook release uses to pin the bundled cimvocabcheck version. The--merged HEADfilter matters: it ignores tags that are not ancestors of the commit being released, so a release never pins to a version that does not exist in its own history.
set-versions.sh <cimxml> [<cimvocabcheck>] [<cimnotebook>]
Applies the computed versions across every build file: the cimxml pom; the cimvocabcheck core/cli/lsp poms and their inter-module dependency properties (ver.cimxml, ver.cimvocabcheck-core); and the cimnotebook plugin versions (pluginVersion in gradle.properties, version in package.json). The Gradle and npm toolchains strip the -SNAPSHOT suffix because they don't use Maven snapshot conventions. A cimnotebook build still needs a cimvocabcheck version because it bundles the LSP fat JAR.
The three trains are versioned independently — cimvocabcheck and cimnotebook carry separate version numbers.
Supply chain (SBOM + licenses)
Each release-able toolchain ships a committed CycloneDX 1.6 SBOM and a THIRD-PARTY attribution file, regenerated and drift-checked in CI:
| SBOM | Location | Owned by | Covers |
|---|---|---|---|
| Maven | cimvocabcheck/sbom/maven/ | cimvocabcheck-ci | cimxml + cimvocabcheck core/cli/lsp and shipped deps |
| VS Code | cimnotebook/sbom/vscode/ | cimnotebook-ci | shipped npm deps |
| IntelliJ | cimnotebook/sbom/intellij/ | cimnotebook-ci | IntelliJ Platform (2024.2) + LSP4IJ compile deps |
Regenerate them with scripts/generate-sbom.sh (run the relevant subset — maven, vscode, intellij, or no args for all three). Each CI sbom job:
- License gate — fails if any dependency uses a license that is not on the reviewed open-source allow-list (or has no detectable license). The allow-list lives in the root
pom.xml(license-maven-plugin) for Maven and inscripts/check-sbom-licenses.pyfor npm/Gradle. - Drift check —
git diff --exit-codeagainst the committed SBOMs; fails if dependencies changed without regenerating.
Any change to a pom.xml version, package.json/package-lock.json, or the platformVersion/lsp4ijVersion properties means you must re-run scripts/generate-sbom.sh and commit the result in the same change — otherwise the drift check fails CI. See the SBOM READMEs under cimvocabcheck/sbom/ and cimnotebook/sbom/.