Skip to content

Release publishing relies on an unwritten convention, not a gate: nothing stops a publish from an unverified ref #264

Description

@monkopedia-coder

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:

  1. 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.
  2. Have publish.yaml assert its own precondition: fail fast if the resolved
    ref has no successful CI run.
  3. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedDepends on another issue, PR, or external blocker

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions