publish.yaml runs ./gradlew publish and nothing else — it invokes no test,
apiCheck, ktlintCheck or check task. Publication goes to Maven Central,
which cannot be undone: a version, once released, stays released.
That by itself is not a defect. Coverage can live upstream of the publish
workflow, and here it does:
ci.yaml runs on push: branches: [main], so every commit that lands on
main gets a full CI run.
- Every release so far was cut from a main commit. Checked the six most recent
(v1.1.0 through v1.1.5): each tag's SHA has a push-event CI run with
conclusion success.
So in practice every published artifact was built from a ref whose CI was
green. The problem is that this is a convention, not a gate, and it is
written down nowhere.
Specifically, nothing mechanically prevents publishing from an unverified ref:
main has no branch protection and the repository has no rulesets
(/branches/main/protection returns 404, /rulesets returns []), so no
status check is required for anything.
publish.yaml triggers on release: [created]. A release can be created
against any commitish, not just a main commit that CI has run on.
publish.yaml also triggers on workflow_dispatch, which can be dispatched
against any ref and skips the release path entirely.
ci.yaml does not trigger on tags, so a tag placed on a non-main commit
would have no CI run at all — and an absent check rollup reads the same as a
passing one to anyone eyeballing it.
There is a second limit worth recording alongside this, because "CI was green
at that ref" sounds stronger than what it covers. ci.yaml is ubuntu-only:
lint, jvm-tests, jni-tests, native-tests (linux) and compiler-tests.
It executes no Apple tests, and no js or wasm tests (#251). Green main CI at a
release ref is real coverage, but it is not coverage of every published
platform.
Suggested resolution
No workflow change is required to close this. The options, roughly in order of
cost:
- Document the release procedure — "cut releases only from a main commit whose
CI is green" — in CONTRIBUTING/release notes, so the convention is
discoverable rather than tribal.
- Have
publish.yaml assert its own precondition: fail fast if the resolved
ref has no successful CI run.
- Require the CI checks on
main via a ruleset, which closes the "release cut
from an unverified ref" path directly.
Filed as documentation of an unwritten guarantee, not as an assertion that a
bad artifact has shipped. Nothing in the release history suggests one has.
publish.yamlruns./gradlew publishand nothing else — it invokes no test,apiCheck,ktlintCheckorchecktask. Publication goes to Maven Central,which cannot be undone: a version, once released, stays released.
That by itself is not a defect. Coverage can live upstream of the publish
workflow, and here it does:
ci.yamlruns onpush: branches: [main], so every commit that lands onmain gets a full CI run.
(v1.1.0 through v1.1.5): each tag's SHA has a
push-event CI run withconclusion
success.So in practice every published artifact was built from a ref whose CI was
green. The problem is that this is a convention, not a gate, and it is
written down nowhere.
Specifically, nothing mechanically prevents publishing from an unverified ref:
mainhas no branch protection and the repository has no rulesets(
/branches/main/protectionreturns 404,/rulesetsreturns[]), so nostatus check is required for anything.
publish.yamltriggers onrelease: [created]. A release can be createdagainst any commitish, not just a main commit that CI has run on.
publish.yamlalso triggers onworkflow_dispatch, which can be dispatchedagainst any ref and skips the release path entirely.
ci.yamldoes not trigger on tags, so a tag placed on a non-main commitwould have no CI run at all — and an absent check rollup reads the same as a
passing one to anyone eyeballing it.
There is a second limit worth recording alongside this, because "CI was green
at that ref" sounds stronger than what it covers.
ci.yamlis ubuntu-only:lint,jvm-tests,jni-tests,native-tests(linux) andcompiler-tests.It executes no Apple tests, and no js or wasm tests (#251). Green main CI at a
release ref is real coverage, but it is not coverage of every published
platform.
Suggested resolution
No workflow change is required to close this. The options, roughly in order of
cost:
CI is green" — in
CONTRIBUTING/release notes, so the convention isdiscoverable rather than tribal.
publish.yamlassert its own precondition: fail fast if the resolvedref has no successful CI run.
mainvia a ruleset, which closes the "release cutfrom an unverified ref" path directly.
Filed as documentation of an unwritten guarantee, not as an assertion that a
bad artifact has shipped. Nothing in the release history suggests one has.