This document provides detailed information about the PreviewEnvironment Custom Resource Definition (CRD).
- Group:
preview.previewd.io - Version:
v1alpha1 - Kind:
PreviewEnvironment
previewpreviews
PreviewEnvironment is the Schema for the previewenvironments API. It represents a preview environment for a pull request, including all necessary configuration and status information.
The spec field defines the desired state of the PreviewEnvironment.
| Field | Type | Description | Validation |
|---|---|---|---|
repository |
string | GitHub repository in "owner/repo" format | Pattern: ^[a-zA-Z0-9-]+/[a-zA-Z0-9-]+$ |
prNumber |
integer | Pull request number | Minimum: 1 |
headSHA |
string | Commit SHA of the PR head | Pattern: ^[a-f0-9]{40}$ (40-character lowercase hex) |
| Field | Type | Description | Default |
|---|---|---|---|
baseBranch |
string | Base branch name (e.g., "main", "develop") | - |
headBranch |
string | Head branch name (e.g., "feature/my-feature") | - |
services |
[]string | List of service names to deploy | - |
ttl |
string | Time-to-live duration for the preview environment | "4h" |
The status field defines the observed state of the PreviewEnvironment. This is managed by the operator and should not be set directly by users.
| Field | Type | Description |
|---|---|---|
phase |
string | Current phase of the preview environment. Valid values: Pending, Creating, Ready, Updating, Deleting, Failed |
url |
string | Public URL to access the preview environment |
namespace |
string | Kubernetes namespace created for this preview environment |
services |
[]ServiceStatus | Status information for deployed services |
costEstimate |
CostEstimate | Estimated costs for running this environment |
conditions |
[]metav1.Condition | Standard Kubernetes conditions |
createdAt |
metav1.Time | Timestamp when the environment was created |
expiresAt |
metav1.Time | Timestamp when the environment will be automatically deleted |
lastSyncedAt |
metav1.Time | Timestamp of the last successful sync |
observedGeneration |
int64 | Generation of the most recently observed spec |
Represents the status of a deployed service.
| Field | Type | Description | Required |
|---|---|---|---|
name |
string | Service name | Yes |
ready |
boolean | Indicates if the service is ready | Yes |
url |
string | Service URL (if exposed) | No |
Provides cost estimation for the preview environment.
| Field | Type | Description | Required |
|---|---|---|---|
currency |
string | Cost currency (e.g., "USD") | Yes |
hourlyCost |
string | Estimated hourly cost | Yes |
totalCost |
string | Total estimated cost based on TTL | No |
apiVersion: preview.previewd.io/v1alpha1
kind: PreviewEnvironment
metadata:
name: pr-123
spec:
repository: myorg/myrepo
prNumber: 123
headSHA: 1234567890abcdef1234567890abcdef12345678This will create a preview environment with default TTL of 4 hours.
apiVersion: preview.previewd.io/v1alpha1
kind: PreviewEnvironment
metadata:
name: pr-456-feature-auth
namespace: preview-system
spec:
repository: myorg/myrepo
prNumber: 456
headSHA: abcdef1234567890abcdef1234567890abcdef12
baseBranch: main
headBranch: feature/auth-improvements
ttl: "8h"
services:
- api
- web
- worker
- databaseapiVersion: preview.previewd.io/v1alpha1
kind: PreviewEnvironment
metadata:
name: pr-789
spec:
repository: myorg/myrepo
prNumber: 789
headSHA: fedcba0987654321fedcba0987654321fedcba09
status:
phase: Ready
url: https://pr-789.preview.example.com
namespace: preview-pr-789
services:
- name: api
ready: true
url: https://api-pr-789.preview.example.com
- name: web
ready: true
url: https://pr-789.preview.example.com
costEstimate:
currency: USD
hourlyCost: "0.15"
totalCost: "0.60"
conditions:
- type: Ready
status: "True"
reason: ServicesReady
message: All services are healthy
lastTransitionTime: "2025-11-09T12:00:00Z"
createdAt: "2025-11-09T08:00:00Z"
expiresAt: "2025-11-09T16:00:00Z"
lastSyncedAt: "2025-11-09T12:00:00Z"
observedGeneration: 1kubectl apply -f preview.yamlkubectl get previews
# or
kubectl get previewenvironmentsOutput includes custom columns:
- PR: Pull request number
- Phase: Current phase (Pending, Creating, Ready, etc.)
- URL: Preview environment URL
- Age: Time since creation
Example output:
NAME PR PHASE URL AGE
pr-123 123 Ready https://pr-123.preview.example.com 2h
pr-456 456 Creating 5m
kubectl get preview pr-123 -o yamlThe operator updates the status subresource:
kubectl patch preview pr-123 --subresource=status --type=merge -p '{"status":{"phase":"Ready"}}'kubectl delete preview pr-123- Pattern:
^[a-zA-Z0-9-]+/[a-zA-Z0-9-]+$ - Valid:
myorg/myrepo,My-Org-123/my-repo-456 - Invalid:
myorg,myorg/,/myrepo,myorg/my/repo
- Minimum: 1
- Valid: 1, 123, 999999
- Invalid: 0, -1
- Pattern:
^[a-f0-9]{40}$ - Length: Exactly 40 characters
- Characters: Lowercase hexadecimal only (0-9, a-f)
- Valid:
1234567890abcdef1234567890abcdef12345678 - Invalid:
short(too short)1234567890ABCDEF...(uppercase not allowed)1234567890ghijkl...(invalid hex characters)
- Format: Duration string (e.g., "4h", "30m", "2h30m")
- Default:
"4h" - Examples: "1h", "2h30m", "8h", "24h"
Valid values:
Pending: Environment is queued for creationCreating: Resources are being provisionedReady: Environment is fully operationalUpdating: Environment is being updatedDeleting: Environment is being torn downFailed: Environment creation or operation failed
- The
statussubresource is enabled, allowing separate RBAC permissions for status updates - All timestamps use RFC3339 format
- The operator automatically sets owner references for garbage collection
- Finalizers ensure proper cleanup when a PreviewEnvironment is deleted