1
0
Fork 0

Add post-processing for yaml files to convert env variables

Fixes #1
This commit is contained in:
Lauris BH 2022-08-01 18:01:09 +03:00
parent e49c3beda5
commit 32136eae34
No known key found for this signature in database
GPG Key ID: DFDE60A0093EB926
5 changed files with 141 additions and 4 deletions

View File

@ -62,7 +62,7 @@ func ReadSource(path string) ([]*transform.Source, error) {
return sources, nil
}
func WriteDest(pipelines []*transform.Pipeline, path string) error {
func WriteDest(tr transform.Transformer, pipelines []*transform.Pipeline, path string) error {
if len(pipelines) == 0 {
return nil
}
@ -95,6 +95,10 @@ func WriteDest(pipelines []*transform.Pipeline, path string) error {
if err != nil {
return err
}
buf, err = tr.PostProcess(buf)
if err != nil {
return err
}
if err = os.WriteFile(p, buf, 0o644); err != nil {
return err
}
@ -135,7 +139,7 @@ Currently supports converting from Drone CI pipelines to Woodpecker CI pipeline
fmt.Printf("Error: failed to convert pipeline: %v\n", err)
os.Exit(1)
}
if err = WriteDest(pipelines, destPath); err != nil {
if err = WriteDest(p, pipelines, destPath); err != nil {
fmt.Printf("Error: failed to write converted pipeline to destination: %v\n", err)
os.Exit(1)
}

View File

@ -7,6 +7,7 @@ package drone
import (
"bytes"
"errors"
"fmt"
"strings"
transform "codeberg.org/lafriks/woodpecker-pipeline-transform"
@ -23,7 +24,7 @@ func (e UnsupportedEventError) Error() string {
return "unsupported event: " + e.Event
}
func New() *DronePipeline {
func New() transform.Transformer {
return &DronePipeline{}
}
@ -384,3 +385,117 @@ func (d DronePipeline) Transform(sources []*transform.Source) ([]*transform.Pipe
}
return p, nil
}
var envMap map[string]string = map[string]string{
"CI": "CI",
"DRONE": "",
"DRONE_BRANCH": "CI_COMMIT_BRANCH",
"DRONE_BUILD_ACTION": "",
"DRONE_BUILD_CREATED": "CI_BUILD_CREATED",
"DRONE_BUILD_EVENT": "CI_BUILD_EVENT",
"DRONE_BUILD_FINISHED": "CI_BUILD_FINISHED",
"DRONE_BUILD_LINK": "CI_BUILD_LINK",
"DRONE_BUILD_NUMBER": "CI_BUILD_NUMBER",
"DRONE_BUILD_PARENT": "CI_BUILD_PARENT",
"DRONE_BUILD_STARTED": "CI_BUILD_STARTED",
"DRONE_BUILD_STATUS": "CI_BUILD_STATUS",
"DRONE_CALVER": "",
"DRONE_COMMIT": "CI_COMMIT_SHA",
"DRONE_COMMIT_AFTER": "",
"DRONE_COMMIT_AUTHOR": "CI_COMMIT_AUTHOR",
"DRONE_COMMIT_AUTHOR_AVATAR": "CI_COMMIT_AUTHOR_AVATAR",
"DRONE_COMMIT_AUTHOR_EMAIL": "CI_COMMIT_AUTHOR_EMAIL",
"DRONE_COMMIT_AUTHOR_NAME": "",
"DRONE_COMMIT_BEFORE": "",
"DRONE_COMMIT_BRANCH": "CI_COMMIT_BRANCH",
"DRONE_COMMIT_LINK": "CI_COMMIT_LINK",
"DRONE_COMMIT_MESSAGE": "CI_COMMIT_MESSAGE",
"DRONE_COMMIT_REF": "CI_COMMIT_REF",
"DRONE_COMMIT_SHA": "CI_COMMIT_SHA",
"DRONE_DEPLOY_TO": "CI_BUILD_DEPLOY_TARGET",
"DRONE_FAILED_STAGES": "",
"DRONE_FAILED_STEPS": "",
"DRONE_GIT_HTTP_URL": "",
"DRONE_GIT_SSH_URL": "",
"DRONE_PULL_REQUEST": "CI_COMMIT_PULL_REQUEST",
"DRONE_PULL_REQUEST_TITLE": "",
"DRONE_REMOTE_URL": "CI_REPO_REMOTE",
"DRONE_REPO": "CI_REPO",
"DRONE_REPO_BRANCH": "CI_REPO_DEFAULT_BRANCH",
"DRONE_REPO_LINK": "CI_REPO_LINK",
"DRONE_REPO_NAME": "CI_REPO_NAME",
"DRONE_REPO_NAMESPACE": "CI_REPO_OWNER",
"DRONE_REPO_OWNER": "CI_REPO_OWNER",
"DRONE_REPO_PRIVATE": "CI_REPO_PRIVATE",
"DRONE_REPO_SCM": "CI_REPO_SCM",
"DRONE_REPO_VISIBILITY": "",
"DRONE_SEMVER": "",
"DRONE_SEMVER_BUILD": "",
"DRONE_SEMVER_ERROR": "",
"DRONE_SEMVER_MAJOR": "",
"DRONE_SEMVER_MINOR": "",
"DRONE_SEMVER_PATCH": "",
"DRONE_SEMVER_PRERELEASE": "",
"DRONE_SEMVER_SHORT": "",
"DRONE_SOURCE_BRANCH": "CI_COMMIT_SOURCE_BRANCH",
"DRONE_STAGE_ARCH": "",
"DRONE_STAGE_DEPENDS_ON": "",
"DRONE_STAGE_FINISHED": "",
"DRONE_STAGE_KIND": "",
"DRONE_STAGE_MACHINE": "",
"DRONE_STAGE_NAME": "",
"DRONE_STAGE_NUMBER": "",
"DRONE_STAGE_OS": "",
"DRONE_STAGE_STARTED": "",
"DRONE_STAGE_STATUS": "",
"DRONE_STAGE_TYPE": "",
"DRONE_STAGE_VARIANT": "",
"DRONE_STEP_NAME": "",
"DRONE_STEP_NUMBER": "",
"DRONE_SYSTEM_HOST": "CI_SYSTEM_HOST",
"DRONE_SYSTEM_HOSTNAME": "",
"DRONE_SYSTEM_PROTO": "",
"DRONE_SYSTEM_VERSION": "CI_SYSTEM_VERSION",
"DRONE_TAG": "CI_COMMIT_TAG",
"DRONE_TARGET_BRANCH": "CI_COMMIT_TARGET_BRANCH",
}
var (
envStart []byte = []byte("${")
envEnd []byte = []byte("}")
)
func (d DronePipeline) PostProcess(yaml []byte) ([]byte, error) {
buf := bytes.NewBuffer(nil)
for i := bytes.Index(yaml, envStart); i >= 0; i = bytes.Index(yaml, envStart) {
buf.Write(yaml[:i+len(envStart)])
yaml = yaml[i+len(envStart):]
e := bytes.Index(yaml, envEnd)
if e < 0 {
return nil, errors.New("unclosed environment variable")
}
exp := yaml[:e]
c := bytes.IndexAny(exp, "^,:#%/=")
env := exp
if c == 0 {
env = exp[1:]
} else if c > 0 {
env = exp[:c]
}
if v, ok := envMap[string(env)]; ok {
if c == 0 {
buf.WriteByte(exp[0])
}
buf.Write([]byte(v))
if c > 0 {
buf.Write(exp[c:])
}
} else {
return nil, fmt.Errorf("unknown environment variable %s" + string(env))
}
buf.Write(yaml[e : e+len(envEnd)])
yaml = yaml[e+len(envEnd):]
}
buf.Write(yaml)
return buf.Bytes(), nil
}

View File

@ -133,3 +133,20 @@ func TestTransformSimple(t *testing.T) {
assert.ElementsMatch(t, []string{"deploy"}, pipeline.DependsOn)
}
func TestPostProcess(t *testing.T) {
d := drone.New()
buf, err := d.PostProcess([]byte(`pipeline:
step1:
image: bash
commands:
- echo "Test $${DRONE_COMMIT_SHA:0:7}"
`))
require.NoError(t, err)
assert.Equal(t, `pipeline:
step1:
image: bash
commands:
- echo "Test $${CI_COMMIT_SHA:0:7}"
`, string(buf))
}

View File

@ -92,7 +92,7 @@ steps:
PASSWORD:
from_secret: password
commands:
- echo "Deploy"
- echo "Deploy $${DRONE_COMMIT_SHA:0:8}"
when:
status: [ success, failure ]
instance:

View File

@ -11,4 +11,5 @@ type Source struct {
type Transformer interface {
Transform([]*Source) ([]*Pipeline, error)
PostProcess([]byte) ([]byte, error)
}