Add pipeline services
This commit is contained in:
parent
ac85763829
commit
080c2089fd
@ -17,6 +17,14 @@ Currently supports converting only from Drone CI pipeline format with limited fu
|
|||||||
* `arch`
|
* `arch`
|
||||||
* `version` - not supported by Woodpecker CI
|
* `version` - not supported by Woodpecker CI
|
||||||
* `node`
|
* `node`
|
||||||
|
* `services`
|
||||||
|
* `name`
|
||||||
|
* `image`
|
||||||
|
* `pull`
|
||||||
|
* `privileged` - not supported by Woodpecker CI
|
||||||
|
* `environment` - including `from_secret`
|
||||||
|
* `entrypoint`
|
||||||
|
* `commands`
|
||||||
* `steps`
|
* `steps`
|
||||||
* `name`
|
* `name`
|
||||||
* `image`
|
* `image`
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
package transform
|
package transform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"codeberg.org/lafriks/woodpecker-pipeline-transform/core"
|
||||||
|
)
|
||||||
|
|
||||||
type Conditions struct {
|
type Conditions struct {
|
||||||
Conditions []string `yaml:"-"`
|
Conditions []string `yaml:"-"`
|
||||||
Include []string `yaml:"include,omitempty"`
|
Include []string `yaml:"include,omitempty"`
|
||||||
@ -64,3 +68,29 @@ func (c PathConditions) MarshalYAML() (interface{}, error) {
|
|||||||
IgnoreMessage: c.IgnoreMessage,
|
IgnoreMessage: c.IgnoreMessage,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type When struct {
|
||||||
|
Repo core.Strings `yaml:"repo,omitempty"`
|
||||||
|
Branch *Conditions `yaml:"branch,omitempty"`
|
||||||
|
Event core.Strings `yaml:"event,omitempty"`
|
||||||
|
Tag string `yaml:"tag,omitempty"`
|
||||||
|
Status []string `yaml:"status,omitempty"`
|
||||||
|
Platform core.Strings `yaml:"platform,omitempty"`
|
||||||
|
Environment string `yaml:"environment,omitempty"`
|
||||||
|
Matrix map[string]string `yaml:"matrix,omitempty"`
|
||||||
|
Instance string `yaml:"instance,omitempty"`
|
||||||
|
Path *PathConditions `yaml:"path,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s When) IsEmpty() bool {
|
||||||
|
return len(s.Repo) == 0 &&
|
||||||
|
s.Branch.IsEmpty() &&
|
||||||
|
len(s.Event) == 0 &&
|
||||||
|
s.Tag == "" &&
|
||||||
|
len(s.Status) == 0 &&
|
||||||
|
len(s.Platform) == 0 &&
|
||||||
|
s.Environment == "" &&
|
||||||
|
len(s.Matrix) == 0 &&
|
||||||
|
s.Instance == "" &&
|
||||||
|
s.Path.IsEmpty()
|
||||||
|
}
|
||||||
|
@ -37,3 +37,14 @@ func (c *Conditions) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||||||
c.Conditions = v2
|
c.Conditions = v2
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type When struct {
|
||||||
|
Branch *Conditions `yaml:"branch"`
|
||||||
|
Event core.Strings `yaml:"event"`
|
||||||
|
Refs *Conditions `yaml:"refs"`
|
||||||
|
Repositories *Conditions `yaml:"repo"`
|
||||||
|
Instance *Conditions `yaml:"instance"`
|
||||||
|
Status core.Strings `yaml:"status"`
|
||||||
|
Target *Conditions `yaml:"target"`
|
||||||
|
Cron *Conditions `yaml:"cron"`
|
||||||
|
}
|
||||||
|
@ -53,7 +53,7 @@ func (d DronePipeline) ConvertEvents(events core.Strings) (core.Strings, error)
|
|||||||
return ev, nil
|
return ev, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d DronePipeline) ConvertConditions(when *StepWhen) (*transform.StepWhen, error) {
|
func (d DronePipeline) ConvertConditions(when *When) (*transform.When, error) {
|
||||||
if when == nil {
|
if when == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ func (d DronePipeline) ConvertConditions(when *StepWhen) (*transform.StepWhen, e
|
|||||||
target = when.Target.Include[0]
|
target = when.Target.Include[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r := &transform.StepWhen{
|
r := &transform.When{
|
||||||
Branch: branch,
|
Branch: branch,
|
||||||
Event: ev,
|
Event: ev,
|
||||||
Tag: tags,
|
Tag: tags,
|
||||||
@ -190,6 +190,41 @@ func (d DronePipeline) Convert(pipeline *Pipeline) (*transform.Pipeline, error)
|
|||||||
p.Platform = pipeline.Platform.OS + "/" + pipeline.Platform.Arch
|
p.Platform = pipeline.Platform.OS + "/" + pipeline.Platform.Arch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Services
|
||||||
|
for _, service := range pipeline.Services {
|
||||||
|
if service.Privileged {
|
||||||
|
return nil, errors.New("unsupported service property: privileged")
|
||||||
|
}
|
||||||
|
if len(service.WorkingDir) > 0 {
|
||||||
|
return nil, errors.New("unsupported service property: working_dir")
|
||||||
|
}
|
||||||
|
env := make([]string, 0, len(service.Environment))
|
||||||
|
for k, v := range service.Environment {
|
||||||
|
if v.Secret != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
env = append(env, k+"="+v.Value)
|
||||||
|
}
|
||||||
|
secrets := make(transform.Secrets, 0)
|
||||||
|
for k, v := range service.Environment {
|
||||||
|
if v.Secret == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
secrets = append(secrets, transform.Secret{
|
||||||
|
Target: k,
|
||||||
|
Source: v.Secret,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
p.Services = append(p.Services, &transform.Service{
|
||||||
|
Name: service.Name,
|
||||||
|
Image: service.Image,
|
||||||
|
Pull: service.Pull == "always",
|
||||||
|
Environment: env,
|
||||||
|
Secrets: secrets,
|
||||||
|
Commands: append(service.Entrypoint, service.Commands...),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Steps
|
// Steps
|
||||||
for _, step := range pipeline.Steps {
|
for _, step := range pipeline.Steps {
|
||||||
if len(step.DependsOn) > 0 {
|
if len(step.DependsOn) > 0 {
|
||||||
|
@ -42,6 +42,12 @@ func TestTransformSimple(t *testing.T) {
|
|||||||
pipeline := getPipelineByName(pipelines, "build")
|
pipeline := getPipelineByName(pipelines, "build")
|
||||||
require.NotNil(t, pipeline, "build pipeline not found")
|
require.NotNil(t, pipeline, "build pipeline not found")
|
||||||
|
|
||||||
|
require.Len(t, pipeline.Services, 1)
|
||||||
|
assert.Equal(t, "database", pipeline.Services[0].Name)
|
||||||
|
assert.Equal(t, "postgres:latest", pipeline.Services[0].Image)
|
||||||
|
assert.True(t, pipeline.Services[0].Pull)
|
||||||
|
assert.Equal(t, []string{"docker-entrypoint.sh postgres"}, pipeline.Services[0].Commands)
|
||||||
|
|
||||||
assert.Equal(t, "linux/amd64", pipeline.Platform)
|
assert.Equal(t, "linux/amd64", pipeline.Platform)
|
||||||
assert.Equal(t, map[string]string{"location": "europe"}, pipeline.Labels)
|
assert.Equal(t, map[string]string{"location": "europe"}, pipeline.Labels)
|
||||||
|
|
||||||
|
@ -15,17 +15,6 @@ type Platform struct {
|
|||||||
Version string `yaml:"version"`
|
Version string `yaml:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type StepWhen struct {
|
|
||||||
Branch *Conditions `yaml:"branch"`
|
|
||||||
Event core.Strings `yaml:"event"`
|
|
||||||
Refs *Conditions `yaml:"refs"`
|
|
||||||
Repositories *Conditions `yaml:"repo"`
|
|
||||||
Instance *Conditions `yaml:"instance"`
|
|
||||||
Status core.Strings `yaml:"status"`
|
|
||||||
Target *Conditions `yaml:"target"`
|
|
||||||
Cron *Conditions `yaml:"cron"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Step struct {
|
type Step struct {
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Image string `yaml:"image"`
|
Image string `yaml:"image"`
|
||||||
@ -37,7 +26,18 @@ type Step struct {
|
|||||||
Detach bool `yaml:"detach"`
|
Detach bool `yaml:"detach"`
|
||||||
Privileged bool `yaml:"privileged"`
|
Privileged bool `yaml:"privileged"`
|
||||||
Failure string `yaml:"failure"`
|
Failure string `yaml:"failure"`
|
||||||
When *StepWhen `yaml:"when"`
|
When *When `yaml:"when"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Image string `yaml:"image"`
|
||||||
|
Pull string `yaml:"pull"`
|
||||||
|
Environment core.MapOrEnvArray `yaml:"environment"`
|
||||||
|
Commands []string `yaml:"commands"`
|
||||||
|
Entrypoint []string `yaml:"entrypoint"`
|
||||||
|
Privileged bool `yaml:"privileged"`
|
||||||
|
WorkingDir string `yaml:"working_dir"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pipeline struct {
|
type Pipeline struct {
|
||||||
@ -46,6 +46,7 @@ type Pipeline struct {
|
|||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Platform *Platform `yaml:"platform"`
|
Platform *Platform `yaml:"platform"`
|
||||||
Node map[string]string `yaml:"node"`
|
Node map[string]string `yaml:"node"`
|
||||||
|
Services []*Service `yaml:"services"`
|
||||||
Steps []*Step `yaml:"steps"`
|
Steps []*Step `yaml:"steps"`
|
||||||
DependsOn []string `yaml:"depends_on"`
|
DependsOn []string `yaml:"depends_on"`
|
||||||
}
|
}
|
||||||
|
7
drone/testdata/.drone.yml
vendored
7
drone/testdata/.drone.yml
vendored
@ -10,6 +10,13 @@ platform:
|
|||||||
node:
|
node:
|
||||||
location: europe
|
location: europe
|
||||||
|
|
||||||
|
services:
|
||||||
|
- name: database
|
||||||
|
image: postgres:latest
|
||||||
|
pull: always
|
||||||
|
commands:
|
||||||
|
- "docker-entrypoint.sh postgres"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: test
|
- name: test
|
||||||
image: golang:1.18
|
image: golang:1.18
|
||||||
|
@ -18,7 +18,7 @@ func FormatWoodpeckerYAML(data []byte) ([]byte, error) {
|
|||||||
var i int
|
var i int
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
if line == "pipeline:" {
|
if line == "pipeline:" || line == "services:" {
|
||||||
isPipeline = true
|
isPipeline = true
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
out.WriteByte('\n')
|
out.WriteByte('\n')
|
||||||
|
55
pipeline.go
55
pipeline.go
@ -7,39 +7,11 @@ package transform
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"codeberg.org/lafriks/woodpecker-pipeline-transform/core"
|
|
||||||
|
|
||||||
"github.com/goccy/go-yaml"
|
"github.com/goccy/go-yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
var UnsupportedError = errors.New("unsupported pipeline")
|
var UnsupportedError = errors.New("unsupported pipeline")
|
||||||
|
|
||||||
type StepWhen struct {
|
|
||||||
Repo core.Strings `yaml:"repo,omitempty"`
|
|
||||||
Branch *Conditions `yaml:"branch,omitempty"`
|
|
||||||
Event core.Strings `yaml:"event,omitempty"`
|
|
||||||
Tag string `yaml:"tag,omitempty"`
|
|
||||||
Status []string `yaml:"status,omitempty"`
|
|
||||||
Platform core.Strings `yaml:"platform,omitempty"`
|
|
||||||
Environment string `yaml:"environment,omitempty"`
|
|
||||||
Matrix map[string]string `yaml:"matrix,omitempty"`
|
|
||||||
Instance string `yaml:"instance,omitempty"`
|
|
||||||
Path *PathConditions `yaml:"path,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s StepWhen) IsEmpty() bool {
|
|
||||||
return len(s.Repo) == 0 &&
|
|
||||||
s.Branch.IsEmpty() &&
|
|
||||||
len(s.Event) == 0 &&
|
|
||||||
s.Tag == "" &&
|
|
||||||
len(s.Status) == 0 &&
|
|
||||||
len(s.Platform) == 0 &&
|
|
||||||
s.Environment == "" &&
|
|
||||||
len(s.Matrix) == 0 &&
|
|
||||||
s.Instance == "" &&
|
|
||||||
s.Path.IsEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Step struct {
|
type Step struct {
|
||||||
Name string `yaml:"-"`
|
Name string `yaml:"-"`
|
||||||
Image string `yaml:"image"`
|
Image string `yaml:"image"`
|
||||||
@ -50,7 +22,7 @@ type Step struct {
|
|||||||
Settings Settings `yaml:"settings,omitempty"`
|
Settings Settings `yaml:"settings,omitempty"`
|
||||||
Detach bool `yaml:"detach,omitempty"`
|
Detach bool `yaml:"detach,omitempty"`
|
||||||
Privileged bool `yaml:"privileged,omitempty"`
|
Privileged bool `yaml:"privileged,omitempty"`
|
||||||
When *StepWhen `yaml:"when,omitempty"`
|
When *When `yaml:"when,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Steps []*Step
|
type Steps []*Step
|
||||||
@ -66,6 +38,30 @@ func (s Steps) MarshalYAML() (interface{}, error) {
|
|||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
Name string `yaml:"-"`
|
||||||
|
Image string `yaml:"image"`
|
||||||
|
Pull bool `yaml:"pull,omitempty"`
|
||||||
|
Environment []string `yaml:"environment,omitempty"`
|
||||||
|
Secrets Secrets `yaml:"secrets,omitempty"`
|
||||||
|
Commands []string `yaml:"commands,omitempty"`
|
||||||
|
Settings Settings `yaml:"settings,omitempty"`
|
||||||
|
When *When `yaml:"when,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Services []*Service
|
||||||
|
|
||||||
|
func (s Services) MarshalYAML() (interface{}, error) {
|
||||||
|
v := make(yaml.MapSlice, len(s))
|
||||||
|
for i, step := range s {
|
||||||
|
v[i] = yaml.MapItem{
|
||||||
|
Key: step.Name,
|
||||||
|
Value: step,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
type Workspace struct {
|
type Workspace struct {
|
||||||
Base string `yaml:"base"`
|
Base string `yaml:"base"`
|
||||||
Path string `yaml:"path"`
|
Path string `yaml:"path"`
|
||||||
@ -76,6 +72,7 @@ type Pipeline struct {
|
|||||||
Workspace *Workspace `yaml:"workspace,omitempty"`
|
Workspace *Workspace `yaml:"workspace,omitempty"`
|
||||||
Platform string `yaml:"platform,omitempty"`
|
Platform string `yaml:"platform,omitempty"`
|
||||||
Labels map[string]string `yaml:"labels,omitempty"`
|
Labels map[string]string `yaml:"labels,omitempty"`
|
||||||
|
Services Services `yaml:"services,omitempty"`
|
||||||
Steps Steps `yaml:"pipeline"`
|
Steps Steps `yaml:"pipeline"`
|
||||||
DependsOn []string `yaml:"depends_on,omitempty"`
|
DependsOn []string `yaml:"depends_on,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ func TestPipelineUnmarshal(t *testing.T) {
|
|||||||
Name: "step1",
|
Name: "step1",
|
||||||
Image: "alpine:latest",
|
Image: "alpine:latest",
|
||||||
Commands: []string{"echo Step 1", "echo $${CI_JOB_ID}"},
|
Commands: []string{"echo Step 1", "echo $${CI_JOB_ID}"},
|
||||||
When: &transform.StepWhen{
|
When: &transform.When{
|
||||||
Event: []string{"push", "pull_request"},
|
Event: []string{"push", "pull_request"},
|
||||||
Branch: &transform.Conditions{
|
Branch: &transform.Conditions{
|
||||||
Conditions: []string{"main"},
|
Conditions: []string{"main"},
|
||||||
|
Loading…
Reference in New Issue
Block a user