Skip to content

feat(monitoring): show the build this instance runs - #6644

Merged
delchev merged 1 commit into
masterfrom
feat/monitoring-instance-version
Aug 10, 2026
Merged

feat(monitoring): show the build this instance runs#6644
delchev merged 1 commit into
masterfrom
feat/monitoring-instance-version

Conversation

@delchev

@delchev delchev commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Why

"Which version is deployed on this instance?" had no answer outside the Workbench — and on a stock instance it had no answer at all: /services/core/version reports the raw Maven placeholders.

$ curl -s https://trial.dirigible.io/services/core/version
{"productName":"${project.title}","productVersion":"${project.version}","productCommitId":"${git.commit.id}", ...}

DIRIGIBLE_PRODUCT_NAME / _VERSION / _COMMIT_ID are declared in dirigible-commons.properties, and that module does not filter its resources — which is also why the Workbench's About window hides its Version and Commit rows (it compares against the literal placeholder).

What

  • build/application/src/main/resources/dirigible.properties re-declares the three product keys. That module filters its resources and runs the git-commit-id plugin, so they resolve (Eclipse Dirigible / 15.0.0-SNAPSHOT / the HEAD sha). A downstream distribution keeps overriding them with its own dirigible.properties; the About window now shows the rows it used to hide.
  • Monitoring → System opens with a Build card: product, version, the commit linked to the product repository, instance name, repository/database providers, and the engines this assembly ships (a curated build carries fewer — the answer to "why is that feature missing here?"). It sits outside the metrics block on purpose, so it still answers when the JVM snapshot is unavailable.
  • The sidebar footer carries the same identity condensed to one line, so every page of the shell shows it (commit and instance on hover).
  • A version store reads /services/core/version once — a running instance never changes its build. A value that still looks like a Maven placeholder is treated as unknown, so older or unfiltered builds degrade to a dash instead of printing ${project.version}.

Verification

  • MonitoringShellIT — 3/3 green headless, including the new systemNamesTheDeployedBuild (the card + the sidebar line). The Alpine-bootstrap failure mode has no server-side symptom, so only a real browser catches it.
  • Ran the built jar: GET /services/core/versionproductName: "Eclipse Dirigible", productVersion: "15.0.0-SNAPSHOT" (the commit resolves from the git-commit-id plugin, verified separately — it is skipped in a git worktree build).
  • mvn formatter:validate on the touched module.

🤖 Generated with Claude Code

"Which version is deployed here?" had no answer outside the Workbench, and on a
stock instance it had no answer at all.

The Monitoring shell now reads /services/core/version - the same payload the
Workbench's About window renders - through a `version` store that loads once (a
running instance never changes its build). The System page opens with a Build
card (product, version, the commit linked to the product repository, instance,
repository/database providers and the engines this assembly ships), rendered
outside the metrics block so it still answers when the JVM snapshot is
unavailable; the sidebar footer carries the same identity condensed to one line,
so every page shows it.

The card needed a platform fix to have anything to show: DIRIGIBLE_PRODUCT_NAME
/ _VERSION / _COMMIT_ID live in dirigible-commons.properties, whose module does
not filter its resources, so every Dirigible instance reported the raw Maven
placeholders - which is also why the About window hid its Version and Commit
rows. build/application re-declares the three keys; that module filters its
resources and runs the git-commit-id plugin, so they resolve. A downstream
distribution keeps overriding them with its own dirigible.properties, and the UI
treats a value that still looks like a placeholder as unknown.

MonitoringShellIT covers the card and the sidebar line - the Alpine bootstrap
failure mode has no server-side symptom, so only a real browser catches it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@delchev
delchev merged commit 3c057aa into master Aug 10, 2026
15 of 16 checks passed
@delchev
delchev deleted the feat/monitoring-instance-version branch August 10, 2026 10:53
delchev added a commit that referenced this pull request Aug 11, 2026
…ssertion (#6653)

EntityDecoratorsSampleProjectIT compared the served /services/openapi document
against a literal that carried `"version":"${project.version}"` - the UNFILTERED
placeholder every stock instance used to report. #6644 made the instance report
its real build version, so the literal stopped matching, the assertion retried
for its full minute and the nightly went red on BOTH the H2 and the PostgreSQL
leg (run 31453258683) - a string comparison, hence database-independent.

Normalise `info.version` out of both sides instead of pinning it: the served
version changes on every release and every development bump, so any literal here
is a landmine that fires on the next `version set to ...` commit. Verified
locally against current master, where the instance serves 15.0.0-SNAPSHOT - so
the test now passes with a REAL version present, not because the placeholder
survived.
delchev added a commit that referenced this pull request Aug 11, 2026
…at a URL (#6654) (#6655)

#6641 taught the synchronization pass to defer artefact cleanup while the
registry is half-written, but fed RegistryMutationTracker from a servlet filter
mapped on the publisher and workspace endpoints. Every other publish path stayed
invisible - and the most frequent publisher in practice is not that endpoint: the
model-to-code generation service publishes through the JS `lifecycle` API from a
`/services/js/...` URL the filter never sees.

So the race survived. On PR #6644's smoke leg, whose build already contained
#6641, a scheduled pass walked into a 680 ms hole opened by
service-generate/generate.mjs, removed six client-Java artefacts whose sources
were about to be copied back, and the batch compile that followed produced ZERO
class files ("package gen.invoices.data.invoice does not exist", then a cascade
of "cannot find symbol"). No controller was registered, and
IntentCrossModelFieldRetirementIT's 60s poll saw only 404s. The same window is
the likeliest explanation for IntentEmissionCoverageIT reading a null status two
seconds after a republish on PR #6647's leg.

PublisherService now brackets its own writes, so every caller is covered by
construction - the HTTP endpoint, the JS lifecycle API, generated client Java and
tests alike. Enumerating callers was the bug; the service is the one place they
all funnel through, and the tracker's javadoc now says so, because the next
publish path must bracket its write rather than add a mapping.

SynchronizerCleanupRaceIT gains the contract test: a publish that never touches
the HTTP layer must still register as a completed registry mutation, since that
count is exactly what the pass compares. It fails on master at that assertion.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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