hoist

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2026 License: Apache-2.0

README ยถ

hoist

๐Ÿค– AI Agents: read AGENTS.md instead. This README is for humans.

A terminal UI that promotes container images between environments in an Argo CD GitOps repo, and drives the whole path from edit to rollout.

hoist reads a repo laid out as <apps-root>/<env>/<family>/*.yaml, shows every environment's images side by side, and moves an environment's image set to the next environment as a block โ€” staging โ†’ production for web, worker, queue and friends in one reviewable PR. It can also write one fresh build straight from the registry into a single environment, or roll an environment's Deployments without changing anything they declare.

The interesting part is what happens after you press enter: hoist commits to a worktree, opens the PR, waits for CI, waits for a person to comment hoist approve <id> (production only, by default), squash-merges, asks Argo CD to refresh, and follows the rollout โ€” telling you at every step what it is doing and what it is waiting for. Kill it once it is under way and hoist resume <id> (or hoist resume --env <target>) picks up where the world actually is, not where a log file says it was. (The one narrow exception is the first second or so before its state file exists: a process killed there leaves a claim file naming the target env, and the next attempt tells you where it is so you can delete it.)

What it looks like

The matrix is the entry screen: one row per family, one column per environment, every cell the reference that environment declares and its state as a word. Under it, whatever is promoting right now โ€” re-observed against GitHub and the cluster, not read from a log โ€” with the one thing that is yours to do.

โ•ญโ”€ hoist ยท matrix ยท repo โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ FAMILY      โ–ธ A                   B                    C                     โ”‚
โ”‚ absent      v1            pinned                       v9    pinned          โ”‚
โ”‚ drift       v1          unpinned  v2           pinned  v2  unpinned          โ”‚
โ”‚ empty                             no images                                  โ”‚
โ”‚ mixedtags   2 versions     split                                             โ”‚
โ”‚ multi       2 images      pinned  2 images   unpinned                        โ”‚
โ”‚ pinned      v1            pinned  v1           pinned  v1    pinned          โ”‚
โ”‚ sidecar     v1            pinned  v1           pinned                        โ”‚
โ”‚ thirdparty  7           external  8          external  8   external          โ”‚
โ”‚                                                                              โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ•ญโ”€ in flight (1) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚5pr6sd333t   app-staging โ†’ app-production   started 12m ago                   โ”‚
โ”‚โ— branch  โ— commit  โ— push  โ— PR #103  โ— CI  โ— approval  โ—‹ merge              โ”‚
โ”‚โ—‹ argo refresh  โ—‹ argo sync  โ—‹ rollout                                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚blocked on you โ€” comment on PR #103 to release it:    hoist approve 5pr6sd333tโ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
env a                          p promote โ€ข d deploy โ€ข r resume โ€ข ? help โ€ข q quit

(Rendered from the test fixture, which is why the environments are called A, B and C; a real repo's columns are its Argo destination namespaces, and a production column is marked โš .)

Before any write, the confirm screen leads with what is being shipped โ€” the commits between the build an environment declares and the one about to be written, and which of them migrate the database โ€” with the YAML diff one key away:

โ•ญโ”€ hoist ยท confirm deploy โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ghcr.io/example/web:v9   โ†’   app-production              mode: PR ยท productionโ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚rolling out 14 commits ยท 2 migrations ยท replacing v202601010101, live 4 weeks โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  4a1c2ef  Add rate limiting to the public API                                โ”‚
โ”‚  e9b0d31  Fix N+1 query when resolving digests                               โ”‚
โ”‚  77c0ffe  db: add index on events.created_at  migration                      โ”‚
โ”‚  1b2d3e4  Bump temporal SDK to 1.31                                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚2 migrations run on this deploy:                                              โ”‚
โ”‚  db/migrate/20260225T101500_add_events_created_at_index.rb                   โ”‚
โ”‚  db/migrate/20260301T090200_backfill_events_tenant_id.rb                     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚writes 3 occurrences in 1 file ยท digest dddddddddddd           d  see the yamlโ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
                              enter deploy ยท โ†‘/โ†“ scroll ยท d yaml diff ยท esc back

Install

go install github.com/abradner/hoist/cmd/hoist@latest

That builds the newest tagged release (or main, before the first tag exists). Prebuilt binaries for macOS and Linux, amd64 and arm64, are attached to every release with a checksums.txt; hoist --version names what you are running. hoist shells out to git and gh โ€” both on PATH, and gh auth status logged in, is the whole prerequisite.

The three operations

Everything hoist does is one of these. The user guide walks each screen and key, says what to do when a promotion stops, and covers resuming, registry credentials and direct mode. Each is a subcommand and a key on the matrix, with the same gates either way, and each has a read-only form that prints what would happen and touches nothing: plan for a promotion, --dry-run on deploy and restart.

Promote a pair โ€” copy what one environment runs into the next, every first-party image the target already carries (the promotable prefixes; anything else is listed as untouched):

hoist plan --from app-staging --to app-production --dry-run   # the diff, nothing written
hoist promote --from app-staging --to app-production           # branch, commit, push, PR, CI โ€ฆ

promote resolves each image to a digest โ€” by default what the source environment's pods are running, else the manifest's own pin, else the registry, in the order digest_sources gives โ€” rewrites only the image lines in the target environment, and opens one PR carrying all of them. Then it waits: for CI, for hoist approve <id> on the PR when the target is production, for the merge, for Argo to sync, for every Deployment it touched to roll out. On the matrix this is p.

Deploy a build โ€” write one named image into one environment, through the same pipeline:

hoist deploy --env app-staging --image ghcr.io/me/web:v3@sha256:โ€ฆ

The reference must carry its digest; hoist will not resolve a bare tag on the way in. On the matrix this is d: a picker lists the registry's tags with the build age of each, whether the paired staging environment has committed it, and the commits and migrations between the build the environment declares and the one under the cursor.

Restart a family โ€” roll an environment's Deployments without changing what they declare:

hoist restart --env app-staging --family web

This is the one operation that writes to the cluster instead of to git: it stamps the same annotation kubectl rollout restart does, so there is no branch, no PR and nothing to resume. Before rolling anything it names every target with its replica count and strategy and warns where the restart will not be graceful. On the matrix this is R.

Rules hoist enforces

When hoist refuses to do something, it is one of these. They are enforced in code, not by convention, and the refusal says which one:

  • Production always goes through a PR. Any env listed under envs.production is refused direct mode outright, whatever a flag or a keypress asked for.
  • Production waits for a person โ€” a hoist approve <id> comment on the PR โ€” unless that env is explicitly set to approval: auto.
  • Nothing written is a bare tag. Every image reference hoist writes is tag@sha256:โ€ฆ, and a tag with no digest is refused rather than resolved on the fly. The tag picker will not let you select a build whose digest it could not read, for the same reason.
  • A direct commit takes the env's name twice โ€” --confirm-direct=<env> at the CLI, a keypress and a confirmation in the TUI โ€” so a write with no PR is never one flag or one key.
  • A restart changes no declared reference, and warns where it may still not be a no-op: an unpinned tag can pull a different build when the replacement pod lands. Restarting production takes --confirm-production=<env>.
  • One promotion per target environment until it lands. While an env's promotion is still before its merge (or its direct push), a second one for that env is refused and named; hoist promotions lists them and hoist resume <id> continues one. Once the change has landed the guard lifts, even if Argo is still converging.

These, by contrast, are warnings and never refusals: a digest the source's pods and manifest disagree on, a promotion that jumps straight to production, a build staging has never committed, a migration in the delta, a restart that will not be graceful. hoist says so and lets you decide.

What hoist is not

It is not a controller, an operator, or a platform. It runs on a laptop, holds no state a person cannot delete (~/.local/state/hoist/, an index of where to look, never a record of what happened), and stops when you close it โ€” a promotion it started is a branch, a PR and Argo doing what Argo does, all of which are there whether hoist is running or not. It is not Kargo or Argo Rollouts: it drives your GitOps repo through your PR review and lets Argo deploy, rather than replacing either.

Configuration

hoist reads $XDG_CONFIG_HOME/hoist/config.yaml (usually ~/.config/hoist/config.yaml). Nothing cluster-specific lives in the GitOps repo itself. A minimal example:

repos:
  - path: ~/src/my-gitops
    github: me/my-gitops
    apps_root: cluster/apps
    envs:
      production: [app-production]
      pairs: { app-staging: app-production }
    approvers: [me]
    kube: { context: my-cluster }
    apps: { ghcr.io/me/web: me/web }        # image repo โ†’ app repo, for commit history
registries:
  - prefix: ghcr.io/me/
    auth: [env, keychain]

docs/config.example.yaml is the annotated schema: every key, its default, and why. Unknown keys are errors, and hoist config show prints the effective config with defaults filled in.

License

Apache-2.0. See LICENSE.

Directories ยถ

Path Synopsis
cmd
hoist command
Command hoist is a terminal UI that promotes container images between environments in an Argo CD GitOps repository and follows the change through PR, merge and rollout.
Command hoist is a terminal UI that promotes container images between environments in an Argo CD GitOps repository and follows the change through PR, merge and rollout.
internal
app
Package app is the root Bubble Tea model for the hoist TUI.
Package app is the root Bubble Tea model for the hoist TUI.
app/deploy
Package deploy is the confirm screen for writing one named image into one env โ€” the "image bump" half of hoist's problem statement, reached with d on the matrix and a tag chosen in internal/app/tags.
Package deploy is the confirm screen for writing one named image into one env โ€” the "image bump" half of hoist's problem statement, reached with d on the matrix and a tag chosen in internal/app/tags.
app/flight
Package flight is the flight screen: shown once a promotion starts driving through engine.AllSteps (branch, commit, push, PR, CI green, approved, merged, then (M5) Argo refresh, Argo sync, rollout), it lists every step with a glyph for its current state, the active step's own human detail text, a stopwatch since the promotion started, and a togglable scrollback of PromotionState.History.
Package flight is the flight screen: shown once a promotion starts driving through engine.AllSteps (branch, commit, push, PR, CI green, approved, merged, then (M5) Argo refresh, Argo sync, rollout), it lists every step with a glyph for its current state, the active step's own human detail text, a stopwatch since the promotion started, and a togglable scrollback of PromotionState.History.
app/history
Package history holds the function types through which screens ask about commit history and migration deltas โ€” types only, no Bubble Tea, no adaptor construction.
Package history holds the function types through which screens ask about commit history and migration deltas โ€” types only, no Bubble Tea, no adaptor construction.
app/matrix
Package matrix is the env ร— family screen: one row per family, one column per env, the family's image tag in each cell with its state spelled out โ€” pinned, unpinned, split, external, drifted โ€” as a word an operator can read without a legend.
Package matrix is the env ร— family screen: one row per family, one column per env, the family's image tag in each cell with its state spelled out โ€” pinned, unpinned, split, external, drifted โ€” as a word an operator can read without a legend.
app/plan
Package plan is the plan/confirm screen: it runs discovery + digest resolution + gitops.BuildPlan for one source/target env pair, shows a tickable list of image repos on the left and, on the right, what the promotion ships for the repo under the cursor โ€” the commits between what the target declares and what the source resolved to, and the migrations among them (M10, #85 screen 04/12) โ€” with the unified diff one key away.
Package plan is the plan/confirm screen: it runs discovery + digest resolution + gitops.BuildPlan for one source/target env pair, shows a tickable list of image repos on the left and, on the right, what the promotion ships for the repo under the cursor โ€” the commits between what the target declares and what the source resolved to, and the migrations among them (M10, #85 screen 04/12) โ€” with the unified diff one key away.
app/restart
Package restart is the matrix's R key: the screen that shows what a restart would roll, takes the confirmation, and follows the rollout.
Package restart is the matrix's R key: the screen that shows what a restart would roll, takes the confirmation, and follows the rollout.
app/tags
Package tags is the tag-picker screen: given one image repo, it lists the registry's own tags and, once each row's metadata loads, its created time and digest โ€” sorted per AGENTS.md's M6 brief invariant 3 (prefer the app repo's own git tags for ordering when the image repo is mapped; fall back to the registry's own Created metadata otherwise).
Package tags is the tag-picker screen: given one image repo, it lists the registry's own tags and, once each row's metadata loads, its created time and digest โ€” sorted per AGENTS.md's M6 brief invariant 3 (prefer the app repo's own git tags for ordering when the image repo is mapped; fall back to the registry's own Created metadata otherwise).
config
Package config loads hoist's config file: $XDG_CONFIG_HOME/hoist/config.yaml, or ~/.config/hoist/config.yaml when XDG_CONFIG_HOME is unset โ€” the same rule on every platform, so the docs stay one sentence โ€” overridable with --config <path>.
Package config loads hoist's config file: $XDG_CONFIG_HOME/hoist/config.yaml, or ~/.config/hoist/config.yaml when XDG_CONFIG_HOME is unset โ€” the same rule on every platform, so the docs stay one sentence โ€” overridable with --config <path>.
engine
Package engine drives one promotion's four steps โ€” branch, commit, push, PR โ€” to completion, re-observing the remote before every action (AGENTS.md ยง4.1: "the world is the state").
Package engine drives one promotion's four steps โ€” branch, commit, push, PR โ€” to completion, re-observing the remote before every action (AGENTS.md ยง4.1: "the world is the state").
restart
Package restart is the shared core of `hoist restart` and the matrix's R key: what a restart targets, what is worth warning about before it runs, how the write is made safely, and how the rollout that follows is observed.
Package restart is the shared core of `hoist restart` and the matrix's R key: what a restart targets, what is worth warning about before it runs, how the write is made safely, and how the rollout that follows is observed.
ui
Package ui holds what every hoist screen shares: one Styles palette built from a light/dark flag, the frame and pane chrome every screen is drawn in (frame.go), the dialog compositor (dialog.go), relative-time wording (time.go) and the status-bar line helper.
Package ui holds what every hoist screen shares: one Styles palette built from a light/dark flag, the frame and pane chrome every screen is drawn in (frame.go), the dialog compositor (dialog.go), relative-time wording (time.go) and the status-bar line helper.
ui/uitest
Package uitest is the one harness every screen's tests render through (AGENTS.md ยง4.8, M10): a golden comparison at a stated terminal size that also asserts the shape a terminal would actually show โ€” exactly height lines, none wider than width โ€” and a way to drive a screen with real keypresses, so a test can never pass by setting the field a key would have set.
Package uitest is the one harness every screen's tests render through (AGENTS.md ยง4.8, M10): a golden comparison at a stated terminal size that also asserts the shape a terminal would actually show โ€” exactly height lines, none wider than width โ€” and a way to drive a screen with real keypresses, so a test can never pass by setting the field a key would have set.
pkg
argo
Package argo drives Argo CD entirely through the Kubernetes API: the dynamic client against the Application custom resource (argoproj.io/v1alpha1), never Argo's own REST/gRPC server and never an Argo API token (AGENTS.md ยง4.7, docs/repo-map.md's Kubernetes API row).
Package argo drives Argo CD entirely through the Kubernetes API: the dynamic client against the Application custom resource (argoproj.io/v1alpha1), never Argo's own REST/gRPC server and never an Argo API token (AGENTS.md ยง4.7, docs/repo-map.md's Kubernetes API row).
forge
Package forge is the code-host boundary (GitHub today; AGENTS.md ยง11 leaves GitLab as an interface with no adaptor until a GitLab repo needs one).
Package forge is the code-host boundary (GitHub today; AGENTS.md ยง11 leaves GitLab as an interface with no adaptor until a GitLab repo needs one).
forge/github
Package github implements pkg/forge.Forge against the real GitHub REST API, using github.com/cli/go-gh/v2 (AGENTS.md ยง4.7's one sanctioned new dependency for M3 โ€” not google/go-github, not a hand-rolled REST client, not the full gh CLI as a library).
Package github implements pkg/forge.Forge against the real GitHub REST API, using github.com/cli/go-gh/v2 (AGENTS.md ยง4.7's one sanctioned new dependency for M3 โ€” not google/go-github, not a hand-rolled REST client, not the full gh CLI as a library).
git
Package git drives the git binary โ€” never go-git (AGENTS.md ยง4.6) โ€” so that a commit made on the user's behalf inherits the user's own signing configuration (gpg.format=ssh, user.signingkey, 1Password's gpg.ssh.program, includeIf) exactly as if the user had typed the command themselves.
Package git drives the git binary โ€” never go-git (AGENTS.md ยง4.6) โ€” so that a commit made on the user's behalf inherits the user's own signing configuration (gpg.format=ssh, user.signingkey, 1Password's gpg.ssh.program, includeIf) exactly as if the user had typed the command themselves.
gitops
Package gitops reads an Argo CD GitOps repository and plans, applies and verifies byte-minimal image promotions between its environments.
Package gitops reads an Argo CD GitOps repository and plans, applies and verifies byte-minimal image promotions between its environments.
image
Package image parses, prints and identifies container image references.
Package image parses, prints and identifies container image references.
k8s
Package k8s reads what a namespace is running and, opt-in, one image pull secret.
Package k8s reads what a namespace is running and, opt-in, one image pull secret.
migrate
Package migrate answers the question the confirm screens lead with: between the build an env is running and the build about to be written into it, which commits ship, and does any of them migrate the database (R-005 in docs/repo-map.md โ€” on the target repo every Application auto-syncs and the app entrypoint runs db:prepare, so a merge can migrate production as a side effect).
Package migrate answers the question the confirm screens lead with: between the build an env is running and the build about to be written into it, which commits ship, and does any of them migrate the database (R-005 in docs/repo-map.md โ€” on the target repo every Application auto-syncs and the app entrypoint runs db:prepare, so a merge can migrate production as a side effect).
redact
Package redact turns transport errors into messages that carry no address and no secret.
Package redact turns transport errors into messages that carry no address and no secret.
registry
Package registry resolves tags to digests and lists tags, behind an ordered, explicit credential chain.
Package registry resolves tags to digests and lists tags, behind an ordered, explicit credential chain.
resolve
Package resolve turns the source env's image occurrences into the pinned references a promotion writes, from what the env is running first, then its manifests, then the registry โ€” never a guess (AGENTS.md ยง4.2, principle 3).
Package resolve turns the source env's image occurrences into the pinned references a promotion writes, from what the env is running first, then its manifests, then the registry โ€” never a guess (AGENTS.md ยง4.2, principle 3).
rollout
Package rollout reads Deployment rollout completeness, and reports current Job/CronJob state, through the typed client-go clientset (k8s.io/api/apps/v1, k8s.io/api/batch/v1) โ€” no dynamic client needed, since these are stable, already-vendored Go types โ€” following the same client-go adaptor shape pkg/k8s established (cluster.go/kubeconfig.go/fake.go): a thin wrapper over kubernetes.Interface, redaction at every error boundary, a fake clientset for tests.
Package rollout reads Deployment rollout completeness, and reports current Job/CronJob state, through the typed client-go clientset (k8s.io/api/apps/v1, k8s.io/api/batch/v1) โ€” no dynamic client needed, since these are stable, already-vendored Go types โ€” following the same client-go adaptor shape pkg/k8s established (cluster.go/kubeconfig.go/fake.go): a thin wrapper over kubernetes.Interface, redaction at every error boundary, a fake clientset for tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL