config: add run when field

Don't create a run if a when condition is defined and it doesn't match.
This commit is contained in:
Simone Gotti 2019-08-01 18:16:34 +02:00
parent 4fe4631729
commit db742a6cd6
4 changed files with 151 additions and 79 deletions

View File

@ -98,6 +98,7 @@ type Container struct {
type Run struct {
Name string `json:"name"`
Tasks []*Task `json:"tasks"`
When *When `json:"when"`
DockerRegistriesAuth map[string]*DockerRegistryAuth `json:"docker_registries_auth"`
}
@ -453,6 +454,17 @@ type when struct {
Ref interface{} `json:"ref"`
}
func (w *When) ToCSWhen() *cstypes.When {
if w == nil {
return nil
}
return &cstypes.When{
Branch: w.Branch,
Tag: w.Tag,
Ref: w.Ref,
}
}
func (w *When) UnmarshalJSON(b []byte) error {
var wi *when
if err := json.Unmarshal(b, &wi); err != nil {

View File

@ -48,17 +48,6 @@ func genRuntime(c *config.Config, ce *config.Runtime, variables map[string]strin
}
}
func whenFromConfigWhen(cw *config.When) *cstypes.When {
if cw == nil {
return nil
}
return &cstypes.When{
Branch: cw.Branch,
Tag: cw.Tag,
Ref: cw.Ref,
}
}
func stepFromConfigStep(csi interface{}, variables map[string]string) interface{} {
switch cs := csi.(type) {
case *config.CloneStep:
@ -194,7 +183,7 @@ func GenRunConfigTasks(uuid util.UUIDGenerator, c *config.Config, runName string
rcts := map[string]*rstypes.RunConfigTask{}
for _, ct := range cr.Tasks {
include := cstypes.MatchWhen(whenFromConfigWhen(ct.When), branch, tag, ref)
include := cstypes.MatchWhen(ct.When.ToCSWhen(), branch, tag, ref)
steps := make(rstypes.Steps, len(ct.Steps))
for i, cpts := range ct.Steps {

View File

@ -478,6 +478,11 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e
}
for _, run := range config.Runs {
if match := cstypes.MatchWhen(run.When.ToCSWhen(), req.Branch, req.Tag, req.Ref); !match {
h.log.Debugf("skipping run since when condition doesn't match")
continue
}
rcts := runconfig.GenRunConfigTasks(util.DefaultUUIDGenerator{}, config, run.Name, variables, req.Branch, req.Tag, req.Ref)
createRunReq := &rsapitypes.RunCreateRequest{

View File

@ -450,60 +450,13 @@ func createProject(ctx context.Context, t *testing.T, giteaClient *gitea.Client,
return giteaRepo, project
}
func TestRun(t *testing.T) {
dir, err := ioutil.TempDir("", "agola")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
defer os.RemoveAll(dir)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
tetcd, tgitea, c := setup(ctx, t, dir)
defer shutdownGitea(tgitea)
defer shutdownEtcd(tetcd)
giteaAPIURL := fmt.Sprintf("http://%s:%s", tgitea.HTTPListenAddress, tgitea.HTTPPort)
giteaToken, token := createLinkedAccount(ctx, t, tgitea, c)
giteaClient := gitea.NewClient(giteaAPIURL, giteaToken)
gwClient := gwclient.NewClient(c.Gateway.APIExposedURL, token)
giteaRepo, project := createProject(ctx, t, giteaClient, gwClient)
func push(t *testing.T, config, cloneURL, remoteToken string) {
gitfs := memfs.New()
f, err := gitfs.Create(".agola/config.jsonnet")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
_, err = f.Write([]byte(
`{
runs: [
{
name: 'run01',
tasks: [
{
name: 'task01',
runtime: {
containers: [
{
image: 'alpine/git',
},
],
},
steps: [
{ type: 'clone' },
{ type: 'run', command: 'env' },
],
},
],
},
],
}
`))
if err != nil {
if _, err = f.Write([]byte(config)); err != nil {
t.Fatalf("unexpected err: %v", err)
}
@ -514,7 +467,7 @@ func TestRun(t *testing.T) {
if _, err := r.CreateRemote(&gitconfig.RemoteConfig{
Name: "origin",
URLs: []string{giteaRepo.CloneURL},
URLs: []string{cloneURL},
}); err != nil {
t.Fatalf("unexpected err: %v", err)
}
@ -537,37 +490,150 @@ func TestRun(t *testing.T) {
t.Fatalf("unexpected err: %v", err)
}
t.Logf("sshurl: %s", giteaRepo.CloneURL)
t.Logf("sshurl: %s", cloneURL)
if err := r.Push(&git.PushOptions{
RemoteName: "origin",
Auth: &http.BasicAuth{
Username: giteaUser01,
Password: giteaToken,
Password: remoteToken,
},
}); err != nil {
t.Fatalf("unexpected err: %v", err)
}
// TODO(sgotti) add an util to wait for a run phase
time.Sleep(10 * time.Second)
}
runs, _, err := gwClient.GetRuns(ctx, nil, nil, []string{path.Join("/project", project.ID)}, nil, "", 0, false)
if err != nil {
t.Fatalf("unexpected err: %v", err)
func TestPush(t *testing.T) {
tests := []struct {
name string
config string
num int
annotations map[string]string
}{
{
name: "test push",
config: `
{
runs: [
{
name: 'run01',
tasks: [
{
name: 'task01',
runtime: {
containers: [
{
image: 'alpine/git',
},
],
},
steps: [
{ type: 'clone' },
{ type: 'run', command: 'env' },
],
},
],
},
],
}
`,
num: 1,
annotations: map[string]string{
"branch": "master",
"ref": "refs/heads/master",
"ref_type": "branch",
},
},
{
name: "test push with unmatched branch",
config: `
{
runs: [
{
name: 'run01',
tasks: [
{
name: 'task01',
runtime: {
containers: [
{
image: 'alpine/git',
},
],
},
steps: [
{ type: 'clone' },
{ type: 'run', command: 'env' },
],
},
],
when: {
branch: 'notmaster',
},
},
],
}
`,
num: 0,
},
}
t.Logf("runs: %s", util.Dump(runs))
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if len(runs) != 1 {
t.Fatalf("expected 1 run got: %d", len(runs))
}
dir, err := ioutil.TempDir("", "agola")
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
defer os.RemoveAll(dir)
run := runs[0]
if run.Phase != rstypes.RunPhaseFinished {
t.Fatalf("expected run phase %q, got %q", rstypes.RunPhaseFinished, run.Phase)
}
if run.Result != rstypes.RunResultSuccess {
t.Fatalf("expected run result %q, got %q", rstypes.RunResultSuccess, run.Result)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
tetcd, tgitea, c := setup(ctx, t, dir)
defer shutdownGitea(tgitea)
defer shutdownEtcd(tetcd)
giteaAPIURL := fmt.Sprintf("http://%s:%s", tgitea.HTTPListenAddress, tgitea.HTTPPort)
giteaToken, token := createLinkedAccount(ctx, t, tgitea, c)
giteaClient := gitea.NewClient(giteaAPIURL, giteaToken)
gwClient := gwclient.NewClient(c.Gateway.APIExposedURL, token)
giteaRepo, project := createProject(ctx, t, giteaClient, gwClient)
push(t, tt.config, giteaRepo.CloneURL, giteaToken)
// TODO(sgotti) add an util to wait for a run phase
time.Sleep(10 * time.Second)
runs, _, err := gwClient.GetRuns(ctx, nil, nil, []string{path.Join("/project", project.ID)}, nil, "", 0, false)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
t.Logf("runs: %s", util.Dump(runs))
if len(runs) != tt.num {
t.Fatalf("expected %d run got: %d", tt.num, len(runs))
}
if len(runs) > 0 {
run := runs[0]
if run.Phase != rstypes.RunPhaseFinished {
t.Fatalf("expected run phase %q, got %q", rstypes.RunPhaseFinished, run.Phase)
}
if run.Result != rstypes.RunResultSuccess {
t.Fatalf("expected run result %q, got %q", rstypes.RunResultSuccess, run.Result)
}
for k, v := range tt.annotations {
if run.Annotations[k] != v {
t.Fatalf("expected run annotation %q value %q, got %q", k, v, run.Annotations[k])
}
}
}
})
}
}