Skip to content

feat(template): add versions list/get/diff subcommands - #80

Merged
omattsson merged 4 commits into
mainfrom
feat/62-template-versions
May 16, 2026
Merged

feat(template): add versions list/get/diff subcommands#80
omattsson merged 4 commits into
mainfrom
feat/62-template-versions

Conversation

@omattsson

Copy link
Copy Markdown
Owner

Summary

Adds template versions subcommand group with three subcommands.

Closes #62

Commands

stackctl template versions list <id>        # List version history (newest first)
stackctl template versions get <id> <ver>   # Show a specific version snapshot
stackctl template versions diff <id> <l> <r># Compare two versions side by side

Output modes

  • table: human-readable summary / chart-diff table with change type
  • json/yaml: structured response (full TemplateVersionDiff for diff)
  • quiet: IDs for list; chart names with differences for diff

Changes

  • pkg/types/types.go: 8 new types — TemplateVersion, TemplateVersionDetail, TemplateSnapshot, TemplateSnapshotData, TemplateChartSnapshotData, TemplateVersionDiff, TemplateVersionSide, ChartDiffEntry
  • pkg/client/client.go: ListTemplateVersions, GetTe- pkg/client/client.go: ListTemplateVersions, GetTe- pkg/client/client.go: ListTemplateVersions, GetTe- pkand- pkg/client/client.go: ListTemplateVersions, GetTe- p th- `pkg/cnds (client + cmd layers)
  • Integration tests: list/get/diff round-trip via in-process mock server
  • E2E test: happy-path template versions diff scenario

Implements issue #62.

- types: TemplateVersion, TemplateVersionDetail, TemplateSnapshot,
  TemplateSnapshotData, TemplateChartSnapshotData, TemplateVersionDiff,
  TemplateVersionSide, ChartDiffEntry
- client: ListTemplateVersions, GetTemplateVersion, DiffTemplateVersions
- cmd: `template versions list|get|diff` subcommand group
  - table mode: human-readable summary / chart-diff table
  - json/yaml mode: structured output
  - quiet mode: IDs for list; chart names with differences for diff
- unit tests: all output modes + 404 for all three commands
- integration tests: list/get/diff round-trip via mock server
- e2e test: happy-path diff scenario
Copilot AI review requested due to automatic review settings May 15, 2026 19:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a template versions command group for inspecting and comparing published template snapshots through the stackctl CLI.

Changes:

  • Added template version/diff response types and client methods for list/get/diff endpoints.
  • Added Cobra subcommands for template versions list, get, and diff with table/JSON/YAML/quiet output handling.
  • Added unit, integration, and E2E coverage for the new version workflows.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
cli/pkg/types/types.go Defines template version snapshot and diff response models.
cli/pkg/client/client.go Adds client methods for template version list/get/diff API calls.
cli/pkg/client/client_test.go Adds client unit tests for the new API methods.
cli/cmd/template.go Adds the new template versions Cobra command group and output rendering.
cli/cmd/template_test.go Adds command tests for versions list/get/diff behavior.
cli/test/integration/template_definition_integration_test.go Extends integration mock and tests version list/get/diff round trips.
cli/test/e2e/cli_e2e_test.go Adds E2E mock support and a happy-path diff test.

Comment thread cli/pkg/client/client.go
var diff types.TemplateVersionDiff
err := c.GetWithQuery(
fmt.Sprintf("/api/v1/templates/%s/versions/diff", templateID),
map[string]string{"left": leftID, "right": rightID},
Comment thread cli/cmd/template.go Outdated
Comment on lines +608 to +609
fmt.Fprintf(printer.Writer, "Comparing %s → %s\n\n", diff.Left.Version, diff.Right.Version)
headers := []string{"CHART", "CHANGE", "REPO URL CHANGED", "VALUES CHANGED"}
Comment thread cli/cmd/template.go
Comment on lines +605 to +606
case output.FormatYAML:
return printer.PrintYAML(diff)
omattsson added 2 commits May 16, 2026 08:12
- types: add Category to TemplateSnapshotData to match backend model
- types: add LeftLocked/RightLocked/LeftRequired/RightRequired/
  LeftSortOrder/RightSortOrder to ChartDiffEntry (silent data loss fix)
- cmd: rename <version>/<left>/<right> args to <version-id>/
  <left-version-id>/<right-version-id> — clarify UUID requirement
- cmd: update examples to show correct usage pattern with -q pipe
- cmd: diff quiet mode — add comment documenting chart-name deviation
- cmd: versions get table — show individual chart names instead of count
- cmd: use ASCII '->' instead of UTF-8 '→' for Windows compatibility
- test: add TestTemplateVersionsGetCmd_NotFound
- test: add TestTemplateVersionsDiffCmd_NotFound
- test: add assertions on 'Comparing v1 -> v2' and 'CHART' header
- e2e: add TestE2E_TemplateVersionsList with table + quiet assertions
- cmd: render per-chart unified text diff in table mode (satisfies
  issue #62 acceptance criteria: 'diff renders unified text in table mode')
  uses go-difflib to show left/right values diff after summary table
- test: add YAML output tests for versions list, get, and diff commands
- go.mod: promote go-difflib from indirect to direct dependency

Note: Copilot's suggestion to change 'left'/'right' query params to 'from'/'to'
is incorrect — the backend (k8s-stack-manager) uses 'left'/'right'.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread cli/pkg/client/client.go
var diff types.TemplateVersionDiff
err := c.GetWithQuery(
fmt.Sprintf("/api/v1/templates/%s/versions/diff", templateID),
map[string]string{"left": leftID, "right": rightID},
Comment thread cli/pkg/types/types.go Outdated
Comment on lines +486 to +489
LeftRequired bool `json:"left_required,omitempty" yaml:"left_required,omitempty"`
RightRequired bool `json:"right_required,omitempty" yaml:"right_required,omitempty"`
LeftSortOrder int `json:"left_sort_order,omitempty" yaml:"left_sort_order,omitempty"`
RightSortOrder int `json:"right_sort_order,omitempty" yaml:"right_sort_order,omitempty"`
Comment thread cli/cmd/template.go
Comment on lines +639 to +640
for _, ch := range diff.ChartDiffs {
if ch.LeftValues == ch.RightValues {
- types: remove omitempty from ChartDiffEntry bool/int fields
  (LeftRequired, RightRequired, LeftSortOrder, RightSortOrder) --
  false and 0 are meaningful values that must not be silently dropped
  in JSON/YAML output
- test: add TestTemplateVersionsDiffCmd_UnifiedDiffOutput to verify the
  unified text diff path is exercised (left/right values differ, asserts
  ---, +++, @@ markers and changed lines in output)

Note: Copilot's repeated suggestion to rename 'left'/'right' to 'from'/'to'
is incorrect -- the k8s-stack-manager backend uses 'left'/'right' (confirmed
in handlers/template_versions.go:161).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment thread cli/pkg/client/client.go
var diff types.TemplateVersionDiff
err := c.GetWithQuery(
fmt.Sprintf("/api/v1/templates/%s/versions/diff", templateID),
map[string]string{"left": leftID, "right": rightID},
@omattsson
omattsson merged commit e9d4ba4 into main May 16, 2026
7 checks passed
@omattsson
omattsson deleted the feat/62-template-versions branch May 16, 2026 06:44
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.

feat(template): version list/get/diff

2 participants