drone-yaml/yaml/converter/gitlab/convert.go

107 lines
2.5 KiB
Go

// Copyright 2019 Drone.IO Inc. All rights reserved.
// Use of this source code is governed by the Drone Non-Commercial License
// that can be found in the LICENSE file.
package gitlab
import (
"bytes"
"strings"
droneyaml "github.com/drone/drone-yaml/yaml"
"github.com/drone/drone-yaml/yaml/compiler/image"
"github.com/drone/drone-yaml/yaml/pretty"
"github.com/buildkite/yaml"
)
// Convert converts the yaml configuration file from
// the legacy format to the 1.0+ format.
func Convert(b []byte) ([]byte, error) {
config := new(Config)
err := yaml.Unmarshal(b, config)
if err != nil {
return nil, err
}
manifest := &droneyaml.Manifest{}
// if no stages are defined, we create a single,
// default stage that will be used for all jobs.
if len(config.Stages) == 0 {
for name, job := range config.Jobs {
config.Stages = append(config.Stages, name)
job.Stage = name
}
}
// create a new pipeline for each stage.
var prevstage string
for _, stage := range config.Stages {
pipeline := &droneyaml.Pipeline{}
pipeline.Name = stage
pipeline.Kind = droneyaml.KindPipeline
manifest.Resources = append(manifest.Resources, pipeline)
for name, job := range config.Jobs {
if job.Stage != stage {
continue
}
cmds := []string(config.Before)
cmds = append(cmds, []string(job.Before)...)
cmds = append(cmds, []string(job.Script)...)
cmds = append(cmds, []string(job.After)...)
cmds = append(cmds, []string(config.After)...)
step := &droneyaml.Container{
Name: name,
Image: job.Image.Name,
Command: job.Image.Command,
Entrypoint: job.Image.Entrypoint,
Commands: cmds,
}
if job.AllowFailure {
step.Failure = "ignore"
}
if step.Image == "" {
step.Image = config.Image.Name
}
// TODO: handle Services
// TODO: handle Only
// TODO: handle Except
// TODO: handle Variables
// TODO: handle When
pipeline.Steps = append(pipeline.Steps, step)
}
for _, step := range config.Services {
step := &droneyaml.Container{
Name: step.Alias,
Image: step.Name,
Command: step.Command,
Entrypoint: step.Entrypoint,
}
if step.Name == "" {
step.Name = serviceSlug(step.Image)
}
pipeline.Services = append(pipeline.Services, step)
}
if prevstage != "" {
pipeline.DependsOn = []string{prevstage}
}
prevstage = stage
}
buf := new(bytes.Buffer)
pretty.Print(buf, manifest)
return buf.Bytes(), nil
}
func serviceSlug(s string) string {
s = image.Trim(s)
s = strings.Replace(s, "/", "__", -1)
return s
}