Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
91ea7f8
feat: add DecoBuild CRD and BuildReconciler for cfworkers builds
igoramf Apr 30, 2026
6e20af2
chore: go mod tidy — add aws-sdk-go-v2 go.sum entries
igoramf Apr 30, 2026
a40192d
fix: gofmt formatting in build/job.go constants
igoramf Apr 30, 2026
fae09d3
fix: wire DecoBuild CRD and cfworkers env vars into Helm generator
igoramf Apr 30, 2026
a5c968f
feat: replace DecoBuild CRD with Deco CR for cfworkers builds and pre…
igoramf May 4, 2026
978c541
fix: also set WORKER_NAME env var for backwards compat with existing …
igoramf May 4, 2026
fdf6a67
revert: remove WORKER_NAME backwards compat, use DECO_SITE_NAME only
igoramf May 4, 2026
78ce233
chore: remove DecoBuild CRD — using Deco CR directly for cfworkers bu…
igoramf May 4, 2026
62f71a3
refactor(operator): decouple reconciler from cfworkers via JobFactory
igoramf May 4, 2026
f071d3e
refactor(operator): move platform-specific constants into JobFactory
igoramf May 4, 2026
36d2818
refactor(operator): support multiple serving types via factory registry
igoramf May 4, 2026
4c1c38a
rename: JobOpts → CfWorkersJobOpts, NewJob → NewCfWorkersJob
igoramf May 4, 2026
d2eaaef
refactor(operator): introduce build.Registry for platform dispatch
igoramf May 4, 2026
32131fa
rename: build/job.go → build/cfworkers.go
igoramf May 4, 2026
e145449
chore: bump version to 0.2.7
igoramf May 4, 2026
8a53c1f
chore: revert version to 0.2.6
igoramf May 4, 2026
a6d5f77
chore: move s3Region from values to secret
igoramf May 4, 2026
9b658c0
feat: add cfworkers build duration and count metrics
igoramf May 4, 2026
1ca83c3
fix: address CI lint failures and move S3_REGION to secretKeyRef
igoramf May 4, 2026
a390197
fix: pin CRD plural to 'decos' via +kubebuilder:resource:path=decos
igoramf May 4, 2026
35288f8
chore: regenerate helm chart CRD template from updated deco.sites_dec…
igoramf May 4, 2026
0f5c11b
refactor(build): replace Factory func type with Builder interface
igoramf May 6, 2026
aebeb07
feat(build): add CfWorkersConfig, cfWorkersBuilder, NewCloudflareFactory
igoramf May 6, 2026
2794a10
refactor(controller): hold build.Builder interface; update default bu…
igoramf May 6, 2026
e75a3ce
refactor(main): remove CF/S3 specifics — wire via build.NewCloudflare…
igoramf May 6, 2026
9064d11
refactor(build): unexport internal types NewCfWorkersJob, CfWorkersJo…
igoramf May 6, 2026
0cdc4f4
refactor(build): remove defaults test — buckets are env-configurable
igoramf May 6, 2026
f109761
chore: remove cfworkers_test.go — follow-up PR
igoramf May 6, 2026
c5c0429
refactor(build): remove hardcoded default bucket/image names — repo i…
igoramf May 6, 2026
628ecb6
feat(helm): move S3_REGION to values; add builderImage, s3LogsBucket,…
igoramf May 6, 2026
288d89a
refactor(helm): split S3 into dedicated s3.existingSecret — shared ac…
igoramf May 6, 2026
1d66d7e
refactor(build): rename Registry to BuilderRegistry for clarity
igoramf May 6, 2026
81bdc4a
fix(build): update compile-time check to BuilderRegistry after rename
igoramf May 6, 2026
441f5a0
feat(crd): add envs and secrets fields to DecoSpecBuild for custom Jo…
igoramf May 6, 2026
f0754a2
refactor(build): read envs/secrets directly from Deco spec in newCfWo…
igoramf May 6, 2026
4e97e15
fix(build): prealloc envFrom, make TTLSecondsAfterFinished configurab…
igoramf May 6, 2026
16e579e
fix(build): fix prealloc lint — use make+index instead of make+append…
igoramf May 7, 2026
32b1896
refactor(s3): rename cacheBucket to artifactsBucket — build artifacts…
igoramf May 7, 2026
7ba57fb
chore: remove values-local.yaml from .gitignore
igoramf May 7, 2026
01b900d
refactor: move artifactsBucket from s3 to cfworkers in chart values
igoramf May 7, 2026
01f1cd3
fix: use Status().Patch() to avoid optimistic concurrency conflicts o…
igoramf May 7, 2026
c0506fe
fix: resolve helm-verify and lint CI failures
igoramf May 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ linters:
- unparam
- unused
settings:
goconst:
min-occurrences: 3
revive:
rules:
- name: comment-spacings
Expand All @@ -36,6 +38,9 @@ linters:
- dupl
- lll
path: internal/*
- linters:
- goconst
path: _test\.go$
paths:
- third_party$
- builtin$
Expand Down
225 changes: 225 additions & 0 deletions api/v1alpha1/deco_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
package v1alpha1

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

// DecoSpec defines the desired state of a Deco workload.
type DecoSpec struct {
// Type is the workload type. site | server | admin | preview
// +optional
Type string `json:"type,omitempty"`
Comment thread
nicacioliveira marked this conversation as resolved.

// Site is the site/repository name.
// +kubebuilder:validation:Required
Site string `json:"site"`

// Org is the GitHub organization or owner.
// +kubebuilder:validation:Required
Org string `json:"org"`

// Framework is the site framework. deno | tanstack | next | remix | static
// +optional
Framework string `json:"framework,omitempty"`
Comment thread
nicacioliveira marked this conversation as resolved.

// Build describes the production build pipeline.
// +optional
Build *DecoSpecBuild `json:"build,omitempty"`

// Serving describes the runtime serving configuration.
// +optional
Serving *DecoSpecServing `json:"serving,omitempty"`

// Previews configures preview builds for this site.
// Admin adds entries to Previews.Active on PR open and removes on PR close.
// +optional
Previews *DecoPreviewPolicy `json:"previews,omitempty"`
}

// DecoEnvVar is a plain environment variable injected into the build Job.
type DecoEnvVar struct {
// Name is the environment variable name.
// +kubebuilder:validation:Required
Name string `json:"name"`
// Value is the literal value.
// +optional
Value string `json:"value,omitempty"`
}

// DecoSecretRef mounts all keys of a K8s Secret as environment variables in the build Job.
type DecoSecretRef struct {
// Name is the name of the K8s Secret in the same namespace as the Job.
// +kubebuilder:validation:Required
Name string `json:"name"`
// Optional specifies whether the Secret must exist. Defaults to false.
// +optional
Optional *bool `json:"optional,omitempty"`
}

// DecoSpecBuild describes the build pipeline for a workload.
type DecoSpecBuild struct {
// Type is the build mechanism. Currently only k8s-job is supported.
// +optional
Type string `json:"type,omitempty"`

// Source identifies the code revision to build.
// Repository and owner come from spec.site and spec.org.
Source DecoSpecBuildSource `json:"source"`

// Builder overrides the builder image (repository:tag).
// +optional
Builder string `json:"builder,omitempty"`

// Envs are additional plain environment variables injected into the build Job.
// +optional
Envs []DecoEnvVar `json:"envs,omitempty"`

// Secrets are K8s Secrets whose keys are mounted as environment variables in the build Job.
// The secrets must exist in the same namespace as the Job (the site namespace).
// +optional
Secrets []DecoSecretRef `json:"secrets,omitempty"`

// TTLSecondsAfterFinished controls how long the Job is kept after completion.
// Defaults to 600 (10 minutes) when not set.
// +optional
// +kubebuilder:validation:Minimum=0
TTLSecondsAfterFinished *int32 `json:"ttlSecondsAfterFinished,omitempty"`
}

// DecoSpecBuildSource identifies the code revision to build.
type DecoSpecBuildSource struct {
// CommitSha is the git commit SHA to build.
// Updating this field triggers a new build.
// +kubebuilder:validation:Required
CommitSha string `json:"commitSha"`

// Production indicates whether this is a production deploy.
// +optional
Production bool `json:"production,omitempty"`

// BranchRef is the branch name for preview aliases (non-production only).
// +optional
BranchRef string `json:"branchRef,omitempty"`
}

// DecoSpecServing describes the runtime serving configuration.
type DecoSpecServing struct {
// Type is the serving runtime. Drives both serving and build job selection.
// Supported: cloudflare-worker | knative | deployment
// +kubebuilder:validation:Required
Type string `json:"type"`
Comment thread
nicacioliveira marked this conversation as resolved.
}

// DecoPreviewPolicy configures the preview system for this site.
type DecoPreviewPolicy struct {
// Type is the preview runtime. cloudflare-preview | statefulset | sandbox
// +kubebuilder:validation:Required
Type string `json:"type"`

// MaxActive is the maximum number of concurrent previews the operator will build.
// Operator processes only the most recent MaxActive entries in Active.
// +optional
MaxActive int32 `json:"maxActive,omitempty"`

// TTL is the duration after which completed previews are eligible for cleanup (e.g. "48h").
// +optional
TTL string `json:"ttl,omitempty"`

// Active is the list of preview builds currently requested.
// Admin adds entries on PR open, removes on PR close.
// +optional
Active []DecoPreviewRequest `json:"active,omitempty"`
}

// DecoPreviewRequest identifies a single preview build request.
type DecoPreviewRequest struct {
// CommitSha is the git commit SHA to build.
// +kubebuilder:validation:Required
CommitSha string `json:"commitSha"`

// BranchRef is the branch or PR ref (used as the wrangler preview alias).
// +kubebuilder:validation:Required
BranchRef string `json:"branchRef"`

// PrId is the pull request ID, for tracking.
// +optional
PrId string `json:"prId,omitempty"`
}

// DecoStatus defines the observed state of a Deco workload.
type DecoStatus struct {
// Build tracks the current production build lifecycle.
// +optional
Build *DecoStatusBuild `json:"build,omitempty"`

// Previews tracks the build status of each active preview.
// +optional
Previews []DecoPreviewStatus `json:"previews,omitempty"`
}

// DecoStatusBuild tracks the production build lifecycle.
type DecoStatusBuild struct {
// Phase is the current build phase: Running | Succeeded | Failed
// +optional
Phase string `json:"phase,omitempty"`

// CommitSha is the commit currently being built (or last attempted).
// +optional
CommitSha string `json:"commitSha,omitempty"`

// LastBuiltCommit is the commit SHA of the last successful build.
// +optional
LastBuiltCommit string `json:"lastBuiltCommit,omitempty"`

// JobName is the K8s Job name for the current build.
// +optional
JobName string `json:"jobName,omitempty"`

// StartTime is when the current build started.
// +optional
StartTime *metav1.Time `json:"startTime,omitempty"`

// CompletionTime is when the current build finished.
// +optional
CompletionTime *metav1.Time `json:"completionTime,omitempty"`
}

// DecoPreviewStatus tracks the build status of a single preview.
type DecoPreviewStatus struct {
CommitSha string `json:"commitSha"`
BranchRef string `json:"branchRef"`
PrId string `json:"prId,omitempty"`
JobName string `json:"jobName,omitempty"`
Phase string `json:"phase"`
StartTime *metav1.Time `json:"startTime,omitempty"`
CompletionTime *metav1.Time `json:"completionTime,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=decos
// +kubebuilder:printcolumn:name="Site",type=string,JSONPath=`.spec.site`
// +kubebuilder:printcolumn:name="Serving",type=string,JSONPath=`.spec.serving.type`
// +kubebuilder:printcolumn:name="Commit",type=string,JSONPath=`.spec.build.source.commitSha`
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.build.phase`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`

// Deco is the Schema for the decos API.
type Deco struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec DecoSpec `json:"spec,omitempty"`
Status DecoStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// DecoList contains a list of Deco.
type DecoList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Deco `json:"items"`
}

func init() {
SchemeBuilder.Register(&Deco{}, &DecoList{})
}
Loading
Loading