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