This page explains how the ecosystem master-only release flow is enforced by GitHub Actions.
Arch Toolkit retains its branch policy workflow. The build workflow validates pull requests against master on Linux and macOS, and also supports manual validation. It runs library builds, Android/desktop samples, tests, coverage, Android lint, Detekt, Ktlint, Dokka and strict MkDocs. macOS covers the configured iOS targets; Linux cannot execute their compiler or simulator tests.
PR opened or updated
|
v
Branch Policy
|
+-- base master -> head must be feature/*, fix/*, bugfix/*, config/*,
docs/*, chore/*, dependabot/*, release/x.y.0[-rcN],
or hotfix/x.y.z[-rcN]
The branch policy runs before expensive build work. It keeps repository history aligned with the release model.
Pull requests into master use the normal development and release gate:
branch policy -> lint -> build -> tests -> coverage -> docs -> affected samples
release/* and hotfix/* branches are publication candidates. Other branch types are normal code,
docs, dependency, or repository maintenance changes and do not publish artifacts.
When a release or hotfix PR is merged into master, CI reads the source branch name:
release/2.0.0 -> 2.0.0
release/2.0.0-rc1 -> 2.0.0-rc1
hotfix/2.0.1 -> 2.0.1
hotfix/2.0.1-rc1 -> 2.0.1-rc1
The release workflow creates the annotated tag from that version.
The tag name does not use a v prefix.
The main release path is a single CI run after the PR merge:
merge into master
|
v
resolve version from branch
|
v
write the explicit version file
|
v
verify build and quality gates
|
v
publish artifacts
|
v
push tag
|
v
create GitHub Release
The tag-triggered workflow is not part of this path, which prevents duplicate publication. Gradle receives the resolved version explicitly, and the remote tag is pushed only after every publisher succeeds.
The master release workflow supports manual recovery after its workflow fix has reached master.
The operator must provide both the original release/* or hotfix/* branch name and the exact
master commit SHA. CI validates an existing tag against that commit, reuses it when correct, and
rejects it when it points elsewhere.
The branch and version rules are shared. Build and publication commands stay repository-specific.
| Repository | Release verification | Publication |
|---|---|---|
arch-toolkit |
Linux/macOS build, lint, tests, docs and samples | Splinter variants only; Maven Central from macOS |
arch-android |
./gradlew ciBuild |
ciPublishMavenCentral, ciPublishGithubPackages |
arch-event-observer |
./gradlew ciBuild |
ciPublishMavenCentral, ciPublishGithubPackages |
arch-lumber |
./gradlew build, :lumber:koverVerify |
Maven Central and GitHub Packages tasks |
Repositories may keep a manually dispatched release workflow as an escape hatch. It must not react to the tag pushed by the automatic master merge flow, otherwise both workflows can publish the same version concurrently.
The normal path is still:
release/hotfix PR -> master -> tag + publish in the same workflow
buildSrc/src/main/kotlin/com/toolkit/plugin/ToolkitCoveragePlugin.kt is the single source of report exclusions. It applies the same Kover filter
to every covered module and the root report. Only Android-generated *.BuildConfig, *.R
and *.R$* are excluded: they contain generated constants/resources, not application behavior.
Do not exclude DTOs, state classes, Compose functions or entire packages just to raise coverage.
./gradlew ciCoverage
# Root report only (automatically runs the required JVM/Android host tests):
./gradlew :koverXmlReport :koverHtmlReport :koverVerify
Open build/reports/kover/html/index.html locally. Codecov receives only
build/reports/kover/report.xml, with disable_search: true; automatic discovery would also find
module or older reports and could merge excluded classes back into the result.
There is deliberately no second ignore list in codecov.yml: Codecov consumes the already-filtered
XML. Its ignore patterns describe source paths, while Kover filters describe JVM class names.
An IDE coverage run or another coverage tool must use this Gradle report to share these exclusions.
Compare the same commit and line metric. Codecov’s treatment of partially covered lines can differ from Kover, so equal file scope does not promise identical percentages. Existing Gradle verification rules remain authoritative; Codecov provides visibility rather than an additional threshold. JVM/Android host execution supplies the coverage counters. Apple, JS and Wasm tests still run in the platform test suite but do not add Kover coverage. Coverage uploads occur only after successful master validation (release validation for Toolkit).
References: Kover report filtering, Codecov file search and Codecov path ignores.
The root report covers the published Splinter module. Samples and test helpers are outside that
library report, while their tests still run through ciTest. The former settings aggregation plugin
used a different task contract; the project plugin supplies the tasks required by ciCoverage.
Toolkit currently has no numerical coverage floor configured. ciCoverage runs tests and generates
the reports; koverVerify becomes a percentage gate only when explicit rules are added.
The GitHub Release body is extracted from the exact version section in docs/CHANGELOG.md.
Historical versions without a section use generated GitHub notes. No root release-notes copy is maintained.