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