Skip to main content

rk 0.1.12 copy "rk: ^0.1.12" to clipboard
rk: ^0.1.12 copied to clipboard

A release tool.

rk #

Release kit manages releasing a project to your configured targets: Git tags, a GitHub Release, Homebrew, standalone binaries — as one checked plan instead of a release script.

Features #

  • One small file, written for you. rk init proposes it; versions, names, and repositories come from native manifests and Git. Unknown fields are errors.
  • Reality first. A target that is already public is recorded, not published again.
  • Fail-closed. The complete plan is validated before the first step acts, and every refusal names the problem and the fix (doc/codes.md).
  • No secrets. Publication sessions belong to dart pub, gh, codesign, notarytool, and git. rk asks for them only after private work is finished and checked; status and release --stage never do. A session rk had to create is cleared when the run ends, so a release leaves no credential behind; one that already existed is left exactly as it was.
  • Signed when you say so. tag.gpgSign, or a release history that is already signed, makes a signature required rather than incidental — and rk reads it back off the tag it created instead of trusting the config. A signature it cannot verify is refused, not reported as signed.
  • Final bytes checked. Linux executables and macOS Dart bundles use one artifact contract. Every macOS code file is signed; the installed command is tested before and after archiving. See CLI artifacts for layouts, signing and compile-time metadata.
  • Monorepos. Cross-unit version constraints are checked before anything acts.

Getting Started #

rk init reads the repository and proposes a configuration.

$ rk init
Select release outputs

                         Produce              Publish
  Unit                    Binary   Git tag   pub.dev   GitHub   Homebrew
› rk                      [ ]      [x]       [x]       [ ]      [ ]

Binary — standalone rk archives for macos-arm64

↑↓ unit   ←→ option   space toggle   enter review   q cancel

The selector keeps workspace grouping roots out of the way and hides publish_to: none packages by default. If one of those packages intentionally ships through tags, binaries, GitHub, or Homebrew, press a to show it. JSON output still reports every discovered candidate.

That proposal is the whole configuration. Targets are opt-in — release-kit's own file says yes to all of them. rk plan draws the configured release graph before rk observes public state or changes anything:

$ rk plan
RELEASE-KIT RELEASE PLAN
main@888444b

└─ 1 · rk 0.1.0
   ├─ STAGE
   │  └─ [source snapshot]
   │     ├─▶ [package archive]
   │     ├─▶ [release notes]
   │     ├─▶ linux-arm64  [build] ─▶ [archive]
   │     ├─▶ linux-x64  [build] ─▶ [archive]
   │     ├─▶ macos-arm64  [build + sign] ─▶ [notarize] ─▶ [archive]
   │     ├─▶ [Homebrew formula] · needs archives
   │     └─▶ [finalize stage]
   └─ PUBLISH
      └─▶ [tag v0.1.0]
          ├─▶ [pub.dev rk@0.1.0]
          └─▶ [GitHub Release · 4 assets]
              └─▶ [Homebrew · rk.rb]

no destination checks · no changes

The graph and its direct dependency edges come from the same stage and public contracts that rk release executes. It is source-only: it does not inspect destinations, acquire credentials, build artifacts, or write a stage. Wide terminals receive the tree; narrow terminals and pipes receive an outline, and --json exposes the canonical nodes.

rk status checks the destinations themselves, not a log; "Not staged" is the private work that must finish before anything goes public:

When Binary or Homebrew is selected, rk init proposes every binary platform the current host can produce. A macOS host can build its native macOS binary and cross-compile pure-Dart Linux binaries; a Linux host does not add a macOS artifact that requires a macOS release host. Docker and Podman are optional: they run cross-built Linux binaries for the smoke test. Without one, the Linux binary is still cross-compiled and is recorded as built but not executed.

$ rk status
release-kit · main@888444b

  rk 0.1.0

    Not published
      Git tag                    v0.1.0
      pub.dev                    rk
      GitHub Release             danReynolds/release-kit
      Homebrew                   danReynolds/homebrew-tap

    Not staged
      Local binaries
        producers/rk/archives/rk-0.1.0-linux-arm64.tar.gz
        producers/rk/archives/rk-0.1.0-linux-x64.tar.gz
        producers/rk/archives/rk-0.1.0-macos-arm64.tar.gz
      pub.dev                    rk source
      GitHub Release             4 artifacts
      Homebrew                   rk.rb

The release itself — ordered, staged, disclosed, one yes per unit — is shown in Two packages, one release.

Install #

$ dart pub global activate rk
$ brew install danreynolds/tap/rk

The same CLI ships from pub.dev, Homebrew, and GitHub Releases — rk --version reports what you are running.

The maintained production release protocol and 0.1.4 canary receipt show the proof required before calling those channels released.

Targets #

git-tag create and push a version tag
pub.dev publish a Dart package
github-release create a GitHub Release with selected outputs
homebrew publish the executable through a Homebrew tap
binary build standalone executable archives, publishing nothing

Planned: npm, RubyGems. rk target list is always the set your installed rk supports.

Developing another built-in target? Start with Adding a release target, which uses GitHub Release as the worked example and defines the modularity and correctness bar. The release pipeline architecture shows how target modules join the shared stage and publication coordinators.

Two packages, one release #

Each [release.<name>] is a unit, released on its own version. Two units, cli depending on core, publishing under their pubspec names — init writes this file too, and it stays yours to edit:

schema = 2

[release.core]
path = "packages/core"
publish = ["pub.dev"]

[release.cli]
path = "packages/cli"
publish = ["pub.dev"]

rk release orders the units, stages and checks the private work, and says what a yes makes permanent — before anything permanent acts:

$ rk release
Release order: core 0.3.0 -> cli 0.3.0

    pub.dev · example_core                         not published
core 0.3.0 · staging
    pub.dev · example_core
✓     package archive                              staged
✓   Release inputs · targets · signing · staged bytes checked
✓   pub.dev · example_core                         signed in

  Release
    core 0.3.0
      publish example_core 0.3.0 to pub.dev
  pub.dev never deletes a version. a version can be retracted, which hides it and removes nothing.
  everything before this yes re-runs safely. after it, the first permanent step is: publish example_core 0.3.0 to pub.dev.

  this release claims, for the first time:
    pub.dev          example_core
                     permanent: a package name cannot be renamed, reassigned, or released back
Release core 0.3.0? [y/N]

Commands #

rk init propose a release.toml
rk plan [unit] show the configured source-only release graph
rk status inspect this repository
rk release publish unfinished units
rk release <unit> one unit
rk release --stage private steps only
rk target list what this binary can create or publish
rk target <name> one target: requirements and a minimal example
rk clean remove this repository's private stages

rk -h lists every flag, the output marks, and the exit codes.

Agents #

Releases are driven by agents as much as by hands. Every command speaks --json (doc/json.md) — the same facts as the terminal output, with stable codes. Here, why cli waits for core:

$ rk status --json | jq .problems
[
  {
    "unit": "cli",
    "code": "RK-REL-001",
    "message": "example_core 0.3.0 must be live on pub.dev: not published: example_core has never been published",
    "remedy": "publish the prerequisite first: rk release core"
  }
]

Without a terminal, a needed answer stops the release — "no terminal to answer on — stopped; nothing was published." --yes is the unattended yes, and it skips no inspection. Exit codes: 0 report or completed command, 1 refused or failed, 2 usage, 3 rk itself crashed — --json mirrors it in exit.

Behavior #

Stages live under .rk/work/stages. Keep them while a binary release is partly public so the remaining targets receive the exact staged bytes the public ones already pinned; rk clean removes this repository's stages, and asks first.

Git-identified targets (git-tag, github-release, homebrew) need a clean working tree. A registry-only or local release may include uncommitted work: rk warns, snapshots that tree, and rechecks the snapshot before publishing.

Releases run from your machine. The design anticipates CI; support is deferred.

This repository #

rk releases itself, from a clean checkout:

$ dart run bin/rk.dart status
$ dart run bin/rk.dart release rk

MIT. Working notes in doc/.

0
likes
0
points
751
downloads

Publisher

unverified uploader

Weekly Downloads

A release tool.

Repository (GitHub)
View/report issues

License

unknown (license)

More

Packages that depend on rk