Skip to content

refactor(get artifact, assert artifact): fetch through the Kosli API client - #1269

Draft
dangrondahl wants to merge 7 commits into
refactor/kosli-get-trailfrom
refactor/kosli-artifacts
Draft

dangrondahl wants to merge 7 commits into
refactor/kosli-get-trailfrom
refactor/kosli-artifacts

Conversation

@dangrondahl

@dangrondahl dangrondahl commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #1249. This adds the Artifacts and Asserts endpoints to internal/kosli, and moves get artifact and assert artifact onto them.

  • internal/kosli/artifacts.go
  • internal/kosli/asserts.go adds AssertArtifact(ctx, fingerprint, AssertArtifactFilter{Flow, Environment, Policies}). Assert has its own tag in the spec, so it gets its own file.
  • client.go gets withQuery, which appends a query string only when there is one.
  • get artifact
    • Table output: decodes the artifacts with Value() and prints them. A fingerprint lookup becomes a one-element list, so the shim that wrapped a single object in [...] is gone.
    • json output: prints the raw body and never decodes. A field the Artifact type can't take fails only the table. TestGetArtifactPrintsJSONThatTheTableCannotDecode pins this down, using created_at: "".
  • assert artifact goes through kosliAPI().AssertArtifact.
  • Both commands take run(ctx, out, args). RunE passes cmd.Context().

Why AssertArtifact returns the raw body

Reads normally return a typed Response[T], which decodes only when Value() is called. assert artifact is an exception for now. Its exit code, which CI gates on, deliberately decodes only compliant (#1246). TestAssertCompliantDependsOnlyOnCompliant pins that down: a malformed policy_evaluations must not fail a compliant artifact. Its result types stay in cmd as the table printer's own view, so the client returns *Result. Because decoding is lazy, it can become a Response[T] without risk once those types move.

operationIds

These come from the published spec:

Method operationId Tag
GetArtifactByFingerprint get_artifact_by_fingerprint Artifacts
ListArtifactsByCommitSHA list_artifacts_by_commit_sha Artifacts
AssertArtifact assert_artifact Asserts

Verification

  • internal/kosli has 7 new httptest tests:
    • path, query, decode and raw body for each method
    • no query when there is no trail or filter
    • string timestamps decode as json.Number
    • a present-but-empty trail_name decodes as a non-nil pointer
  • The get artifact printer tests now build typed kosli.Artifact values. The decoding cases they used to cover moved into internal/kosli.
  • go test -race ./internal/kosli passes, and make lint is clean.
  • I compared refactor(get trail, evaluate): fetch the trail through the Kosli API client #1249's binary with this branch's binary against a local fake server. Output and exit codes are byte-identical in every case, and the fake server logged the expected path and query each time. Cases:
    • get artifact: by fingerprint and by commit, with and without --trail, table and json, and a 404
    • assert artifact: compliant and non-compliant, with --environment, with --flow and --policy p1,p2, -o json, and --dry-run
  • I have not run the integration suites locally. CI covers them: GetArtifactCommandTestSuite and AssertArtifactCommandTestSuite.

Found, not fixed

When there are several artifacts, printArtifactsAsTable writes the separator between them with fmt.Print. That goes to stdout instead of out. I left it alone so this PR doesn't change output, and it's listed for the later output slice.

Checklist

@github-actions github-actions Bot added go Pull requests that update go code refactor labels Oct 15, 2026
@dangrondahl
dangrondahl force-pushed the refactor/kosli-get-trail branch from 33c5375 to ff4a1ab Compare October 15, 2026 14:22
@dangrondahl
dangrondahl force-pushed the refactor/kosli-artifacts branch from 9fc2ea4 to eb12fe0 Compare October 15, 2026 14:22
@dangrondahl dangrondahl reopened this Oct 15, 2026
@claude

claude Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @dangrondahl's task in 2m 8s —— View job


Follow-up review complete

  • Fetch prior review comments
  • Diff BEFORE..AFTER (eb12fe0e..799d943c) — isolated to the fix commit 799d943c
  • Check status of each prior finding
  • Check new commits for new bugs/regressions
  • Post summary comment

Result: The one previous finding (-o json breaking on typed-decode failures) is resolved. 799d943c makes Response[T].Value() a lazy-decode method (internal/kosli/client.go), so getArtifact.go's run now passes Raw straight through to -o json and only decodes inside the "table" closure. Verified by tracing the code path and confirming the new test TestGetArtifactPrintsJSONThatTheTableCannotDecode exercises exactly this. I resolved the corresponding review thread and posted a summary comment.

No new issues found in the fix commit itself.

Note: go test/git fetch required interactive approval not available in this run, so verification was done via direct code/diff inspection rather than executing the test suite.

Comment thread cmd/kosli/getArtifact.go
@claude

claude Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Follow-up review (commits eb12fe0..799d943)

Previous finding — -o json fails when typed decode can't handle a field shape (comment): Resolved.

Verified by tracing the actual code path (couldn't run go test in this sandbox — fetch/test commands required approval that wasn't available):

  • internal/kosli/client.go:47-61 — Response[T] now embeds Result and decodes lazily: Value() is a method, not a field, called only on demand.
  • cmd/kosli/getArtifact.go:89-126 — run takes raw straight from artifact.Raw/listed.Raw and passes it to output.FormattedPrint undecoded. Only the "table" closure calls artifacts() (which calls .Value()); the "json" path (output.PrintJson) never decodes.
  • internal/output/output.go:13-17 — FormattedPrint invokes only the selected format function, so -o json never touches the decode path.
  • New test TestGetArtifactPrintsJSONThatTheTableCannotDecode (cmd/kosli/getArtifact_test.go) pins this with created_at: "", which json.Number can't unmarshal: -o json succeeds, default table output fails with the decode error.

I resolved the corresponding review thread.

No new issues found in the fix commit (799d943) itself — the change is scoped to getArtifact.go, artifacts.go, and their tests, and is internally consistent.

View job run

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

go Pull requests that update go code refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant