Skip to content

build: scaffold the model-driven build under emf with its gates and CI job - #104

Merged
ExtraToast merged 3 commits into
mainfrom
chore/80-emf-scaffold
Sep 14, 2026
Merged

ExtraToast merged 3 commits into
mainfrom
chore/80-emf-scaffold

Conversation

@ExtraToast

@ExtraToast ExtraToast commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Closes #80 (parent #78)

What this branch does

The model-driven implementation gets its build before it gets any EMF code, so the walking skeleton (#81) lands into gates that already hold. This is the EMF scaffold: a Maven reactor under emf/, its gates, its CI job and the root wiring that watches it. It has no EMF, OCL, Xtext, QVTo or Acceleo dependency and no Tycho yet.

  • The build. A Maven reactor run through a script-only wrapper: mvnw downloads Maven 3.9.16, pinned by SHA-256, and no wrapper jar is committed. JDK 21 comes from emf/.java-version, which CI reads too. Coordinates dev.jorisjonkers.deploykit.emf, version 0.1.0-SNAPSHOT, and the enforcer bans any distribution target, so nothing can be published.
  • One module, parity, holding the first real code the parity contract needs. CanonicalJson writes RFC 8785 canonical JSON: keys sorted by UTF-16 code units, numbers as ECMAScript formats a double, null refused with the JSON Pointer of where it sat. Ledgers checks the witness list and the rule ledger against the repository.
  • The gates (ADR 0115): the enforcer (JDK 21, Maven 3.9, pinned plugins, dependency convergence, no distribution target), -Xlint:all -Werror, JUnit 6 with AssertJ, ArchUnit enforcing the module direction emf/docs/architecture.md states, Spotless with palantir-java-format, JaCoCo line and branch floors, and PIT mutation testing. emf/docs/rules.md lists all 14 rules with the literal that enforces each, and the build fails when one is removed while its row stays.
  • The emf CI job runs ./mvnw -B -ntp verify in emf/, is required by Pipeline Complete, and writes one summary line: 44 tests, line coverage 100.0%, mutation score 100.0% (87 of 87).
  • CodeQL is now a gate. codeql.yml is a reusable workflow that ci.yml calls as the codeql job ("Code scanning"), which Pipeline Complete needs, on every pull request and every push to main, plus its weekly schedule. A last step reads the analysis output and fails on any unsuppressed finding of any severity, notes included, so a finding blocks the merge instead of only landing in the Security tab; a wrong one is filtered in .github/codeql/codeql-config.yml with its reason. It scans java-kotlin alongside JavaScript, TypeScript and workflow logic, all with build-mode: none, so the Autobuild step and the old path filter are gone, and ignores target/ and generated sources.
  • Root wiring. test/emf-wiring.test.ts fails when a workflow runs the Maven wrapper where there is no POM or wrapper, when the reactor names a module that is not on disk, or when CodeQL stops scanning the Java. It adds RULE-061, RULE-062 and REQ-015; test/pipeline-wiring.test.ts holds the CodeQL gate's wiring, with RULE-063 and REQ-016. release-please excludes emf, Renovate groups the maven and maven-wrapper managers under emf maven, and CODEOWNERS, .gitattributes, README, the gates table (now sixteen) and CONTEXT.md (EMF scaffold and walking skeleton, so bootstrap keeps its model meaning) all name it. ESLint and Prettier ignore Maven's target/ output.

The decisions later tickets inherit

Thresholds are measured, not chosen. The first build reached 100% line coverage, 100% branch coverage and 87 of 87 mutants killed, so those are the floors, and they only rise. Three mutants were equivalent (a boundary no input can reach); they were removed by restructuring the number formatter, not by lowering the score.

The gates follow the estate, with Java-shaped additions. An audit of the estate's JVM repositories found JDK 21, warnings as errors, JaCoCo, JUnit with AssertJ and ArchUnit, and nothing for Java formatting or static analysis. Spotless is the Java counterpart of the estate's ktlint. PIT is new to the estate's JVM code and is kept because the parity code decides what counts as agreement. SpotBugs, Error Prone, NullAway, SBOM generation and signing are rejected, for the reasons in 0115.

JaCoCo does not append. Its default appends to the previous run's jacoco.exec, which let a deleted test pass the coverage floor locally. Coverage is now one run's.

Gate order in verify: enforcer, compile, tests, format, coverage, mutation. ./mvnw spotless:apply fixes formatting.

The first CodeQL run found a real defect, which is why it became a gate. Ledgers parsed a ledger's stated row count with Integer.parseInt, so a count too large for an int threw instead of being reported (java/uncaught-number-format-exception). The count is now compared as text, with a test for an oversized number.

Verification

Each gate broken on this branch from a clean build, then restored:

  • A weakened test (the 0.5 number case removed): Mutation score of 99 is below threshold of 100
  • A removed test (the NaN and range refusals): lines covered ratio is 0.98, but expected minimum is 1.00
  • A misformatted constructor: The following files had format violations
  • A raw List field: warnings found and -Werror specified
  • A metamodel class importing parity: where layer 'metamodel' may only be accessed by layers ['syntax', 'resolve', 'render', 'cli', 'parity']' was violated
  • The wiring test's negative cases: which names a POM that does not exist and emf/pom.xml names module gone, which is not on disk
  • The CodeQL gate step, run against sample analysis output: a finding prints java/uncaught-number-format-exception emf/parity/src/main/java/Ledgers.java:109 ... and exits 1, a suppressed finding is ignored, and an empty result prints No CodeQL findings. and exits 0

./mvnw -B -ntp clean verify in emf/: BUILD SUCCESS, 44 tests. npm run verify exit 0, 313 tests, coverage unchanged. node scripts/lint-adrs.ts emf reports 10 files clean. actionlint 1.7.7, the version CI pins, clean over every workflow; shellcheck clean on emf/scripts/summary.sh. exclude-paths checked against the release-please config schema.

On this pull request, every check passes, including Code scanning / Analyze (java-kotlin) and Pipeline Complete, with no open code scanning alert. Not verifiable before merge: that a feat: commit touching only emf/ produces no release-please change.

@ExtraToast ExtraToast added type: chore Maintenance work without intended behavior change. area: tooling Reusable workflows, Gradle, templates, Renovate, and API tooling. component: build Gradle, npm, packaging, or local build tooling. component: ci Continuous integration workflow or check behavior. labels Sep 14, 2026
@ExtraToast ExtraToast self-assigned this Sep 14, 2026
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@ExtraToast
ExtraToast merged commit 5a60cae into main Sep 14, 2026
18 checks passed
@ExtraToast
ExtraToast deleted the chore/80-emf-scaffold branch September 14, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: tooling Reusable workflows, Gradle, templates, Renovate, and API tooling. component: build Gradle, npm, packaging, or local build tooling. component: ci Continuous integration workflow or check behavior. type: chore Maintenance work without intended behavior change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build the EMF scaffold: the Maven reactor, its gates and its CI job

2 participants