Skip to content

Add image tag command - #65

Draft
chruffins wants to merge 5 commits into
mainfrom
hypeship/image-tag
Draft

Add image tag command#65
chruffins wants to merge 5 commits into
mainfrom
hypeship/image-tag

Conversation

@chruffins

@chruffins chruffins commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

summary

Before this change, the CLI could pull images with hypeman pull / hypeman image create and push a cached Hypeman image with the two-argument form hypeman push IMAGE TARGET. The one-argument form, hypeman push TARGET, only looked for TARGET in the local Docker daemon and staged it in Hypeman first. There was no CLI command to create a new local Hypeman image tag from an existing cached image.

This PR adds hypeman tag SOURCE TARGET and makes the one-argument push form prefer cached Hypeman images:

  • hypeman tag calls the server’s local tag endpoint, resolving an already-ready source tag or digest and creating the target alias without pulling or reconverting image content.
  • hypeman push TARGET first checks Hypeman for TARGET; when present, it pushes that cached image to the matching remote reference.
  • If Hypeman does not have TARGET, the existing local-Docker staging fallback remains available.
  • The explicit hypeman push IMAGE TARGET form remains available for pushing a cached image to a different remote target.

Sources and targets may use different repositories.

new UX

The primary workflow now matches Docker’s tag-then-push flow, with Hypeman as the image store:

hypeman tag alpine:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:v1
hypeman push 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:v1

The first command creates a local Hypeman alias; it does not pull or reconvert the image. The second command pushes that cached alias to ECR. No local Docker daemon is required.

The command supports the existing global output options:

  • default auto output prints the normalized image name returned by the API
  • --format json|jsonl|yaml|pretty|... prints the API response
  • --transform continues to apply to non-auto output
  • --debug logs the request and response through the shared middleware

The command is registered at the root level alongside pull and push. It uses the generic SDK request helper until the generated SDK includes the new endpoint.

validation

  • go test ./pkg/cmd

Depends on the image tag API in kernel/hypeman#425.


Note

Medium Risk
One-arg push behavior changes order of resolution (Hypeman before Docker), which could surprise scripts that assumed Docker-first; tag depends on the server tag API in hypeman#425.

Overview
Adds hypeman tag <source> <target>, which creates a local Hypeman alias via POST /images/{source}/tag (or stages from Docker when the source is missing). Default output prints the normalized image name; global --format / --transform apply as elsewhere.

hypeman push TARGET now looks up TARGET in Hypeman first and pushes that cached image when ready; the previous Docker-daemon staging path remains as a fallback. Docker staging logic is factored into stageDockerImage for reuse by tag and push.

README and push help document the tag-then-push workflow (e.g. retag to ECR, then one-arg push). Tests cover tag URL escaping, auto output, Hypeman-miss errors, and push preferring cache without Docker.

Reviewed by Cursor Bugbot for commit 61d1aca. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread pkg/cmd/pushcmd.go
if err := waitForImageReady(ctx, &client, cachedImage); err != nil {
return err
}
return runRemotePush(ctx, cmd, target, target)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cached push skips newer Docker image

High Severity

A successful Images.Get now short-circuits staging, so one-arg hypeman push TARGET never reloads Docker when that tag already exists in Hypeman. Rebuilds that retag the same name and push again keep shipping the previous cached digest, including when the cached record is failed and waitForImageReady errors out. The still-documented docker tag then hypeman push TARGET loop is the common path this breaks.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5010e06. Configure here.

@cursor cursor Bot 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.

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

There are 2 total unresolved issues (including 1 from previous review).

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 61d1aca. Configure here.

Comment thread pkg/cmd/tag.go
staged, stageErr := stageDockerImage(ctx, cmd, &client, source, target)
if stageErr != nil {
return fmt.Errorf("image %q was not found in Hypeman or Docker: %w", source, stageErr)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Tag errors claim image not found

Low Severity

Every stageDockerImage failure is wrapped as if the image was missing. Upload, wait, and follow-up GET errors are reported as not found in Hypeman or Docker for tag, and as a failed local Docker load for one-argument push, including cases where Docker load already succeeded.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 61d1aca. Configure here.

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.

1 participant