Revision control

Other Tools

1
# This file is rendered via JSON-e by
2
# - mozilla-taskcluster - See
4
# {
5
# tasks_for: 'hg-push',
6
# push: {owner, comment, pushlog_id, pushdate},
7
# repository: {url, project, level},
8
# now,
9
# as_slugid: // function
10
# ownTaskId: // taskId of the task that will be created
11
# }
12
#
13
# - cron tasks - See taskcluster/taskgraph/cron/decision.py
14
# {
15
# tasks_for: 'cron',
16
# push: {revision, pushlog_id, pushdate, owner}
17
# repository: {url, project, level},
18
# cron: {task_id, job_name, job_symbol, quoted_args},
19
# now,
20
# ownTaskId: // taskId of the task that will be created
21
# }
22
#
23
# - action tasks - See:
24
# * taskcluster/taskgraph/actions/registry.py,
26
# * ci-admin:ciadmin/generate/in_tree_actions.py
27
#
28
# The registry generates the hookPayload that appears in actions.json, and
29
# contains data from the decision task as well as JSON-e code to combine that
30
# with data supplied as part of the action spec. When the hook is fired, the
31
# hookPayload is rendered with JSON-e to produce a payload for the hook task
32
# template.
33
#
34
# The ci-admin code wraps the content of this file (.taskcluster.yml) with a
35
# JSON-e $let statement that produces the context described below, and
36
# installs that as the hook task template.
37
#
38
# {
39
# tasks_for: 'action',
40
# push: {owner, pushlog_id, revision},
41
# repository: {url, project, level},
42
# input,
43
# taskId, // targetted taskId
44
# taskGroupId, // targetted taskGroupId
45
# action: {name, title, description, taskGroupId, symbol, repo_scope, cb_name}
46
# ownTaskId: // taskId of the task that will be created
47
# clientId: // clientId that triggered this hook
48
# }
49
50
version: 1
51
tasks:
52
# NOTE: support for actions in ci-admin requires that the `tasks` property be an array *before* JSON-e rendering
53
# takes place.
54
- $if: 'tasks_for in ["hg-push", "action", "cron"]'
55
then:
56
$let:
57
# sometimes the push user is just `ffxbld` or the like, but we want an email-like field..
58
ownerEmail: {$if: '"@" in push.owner', then: '${push.owner}', else: '${push.owner}@noreply.mozilla.org'}
59
# ensure there's no trailing `/` on the repo URL
60
repoUrl: {$if: 'repository.url[-1] == "/"', then: {$eval: 'repository.url[:-1]'}, else: {$eval: 'repository.url'}}
61
# expire try earlier than other branches
62
expires:
63
$if: 'repository.project == "try"'
64
then: {$fromNow: '28 days'}
65
else: {$fromNow: '1 year'}
66
in:
67
taskId: {$if: 'tasks_for != "action"', then: '${ownTaskId}'}
68
taskGroupId:
69
$if: 'tasks_for == "action"'
70
then:
71
'${action.taskGroupId}'
72
else:
73
'${ownTaskId}' # same as taskId; this is how automation identifies a decision tsak
74
schedulerId: 'gecko-level-${repository.level}'
75
76
created: {$fromNow: ''}
77
deadline: {$fromNow: '1 day'}
78
expires: {$eval: 'expires'}
79
metadata:
80
$merge:
81
- owner: "${ownerEmail}"
82
source: "${repoUrl}/raw-file/${push.revision}/.taskcluster.yml"
83
- $if: 'tasks_for == "hg-push"'
84
then:
85
name: "Gecko Decision Task"
86
description: 'The task that creates all of the other tasks in the task graph'
87
else:
88
$if: 'tasks_for == "action"'
89
then:
90
name: "Action: ${action.title}"
91
description: |
92
${action.description}
93
94
Action triggered by clientID `${clientId}`
95
else:
96
name: "Decision Task for cron job ${cron.job_name}"
97
description: 'Created by a [cron task](https://tools.taskcluster.net/tasks/${cron.task_id})'
98
99
provisionerId: "aws-provisioner-v1"
100
workerType: "gecko-${repository.level}-decision"
101
102
tags:
103
$if: 'tasks_for == "hg-push"'
104
then:
105
createdForUser: "${ownerEmail}"
106
kind: decision-task
107
else:
108
$if: 'tasks_for == "action"'
109
then:
110
createdForUser: '${ownerEmail}'
111
kind: 'action-callback'
112
else:
113
$if: 'tasks_for == "cron"'
114
then:
115
kind: cron-task
116
117
routes:
118
$flattenDeep:
119
- "tc-treeherder.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
120
- $if: 'tasks_for == "hg-push"'
121
then:
122
- "index.gecko.v2.${repository.project}.latest.taskgraph.decision"
123
- "index.gecko.v2.${repository.project}.revision.${push.revision}.taskgraph.decision"
124
- "index.gecko.v2.${repository.project}.pushlog-id.${push.pushlog_id}.decision"
125
- "notify.email.${ownerEmail}.on-failed"
126
- "notify.email.${ownerEmail}.on-exception"
127
# Send a notification email if the push comes from try
128
- $if: 'repository.project == "try"'
129
then:
130
"notify.email.${ownerEmail}.on-completed"
131
# These are the old index routes for the decision task.
132
# They are still here so external tools that referenced them continue to work.
133
- "index.gecko.v2.${repository.project}.latest.firefox.decision"
134
- "index.gecko.v2.${repository.project}.revision.${push.revision}.firefox.decision"
135
else:
136
$if: 'tasks_for == "action"'
137
then:
138
- "index.gecko.v2.${repository.project}.pushlog-id.${push.pushlog_id}.actions.${ownTaskId}"
139
else: # cron
140
- "index.gecko.v2.${repository.project}.latest.taskgraph.decision-${cron.job_name}"
141
- "index.gecko.v2.${repository.project}.revision.${push.revision}.taskgraph.decision-${cron.job_name}"
142
- "index.gecko.v2.${repository.project}.pushlog-id.${push.pushlog_id}.decision-${cron.job_name}"
143
# list each cron task on this revision, so actions can find them
144
- 'index.gecko.v2.${repository.project}.revision.${push.revision}.cron.${ownTaskId}'
145
# BUG 1500166 Notify ciduty by email if a nightly hook fails
146
- $if: 'repository.project != "try"'
147
then:
148
- "notify.email.ciduty+failedcron@mozilla.com.on-failed"
149
- "notify.email.ciduty+exceptioncron@mozilla.com.on-exception"
150
- "notify.email.sheriffs+failedcron@mozilla.org.on-failed"
151
- "notify.email.sheriffs+exceptioncron@mozilla.org.on-exception"
152
# These are the old index routes for the decision task.
153
- "index.gecko.v2.${repository.project}.latest.firefox.decision-${cron.job_name}"
154
155
scopes:
156
$if: 'tasks_for == "hg-push"'
157
then:
158
- 'assume:repo:${repoUrl[8:]}:branch:default'
159
- 'queue:route:notify.email.${ownerEmail}.*'
160
- 'in-tree:hook-action:project-gecko/in-tree-action-${repository.level}-*'
161
else:
162
$if: 'tasks_for == "action"'
163
then:
164
# when all actions are hooks, we can calculate this directly rather than using a variable
165
- '${action.repo_scope}'
166
else:
167
- 'assume:repo:${repoUrl[8:]}:cron:${cron.job_name}'
168
169
dependencies: []
170
requires: all-completed
171
172
priority:
173
# Most times, there is plenty of worker capacity so everything runs
174
# quickly, but sometimes a storm of action tasks lands. Then we
175
# want, from highest to lowest:
176
# - cron tasks (time-sensitive) (low)
177
# - action tasks (avoid interfering with the other two) (very-low)
178
# - decision tasks (minimize user-visible delay) (lowest)
179
# SCM levels all use different workerTypes, so there is no need for priority
180
# between levels; "low" is the highest priority available at all levels, and
181
# nothing runs at any higher priority on these workerTypes.
182
$if: "tasks_for == 'cron'"
183
then: low
184
else:
185
$if: "tasks_for == 'action'"
186
then: very-low
187
else: lowest # tasks_for == 'hg-push'
188
retries: 5
189
190
payload:
191
env:
192
# checkout-gecko uses these to check out the source; the inputs
193
# to `mach taskgraph decision` are all on the command line.
194
$merge:
195
- GECKO_BASE_REPOSITORY: 'https://hg.mozilla.org/mozilla-unified'
196
GECKO_HEAD_REPOSITORY: '${repoUrl}'
197
GECKO_HEAD_REF: '${push.revision}'
198
GECKO_HEAD_REV: '${push.revision}'
199
HG_STORE_PATH: /builds/worker/checkouts/hg-store
200
TASKCLUSTER_CACHES: /builds/worker/checkouts
201
# someday, these will be provided by the worker - Bug 1492664
202
TASKCLUSTER_ROOT_URL: https://taskcluster.net
203
TASKCLUSTER_PROXY_URL: http://taskcluster
204
- $if: 'tasks_for == "action"'
205
then:
206
ACTION_TASK_GROUP_ID: '${action.taskGroupId}' # taskGroupId of the target task
207
ACTION_TASK_ID: {$json: {$eval: 'taskId'}} # taskId of the target task (JSON-encoded)
208
ACTION_INPUT: {$json: {$eval: 'input'}}
209
ACTION_CALLBACK: '${action.cb_name}'
210
211
cache:
212
level-${repository.level}-checkouts-sparse-v2: /builds/worker/checkouts
213
214
features:
215
taskclusterProxy: true
216
chainOfTrust: true
217
218
# Note: This task is built server side without the context or tooling that
219
# exist in tree so we must hard code the hash
220
image: 'taskcluster/decision:2.2.0@sha256:0e9689e94605eb8395f5b49141a48148416b0d825f6f7be04c29642d1a85ee3d'
221
222
maxRunTime: 1800
223
224
command:
225
- /builds/worker/bin/run-task
226
- '--gecko-checkout=/builds/worker/checkouts/gecko'
227
- '--gecko-sparse-profile=build/sparse-profiles/taskgraph'
228
- '--'
229
- bash
230
- -cx
231
- $let:
232
extraArgs: {$if: 'tasks_for == "cron"', then: '${cron.quoted_args}', else: ''}
233
in:
234
$if: 'tasks_for == "action"'
235
then: >
236
cd /builds/worker/checkouts/gecko &&
237
ln -s /builds/worker/artifacts artifacts &&
238
./mach --log-no-times taskgraph action-callback
239
else: >
240
cd /builds/worker/checkouts/gecko &&
241
ln -s /builds/worker/artifacts artifacts &&
242
./mach --log-no-times taskgraph decision
243
--pushlog-id='${push.pushlog_id}'
244
--pushdate='${push.pushdate}'
245
--project='${repository.project}'
246
--owner='${ownerEmail}'
247
--level='${repository.level}'
248
--tasks-for='${tasks_for}'
249
--base-repository="$GECKO_BASE_REPOSITORY"
250
--head-repository="$GECKO_HEAD_REPOSITORY"
251
--head-ref="$GECKO_HEAD_REF"
252
--head-rev="$GECKO_HEAD_REV"
253
${extraArgs}
254
255
artifacts:
256
'public':
257
type: 'directory'
258
path: '/builds/worker/artifacts'
259
expires: {$eval: expires}
260
261
extra:
262
$merge:
263
- treeherder:
264
$merge:
265
- machine:
266
platform: gecko-decision
267
- $if: 'tasks_for == "hg-push"'
268
then:
269
symbol: D
270
else:
271
$if: 'tasks_for == "action"'
272
then:
273
groupName: 'action-callback'
274
groupSymbol: AC
275
symbol: "${action.symbol}"
276
else:
277
groupSymbol: cron
278
symbol: "${cron.job_symbol}"
279
- $if: 'tasks_for == "action"'
280
then:
281
parent: '${action.taskGroupId}'
282
action:
283
name: '${action.name}'
284
context:
285
taskGroupId: '${action.taskGroupId}'
286
taskId: {$eval: 'taskId'}
287
input: {$eval: 'input'}
288
clientId: {$eval: 'clientId'}
289
- $if: 'tasks_for == "cron"'
290
then:
291
cron: {$json: {$eval: 'cron'}}
292
- tasks_for: '${tasks_for}'
293
# Email for all pushes should link to treeherder
294
- $if: 'tasks_for == "hg-push"'
295
then:
296
notify:
297
email:
298
$merge:
299
- link:
300
text: "Treeherder Jobs"
302
# Email for try pushes should thank you for your revision
303
- $if: 'repository.project == "try"'
304
then:
305
subject: "Thank you for your try submission of ${push.revision}. It's the best!"
306
content: "Your try push has been submitted. It's the best! Use the link to view the status of your jobs."
307