Skip to content

Commit

Permalink
enhance(yaml): allow for users to set version legacy for buildkite
Browse files Browse the repository at this point in the history
  • Loading branch information
ecrupper committed Dec 23, 2024
1 parent fa93fa8 commit bbe50df
Show file tree
Hide file tree
Showing 10 changed files with 526 additions and 29 deletions.
197 changes: 197 additions & 0 deletions compiler/native/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1981,6 +1981,203 @@ func TestNative_Compile_StepsandStages(t *testing.T) {
}
}

func TestNative_Compile_LegacyMergeAnchor(t *testing.T) {
// setup types
set := flag.NewFlagSet("test", 0)
set.String("clone-image", defaultCloneImage, "doc")
c := cli.NewContext(nil, set, nil)
name := "foo"
author := "author"
event := "push"
number := 1

m := &internal.Metadata{
Database: &internal.Database{
Driver: "foo",
Host: "foo",
},
Queue: &internal.Queue{
Channel: "foo",
Driver: "foo",
Host: "foo",
},
Source: &internal.Source{
Driver: "foo",
Host: "foo",
},
Vela: &internal.Vela{
Address: "foo",
WebAddress: "foo",
},
}

compiler, err := FromCLIContext(c)
if err != nil {
t.Errorf("Creating compiler returned err: %v", err)
}

compiler.repo = &api.Repo{Name: &author}
compiler.build = &api.Build{Author: &name, Number: &number, Event: &event}
compiler.WithMetadata(m)

testEnv := environment(&api.Build{Author: &name, Number: &number, Event: &event}, m, &api.Repo{Name: &author}, nil, nil)

serviceEnv := environment(&api.Build{Author: &name, Number: &number, Event: &event}, m, &api.Repo{Name: &author}, nil, nil)
serviceEnv["REGION"] = "dev"

alphaEnv := environment(&api.Build{Author: &name, Number: &number, Event: &event}, m, &api.Repo{Name: &author}, nil, nil)
alphaEnv["VELA_BUILD_SCRIPT"] = generateScriptPosix([]string{"echo alpha"})
alphaEnv["HOME"] = "/root"
alphaEnv["SHELL"] = "/bin/sh"

betaEnv := environment(&api.Build{Author: &name, Number: &number, Event: &event}, m, &api.Repo{Name: &author}, nil, nil)
betaEnv["VELA_BUILD_SCRIPT"] = generateScriptPosix([]string{"echo beta"})
betaEnv["HOME"] = "/root"
betaEnv["SHELL"] = "/bin/sh"

gammaEnv := environment(&api.Build{Author: &name, Number: &number, Event: &event}, m, &api.Repo{Name: &author}, nil, nil)
gammaEnv["VELA_BUILD_SCRIPT"] = generateScriptPosix([]string{"echo gamma"})
gammaEnv["HOME"] = "/root"
gammaEnv["SHELL"] = "/bin/sh"
gammaEnv["REGION"] = "dev"

want := &pipeline.Build{
Version: "legacy",
ID: "_author_1",
Metadata: pipeline.Metadata{
Clone: true,
Template: false,
Environment: []string{"steps", "services", "secrets"},
AutoCancel: &pipeline.CancelOptions{
Running: false,
Pending: false,
DefaultBranch: false,
},
},
Worker: pipeline.Worker{
Flavor: "",
Platform: "",
},
Services: pipeline.ContainerSlice{
&pipeline.Container{
ID: "service__author_1_service-a",
Detach: true,
Directory: "",
Environment: serviceEnv,
Image: "postgres",
Name: "service-a",
Number: 1,
Pull: "not_present",
Ports: []string{"5432:5432"},
},
},
Steps: pipeline.ContainerSlice{
&pipeline.Container{
ID: "step__author_1_init",
Directory: "/vela/src/foo//author",
Environment: testEnv,
Image: "#init",
Name: "init",
Number: 1,
Pull: "not_present",
},
&pipeline.Container{
ID: "step__author_1_clone",
Directory: "/vela/src/foo//author",
Environment: testEnv,
Image: defaultCloneImage,
Name: "clone",
Number: 2,
Pull: "not_present",
},
&pipeline.Container{
ID: "step__author_1_alpha",
Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"},
Directory: "/vela/src/foo//author",
Entrypoint: []string{"/bin/sh", "-c"},
Environment: alphaEnv,
Image: "alpine:latest",
Name: "alpha",
Number: 3,
Pull: "not_present",
Ruleset: pipeline.Ruleset{
If: pipeline.Rules{
Event: []string{"push"},
},
Matcher: "filepath",
Operator: "and",
},
},
&pipeline.Container{
ID: "step__author_1_beta",
Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"},
Directory: "/vela/src/foo//author",
Entrypoint: []string{"/bin/sh", "-c"},
Environment: betaEnv,
Image: "alpine:latest",
Name: "beta",
Number: 4,
Pull: "not_present",
Ruleset: pipeline.Ruleset{
If: pipeline.Rules{
Event: []string{"push"},
},
Matcher: "filepath",
Operator: "and",
},
},
&pipeline.Container{
ID: "step__author_1_gamma",
Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"},
Directory: "/vela/src/foo//author",
Entrypoint: []string{"/bin/sh", "-c"},
Environment: gammaEnv,
Image: "alpine:latest",
Name: "gamma",
Number: 5,
Pull: "not_present",
Ruleset: pipeline.Ruleset{
If: pipeline.Rules{
Event: []string{"push"},
},
Matcher: "filepath",
Operator: "and",
},
},
},
}

// run test on legacy version
yaml, err := os.ReadFile("testdata/steps_merge_anchor.yml")
if err != nil {
t.Errorf("Reading yaml file return err: %v", err)
}

got, _, err := compiler.Compile(context.Background(), yaml)
if err != nil {
t.Errorf("Compile returned err: %v", err)
}

if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("Compile() mismatch (-want +got):\n%s", diff)
}

// run test on current version (should fail)
yaml, err = os.ReadFile("../types/yaml/buildkite/testdata/merge_anchor.yml") // has `version: "1"` instead of `version: "legacy"`
if err != nil {
t.Errorf("Reading yaml file return err: %v", err)
}

got, _, err = compiler.Compile(context.Background(), yaml)
if err == nil {
t.Errorf("Compile should have returned err")
}

if got != nil {
t.Errorf("Compile is %v, want %v", got, nil)
}
}

// convertResponse converts the build to the ModifyResponse.
func convertResponse(build *yaml.Build) (*ModifyResponse, error) {
data, err := yml.Marshal(build)
Expand Down
4 changes: 2 additions & 2 deletions compiler/native/expand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ func TestNative_ExpandStepsMulti(t *testing.T) {
"auth_method": "token",
"username": "octocat",
"items": []interface{}{
map[interface{}]interface{}{"path": "docker", "source": "secret/docker"},
map[string]interface{}{"path": "docker", "source": "secret/docker"},
},
},
},
Expand All @@ -715,7 +715,7 @@ func TestNative_ExpandStepsMulti(t *testing.T) {
"auth_method": "token",
"username": "octocat",
"items": []interface{}{
map[interface{}]interface{}{"path": "docker", "source": "secret/docker"},
map[string]interface{}{"path": "docker", "source": "secret/docker"},
},
},
},
Expand Down
13 changes: 4 additions & 9 deletions compiler/native/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ import (
"io"
"os"

bkYaml "github.com/buildkite/yaml"

"github.com/go-vela/server/compiler/template/native"
"github.com/go-vela/server/compiler/template/starlark"
typesRaw "github.com/go-vela/server/compiler/types/raw"
bkYamlTypes "github.com/go-vela/server/compiler/types/yaml/buildkite"
"github.com/go-vela/server/compiler/types/yaml/yaml"
"github.com/go-vela/server/constants"
"github.com/go-vela/server/internal"
)

// ParseRaw converts an object to a string.
Expand Down Expand Up @@ -114,12 +112,9 @@ func (c *client) Parse(v interface{}, pipelineType string, template *yaml.Templa

// ParseBytes converts a byte slice to a yaml configuration.
func ParseBytes(data []byte) (*yaml.Build, []byte, error) {
config := new(bkYamlTypes.Build)

// unmarshal the bytes into the yaml configuration
err := bkYaml.Unmarshal(data, config)
config, err := internal.ParseYAML(data)
if err != nil {
return nil, data, fmt.Errorf("unable to unmarshal yaml: %w", err)
return nil, nil, err
}

// initializing Environment to prevent nil error
Expand All @@ -129,7 +124,7 @@ func ParseBytes(data []byte) (*yaml.Build, []byte, error) {
config.Environment = typesRaw.StringSliceMap{}
}

return config.ToYAML(), data, nil
return config, data, nil
}

// ParseFile converts an os.File into a yaml configuration.
Expand Down
78 changes: 78 additions & 0 deletions compiler/native/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,84 @@ func TestNative_Parse_Stages(t *testing.T) {
}
}

func TestNative_Parse_StagesLegacyMergeAnchor(t *testing.T) {
// setup types
client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil))
want := &yaml.Build{
Version: "legacy",
Metadata: yaml.Metadata{
Environment: []string{"steps", "services", "secrets"},
},
Environment: raw.StringSliceMap{},
Stages: yaml.StageSlice{
&yaml.Stage{
Name: "install",
Needs: raw.StringSlice{"clone"},
Steps: yaml.StepSlice{
&yaml.Step{
Commands: []string{"./gradlew downloadDependencies"},
Environment: map[string]string{
"GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false",
"GRADLE_USER_HOME": ".gradle",
},
Image: "openjdk:latest",
Name: "install",
Pull: "always",
},
},
},
&yaml.Stage{
Name: "test",
Needs: []string{"install", "clone"},
Steps: yaml.StepSlice{
&yaml.Step{
Commands: []string{"./gradlew check"},
Environment: map[string]string{
"GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false",
"GRADLE_USER_HOME": ".gradle",
},
Image: "openjdk:latest",
Name: "test",
Pull: "always",
},
},
},
&yaml.Stage{
Name: "build",
Needs: []string{"install", "clone"},
Steps: yaml.StepSlice{
&yaml.Step{
Commands: []string{"./gradlew build"},
Environment: map[string]string{
"GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false",
"GRADLE_USER_HOME": ".gradle",
},
Image: "openjdk:latest",
Name: "build",
Pull: "always",
},
},
},
},
}

// run test
b, err := os.ReadFile("testdata/stages_merged.yml")
if err != nil {
t.Errorf("Reading file returned err: %v", err)
}

got, _, err := client.Parse(b, "", new(yaml.Template))

if err != nil {
t.Errorf("Parse returned err: %v", err)
}

if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("Parse() mismatch (-want +got):\n%s", diff)
}
}

func TestNative_Parse_Steps(t *testing.T) {
// setup types
client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil))
Expand Down
38 changes: 38 additions & 0 deletions compiler/native/testdata/stages_merged.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
version: "legacy"

stages:
install:
steps:
- name: install
commands:
- ./gradlew downloadDependencies
environment:
GRADLE_OPTS: -Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false
GRADLE_USER_HOME: .gradle
image: openjdk:latest
pull: true

test:
needs: [ install ]
steps:
- name: test
commands:
- ./gradlew check
environment:
GRADLE_OPTS: -Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false
GRADLE_USER_HOME: .gradle
image: openjdk:latest
pull: true

stages:
build:
needs: [ install ]
steps:
- name: build
commands:
- ./gradlew build
environment:
- GRADLE_OPTS=-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false
- GRADLE_USER_HOME=.gradle
image: openjdk:latest
pull: true
Loading

0 comments on commit bbe50df

Please sign in to comment.