types: use a global When type

Currently we are using different `When` types for every service and convert
between them. This is a good approach if we want to keep isolated all the
services (like if we were using different repos for every service instead of the
current monorepo).

But currently, since When is identical between all the services, simplify this by
using a common When type.
This commit is contained in:
Simone Gotti 2019-09-05 09:29:20 +02:00
parent 60df886ad9
commit 70eeddb719
13 changed files with 238 additions and 358 deletions

View File

@ -20,7 +20,6 @@ import (
"os" "os"
config "agola.io/agola/internal/config" config "agola.io/agola/internal/config"
cstypes "agola.io/agola/services/configstore/types"
gwapitypes "agola.io/agola/services/gateway/api/types" gwapitypes "agola.io/agola/services/gateway/api/types"
gwclient "agola.io/agola/services/gateway/client" gwclient "agola.io/agola/services/gateway/client"
@ -123,7 +122,7 @@ func variableCreate(cmd *cobra.Command, ownertype string, args []string) error {
rvalues = append(rvalues, gwapitypes.VariableValueRequest{ rvalues = append(rvalues, gwapitypes.VariableValueRequest{
SecretName: value.SecretName, SecretName: value.SecretName,
SecretVar: value.SecretVar, SecretVar: value.SecretVar,
When: fromCsWhen(value.When.ToCSWhen()), When: value.When.ToWhen(),
}) })
} }
req := &gwapitypes.CreateVariableRequest{ req := &gwapitypes.CreateVariableRequest{
@ -150,36 +149,3 @@ func variableCreate(cmd *cobra.Command, ownertype string, args []string) error {
return nil return nil
} }
func fromCsWhenCondition(apiwc cstypes.WhenCondition) gwapitypes.WhenCondition {
return gwapitypes.WhenCondition{
Type: gwapitypes.WhenConditionType(apiwc.Type),
Match: apiwc.Match,
}
}
func fromCsWhenConditions(apiwcs *cstypes.WhenConditions) *gwapitypes.WhenConditions {
if apiwcs == nil {
return nil
}
wcs := &gwapitypes.WhenConditions{
Include: make([]gwapitypes.WhenCondition, len(apiwcs.Include)),
Exclude: make([]gwapitypes.WhenCondition, len(apiwcs.Exclude)),
}
for i, include := range apiwcs.Include {
wcs.Include[i] = fromCsWhenCondition(include)
}
for i, exclude := range apiwcs.Exclude {
wcs.Exclude[i] = fromCsWhenCondition(exclude)
}
return wcs
}
func fromCsWhen(apiwhen *cstypes.When) *gwapitypes.When {
return &gwapitypes.When{
Branch: fromCsWhenConditions(apiwhen.Branch),
Tag: fromCsWhenConditions(apiwhen.Tag),
Ref: fromCsWhenConditions(apiwhen.Ref),
}
}

View File

@ -94,7 +94,7 @@ func variableUpdate(cmd *cobra.Command, ownertype string, args []string) error {
rvalues = append(rvalues, gwapitypes.VariableValueRequest{ rvalues = append(rvalues, gwapitypes.VariableValueRequest{
SecretName: value.SecretName, SecretName: value.SecretName,
SecretVar: value.SecretVar, SecretVar: value.SecretVar,
When: fromCsWhen(value.When.ToCSWhen()), When: value.When.ToWhen(),
}) })
} }
req := &gwapitypes.UpdateVariableRequest{ req := &gwapitypes.UpdateVariableRequest{

View File

@ -21,7 +21,6 @@ import (
"strings" "strings"
"agola.io/agola/internal/util" "agola.io/agola/internal/util"
cstypes "agola.io/agola/services/configstore/types"
"agola.io/agola/services/types" "agola.io/agola/services/types"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
@ -446,7 +445,7 @@ func (val *Value) UnmarshalJSON(b []byte) error {
return nil return nil
} }
type When cstypes.When type When types.When
type when struct { type when struct {
Branch interface{} `json:"branch"` Branch interface{} `json:"branch"`
@ -454,15 +453,8 @@ type when struct {
Ref interface{} `json:"ref"` Ref interface{} `json:"ref"`
} }
func (w *When) ToCSWhen() *cstypes.When { func (w *When) ToWhen() *types.When {
if w == nil { return (*types.When)(w)
return nil
}
return &cstypes.When{
Branch: w.Branch,
Tag: w.Tag,
Ref: w.Ref,
}
} }
func (w *When) UnmarshalJSON(b []byte) error { func (w *When) UnmarshalJSON(b []byte) error {
@ -497,8 +489,8 @@ func (w *When) UnmarshalJSON(b []byte) error {
return nil return nil
} }
func parseWhenConditions(wi interface{}) (*cstypes.WhenConditions, error) { func parseWhenConditions(wi interface{}) (*types.WhenConditions, error) {
w := &cstypes.WhenConditions{} w := &types.WhenConditions{}
var err error var err error
include := []string{} include := []string{}
@ -546,12 +538,12 @@ func parseWhenConditions(wi interface{}) (*cstypes.WhenConditions, error) {
return w, nil return w, nil
} }
func parseWhenConditionSlice(conds []string) ([]cstypes.WhenCondition, error) { func parseWhenConditionSlice(conds []string) ([]types.WhenCondition, error) {
if len(conds) == 0 { if len(conds) == 0 {
return nil, nil return nil, nil
} }
wcs := []cstypes.WhenCondition{} wcs := []types.WhenCondition{}
for _, cond := range conds { for _, cond := range conds {
wc, err := parseWhenCondition(cond) wc, err := parseWhenCondition(cond)
if err != nil { if err != nil {
@ -563,7 +555,7 @@ func parseWhenConditionSlice(conds []string) ([]cstypes.WhenCondition, error) {
return wcs, nil return wcs, nil
} }
func parseWhenCondition(s string) (*cstypes.WhenCondition, error) { func parseWhenCondition(s string) (*types.WhenCondition, error) {
isRegExp := false isRegExp := false
if len(s) > 2 { if len(s) > 2 {
for _, d := range regExpDelimiters { for _, d := range regExpDelimiters {
@ -575,15 +567,15 @@ func parseWhenCondition(s string) (*cstypes.WhenCondition, error) {
} }
} }
wc := &cstypes.WhenCondition{Match: s} wc := &types.WhenCondition{Match: s}
if isRegExp { if isRegExp {
if _, err := regexp.Compile(s); err != nil { if _, err := regexp.Compile(s); err != nil {
return nil, errors.Errorf("wrong regular expression: %w", err) return nil, errors.Errorf("wrong regular expression: %w", err)
} }
wc.Type = cstypes.WhenConditionTypeRegExp wc.Type = types.WhenConditionTypeRegExp
} else { } else {
wc.Type = cstypes.WhenConditionTypeSimple wc.Type = types.WhenConditionTypeSimple
} }
return wc, nil return wc, nil
} }

View File

@ -19,7 +19,7 @@ import (
"testing" "testing"
"agola.io/agola/internal/util" "agola.io/agola/internal/util"
"agola.io/agola/services/configstore/types" "agola.io/agola/services/types"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
errors "golang.org/x/xerrors" errors "golang.org/x/xerrors"

View File

@ -20,8 +20,8 @@ import (
"agola.io/agola/internal/config" "agola.io/agola/internal/config"
"agola.io/agola/internal/util" "agola.io/agola/internal/util"
cstypes "agola.io/agola/services/configstore/types"
rstypes "agola.io/agola/services/runservice/types" rstypes "agola.io/agola/services/runservice/types"
"agola.io/agola/services/types"
errors "golang.org/x/xerrors" errors "golang.org/x/xerrors"
) )
@ -183,7 +183,7 @@ func GenRunConfigTasks(uuid util.UUIDGenerator, c *config.Config, runName string
rcts := map[string]*rstypes.RunConfigTask{} rcts := map[string]*rstypes.RunConfigTask{}
for _, ct := range cr.Tasks { for _, ct := range cr.Tasks {
include := cstypes.MatchWhen(ct.When.ToCSWhen(), branch, tag, ref) include := types.MatchWhen(ct.When.ToWhen(), branch, tag, ref)
steps := make(rstypes.Steps, len(ct.Steps)) steps := make(rstypes.Steps, len(ct.Steps))
for i, cpts := range ct.Steps { for i, cpts := range ct.Steps {

View File

@ -21,8 +21,8 @@ import (
"agola.io/agola/internal/config" "agola.io/agola/internal/config"
"agola.io/agola/internal/util" "agola.io/agola/internal/util"
cstypes "agola.io/agola/services/configstore/types"
rstypes "agola.io/agola/services/runservice/types" rstypes "agola.io/agola/services/runservice/types"
"agola.io/agola/services/types"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
errors "golang.org/x/xerrors" errors "golang.org/x/xerrors"
@ -763,11 +763,11 @@ func TestGenRunConfig(t *testing.T) {
IgnoreFailure: false, IgnoreFailure: false,
Approval: false, Approval: false,
When: &config.When{ When: &config.When{
Branch: &cstypes.WhenConditions{Include: []cstypes.WhenCondition{{Match: "master"}}}, Branch: &types.WhenConditions{Include: []types.WhenCondition{{Match: "master"}}},
Tag: &cstypes.WhenConditions{Include: []cstypes.WhenCondition{{Match: "v1.x"}, {Match: "v2.x"}}}, Tag: &types.WhenConditions{Include: []types.WhenCondition{{Match: "v1.x"}, {Match: "v2.x"}}},
Ref: &cstypes.WhenConditions{ Ref: &types.WhenConditions{
Include: []cstypes.WhenCondition{{Match: "master"}}, Include: []types.WhenCondition{{Match: "master"}},
Exclude: []cstypes.WhenCondition{{Match: "branch01", Type: cstypes.WhenConditionTypeRegExp}, {Match: "branch02"}}, Exclude: []types.WhenCondition{{Match: "branch01", Type: types.WhenConditionTypeRegExp}, {Match: "branch02"}},
}, },
}, },
}, },

View File

@ -24,11 +24,12 @@ import (
gitsource "agola.io/agola/internal/gitsources" gitsource "agola.io/agola/internal/gitsources"
"agola.io/agola/internal/runconfig" "agola.io/agola/internal/runconfig"
"agola.io/agola/internal/services/common" "agola.io/agola/internal/services/common"
"agola.io/agola/internal/services/types" itypes "agola.io/agola/internal/services/types"
"agola.io/agola/internal/util" "agola.io/agola/internal/util"
cstypes "agola.io/agola/services/configstore/types" cstypes "agola.io/agola/services/configstore/types"
rsapitypes "agola.io/agola/services/runservice/api/types" rsapitypes "agola.io/agola/services/runservice/api/types"
rstypes "agola.io/agola/services/runservice/types" rstypes "agola.io/agola/services/runservice/types"
"agola.io/agola/services/types"
errors "golang.org/x/xerrors" errors "golang.org/x/xerrors"
) )
@ -290,9 +291,9 @@ func (h *ActionHandler) RunTaskAction(ctx context.Context, req *RunTaskActionsRe
} }
type CreateRunRequest struct { type CreateRunRequest struct {
RunType types.RunType RunType itypes.RunType
RefType types.RunRefType RefType itypes.RunRefType
RunCreationTrigger types.RunCreationTriggerType RunCreationTrigger itypes.RunCreationTriggerType
Project *cstypes.Project Project *cstypes.Project
User *cstypes.User User *cstypes.User
@ -341,7 +342,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
var groupType common.GroupType var groupType common.GroupType
var group string var group string
if req.RunType == types.RunTypeProject { if req.RunType == itypes.RunTypeProject {
baseGroupType = common.GroupTypeProject baseGroupType = common.GroupTypeProject
baseGroupID = req.Project.ID baseGroupID = req.Project.ID
} else { } else {
@ -350,13 +351,13 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
} }
switch req.RefType { switch req.RefType {
case types.RunRefTypeBranch: case itypes.RunRefTypeBranch:
groupType = common.GroupTypeBranch groupType = common.GroupTypeBranch
group = req.Branch group = req.Branch
case types.RunRefTypeTag: case itypes.RunRefTypeTag:
groupType = common.GroupTypeTag groupType = common.GroupTypeTag
group = req.Tag group = req.Tag
case types.RunRefTypePullRequest: case itypes.RunRefTypePullRequest:
groupType = common.GroupTypePullRequest groupType = common.GroupTypePullRequest
group = req.PullRequestID group = req.PullRequestID
} }
@ -394,7 +395,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
} }
var variables map[string]string var variables map[string]string
if req.RunType == types.RunTypeProject { if req.RunType == itypes.RunTypeProject {
var err error var err error
variables, err = h.genRunVariables(ctx, req) variables, err = h.genRunVariables(ctx, req)
if err != nil { if err != nil {
@ -417,7 +418,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
AnnotationCompareLink: req.CompareLink, AnnotationCompareLink: req.CompareLink,
} }
if req.RunType == types.RunTypeProject { if req.RunType == itypes.RunTypeProject {
annotations[AnnotationProjectID] = req.Project.ID annotations[AnnotationProjectID] = req.Project.ID
} else { } else {
annotations[AnnotationUserID] = req.User.ID annotations[AnnotationUserID] = req.User.ID
@ -438,7 +439,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
// Since user belong to the same group (the user uuid) we needed another way to differentiate the cache. We'll use the user uuid + the user run repo uuid // Since user belong to the same group (the user uuid) we needed another way to differentiate the cache. We'll use the user uuid + the user run repo uuid
var cacheGroup string var cacheGroup string
if req.RunType == types.RunTypeUser { if req.RunType == itypes.RunTypeUser {
cacheGroup = req.User.ID + "-" + req.UserRunRepoUUID cacheGroup = req.User.ID + "-" + req.UserRunRepoUUID
} }
@ -482,7 +483,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
} }
for _, run := range config.Runs { for _, run := range config.Runs {
if match := cstypes.MatchWhen(run.When.ToCSWhen(), req.Branch, req.Tag, req.Ref); !match { if match := types.MatchWhen(run.When.ToWhen(), req.Branch, req.Tag, req.Ref); !match {
h.log.Debugf("skipping run since when condition doesn't match") h.log.Debugf("skipping run since when condition doesn't match")
continue continue
} }
@ -549,7 +550,7 @@ func (h *ActionHandler) genRunVariables(ctx context.Context, req *CreateRunReque
// find the value match // find the value match
var varval cstypes.VariableValue var varval cstypes.VariableValue
for _, varval = range pvar.Values { for _, varval = range pvar.Values {
match := cstypes.MatchWhen(varval.When, req.Branch, req.Tag, req.Ref) match := types.MatchWhen(varval.When, req.Branch, req.Tag, req.Ref)
if !match { if !match {
continue continue
} }

View File

@ -41,7 +41,7 @@ func createVariableResponse(v *csapitypes.Variable, secrets []*csapitypes.Secret
nv.Values[i] = gwapitypes.VariableValue{ nv.Values[i] = gwapitypes.VariableValue{
SecretName: varvalue.SecretName, SecretName: varvalue.SecretName,
SecretVar: varvalue.SecretVar, SecretVar: varvalue.SecretVar,
When: fromCsWhen(varvalue.When), When: varvalue.When,
} }
// get matching secret for var value // get matching secret for var value
secret := common.GetVarValueMatchingSecret(varvalue, v.ParentPath, secrets) secret := common.GetVarValueMatchingSecret(varvalue, v.ParentPath, secrets)
@ -221,74 +221,8 @@ func fromApiVariableValues(apivalues []gwapitypes.VariableValueRequest) []cstype
values[i] = cstypes.VariableValue{ values[i] = cstypes.VariableValue{
SecretName: v.SecretName, SecretName: v.SecretName,
SecretVar: v.SecretVar, SecretVar: v.SecretVar,
When: fromApiWhen(v.When), When: v.When,
} }
} }
return values return values
} }
func fromApiWhenCondition(apiwc gwapitypes.WhenCondition) cstypes.WhenCondition {
return cstypes.WhenCondition{
Type: cstypes.WhenConditionType(apiwc.Type),
Match: apiwc.Match,
}
}
func fromApiWhenConditions(apiwcs *gwapitypes.WhenConditions) *cstypes.WhenConditions {
if apiwcs == nil {
return nil
}
wcs := &cstypes.WhenConditions{
Include: make([]cstypes.WhenCondition, len(apiwcs.Include)),
Exclude: make([]cstypes.WhenCondition, len(apiwcs.Exclude)),
}
for i, include := range apiwcs.Include {
wcs.Include[i] = fromApiWhenCondition(include)
}
for i, exclude := range apiwcs.Exclude {
wcs.Exclude[i] = fromApiWhenCondition(exclude)
}
return wcs
}
func fromApiWhen(apiwhen *gwapitypes.When) *cstypes.When {
return &cstypes.When{
Branch: fromApiWhenConditions(apiwhen.Branch),
Tag: fromApiWhenConditions(apiwhen.Tag),
Ref: fromApiWhenConditions(apiwhen.Ref),
}
}
func fromCsWhenCondition(apiwc cstypes.WhenCondition) gwapitypes.WhenCondition {
return gwapitypes.WhenCondition{
Type: gwapitypes.WhenConditionType(apiwc.Type),
Match: apiwc.Match,
}
}
func fromCsWhenConditions(apiwcs *cstypes.WhenConditions) *gwapitypes.WhenConditions {
if apiwcs == nil {
return nil
}
wcs := &gwapitypes.WhenConditions{
Include: make([]gwapitypes.WhenCondition, len(apiwcs.Include)),
Exclude: make([]gwapitypes.WhenCondition, len(apiwcs.Exclude)),
}
for i, include := range apiwcs.Include {
wcs.Include[i] = fromCsWhenCondition(include)
}
for i, exclude := range apiwcs.Exclude {
wcs.Exclude[i] = fromCsWhenCondition(exclude)
}
return wcs
}
func fromCsWhen(apiwhen *cstypes.When) *gwapitypes.When {
return &gwapitypes.When{
Branch: fromCsWhenConditions(apiwhen.Branch),
Tag: fromCsWhenConditions(apiwhen.Tag),
Ref: fromCsWhenConditions(apiwhen.Ref),
}
}

View File

@ -17,9 +17,9 @@ package types
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"regexp"
"time" "time"
"agola.io/agola/services/types"
"agola.io/agola/util" "agola.io/agola/util"
) )
@ -353,87 +353,5 @@ type VariableValue struct {
SecretName string `json:"secret_name,omitempty"` SecretName string `json:"secret_name,omitempty"`
SecretVar string `json:"secret_var,omitempty"` SecretVar string `json:"secret_var,omitempty"`
When *When `json:"when,omitempty"` When *types.When `json:"when,omitempty"`
}
type When struct {
Branch *WhenConditions `json:"branch,omitempty"`
Tag *WhenConditions `json:"tag,omitempty"`
Ref *WhenConditions `json:"ref,omitempty"`
}
type WhenConditions struct {
Include []WhenCondition `json:"include,omitempty"`
Exclude []WhenCondition `json:"exclude,omitempty"`
}
type WhenConditionType string
const (
WhenConditionTypeSimple WhenConditionType = "simple"
WhenConditionTypeRegExp WhenConditionType = "regexp"
)
type WhenCondition struct {
Type WhenConditionType `json:"type,omitempty"`
Match string `json:"match,omitempty"`
}
func MatchWhen(when *When, branch, tag, ref string) bool {
include := true
if when != nil {
include = false
// test only if branch is not empty, if empty mean that we are not in a branch
if when.Branch != nil && branch != "" {
// first check includes and override with excludes
if matchCondition(when.Branch.Include, branch) {
include = true
}
if matchCondition(when.Branch.Exclude, branch) {
include = false
}
}
// test only if tag is not empty, if empty mean that we are not in a tag
if when.Tag != nil && tag != "" {
// first check includes and override with excludes
if matchCondition(when.Tag.Include, tag) {
include = true
}
if matchCondition(when.Tag.Exclude, tag) {
include = false
}
}
// we assume that ref always have a value
if when.Ref != nil {
// first check includes and override with excludes
if matchCondition(when.Ref.Include, ref) {
include = true
}
if matchCondition(when.Ref.Exclude, ref) {
include = false
}
}
}
return include
}
func matchCondition(conds []WhenCondition, s string) bool {
for _, cond := range conds {
switch cond.Type {
case WhenConditionTypeSimple:
if cond.Match == s {
return true
}
case WhenConditionTypeRegExp:
re, err := regexp.Compile(cond.Match)
if err != nil {
panic(err)
}
if re.MatchString(s) {
return true
}
}
}
return false
} }

View File

@ -16,12 +16,14 @@ package types
import ( import (
"testing" "testing"
"agola.io/agola/services/types"
) )
func TestMatchWhen(t *testing.T) { func TestMatchWhen(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
when *When when *types.When
branch string branch string
tag string tag string
ref string ref string
@ -34,10 +36,10 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include with empty match value, should not match", name: "test branch when include with empty match value, should not match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeSimple}, {Type: types.WhenConditionTypeSimple},
}, },
}, },
}, },
@ -46,10 +48,10 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include regexp with empty match value, should match", name: "test branch when include regexp with empty match value, should match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp}, {Type: types.WhenConditionTypeRegExp},
}, },
}, },
}, },
@ -58,10 +60,10 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include with empty match value and empty provided branch, should not match", name: "test branch when include with empty match value and empty provided branch, should not match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeSimple}, {Type: types.WhenConditionTypeSimple},
}, },
}, },
}, },
@ -70,10 +72,10 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include regexp with empty match value and empty provided branch, should not match", name: "test branch when include regexp with empty match value and empty provided branch, should not match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp}, {Type: types.WhenConditionTypeRegExp},
}, },
}, },
}, },
@ -82,10 +84,10 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include, should match", name: "test branch when include, should match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeSimple, Match: "master"}, {Type: types.WhenConditionTypeSimple, Match: "master"},
}, },
}, },
}, },
@ -94,10 +96,10 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include, should not match", name: "test branch when include, should not match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeSimple, Match: "master"}, {Type: types.WhenConditionTypeSimple, Match: "master"},
}, },
}, },
}, },
@ -106,15 +108,15 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test tag, ref when include, should not match since when is not nil and we have provided a branch and not a tag", name: "test tag, ref when include, should not match since when is not nil and we have provided a branch and not a tag",
when: &When{ when: &types.When{
Tag: &WhenConditions{ Tag: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeSimple, Match: "master"}, {Type: types.WhenConditionTypeSimple, Match: "master"},
}, },
}, },
Ref: &WhenConditions{ Ref: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeSimple, Match: "master"}, {Type: types.WhenConditionTypeSimple, Match: "master"},
}, },
}, },
}, },
@ -123,10 +125,10 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include regexp, should match", name: "test branch when include regexp, should match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "master"}, {Type: types.WhenConditionTypeRegExp, Match: "master"},
}, },
}, },
}, },
@ -135,10 +137,10 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include, should not match", name: "test branch when include, should not match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "master"}, {Type: types.WhenConditionTypeRegExp, Match: "master"},
}, },
}, },
}, },
@ -147,10 +149,10 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include regexp, should match", name: "test branch when include regexp, should match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "m.*"}, {Type: types.WhenConditionTypeRegExp, Match: "m.*"},
}, },
}, },
}, },
@ -159,10 +161,10 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include, should not match", name: "test branch when include, should not match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "m.*"}, {Type: types.WhenConditionTypeRegExp, Match: "m.*"},
}, },
}, },
}, },
@ -171,13 +173,13 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include regexp, exclude simple, should match", name: "test branch when include regexp, exclude simple, should match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "m.*"}, {Type: types.WhenConditionTypeRegExp, Match: "m.*"},
}, },
Exclude: []WhenCondition{ Exclude: []types.WhenCondition{
{Type: WhenConditionTypeSimple, Match: "maste"}, {Type: types.WhenConditionTypeSimple, Match: "maste"},
}, },
}, },
}, },
@ -186,13 +188,13 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include regexp, exclude simple, should not match", name: "test branch when include regexp, exclude simple, should not match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "m.*"}, {Type: types.WhenConditionTypeRegExp, Match: "m.*"},
}, },
Exclude: []WhenCondition{ Exclude: []types.WhenCondition{
{Type: WhenConditionTypeSimple, Match: "master"}, {Type: types.WhenConditionTypeSimple, Match: "master"},
}, },
}, },
}, },
@ -201,13 +203,13 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include regexp, exclude regexp, should match", name: "test branch when include regexp, exclude regexp, should match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "m.*"}, {Type: types.WhenConditionTypeRegExp, Match: "m.*"},
}, },
Exclude: []WhenCondition{ Exclude: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "mb.*"}, {Type: types.WhenConditionTypeRegExp, Match: "mb.*"},
}, },
}, },
}, },
@ -216,13 +218,13 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when include regexp, exclude regexp, should not match", name: "test branch when include regexp, exclude regexp, should not match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "m.*"}, {Type: types.WhenConditionTypeRegExp, Match: "m.*"},
}, },
Exclude: []WhenCondition{ Exclude: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "ma.*"}, {Type: types.WhenConditionTypeRegExp, Match: "ma.*"},
}, },
}, },
}, },
@ -231,15 +233,15 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when multiple include regexp, multiple exclude regexp, should match", name: "test branch when multiple include regexp, multiple exclude regexp, should match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "m.*"}, {Type: types.WhenConditionTypeRegExp, Match: "m.*"},
{Type: WhenConditionTypeRegExp, Match: "b.*"}, {Type: types.WhenConditionTypeRegExp, Match: "b.*"},
}, },
Exclude: []WhenCondition{ Exclude: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "b.*"}, {Type: types.WhenConditionTypeRegExp, Match: "b.*"},
{Type: WhenConditionTypeRegExp, Match: "c.*"}, {Type: types.WhenConditionTypeRegExp, Match: "c.*"},
}, },
}, },
}, },
@ -248,15 +250,15 @@ func TestMatchWhen(t *testing.T) {
}, },
{ {
name: "test branch when multiple include regexp, multiple exclude regexp, should not match", name: "test branch when multiple include regexp, multiple exclude regexp, should not match",
when: &When{ when: &types.When{
Branch: &WhenConditions{ Branch: &types.WhenConditions{
Include: []WhenCondition{ Include: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "m.*"}, {Type: types.WhenConditionTypeRegExp, Match: "m.*"},
{Type: WhenConditionTypeRegExp, Match: "b.*"}, {Type: types.WhenConditionTypeRegExp, Match: "b.*"},
}, },
Exclude: []WhenCondition{ Exclude: []types.WhenCondition{
{Type: WhenConditionTypeRegExp, Match: "b.*"}, {Type: types.WhenConditionTypeRegExp, Match: "b.*"},
{Type: WhenConditionTypeRegExp, Match: "ma.*"}, {Type: types.WhenConditionTypeRegExp, Match: "ma.*"},
}, },
}, },
}, },
@ -267,7 +269,7 @@ func TestMatchWhen(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
out := MatchWhen(tt.when, tt.branch, tt.tag, tt.ref) out := types.MatchWhen(tt.when, tt.branch, tt.tag, tt.ref)
if tt.out != out { if tt.out != out {
t.Fatalf("expected match: %t, got: %t", tt.out, out) t.Fatalf("expected match: %t, got: %t", tt.out, out)
} }

View File

@ -14,11 +14,15 @@
package types package types
import (
"agola.io/agola/services/types"
)
type VariableValueRequest struct { type VariableValueRequest struct {
SecretName string `json:"secret_name"` SecretName string `json:"secret_name"`
SecretVar string `json:"secret_var"` SecretVar string `json:"secret_var"`
When *When `json:"when"` When *types.When `json:"when"`
} }
type VariableValue struct { type VariableValue struct {
@ -26,7 +30,7 @@ type VariableValue struct {
SecretVar string `json:"secret_var"` SecretVar string `json:"secret_var"`
MatchingSecretParentPath string `json:"matching_secret_parent_path"` MatchingSecretParentPath string `json:"matching_secret_parent_path"`
When *When `json:"when"` When *types.When `json:"when"`
} }
type VariableResponse struct { type VariableResponse struct {

View File

@ -1,38 +0,0 @@
// Copyright 2019 Sorint.lab
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
// See the License for the specific language governing permissions and
// limitations under the License.
package types
type When struct {
Branch *WhenConditions `json:"branch,omitempty"`
Tag *WhenConditions `json:"tag,omitempty"`
Ref *WhenConditions `json:"ref,omitempty"`
}
type WhenConditions struct {
Include []WhenCondition `json:"include,omitempty"`
Exclude []WhenCondition `json:"exclude,omitempty"`
}
type WhenConditionType string
const (
WhenConditionTypeSimple WhenConditionType = "simple"
WhenConditionTypeRegExp WhenConditionType = "regexp"
)
type WhenCondition struct {
Type WhenConditionType `json:"type,omitempty"`
Match string `json:"match,omitempty"`
}

101
services/types/when.go Normal file
View File

@ -0,0 +1,101 @@
// Copyright 2019 Sorint.lab
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"regexp"
)
type When struct {
Branch *WhenConditions `json:"branch,omitempty"`
Tag *WhenConditions `json:"tag,omitempty"`
Ref *WhenConditions `json:"ref,omitempty"`
}
type WhenConditions struct {
Include []WhenCondition `json:"include,omitempty"`
Exclude []WhenCondition `json:"exclude,omitempty"`
}
type WhenConditionType string
const (
WhenConditionTypeSimple WhenConditionType = "simple"
WhenConditionTypeRegExp WhenConditionType = "regexp"
)
type WhenCondition struct {
Type WhenConditionType `json:"type,omitempty"`
Match string `json:"match,omitempty"`
}
func MatchWhen(when *When, branch, tag, ref string) bool {
include := true
if when != nil {
include = false
// test only if branch is not empty, if empty mean that we are not in a branch
if when.Branch != nil && branch != "" {
// first check includes and override with excludes
if matchCondition(when.Branch.Include, branch) {
include = true
}
if matchCondition(when.Branch.Exclude, branch) {
include = false
}
}
// test only if tag is not empty, if empty mean that we are not in a tag
if when.Tag != nil && tag != "" {
// first check includes and override with excludes
if matchCondition(when.Tag.Include, tag) {
include = true
}
if matchCondition(when.Tag.Exclude, tag) {
include = false
}
}
// we assume that ref always have a value
if when.Ref != nil {
// first check includes and override with excludes
if matchCondition(when.Ref.Include, ref) {
include = true
}
if matchCondition(when.Ref.Exclude, ref) {
include = false
}
}
}
return include
}
func matchCondition(conds []WhenCondition, s string) bool {
for _, cond := range conds {
switch cond.Type {
case WhenConditionTypeSimple:
if cond.Match == s {
return true
}
case WhenConditionTypeRegExp:
re, err := regexp.Compile(cond.Match)
if err != nil {
panic(err)
}
if re.MatchString(s) {
return true
}
}
}
return false
}