-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathworkflow.go
More file actions
192 lines (157 loc) · 6.43 KB
/
workflow.go
File metadata and controls
192 lines (157 loc) · 6.43 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
// SPDX-FileCopyrightText: 2021 SAP SE or an SAP affiliate company
// SPDX-License-Identifier: Apache-2.0
package ghworkflow
import (
"os"
"path/filepath"
"strings"
"github.com/sapcc/go-bits/must"
)
func newWorkflow(name, defaultBranch string, ignorePaths []string) *workflow {
return &workflow{
Name: name,
On: pushAndPRTriggers(defaultBranch, ignorePaths),
Permissions: permissions{
Contents: tokenScopeRead, // for actions/checkout to fetch code
},
}
}
type workflow struct {
Name string `yaml:"name"`
On eventTrigger `yaml:"on"`
// Permissions modify the default permissions granted to the GITHUB_TOKEN. If you
// specify the access for any of the scopes, all of those that are not specified are
// set to 'none'.
Permissions permissions `yaml:"permissions"`
// A map of <job_id> to their configuration(s).
Jobs map[string]job `yaml:"jobs"`
}
func (w workflow) getPath() string {
fileName := strings.ToLower(strings.ReplaceAll(w.Name, " ", "-"))
return filepath.Join(workflowDir, fileName+".yaml")
}
func (w workflow) deleteIf(condition bool) bool {
if !condition {
must.Succeed(os.RemoveAll(w.getPath()))
return true
}
return false
}
type githubTokenScope string
const (
tokenScopeNone = "none" //nolint:deadcode,varcheck // this exists for documentation purposes
tokenScopeRead = "read"
tokenScopeWrite = "write"
)
type permissions struct {
Actions githubTokenScope `yaml:"actions,omitempty"`
Checks githubTokenScope `yaml:"checks,omitempty"`
Contents githubTokenScope `yaml:"contents,omitempty"`
Packages githubTokenScope `yaml:"packages,omitempty"`
PullRequests githubTokenScope `yaml:"pull-requests,omitempty"`
SecurityEvents githubTokenScope `yaml:"security-events,omitempty"`
}
// eventTriggers contains rules about the events that trigger a specific
// workflow.
// Ref: https://docs.github.com/en/actions/reference/events-that-trigger-workflows
type eventTrigger struct {
Push pushAndPRTriggerOpts `yaml:"push,omitempty"`
PullRequest pushAndPRTriggerOpts `yaml:"pull_request,omitempty"`
Schedule []cronExpr `yaml:"schedule,omitempty"`
WorkflowDispatch workflowDispatch `yaml:"workflow_dispatch,omitempty"`
}
type cronExpr struct {
// We use quotedString type here because '*' is a special character in YAML so we have
// to quote the string.
Cron quotedString `yaml:"cron"`
}
type pushAndPRTriggerOpts struct {
Branches []string `yaml:"branches,omitempty"`
Paths []string `yaml:"paths,omitempty"`
PathsIgnore []string `yaml:"paths-ignore,omitempty"`
Tags []string `yaml:"tags,omitempty"`
}
type workflowDispatch struct {
manualTrigger bool `yaml:"-"`
}
func (w workflowDispatch) IsZero() bool {
return !w.manualTrigger
}
type job struct {
// The name of the job displayed on GitHub.
Name string `yaml:"name,omitempty"`
// You can use the if conditional to prevent a step from running unless a condition is met.
If string `yaml:"if,omitempty"`
// List of <job_id> that must complete successfully before this job will run.
Needs []string `yaml:"needs,omitempty"`
// The type of machine to run the job on.
// Ref: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners
RunsOn any `yaml:"runs-on,flow"`
// A map of environment variables that are available to all steps in the job.
Env map[string]string `yaml:"env,omitempty"`
// Steps can run commands, run setup tasks, or run an action. Not all steps
// run actions, but all actions run as a step. Each step runs in its own
// process in the runner environment and has access to the workspace and
// filesystem.
Steps []jobStep `yaml:"steps"`
// Strategy creates a build matrix for the job and allows different
// variations to run each job in.
Strategy JobStrategy `yaml:"strategy,omitempty"`
// A map of <service_id> to their configuration(s).
Services map[string]jobService `yaml:"services,omitempty"`
// Permissions modify the default permissions granted to the GITHUB_TOKEN. If you
// specify the access for any of the scopes, all of those that are not specified are
// set to 'none'.
Permissions permissions `yaml:"permissions,omitempty"`
}
type JobStrategy struct {
Matrix struct {
OS []string `yaml:"os"`
} `yaml:"matrix"`
}
// jobService is used to host service containers for a job in a workflow. The
// runner automatically creates a Docker network and manages the life cycle of
// the service containers.
type jobService struct {
// The Docker image to use as the service container to run the action. The
// value can be the Docker Hub image name or a registry name.
Image string `yaml:"image"`
// Sets a map of environment variables in the service container.
Env map[string]string `yaml:"env,omitempty"`
// Sets an array of ports to expose on the service container.
Ports []string `yaml:"ports,omitempty"`
// Additional Docker container resource options.
// For a list of options, see:
// https://docs.docker.com/engine/reference/commandline/create/#options
Options string `yaml:"options,omitempty"`
}
func (j *job) addStep(s jobStep) {
j.Steps = append(j.Steps, s)
}
// jobStep is a task that is run as part of a job.
type jobStep struct {
// A name for your step to display on GitHub.
Name string `yaml:"name"`
// A unique identifier for the step. You can use the id to reference the
// step in contexts.
// Ref: https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions
ID string `yaml:"id,omitempty"`
// You can use the if conditional to prevent a step from running unless a condition is met.
If string `yaml:"if,omitempty"`
// Selects an action to run as part of a step in your job.
//
// It is strongly recommend that the version of the action be specified or
// else it could break workflow when the action owner publishes an update.
// Some actions require inputs that you must set using the with keyword.
// Review the action's README file to determine the inputs required.
Uses string `yaml:"uses,omitempty"`
// A map of the input parameters defined by the action. Each input
// parameter is a key/value pair. Input parameters are set as environment
// variables. The variable is prefixed with INPUT_ and converted to upper
// case.
With map[string]any `yaml:"with,omitempty"`
// A map of environment variables for steps to use.
Env map[string]string `yaml:"env,omitempty"`
// Runs command-line programs using the operating system's shell.
Run string `yaml:"run,omitempty"`
}