Explain the relationship between the apiDump and apiCheck tasks and the typical developer workflow when you intentionally change a public API.
answer
- apiCheck = gate (in `check`), apiDump = update
- apiDump is manual/intentional, never auto
- Removed line = breaking; added line = additive
- Commit code + .api together
- apiCheckAll/apiDumpAll aggregate multi-module
basics
~20 sapiCheck compares your current public API to the saved file and fails if they differ. apiDump regenerates that saved file. When you intentionally change the API, you run apiDump and commit the updated file so the check passes again.
solid answer
~40 s`apiCheck` is the *gate*: it recomputes the public ABI from compiled classes and diffs it against the committed `.api`; any mismatch fails the build, and it runs as part of `check`. `apiDump` is the *update*: it overwrites the `.api` with the current surface. The loop is: change a public declaration → `apiCheck` fails with a diff → if the change is intentional, run `./gradlew apiDump` → review the resulting `.api` diff (a removed line is a potential breaking change; an added line is a new API) → commit code + `.api` together. The key discipline: `apiDump` is a deliberate, human-triggered action, never automatic, so that every API delta is consciously approved. Reviewers gate breaking removals/changes in the PR via the `.api` diff. In multi-module builds, each module has its own `apiCheck`/`apiDump` plus aggregate `apiCheckAll`/`apiDumpAll`.
go deeper
Knows apiCheck fails and apiDump fixes it, even if hazy on why dump is manual.
Articulates the full loop, why apiDump is deliberate, and reads a .api diff as breaking vs additive.
Ties the diff to SemVer decisions and PR review gating; knows multi-module aggregate tasks.
Designs the team process: who approves API deltas, how .api diffs map to release policy, and CI enforcement so apiDump can never be a rubber stamp.
## Two tasks, two roles | Task | Role | When run | |------|------|----------| | `apiCheck` | **Verification gate** — recomputes the public ABI and fails on any diff vs the committed `.api`. Depended on by `check`. | Every CI build / `./gradlew check` | | `apiDump` | **Snapshot update** — regenerates the `.api` from current code. | Manually, only when you intend to change the API | ## Why apiDump is manual If the dump regenerated automatically on every build, breaking changes would silently "pass" because the baseline would always be rewritten to match. Keeping `apiDump` a **deliberate, human-invoked** step is the whole point: an API change must be *consciously approved* and committed, leaving a reviewable diff. ## The workflow ```text 1. Edit code, e.g. rename a public function or change a parameter type. 2. ./gradlew apiCheck # FAILS, prints the offending diff 3. Decide: - accidental? -> revert the code change. - intentional? -> ./gradlew apiDump 4. git diff api/ # eyeball the API delta - a removed/changed line = potential BREAKING change (bump major in SemVer) - an added line = additive (minor) 5. Commit code + updated .api together. ``` ## Reading an .api diff A `.api` line records a JVM signature. A change like ```diff - public final fun parse (Ljava/lang/String;)Lcom/acme/Result; + public final fun parse (Ljava/lang/String;Z)Lcom/acme/Result; ``` shows a parameter was added — binary-breaking, because existing compiled callers reference the old descriptor. Reviewers treat removals/changes as red and weigh them against the version bump. ## Multi-module builds Each subproject gets its own `apiCheck`/`apiDump`. The root project also exposes aggregate `apiCheckAll` and `apiDumpAll` so you can verify/regenerate the whole tree at once. Each module's `.api` lives under that module's `api/` directory. ## Common pitfall Forgetting to run `apiDump` after an intentional change makes CI red; running it *without reviewing* the diff defeats the purpose — always inspect what changed.
- Why shouldn't apiDump run automatically as part of every build?Because the baseline would always be rewritten to match the code, so breaking changes would silently pass. Manual apiDump forces a reviewable, deliberate API delta.
- In a multi-module project, how do you regenerate all dumps at once?Run the aggregate `apiDumpAll` task from the root; each module also has its own `apiDump` and `apiCheck`.
saying these in an interview costs you the question
- Saying apiDump runs automatically on every build
- Running apiDump blindly without reviewing the .api diff
- Not committing the .api change alongside the code
- Thinking apiCheck modifies files (it only reads/compares)
- Confusing which task is wired into `check`