Skip to content

Releases: hops-ops/hops-cli

v0.32.1

07 Jun 17:07

Choose a tag to compare

What's changed in v0.32.1

  • fix(deps): update rust crate distributed_cli to v1.6.3 (#59) (by @renovate[bot])

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

See full diff: v0.32.0...v0.32.1

v0.32.0

07 Jun 16:51

Choose a tag to compare

What's changed in v0.32.0

  • chore(deps): update rust crate log to v0.4.32 (#50) (by @renovate[bot])

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

  • chore(deps): update rust crate uuid to v1.23.2 (#52) (by @renovate[bot])

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

  • feat: mount distributed_cli for hops service (drop local adapter) (#56) (by @patrickleet)

    • feat: mount distributed_cli for hops service instead of a local adapter

    hops service now re-exports distributed_cli's command surface rather than
    carrying its own scaffold/describe/schema adapter: the Service variant holds
    distributed_cli::ServiceArgs and dispatches with distributed_cli::run. Deletes
    src/commands/service (the former ~930-line adapter) and swaps the dependency from
    distributed_tooling to distributed_cli.

    This makes hops a thin, optional front-end: new flags/commands added in
    distributed_cli (e.g. schema --format atlas) reach hops service on a plain
    cargo update, with no code changes here.

    Temporary git dep on the distributed branch until distributed_cli is published;
    swap to a registry version once distributed PR #74 releases.

    • chore: depend on published distributed_cli 1.6 from crates.io

    distributed PR #74 merged and released distributed_cli 1.6.x, so replace the
    temporary git dependency with the registry version. No git source or branch
    tracking; hops service resolves the command surface from the published crate.

    Closes #58

See full diff: v0.31.0...v0.32.0

v0.31.0

06 Jun 06:43

Choose a tag to compare

What's changed in v0.31.0

  • feat: add distributed service scaffold commands (#55) (by @patrickleet)

    • feat: add distributed service scaffold commands

    Implements [[tasks/hops-service-create-microsvc-scaffold]].

    Updates [[customize-hops-service-scaffold-and-schema-output]].

    Updates [[gitops-knative-service-scaffold]].

    Updates [[replace-model-booleans-with-repeatable-model]].

    Updates [[add-service-bus-flag]].

    Updates [[make-service-read-models-opt-in]].

    Updates [[rename-service-create-to-scaffold]].

    Updates [[add-service-scaffold-github-workflows]].

    • refactor: back service scaffold with distributed_tooling crate

    Replace the ~2100-line in-CLI generation logic (ScaffoldNames/ModelScaffold/
    MessageHandler, all the *_rs / *_yaml templates, Knative broker/trigger
    inference, GitHub workflow rendering) with a thin adapter over the new
    distributed_tooling crate. The CLI now:

    • keeps the clap surface (ScaffoldArgs + Framework/Transport/Store/Bus/
      GitopsPromote enums) and maps it to distributed_tooling::ServiceScaffoldSpec
      via From impls;
    • computes output_dir + the relative distributed dependency path as before;
    • calls generate_service_scaffold(), writes each GeneratedFile (creating parents,
      honoring FileMode::Executable), prints warnings, and runs the
      EnsureGithubRepository post-create action via the existing gh logic;
    • keeps describe/schema and the manifest compile-harness unchanged.

    Generation rules now live in (and are tested by) distributed_tooling. Verified
    byte-for-byte identical output against the previous implementation across five
    variants (HTTP, model+read-models, Knative+bus+gitops+promote, full GitHub, and
    preview-only) — the only intended difference is the generated service.rs builder
    (Service::new().with_repo(repo)).

    Dependency uses the meta-repo sibling path (../distributed/distributed_tooling);
    a git dependency will replace it for released/standalone builds.

    cli mod.rs: 2589 -> 930 lines.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • fix(ci): depend on distributed_tooling via git instead of a local path

    The ../distributed/distributed_tooling path dep only resolves in the meta-repo
    sibling layout; standalone hops-cli CI checks out only this repo, so the build
    failed reading the missing Cargo.toml. distributed is public, so a plain HTTPS
    git dep resolves with no secrets. Tracks the PR #53 branch until the crate is
    published to crates.io.

    Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

    • chore: depend on published distributed_tooling 1.5 from crates.io

    distributed v1.5.0 published distributed_tooling, so drop the temporary
    git-branch dependency in favor of the registry version. No git source or
    secrets needed; the crate only pulls in serde_json.

    Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com


    Co-authored-by: Claude Opus 4.8 (1M context) noreply@anthropic.com

See full diff: v0.30.0...v0.31.0

v0.30.0

29 May 23:42

Choose a tag to compare

What's changed in v0.30.0

  • feat(local): label hops provider install resources so doctor knows they're intentional (#54) (by @patrickleet)

    hops provider install now stamps app.kubernetes.io/managed-by: hops-provider-install
    on the Provider, DeploymentRuntimeConfig, and ClusterRoleBinding it manages. A
    custom install (e.g. a forked provider built from source) uses the
    <provider>-runtime DRC convention rather than the bootstrap local-dev-<provider>
    DRC, which hops local doctor previously reported as drift.

    hops local doctor now reads that label: a labeled provider is checked against the
    install convention (<provider>-runtime DRC, <provider>-cluster-admin binding,
    SA <provider>) and reported as a "custom install" with its package, instead of
    false drift — while still verifying cluster-admin and still flagging real drift
    (runtimeConfigRef=default / missing cluster-admin) in both modes.

    Co-authored-by: Claude Opus 4.8 (1M context) noreply@anthropic.com

See full diff: v0.29.0...v0.30.0

v0.29.0

29 May 23:10

Choose a tag to compare

What's changed in v0.29.0

  • feat(local): per-provider DRCs, hops local doctor, and global --context (#53) (by @patrickleet)

    Split the shared local-dev DeploymentRuntimeConfig into per-provider DRCs
    (local-dev-kubernetes, local-dev-helm), each with its own cluster-admin
    ServiceAccount + ClusterRoleBinding, and point each provider's runtimeConfigRef
    at its own DRC. A shared DRC let one provider's runtime image/SA silently
    clobber the other's pod.

    Add hops local doctor: verifies what hops local start set up — crossplane,
    both providers (installed / healthy / runtimeConfigRef pinned to its own DRC /
    DRC present / cluster-admin binding / ProviderConfig) and the registry — and
    reports drift with a non-zero exit + remediation. Catches a provider whose
    runtimeConfigRef reverted to default, dropping its cluster-admin SA (which
    breaks observing XRs through the in-cluster ProviderConfig).

    Add a global --context flag to hops local so every subcommand can target a
    context (e.g. hops local aws --refresh --profile hops --context colima), given
    before or after the subcommand. Plumbs through HOPS_KUBE_CONTEXT_ENV like
    config/provider install.

    Co-authored-by: Claude Opus 4.8 (1M context) noreply@anthropic.com

See full diff: v0.28.0...v0.29.0

v0.28.0

25 May 08:56

Choose a tag to compare

What's changed in v0.28.0

  • feat(local): add hops local listmonk + make --source-context required (#51) (by @patrickleet)

    Mirrors hops local zitadel / hops local github. Bootstraps the
    hops-ops/provider-listmonk Crossplane provider + a cluster-scoped
    ProviderConfig pointing at a Listmonk instance via Basic-Auth
    credentials (JSON Secret).

    Credential resolution waterfall:

    1. Explicit --endpoint / --username / --token flags
    2. LISTMONK_{ENDPOINT,USERNAME,TOKEN} env vars
    3. Read from the chart-bootstrapped Secret on a source cluster
      (with keys username + token — the shape produced by
      listmonk-chart v0.2.0's post-install api-user-bootstrap hook)

    Endpoint is derived from the source Secret name when not explicitly
    set: <release>-provider-creds → in-cluster service
    http://<release>.<source-namespace>.svc.cluster.local:9000.

    Default upjet provider package: ghcr.io/hops-ops/provider-listmonk:v0.0.3.

    Also drops the pat-local default from --source-context on BOTH
    this command and hops local zitadel — that hardcoded value bakes
    the implementer's personal cluster name into a tool meant for
    multiple users. Required positional flag now; users explicitly pass
    their own source context.

    Verified end-to-end on pat-local 2026-05-25:

    • Provider install + Healthy
    • ProviderConfig applied
    • UserRole MR reconciled (Crossplane → upjet → TF provider →
      Listmonk REST API → users / roles table)
    • User MR reconciled with cross-resource userRoleIdRef → numeric
      userRoleId (typed-reference resolution works end-to-end)
    • AppSettings MR reconciled (no-op write of current values; round-
      trip lossless)

See full diff: v0.27.0...v0.28.0

v0.27.0

25 May 08:00

Choose a tag to compare

What's changed in v0.27.0

  • feat: add local zitadel provider bootstrap (#49) (by @patrickleet)

    • feat: add local zitadel provider bootstrap

    • fix: preserve zitadel domain ports

See full diff: v0.26.1...v0.27.0

v0.26.1

22 May 16:50

Choose a tag to compare

What's changed in v0.26.1

  • chore(deps): update rust crate openssl-sys to v0.9.116 (#43) (by @renovate[bot])

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

  • chore(deps): update rust crate tokio to v1.52.3 (#44) (by @renovate[bot])

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

  • chore(deps): update unbounded-tech/workflow-vnext-tag action to v1.21.3 (#45) (by @renovate[bot])

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

  • chore(deps): update unbounded-tech/workflows-rust action to v2.3.0 (#46) (by @renovate[bot])

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

  • chore(deps): update rust crate tar to v0.4.46 (#47) (by @renovate[bot])

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

  • fix(deps): update rust crate serde_json to v1.0.150 (#48) (by @renovate[bot])

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

See full diff: v0.26.0...v0.26.1

v0.26.0

17 May 03:51

Choose a tag to compare

What's changed in v0.26.0

  • feat(secrets): three-bucket list with platform-pushed section, symmetric managed-by tagging (by @patrickleet)

    hops secrets sync aws now writes hops.ops.com.ai/managed-by=sync
    alongside the existing hops.ops.com.ai/secret=true, mirroring the
    managed-by=pushsecret tag that AuthStack-style Crossplane stacks
    attach to ESO-pushed AWS SM entries. Bucketing in secrets list
    becomes a positive match instead of "secret=true minus everything
    else."

    secrets list gains a "Platform-pushed secrets" section between the
    existing "Managed secrets" and "Other AWS secrets" sections. Routing
    by hops.ops.com.ai/managed-by:

    • sync (or absent + secret=true for legacy entries) → Managed
    • pushsecret → Platform-pushed
    • everything else → Other

    Platform-pushed columns: Name | Owner | Cluster | Namespace | KMS Key |
    Status. Owner is derived from the explicit hops.ops.com.ai/kind +
    hops.ops.com.ai/name tags (renders e.g. AuthStack/pat-local); falls
    back to scanning for the older hops.ops.com.ai/<kind.lower>=<name>
    label for entries pushed before the explicit tags were added.

    has_managed_secret_tag() (used by sync --cleanup to decide which
    remote secrets to consider for deletion) was tightened to require
    either managed-by=sync OR no managed-by tag at all. Previously it
    matched any secret=true entry, which would have swept up PushSecret-
    managed entries the moment we added secret=true to that flow.

    Existing managed secrets show remote tags differ in the list output
    until the next hops secrets sync aws writes the new managed-by tag.
    No data is at risk — the migration is just additive.

    Pairs with the AuthStack PushSecret commit + the SecretStack
    push/* IAM grant.

See full diff: v0.25.1...v0.26.0

v0.25.1

15 May 19:45

Choose a tag to compare

What's changed in v0.25.1

  • fix(provider install): never reuse a Provider's existing DRC ref (by @patrickleet)

    apply_provider_resources now always names the DRC -runtime
    instead of inheriting the existing Provider's spec.runtimeConfigRef.name.
    A previous "avoid orphaning the DRC" heuristic blindly reused whatever
    DRC the upstream Provider already referenced, then overwrote that DRC
    with the new install's image — silently corrupting any other Provider
    that happened to reference the same DRC.

    Repro (the bug that surfaced this): provider-helm and provider-kubernetes
    both referenced DRC "local-dev"; a later 'hops provider install helm'
    wrote local-dev with the helm dev image, leaving provider-kubernetes
    pinned to that DRC and therefore running the helm binary in a pod
    labeled as kubernetes.

    After the fix:

    • Each install creates an owned DRC named <existing_provider>-runtime
    • If the existing Provider already pointed at a differently-named DRC,
      a log::warn surfaces the migration ("switching to owned DRC ...; the
      old DRC is not deleted") so leftovers are discoverable
    • The orphaned DRC is left in place; it may still be referenced by
      another Provider, and deletion is the operator's call

    Validated end-to-end on colima: 'hops provider install --repo
    jonasz-lasut/provider-helm' migrated provider-helm from local-dev to
    crossplane-contrib-provider-helm-runtime, helm pod healthy on
    v1.999.2, provider-kubernetes (after clearing its stale local-dev ref)
    healthy on upstream provider-kubernetes:v1.2.0.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

See full diff: v0.25.0...v0.25.1