Recipe: AtlasArc.io CI with JUnit
Put the complete configured AtlasArc evaluator in an ordinary JUnit 5 test. The adapter runs in-process, reads the same .atlasarc/evaluator.json as the standalone CLI, and turns an unaccepted cycle or invalid input into a normal assertion failure. You do not need ArchUnit annotations or a separate evaluator process.
For JVM sources, the configured evaluator still uses ArchUnit's bytecode importer under the hood. Here the evaluator config owns class acquisition; in the separate native ArchUnit recipe, the consuming test imports those classes up front.
How it fits together
- Your build produces evidence: compiled Java/Kotlin classes and, when configured, dependency-cruiser JSON for TypeScript.
- The JUnit adapter runs the evaluator: it reads repository scope and cycle decisions, acquires every source declared in
evaluator.json, and evaluates them together. - The test owns the verdict: clean evaluation passes; problem, invalid, and internal outcomes fail with the evaluator's human detail.
ESLint and SonarJS reports are not prerequisites for this gate. AtlasArc.io CI's native enforcement is cycle-only.
1. Add the JUnit dependency
AtlasArc's Apache-2.0 JUnit adapter is available from Maven Central as io.atlasarc:atlasarc-junit:1.4.0. Add it in test scope beside your project's JUnit 5 dependency:
// build.gradle.kts
dependencies {
testImplementation("io.atlasarc:atlasarc-junit:1.4.0")
}
<dependency>
<groupId>io.atlasarc</groupId>
<artifactId>atlasarc-junit</artifactId>
<version>1.4.0</version>
<scope>test</scope>
</dependency>
2. Configure current evidence
For a module-less Java/Kotlin project, save this as .atlasarc/evaluator.json. The owning build must compile target/classes before the test runs:
{
"$schema": "https://atlasarc.io/schemas/evaluator-config-v1.schema.json",
"configVersion": 1,
"repositoryRoot": "..",
"sources": [{
"id": "jvm:whole-project",
"backend": "jvm-bytecode",
"classDirectories": [{"path": "target/classes"}],
"sourceRoots": [{"path": "src/main/java"}]
}]
}
Kotlin projects add their real Kotlin source roots. Multi-module projects label each class/source-root pair with the same stable module name used by the IDE. Do not mix named and unlabelled roots.
For TypeScript, generate dependency-cruiser JSON before the JUnit task and add a second source:
{
"id": "typescript:frontend",
"backend": "typescript-artifact",
"root": ".",
"dependencyCruiserJson": ".atlasarc/depgraph.json"
}
Keep both source objects in the same sources array when one test should own the complete mixed-stack verdict. If source files are newer than their configured bytecode or dependency graph, the assertion fails as invalid instead of reporting a false clean result.
3. Add one ordinary JUnit test
import io.atlasarc.junit.AtlasArcGovernanceAssertions;
import org.junit.jupiter.api.Test;
class CycleGovernanceTest {
@Test
void repositoryCycleGovernance() {
AtlasArcGovernanceAssertions.assertGovernance();
}
}
The no-argument form resolves .atlasarc/evaluator.json from the test working directory. Pass Path.of("path/to/evaluator.json") when the config lives elsewhere. A second Path argument can set the current directory explicitly for multi-module test tasks.
4. Run the normal test task
Run ./gradlew test, mvn test, or the same task in CI. Ensure any dependency-cruiser generation task runs first. The assertion behaves as follows:
| Evaluator outcome | JUnit result |
|---|---|
| Clean | Test passes |
| Unaccepted cycle | Assertion fails with the cycle summary |
| Invalid config, governance, scope, or stale evidence | Assertion fails closed with the evaluator diagnostic |
| Internal evaluator error | Assertion fails with the available error detail |
The assertion is read-only. It never creates a cycle-debt baseline or writes cycles.json.
When to choose another integration
- Use the standalone CLI when a pipeline needs a process exit code, JSON, or SARIF.
- Use the ArchUnit recipe when an existing Java/Kotlin architecture suite already owns class import and should express AtlasArc as a native
ArchRule.
Related
See Govern cycle exceptions for IDE authoring and stale-record repair, or AtlasArc.io CI for evaluator configuration, baseline adoption, output formats, and exit codes.