-
Notifications
You must be signed in to change notification settings - Fork 370
Expand file tree
/
Copy pathconfig.go
More file actions
269 lines (195 loc) · 7.52 KB
/
Copy pathconfig.go
File metadata and controls
269 lines (195 loc) · 7.52 KB
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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
package job
import (
"log"
"reflect"
"strconv"
"strings"
"time"
"github.com/buildkite/agent/v3/env"
"github.com/buildkite/agent/v3/internal/process"
"github.com/buildkite/agent/v3/tracetools"
)
// 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.
// Also check the protectedEnv map in env/protected.go.
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 `env:"BUILDKITE_GIT_SUBMODULES"`
// Whether to enable Git LFS operations during checkout
GitLFSEnabled bool `env:"BUILDKITE_GIT_LFS_ENABLED"`
// If the commit was part of a pull request, this will container the PR number
PullRequest string
// Whether the agent should attempt to checkout the pull request commit using the merge refspec
PullRequestUsingMergeRefspec bool
// 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"`
// Skip the checkout phase entirely
SkipCheckout bool `env:"BUILDKITE_SKIP_CHECKOUT"`
// Skip git fetch if the commit already exists locally
GitSkipFetchExistingCommits bool `env:"BUILDKITE_GIT_SKIP_FETCH_EXISTING_COMMITS"`
// 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"`
// Selects among preconfigured sets of flags for clones from a mirror
GitMirrorCheckoutMode string `env:"BUILDKITE_GIT_MIRROR_CHECKOUT_MODE"`
// 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"`
// 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
// Additional hooks directories that can be provided
AdditionalHooksPaths []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
// The shell used to execute agent hooks
HooksShell 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
// Traceing context information
TracingTraceParent string
// Accept traceparent context from Buildkite control plane
TracingPropagateTraceparent bool
// Encoding (within base64) for the trace context environment variable.
TraceContextCodec tracetools.Codec
// Whether to start the JobAPI
JobAPI bool
// The warnings that have been disabled by the user
DisabledWarnings []string
// Secrets definition for the job step
Secrets string
// Number of checkout attempts (including the initial attempt).
// Uses exponential backoff with jitter between retries.
CheckoutAttempts int
}
// 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.TypeFor[ExecutorConfig]()
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=%q as bool, ignoring", tag, newStr)
break
}
if newBool == v.Bool() {
break
}
v.SetBool(newBool)
changed[tag] = newStr
case reflect.Slice:
if v.Type().Elem() != reflect.TypeFor[string]() {
log.Printf("warning: cannot parse %s=%q as %v, ignoring", tag, newStr, v.Type())
break
}
slice := strings.Split(newStr, ",")
v.Set(reflect.ValueOf(slice))
changed[tag] = newStr
default:
log.Printf("warning: job.ExecutorConfig.ReadFromEnvironment does not support %v for %s", v.Kind(), tag)
}
}
}
return changed
}