1package models
2
3import (
4 "path"
5
6 "tangled.sh/tangled.sh/core/api/tangled"
7 "tangled.sh/tangled.sh/core/spindle/config"
8)
9
10type Pipeline struct {
11 RepoOwner string
12 RepoName string
13 Workflows []Workflow
14}
15
16type Step struct {
17 Command string
18 Name string
19 Environment map[string]string
20 Kind StepKind
21}
22
23type StepKind int
24
25const (
26 // steps injected by the CI runner
27 StepKindSystem StepKind = iota
28 // steps defined by the user in the original pipeline
29 StepKindUser
30)
31
32type Workflow struct {
33 Steps []Step
34 Environment map[string]string
35 Name string
36 Image string
37}
38
39// setupSteps get added to start of Steps
40type setupSteps []Step
41
42// addStep adds a step to the beginning of the workflow's steps.
43func (ss *setupSteps) addStep(step Step) {
44 *ss = append(*ss, step)
45}
46
47// ToPipeline converts a tangled.Pipeline into a model.Pipeline.
48// In the process, dependencies are resolved: nixpkgs deps
49// are constructed atop nixery and set as the Workflow.Image,
50// and ones from custom registries
51func ToPipeline(pl tangled.Pipeline, cfg config.Config) *Pipeline {
52 workflows := []Workflow{}
53
54 for _, twf := range pl.Workflows {
55 swf := &Workflow{}
56 for _, tstep := range twf.Steps {
57 sstep := Step{}
58 sstep.Environment = stepEnvToMap(tstep.Environment)
59 sstep.Command = tstep.Command
60 sstep.Name = tstep.Name
61 sstep.Kind = StepKindUser
62 swf.Steps = append(swf.Steps, sstep)
63 }
64 swf.Name = twf.Name
65 swf.Environment = workflowEnvToMap(twf.Environment)
66 swf.Image = workflowImage(twf.Dependencies, cfg.Pipelines.Nixery)
67
68 setup := &setupSteps{}
69
70 setup.addStep(nixConfStep())
71 setup.addStep(cloneStep(*twf, *pl.TriggerMetadata, cfg.Server.Dev))
72 // this step could be empty
73 if s := dependencyStep(*twf); s != nil {
74 setup.addStep(*s)
75 }
76
77 // append setup steps in order to the start of workflow steps
78 swf.Steps = append(*setup, swf.Steps...)
79
80 workflows = append(workflows, *swf)
81 }
82 repoOwner := pl.TriggerMetadata.Repo.Did
83 repoName := pl.TriggerMetadata.Repo.Repo
84 return &Pipeline{
85 RepoOwner: repoOwner,
86 RepoName: repoName,
87 Workflows: workflows,
88 }
89}
90
91func workflowEnvToMap(envs []*tangled.Pipeline_Pair) map[string]string {
92 envMap := map[string]string{}
93 for _, env := range envs {
94 if env != nil {
95 envMap[env.Key] = env.Value
96 }
97 }
98 return envMap
99}
100
101func stepEnvToMap(envs []*tangled.Pipeline_Pair) map[string]string {
102 envMap := map[string]string{}
103 for _, env := range envs {
104 if env != nil {
105 envMap[env.Key] = env.Value
106 }
107 }
108 return envMap
109}
110
111func workflowImage(deps []*tangled.Pipeline_Dependency, nixery string) string {
112 var dependencies string
113 for _, d := range deps {
114 if d.Registry == "nixpkgs" {
115 dependencies = path.Join(d.Packages...)
116 }
117 }
118
119 // load defaults from somewhere else
120 dependencies = path.Join(dependencies, "bash", "git", "coreutils", "nix")
121
122 return path.Join(nixery, dependencies)
123}