Implement qrun publish with Voyage integration #38

Open
opened 2026-01-03 23:45:10 +00:00 by KofTwentyTwo · 0 comments
KofTwentyTwo commented 2026-01-03 23:45:10 +00:00 (Migrated from github.com)

Part of #13

User Story

As a developer, I want to run qrun publish to push my image to the Voyage registry and deploy to an environment so that my application is accessible to users.

Design

Command Interface

# Publish to dev environment (default)
qrun publish

# Publish to specific environment
qrun publish --env staging
qrun publish --env prod

# Publish with specific channel
qrun publish --env prod --channel stable

# Publish existing image (skip build)
qrun publish --image myapp:v1.2.3 --env prod

# Dry run (show what would happen)
qrun publish --dry-run --env prod

Publish Workflow

1. Build image (or use --image)
2. Authenticate with Voyage
3. Push image to Voyage OCI registry
4. Verify digest after push
5. Create release record in Voyage
6. Trigger deployment to environment
7. Wait for deployment confirmation

Voyage API Integration

POST /v1/artifacts
{
  "digest": "sha256:abc123...",
  "tag": "myapp:1.2.3",
  "repository": "qrun.io/org/myapp",
  "labels": { ... }
}

POST /v1/deployments
{
  "artifactId": "art_123",
  "environment": "prod",
  "channel": "stable"
}

Output Format

Publishing to prod...
  Image: myapp:1.2.3
  Registry: qrun.io/acme/myapp
  
Pushing layers:
  [1/3] sha256:abc123 (85MB) ✓
  [2/3] sha256:def456 (1.2MB) ✓
  [3/3] sha256:ghi789 (4.5MB) ✓

Verifying digest... ✓
Creating release record... ✓
Deploying to prod... ✓

Deployment successful!
  URL: https://myapp.prod.acme.qrun.io
  Version: 1.2.3
  Replicas: 2/2

Files to Create/Modify

File Action Description
PublishCommand.java Create Main publish command
VoyageClient.java Create HTTP client for Voyage API
RegistryPusher.java Create OCI registry push logic
DeploymentTracker.java Create Monitor deployment status
ArtifactRecord.java Create Artifact metadata model

Implementation Tasks

  • Create PublishCommand with Picocli annotations
  • Implement VoyageClient for API calls
  • Implement OCI registry authentication
  • Implement image push with progress tracking
  • Implement digest verification after push
  • Implement artifact record creation
  • Implement deployment trigger
  • Implement deployment status polling
  • Add --env option with validation
  • Add --channel option
  • Add --image option to skip build
  • Add --dry-run option
  • Add --wait / --no-wait for deployment
  • Handle authentication errors
  • Handle push failures with retry
  • Add unit tests with mock Voyage API

Acceptance Criteria

  • qrun publish pushes image to Voyage registry
  • Digest verified after push
  • Release record created in Voyage
  • Deployment triggered for environment
  • --dry-run shows actions without executing
  • Progress shown during push
  • Deployment URL shown on success
  • Authentication errors produce clear messages
Part of #13 ## User Story As a **developer**, I want to run `qrun publish` to push my image to the Voyage registry and deploy to an environment so that my application is accessible to users. ## Design ### Command Interface ```bash # Publish to dev environment (default) qrun publish # Publish to specific environment qrun publish --env staging qrun publish --env prod # Publish with specific channel qrun publish --env prod --channel stable # Publish existing image (skip build) qrun publish --image myapp:v1.2.3 --env prod # Dry run (show what would happen) qrun publish --dry-run --env prod ``` ### Publish Workflow ``` 1. Build image (or use --image) 2. Authenticate with Voyage 3. Push image to Voyage OCI registry 4. Verify digest after push 5. Create release record in Voyage 6. Trigger deployment to environment 7. Wait for deployment confirmation ``` ### Voyage API Integration ``` POST /v1/artifacts { "digest": "sha256:abc123...", "tag": "myapp:1.2.3", "repository": "qrun.io/org/myapp", "labels": { ... } } POST /v1/deployments { "artifactId": "art_123", "environment": "prod", "channel": "stable" } ``` ### Output Format ``` Publishing to prod... Image: myapp:1.2.3 Registry: qrun.io/acme/myapp Pushing layers: [1/3] sha256:abc123 (85MB) ✓ [2/3] sha256:def456 (1.2MB) ✓ [3/3] sha256:ghi789 (4.5MB) ✓ Verifying digest... ✓ Creating release record... ✓ Deploying to prod... ✓ Deployment successful! URL: https://myapp.prod.acme.qrun.io Version: 1.2.3 Replicas: 2/2 ``` ## Files to Create/Modify | File | Action | Description | |------|--------|-------------| | `PublishCommand.java` | Create | Main publish command | | `VoyageClient.java` | Create | HTTP client for Voyage API | | `RegistryPusher.java` | Create | OCI registry push logic | | `DeploymentTracker.java` | Create | Monitor deployment status | | `ArtifactRecord.java` | Create | Artifact metadata model | ## Implementation Tasks - [ ] Create `PublishCommand` with Picocli annotations - [ ] Implement `VoyageClient` for API calls - [ ] Implement OCI registry authentication - [ ] Implement image push with progress tracking - [ ] Implement digest verification after push - [ ] Implement artifact record creation - [ ] Implement deployment trigger - [ ] Implement deployment status polling - [ ] Add `--env` option with validation - [ ] Add `--channel` option - [ ] Add `--image` option to skip build - [ ] Add `--dry-run` option - [ ] Add `--wait` / `--no-wait` for deployment - [ ] Handle authentication errors - [ ] Handle push failures with retry - [ ] Add unit tests with mock Voyage API ## Acceptance Criteria - [ ] `qrun publish` pushes image to Voyage registry - [ ] Digest verified after push - [ ] Release record created in Voyage - [ ] Deployment triggered for environment - [ ] `--dry-run` shows actions without executing - [ ] Progress shown during push - [ ] Deployment URL shown on success - [ ] Authentication errors produce clear messages
Sign in to join this conversation.