Skip to content

feat(commit): add --tag and --public flags to commit create#203

Merged
AlephNotation merged 1 commit into
mainfrom
feat/commit-create-tag-publish
May 12, 2026
Merged

feat(commit): add --tag and --public flags to commit create#203
AlephNotation merged 1 commit into
mainfrom
feat/commit-create-tag-publish

Conversation

@AlephNotation
Copy link
Copy Markdown
Contributor

Closes #201. Unblocks #202.

Collapses the create+tag+publish dance into a single vers commit create invocation.

What ships

Two new flags on vers commit create:

--tag <repo>:<tag> (repeatable, StringSliceVar)

  • Parses & validates <repo>:<tag> shape before any side effects. Malformed input emits the enumerated form from principle 3: error: --tag must be in <repo>:<tag> form (got: "v1.2").
  • Looks up each referenced repo up-front. Missing repo → fails fast with error: repo "<name>" not found. Create it first with: vers repo create <name> — no commit is created.
  • After the commit lands, for each tag:
    • if it exists → HandleRepoTagUpdate to point at the new commit
    • if it doesn't → HandleRepoTagCreate pointing at the new commit
  • If any tag write fails after the commit succeeds, the returned error includes the new commit ID for manual recovery.

--public

  • After the commit + all tag writes succeed, sets is_public=true on the new commit via the existing HandleCommitUpdate path.
  • Default false.
  • Visibility-mismatch warning: if any --tag target repo is is_public: true and --public was not supplied, a warning: line goes to stderr suggesting --public. Does not auto-publish (the conservative recommendation in Add --tag (repeatable) and auto-publish to vers commit create #201).

Output shape

{
  "commit_id": "...",
  "vm_id": "...",
  "name": "...",
  "tags_written": [
    { "reference": "my-app:v1", "tag_id": "..." },
    { "reference": "my-app:latest", "tag_id": "..." }
  ],
  "is_public": true
}

tags_written and is_public are omitempty, so unaffected flows still produce the existing JSON shape byte-for-byte.

Files

  • cmd/commit.go — flag declarations + wiring; text-mode render delegated to a new presenter helper.
  • internal/handlers/commit_create.go — validation, repo pre-flight, tag create/update branch, publish, warning.
  • internal/presenters/commits_types.goCommitCreateView + CommitTagWritten moved here (handlers re-exports via type alias to keep callers stable).
  • internal/presenters/commits_presenter.goRenderCommitCreate for text mode (mentions tags written + visibility).
  • internal/handlers/commit_create_test.go — table of new cases: bad format, missing repo (no commit created), tag-create-new, tag-update-existing, --public triggers publish, public-repo visibility warning.
  • README.md — short mention of the new flags.

Verification

  • make build
  • gofmt -l cmd/ internal/ empty ✓
  • go test ./internal/... ./cmd/...
  • ./bin/vers agent-context | jq '.commands.commit.subcommands.create.flags."--tag"' returns the new stringSlice flag ✓

Manual smoke against an authenticated API is left to the reviewer; the unit tests cover every branch with a mock server matching the SDK's URL shape.

Out of scope

vers publish top-level command — tracked in #202 as a separate PR that depends on this one.

@AlephNotation
Copy link
Copy Markdown
Contributor Author

Ran the live-API smoke checks the worker flagged. All six scenarios behave correctly against prod:

Scenario Result
--tag bad-format exit 1, enumerated error --tag must be in <repo>:<tag> form (got: "bad-format"), no commit created
--tag nonexistent-repo-xyz:v1 exit 3 (ExitNotFound), enumerated error with vers repo create hint, no commit created
--tag pi-agent:test-v1 (no --public, repo is public) commit + tag created; stderr warning explains the visibility mismatch AND emits the exact recovery command (vers commit publish <id>)
--tag pi-agent:test-v2 --public commit is_public: true, tag written
--tag pi-agent:test-v1 from a different VM (existing tag) tag's tag_id preserved, commit_id swapped, updated_at advanced
--tag pi-agent:test-multi-a --tag pi-agent:test-multi-b --public both tags written atomically (well, sequentially) in one call

The stderr warning is particularly nice — it's a textbook agent-native error message: tells the agent what went wrong, why it matters ("tag references a private commit and will not be reachable"), and exactly how to fix it. Both --public next time and vers commit publish <id> for recovery.

Test artifacts cleaned up: tags deleted, commits deleted, VMs deleted.

Ready to merge from my end. Unblocks #202.

@AlephNotation AlephNotation merged commit 8010630 into main May 12, 2026
6 checks passed
@AlephNotation AlephNotation deleted the feat/commit-create-tag-publish branch May 12, 2026 04:46
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.

Add --tag (repeatable) and auto-publish to vers commit create

1 participant