steps/steps.go (56 lines of code) (raw):
package steps
import (
"encoding/json"
"fmt"
"strconv"
"gitlab.com/gitlab-org/gitlab-runner/common"
"gitlab.com/gitlab-org/step-runner/pkg/api/client"
"gitlab.com/gitlab-org/step-runner/schema/v1"
"gopkg.in/yaml.v2"
)
func NewRequest(build *common.Build) (*client.RunRequest, error) {
steps, err := addStepsPreamble(build.JobResponse.Run)
if err != nil {
return nil, fmt.Errorf("parsing step request: %w", err)
}
return &client.RunRequest{
Id: strconv.FormatInt(build.ID, 10),
WorkDir: build.FullProjectDir(),
BuildDir: build.FullProjectDir(),
Env: map[string]string{},
Steps: steps,
Variables: addVariables(build.GetAllVariables()),
}, nil
}
var variablesToOmit = map[string]bool{
"STEPS": true,
"FF_USE_NATIVE_STEPS": true,
}
func addVariables(vars common.JobVariables) []client.Variable {
result := make([]client.Variable, 0, len(vars))
for _, v := range vars {
if variablesToOmit[v.Key] {
continue
}
result = append(result, client.Variable{
Key: v.Key,
Value: v.Value,
File: v.File,
Masked: v.Masked,
})
}
return result
}
const stepsPreamble = "{}\n---\n"
// When using the run CI keyword, steps are written in yaml, parsed to json, validated, and finally sent over the wire
// (as json) to the runner. However the step-runner expects steps as yaml :-( Plus we have to add this here preamble.
func addStepsPreamble(jsonSteps string) (string, error) {
stepSchema := &schema.Step{}
err := json.Unmarshal([]byte(jsonSteps), &stepSchema.Run)
if err != nil {
return "", fmt.Errorf("unmarshalling steps %q: %w", jsonSteps, err)
}
yamlSteps, err := yaml.Marshal(stepSchema)
if err != nil {
return "", fmt.Errorf("marshalling steps: %w", err)
}
return stepsPreamble + string(yamlSteps), nil
}