Skip to content

Commit

Permalink
introduce image change build trigger logic
Browse files Browse the repository at this point in the history
  • Loading branch information
bparees committed Jan 8, 2015
1 parent 986ac46 commit f4dc902
Show file tree
Hide file tree
Showing 24 changed files with 841 additions and 70 deletions.
50 changes: 41 additions & 9 deletions pkg/build/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,23 @@ type BuildStatus string

// Valid values for BuildStatus.
const (
// BuildNew is automatically assigned to a newly created build.
// BuildStatusNew is automatically assigned to a newly created build.
BuildStatusNew BuildStatus = "New"

// BuildPending indicates that a pod name has been assigned and a build is
// BuildStatusPending indicates that a pod name has been assigned and a build is
// about to start running.
BuildStatusPending BuildStatus = "Pending"

// BuildRunning indicates that a pod has been created and a build is running.
// BuildStatusRunning indicates that a pod has been created and a build is running.
BuildStatusRunning BuildStatus = "Running"

// BuildComplete indicates that a build has been successful.
// BuildStatusComplete indicates that a build has been successful.
BuildStatusComplete BuildStatus = "Complete"

// BuildFailed indicates that a build has executed and failed.
// BuildStatusFailed indicates that a build has executed and failed.
BuildStatusFailed BuildStatus = "Failed"

// BuildError indicates that an error prevented the build from executing.
// BuildStatusError indicates that an error prevented the build from executing.
BuildStatusError BuildStatus = "Error"

// BuildStatusCancelled indicates that a running/pending build was stopped from executing.
Expand All @@ -72,7 +72,7 @@ type BuildSourceType string

// Valid values for BuildSourceType.
const (
//BuildGitSource is a Git SCM
//BuildSourceGit is a Git SCM
BuildSourceGit BuildSourceType = "Git"
)

Expand Down Expand Up @@ -150,6 +150,15 @@ const (
CustomBuildStrategyType BuildStrategyType = "Custom"
)

const (
// CustomBuildStrategyBaseImageKey is the environment variable that indicates the base image to be used when
// performing a custom build, if needed.
CustomBuildStrategyBaseImageKey = "OPENSHIFT_CUSTOM_BUILD_BASE_IMAGE"

// DefaultImageTag is used when an image tag is needed and the configuration
DefaultImageTag string = "latest"
)

// CustomBuildStrategy defines input parameters specific to Custom build.
type CustomBuildStrategy struct {
// Image is the image required to execute the build. If not specified
Expand All @@ -175,6 +184,11 @@ type DockerBuildStrategy struct {
// NoCache if set to true indicates that the docker build must be executed with the
// --no-cache=true flag
NoCache bool `json:"noCache,omitempty" yaml:"noCache,omitempty"`

// BaseImage is optional and indicates the image that the dockerfile for this
// build should "FROM". If present, the build process will substitute this value
// into the FROM line of the dockerfile.
BaseImage string `json:"baseImage,omitempty" yaml:"baseImage,omitempty"`
}

// STIBuildStrategy defines input parameters specific to an STI build.
Expand Down Expand Up @@ -222,6 +236,17 @@ type WebHookTrigger struct {
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
}

// ImageChangeTrigger allows builds to be triggered when an ImageRepository changes
type ImageChangeTrigger struct {
// Image is used to specify the value in the BuildConfig to replace with the
// immutable image id supplied by the ImageRepository when this trigger fires.
Image string `json:"image" yaml:"image"`
// ImageRepositoryRef a reference to a Docker image repository to watch for changes.
ImageRepositoryRef *kapi.ObjectReference `json:"imageRepositoryRef" yaml:"imageRepositoryRef"`
// Tag is the name of an image repository tag to watch for changes.
Tag string `json:"tag,omitempty" yaml:"tag,omitempty"`
}

// BuildTriggerPolicy describes a policy for a single trigger that results in a new Build.
type BuildTriggerPolicy struct {
// Type is the type of build trigger
Expand All @@ -232,6 +257,9 @@ type BuildTriggerPolicy struct {

// GenericWebHook contains the parameters for a Generic webhook type of trigger
GenericWebHook *WebHookTrigger `json:"generic,omitempty" yaml:"generic,omitempty"`

// ImageChange contains parameters for an ImageChange type of trigger
ImageChange *ImageChangeTrigger `json:"imageChange,omitempty" yaml:"imageChange,omitempty"`
}

// BuildTriggerType refers to a specific BuildTriggerPolicy implementation.
Expand All @@ -240,11 +268,15 @@ type BuildTriggerType string
const (
// GithubWebHookType represents a trigger that launches builds on
// Github webhook invocations
GithubWebHookType BuildTriggerType = "github"
GithubWebHookBuildTriggerType BuildTriggerType = "github"

// GenericWebHookType represents a trigger that launches builds on
// generic webhook invocations
GenericWebHookType BuildTriggerType = "generic"
GenericWebHookBuildTriggerType BuildTriggerType = "generic"

// ImageChangeType represents a trigger that launches builds on
// availability of a new version of an image
ImageChangeBuildTriggerType BuildTriggerType = "imageChange"
)

// BuildList is a collection of Builds.
Expand Down
33 changes: 26 additions & 7 deletions pkg/build/api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,23 @@ type BuildStatus string

// Valid values for BuildStatus.
const (
// BuildNew is automatically assigned to a newly created build.
// BuildStatusNew is automatically assigned to a newly created build.
BuildStatusNew BuildStatus = "New"

// BuildPending indicates that a pod name has been assigned and a build is
// BuildStatusPending indicates that a pod name has been assigned and a build is
// about to start running.
BuildStatusPending BuildStatus = "Pending"

// BuildRunning indicates that a pod has been created and a build is running.
// BuildStatusRunning indicates that a pod has been created and a build is running.
BuildStatusRunning BuildStatus = "Running"

// BuildComplete indicates that a build has been successful.
BuildStatusComplete BuildStatus = "Complete"
// BuildStatusComplete indicates that a build has been successful.

// BuildFailed indicates that a build has executed and failed.
// BuildStatusFailed indicates that a build has executed and failed.
BuildStatusFailed BuildStatus = "Failed"

// BuildError indicates that an error prevented the build from executing.
// BuildStatusError indicates that an error prevented the build from executing.
BuildStatusError BuildStatus = "Error"

// BuildStatusCancelled indicates that a running/pending build was stopped from executing.
Expand All @@ -72,7 +72,7 @@ type BuildSourceType string

// Valid values for BuildSourceType.
const (
//BuildGitSource is a Git SCM
//BuildSourceGit is a Git SCM
BuildSourceGit BuildSourceType = "Git"
)

Expand Down Expand Up @@ -175,6 +175,11 @@ type DockerBuildStrategy struct {
// NoCache if set to true indicates that the docker build must be executed with the
// --no-cache=true flag
NoCache bool `json:"noCache,omitempty" yaml:"noCache,omitempty"`

// BaseImage is optional and indicates the image that the dockerfile for this
// build should "FROM". If present, the build process will substitute this value
// into the FROM line of the dockerfile.
BaseImage string `json:"baseImage,omitempty" yaml:"baseImage,omitempty"`
}

// STIBuildStrategy defines input parameters specific to an STI build.
Expand Down Expand Up @@ -226,6 +231,17 @@ type WebHookTrigger struct {
Secret string `json:"secret,omitempty" yaml:"secret,omitempty"`
}

// ImageChangeTrigger allows builds to be triggered when an ImageRepository changes
type ImageChangeTrigger struct {
// Image is used to specify the value in the BuildConfig to replace with the
// immutable image id supplied by the ImageRepository when this trigger fires.
Image string `json:"image" yaml:"image"`
// ImageRepositoryRef a reference to a Docker image repository to watch for changes.
ImageRepositoryRef *kapi.ObjectReference `json:"imageRepositoryRef" yaml:"imageRepositoryRef"`
// Tag is the name of an image repository tag to watch for changes.
Tag string `json:"tag,omitempty" yaml:"tag,omitempty"`
}

// BuildTriggerPolicy describes a policy for a single trigger that results in a new Build.
type BuildTriggerPolicy struct {
// Type is the type of build trigger
Expand All @@ -236,6 +252,9 @@ type BuildTriggerPolicy struct {

// GenericWebHook contains the parameters for a Generic webhook type of trigger
GenericWebHook *WebHookTrigger `json:"generic,omitempty" yaml:"generic,omitempty"`

// ImageChange contains parameters for an ImageChange type of trigger
ImageChange *ImageChangeTrigger `json:"imageChange,omitempty" yaml:"imageChange,omitempty"`
}

// BuildTriggerType refers to a specific BuildTriggerPolicy implementation.
Expand Down
29 changes: 25 additions & 4 deletions pkg/build/api/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,25 +138,31 @@ func validateTrigger(trigger *buildapi.BuildTriggerPolicy) errs.ValidationErrorL

// Ensure that only parameters for the trigger's type are present
triggerPresence := map[buildapi.BuildTriggerType]bool{
buildapi.GithubWebHookType: trigger.GithubWebHook != nil,
buildapi.GenericWebHookType: trigger.GenericWebHook != nil,
buildapi.GithubWebHookBuildTriggerType: trigger.GithubWebHook != nil,
buildapi.GenericWebHookBuildTriggerType: trigger.GenericWebHook != nil,
}
allErrs = append(allErrs, validateTriggerPresence(triggerPresence, trigger.Type)...)

// Validate each trigger type
switch trigger.Type {
case buildapi.GithubWebHookType:
case buildapi.GithubWebHookBuildTriggerType:
if trigger.GithubWebHook == nil {
allErrs = append(allErrs, errs.NewFieldRequired("github", nil))
} else {
allErrs = append(allErrs, validateWebHook(trigger.GithubWebHook).Prefix("github")...)
}
case buildapi.GenericWebHookType:
case buildapi.GenericWebHookBuildTriggerType:
if trigger.GenericWebHook == nil {
allErrs = append(allErrs, errs.NewFieldRequired("generic", nil))
} else {
allErrs = append(allErrs, validateWebHook(trigger.GenericWebHook).Prefix("generic")...)
}
case buildapi.ImageChangeBuildTriggerType:
if trigger.ImageChange == nil {
allErrs = append(allErrs, errs.NewFieldRequired("imageChange", nil))
} else {
allErrs = append(allErrs, validateImageChange(trigger.ImageChange).Prefix("imageChange")...)
}
}
return allErrs
}
Expand All @@ -171,6 +177,21 @@ func validateTriggerPresence(params map[buildapi.BuildTriggerType]bool, t builda
return allErrs
}

func validateImageChange(imageChange *buildapi.ImageChangeTrigger) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if len(imageChange.Image) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("image", ""))
}
if imageChange.ImageRepositoryRef == nil {
allErrs = append(allErrs, errs.NewFieldRequired("imageRepositoryRef", ""))
} else if len(imageChange.ImageRepositoryRef.Name) == 0 {
nestedErrs := errs.ValidationErrorList{errs.NewFieldRequired("name", "")}
nestedErrs.Prefix("imageRepositoryRef")
allErrs = append(allErrs, nestedErrs...)
}
return allErrs
}

func validateWebHook(webHook *buildapi.WebHookTrigger) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if len(webHook.Secret) == 0 {
Expand Down
16 changes: 8 additions & 8 deletions pkg/build/api/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,39 +204,39 @@ func TestValidateTrigger(t *testing.T) {
expected: []*errs.ValidationError{errs.NewFieldRequired("type", "")},
},
"github type with no github webhook": {
trigger: buildapi.BuildTriggerPolicy{Type: buildapi.GithubWebHookType},
trigger: buildapi.BuildTriggerPolicy{Type: buildapi.GithubWebHookBuildTriggerType},
expected: []*errs.ValidationError{errs.NewFieldRequired("github", "")},
},
"github trigger with no secret": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GithubWebHookType,
Type: buildapi.GithubWebHookBuildTriggerType,
GithubWebHook: &buildapi.WebHookTrigger{},
},
expected: []*errs.ValidationError{errs.NewFieldRequired("github.secret", "")},
},
"github trigger with generic webhook": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GithubWebHookType,
Type: buildapi.GithubWebHookBuildTriggerType,
GenericWebHook: &buildapi.WebHookTrigger{
Secret: "secret101",
},
},
expected: []*errs.ValidationError{errs.NewFieldInvalid("generic", "", "long description")},
},
"generic trigger with no generic webhook": {
trigger: buildapi.BuildTriggerPolicy{Type: buildapi.GenericWebHookType},
trigger: buildapi.BuildTriggerPolicy{Type: buildapi.GenericWebHookBuildTriggerType},
expected: []*errs.ValidationError{errs.NewFieldRequired("generic", "")},
},
"generic trigger with no secret": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GenericWebHookType,
Type: buildapi.GenericWebHookBuildTriggerType,
GenericWebHook: &buildapi.WebHookTrigger{},
},
expected: []*errs.ValidationError{errs.NewFieldRequired("generic.secret", "")},
},
"generic trigger with github webhook": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GenericWebHookType,
Type: buildapi.GenericWebHookBuildTriggerType,
GithubWebHook: &buildapi.WebHookTrigger{
Secret: "secret101",
},
Expand All @@ -245,15 +245,15 @@ func TestValidateTrigger(t *testing.T) {
},
"valid github trigger": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GithubWebHookType,
Type: buildapi.GithubWebHookBuildTriggerType,
GithubWebHook: &buildapi.WebHookTrigger{
Secret: "secret101",
},
},
},
"valid generic trigger": {
trigger: buildapi.BuildTriggerPolicy{
Type: buildapi.GenericWebHookType,
Type: buildapi.GenericWebHookBuildTriggerType,
GenericWebHook: &buildapi.WebHookTrigger{
Secret: "secret101",
},
Expand Down
Loading

0 comments on commit f4dc902

Please sign in to comment.