-
Notifications
You must be signed in to change notification settings - Fork 289
/
config.go
218 lines (159 loc) · 5.89 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
package job
import (
"log"
"reflect"
"strconv"
"time"
"github.com/buildkite/agent/v3/env"
"github.com/buildkite/agent/v3/process"
)
// Config provides the configuration for the job executor. Some of the keys are
// read from the environment after hooks are run, so we use struct tags to provide
// that mapping along with some reflection. It's a little bit magical but it's
// less work to maintain in the long run.
//
// To add a new config option that is mapped from an environment variable, add a
// struct tag, then don't forget to add a corresponding CLI flag over in the
// clicommand/bootstrap.go(BootstrapConfig) struct, otherwise it won't work.
type ExecutorConfig struct {
// The command to run
Command string
// The ID of the job being run
JobID string
// If the executor is in debug mode
Debug bool
// The repository that needs to be cloned
Repository string `env:"BUILDKITE_REPO"`
// The commit being built
Commit string
// The branch of the commit
Branch string
// The tag of the job commit
Tag string
// Optional refspec to override git fetch
RefSpec string `env:"BUILDKITE_REFSPEC"`
// Plugin definition for the job
Plugins string
// Should git submodules be checked out
GitSubmodules bool
// If the commit was part of a pull request, this will container the PR number
PullRequest string
// The provider of the pipeline
PipelineProvider string
// Slug of the current organization
OrganizationSlug string
// Slug of the current pipeline
PipelineSlug string
// Name of the agent running the job
AgentName string
// Name of the queue the agent belongs to, if tagged
Queue string
// Should the executor remove an existing checkout before running the job
CleanCheckout bool `env:"BUILDKITE_CLEAN_CHECKOUT"`
// Flags to pass to "git checkout" command
GitCheckoutFlags string `env:"BUILDKITE_GIT_CHECKOUT_FLAGS"`
// Flags to pass to "git clone" command
GitCloneFlags string `env:"BUILDKITE_GIT_CLONE_FLAGS"`
// Flags to pass to "git fetch" command
GitFetchFlags string `env:"BUILDKITE_GIT_FETCH_FLAGS"`
// Flags to pass to "git clone" command for mirroring
GitCloneMirrorFlags string `env:"BUILDKITE_GIT_CLONE_MIRROR_FLAGS"`
// Flags to pass to "git clean" command
GitCleanFlags string `env:"BUILDKITE_GIT_CLEAN_FLAGS"`
// Config key=value pairs to pass to "git" when submodule init commands are invoked
GitSubmoduleCloneConfig []string `env:"BUILDKITE_GIT_SUBMODULE_CLONE_CONFIG" normalize:"list"`
// Whether or not to run the hooks/commands in a PTY
RunInPty bool
// Are arbitrary commands allowed to be executed
CommandEval bool
// Are plugins enabled?
PluginsEnabled bool
// Should we always force a fresh clone of plugins, even if we have a local checkout?
PluginsAlwaysCloneFresh bool `env:"BUILDKITE_PLUGINS_ALWAYS_CLONE_FRESH"`
// Whether to validate plugin configuration
PluginValidation bool
// Are local hooks enabled?
LocalHooksEnabled bool
// Should we enforce that only one checkout and one command hook are run?
StrictSingleHooks bool
// Path where the builds will be run
BuildPath string
// Path where the sockets are stored
SocketsPath string
// Path where the repository mirrors are stored
GitMirrorsPath string
// Seconds to wait before allowing git mirror clone lock to be acquired
GitMirrorsLockTimeout int
// Skip updating the Git mirror before using it
GitMirrorsSkipUpdate bool `env:"BUILDKITE_GIT_MIRRORS_SKIP_UPDATE"`
// Path to the buildkite-agent binary
BinPath string
// Path to the global hooks
HooksPath string
// Path to the plugins directory
PluginsPath string
// Paths to automatically upload as artifacts when the build finishes
AutomaticArtifactUploadPaths string `env:"BUILDKITE_ARTIFACT_PATHS"`
// A custom destination to upload artifacts to (for example, s3://...)
ArtifactUploadDestination string `env:"BUILDKITE_ARTIFACT_UPLOAD_DESTINATION"`
// Whether ssh-keyscan is run on ssh hosts before checkout
SSHKeyscan bool
// The shell used to execute commands
Shell string
// Phases to execute, defaults to all phases
Phases []string
// What signal to use for command cancellation
CancelSignal process.Signal
// Amount of time to wait between sending the CancelSignal and SIGKILL to the process groups
// that the executor starts. The subprocesses should use this time to clean up after themselves.
SignalGracePeriod time.Duration
// List of environment variable globs to redact from job output
RedactedVars []string
// Backend to use for tracing. If an empty string, no tracing will occur.
TracingBackend string
// Service name to use when reporting traces.
TracingServiceName string
// Whether to start the JobAPI
JobAPI bool
// The warnings that have been disabled by the user
DisabledWarnings []string
}
// ReadFromEnvironment reads configuration from the Environment, returns a map
// of the env keys that changed and the new values
func (c *ExecutorConfig) ReadFromEnvironment(environ *env.Environment) map[string]string {
changed := map[string]string{}
// Use reflection for the type and values
fields := reflect.TypeOf(*c)
values := reflect.ValueOf(c).Elem()
// Iterate over all available fields and read the tag value
for i := range fields.NumField() {
f := fields.Field(i)
v := values.Field(i)
// Find struct fields with env tag
if tag := f.Tag.Get("env"); tag != "" && environ.Exists(tag) {
newStr, _ := environ.Get(tag)
switch v.Kind() {
case reflect.String:
if newStr == v.String() {
break
}
v.SetString(newStr)
changed[tag] = newStr
case reflect.Bool:
newBool, err := strconv.ParseBool(newStr)
if err != nil {
log.Printf("warning: cannot parse %s=%s as bool, ignoring", tag, newStr)
break
}
if newBool == v.Bool() {
break
}
v.SetBool(newBool)
changed[tag] = newStr
default:
log.Printf("warning: job.ExecutorConfig.ReadFromEnvironment does not support %v for %s", v.Kind(), tag)
}
}
}
return changed
}