Skip to content

feat: wire up channel releases for KOTS apps#720

Merged
Justiceleeg merged 6 commits intomainfrom
justice/sc-136325/replicated-release-history-cli-command
May 8, 2026
Merged

feat: wire up channel releases for KOTS apps#720
Justiceleeg merged 6 commits intomainfrom
justice/sc-136325/replicated-release-history-cli-command

Conversation

@Justiceleeg
Copy link
Copy Markdown
Member

@Justiceleeg Justiceleeg commented May 8, 2026

Summary

Un-hides replicated channel releases for KOTS apps. The command existed but was hidden and explicitly errored for KOTS — the modern path. Wires it to the existing KotsClient.ListChannelReleases endpoint and exposes the data agents and customers expect from a "release history" lookup.

Reported by Dreadnode: their agent looked for a CLI equivalent of the Vendor Portal Release History page and had to call the Vendor API directly. Closes sc-136325.

What changed

channel releases (and channel history alias)

  • Accepts CHANNEL_ID_OR_NAME (resolved via GetChannelByName, mirroring PR Support lookup by channel name or ID for channel delete command #717's channel rm)
  • -o table|json for agent consumption
  • --page / --page-size for pagination (0-indexed, opt-in via --page-size)
  • New STATE column surfaces active / demoted; JSON includes isDemoted + demotedAt
  • Platform/Helm path preserved — only added optional flags

release inspect

  • Renders the Channels list that has been on the wire for years but was dropped by the 2023 type refactor. Table gets a CHANNELS: row; JSON gets channels.

Out of scope (per the spec)

  • No vendor-api changes — endpoint and wire fields already existed
  • No --include-installer-images flag (defer; not what was asked for)
  • No new release history command (agents compose channel ls + channel releases)
  • No promotion event timeline (isDemoted + demotedAt cover the 90% case)

Test plan

  • Unit: printer table+JSON tests for KOTS channel releases and release inspect channels
  • Manual against local stack: by-name lookup, by-ID lookup, history alias, JSON, pagination across pages, demote/un-demote round-trip surfaces correctly in STATE and JSON, release inspect renders/omits CHANNELS: correctly
  • Reviewer: spot-check platform/Helm app regression — channel releases against a legacy app should produce the same output as before, plus -o json now works

Notes

  • Cursor Bugbot caught a 0-indexed-page bug on the first commit; fixed in 37bf901f.
  • Docs (replicated-cli-channel-releases.md, replicated-cli-release-inspect.md) regenerate via the dagger pipeline, not by hand.

Refs sc-136325

Un-hides the previously KOTS-disabled `channel releases` command and wires it
to the existing `KotsClient.ListChannelReleases` endpoint so customers and
agents have a CLI equivalent of the Vendor Portal Release History page.

- Accept channel ID or name (resolved via GetChannelByName, mirroring rm)
- `history` alias matches Vendor Portal wording
- `-o json` for agent consumption; `--page` / `--page-size` for pagination
- New STATE column surfaces active vs. demoted (adds isDemoted/demotedAt
  to ChannelRelease type)
- release inspect now renders the Channels list that was always in the
  wire response but never exposed

Refs sc-136325
Comment thread pkg/kotsclient/channel.go Outdated
The previous `page > 0` guard silently dropped `--page 0` because Go's
zero-value collides with the valid 0-indexed first page. Result: the help
example `--page 0 --page-size 50` sent only `pageSize`, relying on
implicit API defaults instead of an explicit request.

Gate both params on `pageSize > 0` (pagination is opt-in via page-size),
then always send `currentPage` alongside it. Matches the explicit
`currentPage=0&pageSize=20` pattern already used by ListReleases.

Reported by Cursor Bugbot on PR #720.
Adds pkg/integration/channel_test.go covering the new command end-to-end
against an httptest.Server, including the platform/Helm branch which
couldn't be exercised against any available real-world environment.

Cases:
- KOTS table with active + demoted state rendering
- KOTS JSON includes isDemoted/demotedAt
- Pagination sends currentPage=0 explicitly (regression guard for the
  previously-fixed page-zero bug)
- Empty channel renders the "No releases in channel" message
- Platform/Helm legacy branch produces unchanged column layout
- Error early when --page is set without --page-size, instead of silently
  no-op'ing. Prevents footgun where `--page 2` looks like it's working
  but the API never sees the param.
- Use strconv.Itoa instead of fmt.Sprintf("%d", ...) for page params,
  matching network_list.go and cluster_list.go.
- Update help example to use `--page 1 --page-size 50` (page 0 is the
  default and didn't illustrate pagination semantics).
- Add integration test for by-name channel resolution (exercises the
  ListChannels fallthrough that was previously implicit).
- Add integration test guarding the new --page/--page-size validation.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3b163c0. Configure here.

Comment thread pkg/types/channel.go Outdated
Go's omitempty drops bool fields when false, so non-demoted releases
were missing isDemoted entirely. Agents checking
`release.isDemoted === false` saw undefined instead.

Drop omitempty from both IsDemoted and DemotedAt so non-demoted releases
serialize as `"isDemoted": false, "demotedAt": null` — explicitly
distinguishable from absent.
alicenstar
alicenstar previously approved these changes May 8, 2026
No other command in this CLI has a concept-rename alias; existing
aliases are all pure short/long synonyms (ls↔list, rm↔delete). Per PR
review, dropping `history` keeps `channel releases` consistent with
that convention.
@Justiceleeg Justiceleeg merged commit 8d0a447 into main May 8, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants