Line Code
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
# This file is rendered via JSON-e by
# - mozilla-taskcluster - https://docs.taskcluster.net/reference/integrations/mozilla-taskcluster/docs/taskcluster-yml
# - cron tasks - taskcluster/taskgraph/cron/decision.py
# - action tasks - taskcluster/taskgraph/actions/registry.py
version: 1
tasks:
  - $let:
      # sometimes the push user is just `ffxbld` or the like, but we want an email-like field..
      ownerEmail: {$if: '"@" in push.owner', then: '${push.owner}', else: '${push.owner}@noreply.mozilla.org'}
      # ensure there's no trailing `/` on the repo URL
      repoUrl: {$if: 'repository.url[-1] == "/"', then: {$eval: 'repository.url[:-1]'}, else: {$eval: 'repository.url'}}
    in:
      taskId: {$if: 'tasks_for != "action"', then: '${as_slugid("decision")}'}
      taskGroupId:
        $if: 'tasks_for == "action"'
        then:
          '${action.taskGroupId}'
        else:
          '${as_slugid("decision")}' # same as taskId; this is how automation identifies a decision tsak
      schedulerId: 'gecko-level-${repository.level}'

      created: {$fromNow: ''}
      deadline: {$fromNow: '1 day'}
      expires: {$fromNow: '1 year 1 second'} # 1 second so artifacts expire first, despite rounding errors
      metadata:
        $merge:
          - owner: "${ownerEmail}"
            source: "${repoUrl}/raw-file/${push.revision}/.taskcluster.yml"
          - $if: 'tasks_for == "hg-push"'
            then:
              name: "Gecko Decision Task"
              description: 'The task that creates all of the other tasks in the task graph'
            else:
              $if: 'tasks_for == "action"'
              then:
                name: "Action: ${action.title}"
                description: '${action.description}'
              else:
                name: "Decision Task for cron job ${cron.job_name}"
                description: 'Created by a [cron task](https://tools.taskcluster.net/tasks/${cron.task_id})'

      provisionerId: "aws-provisioner-v1"
      workerType: "gecko-${repository.level}-decision"

      tags:
        $if: 'tasks_for == "hg-push"'
        then: {createdForUser: "${ownerEmail}"}
        else:
          $if: 'tasks_for == "action"'
          then:
            createdForUser: '${ownerEmail}'
            kind: 'action-callback'

      routes:
        $if: 'tasks_for == "hg-push"'
        then:
          - "index.gecko.v2.${repository.project}.latest.firefox.decision"
          - "index.gecko.v2.${repository.project}.pushlog-id.${push.pushlog_id}.decision"
          - "tc-treeherder.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
          - "tc-treeherder-stage.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
          - "notify.email.${ownerEmail}.on-failed"
          - "notify.email.${ownerEmail}.on-exception"
        else:
          - "tc-treeherder.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
          - "tc-treeherder-stage.v2.${repository.project}.${push.revision}.${push.pushlog_id}"
          - $if: 'tasks_for == "action"'
            then: "index.gecko.v2.${repository.project}.pushlog-id.${push.pushlog_id}.actions.$ownTaskId"
            else: "index.gecko.v2.${repository.project}.latest.firefox.decision-${cron.job_name}"

      scopes:
        $if: 'tasks_for == "hg-push"'
        then:
          - 'assume:repo:${repoUrl[8:]}:*'
          - 'queue:route:notify.email.${ownerEmail}.*'
        else:
          $if: 'tasks_for == "action"'
          then:
            - '${action.repo_scope}'
          else:
            - 'assume:repo:${repoUrl[8:]}:cron:${cron.job_name}'

      dependencies: []
      requires: all-completed

      priority: lowest
      retries: 5

      payload:
        env:
          # checkout-gecko uses these to check out the source; the inputs
          # to `mach taskgraph decision` are all on the command line.
          $merge:
            - GECKO_BASE_REPOSITORY: 'https://hg.mozilla.org/mozilla-unified'
              GECKO_HEAD_REPOSITORY: '${repoUrl}'
              GECKO_HEAD_REF: '${push.revision}'
              GECKO_HEAD_REV: '${push.revision}'
              GECKO_COMMIT_MSG: {$if: 'tasks_for != "action"', then: '${push.comment}'}
              HG_STORE_PATH: /builds/worker/checkouts/hg-store
              TASKCLUSTER_CACHES: /builds/worker/checkouts
            - $if: 'tasks_for == "action"'
              then:
                ACTION_TASK_GROUP_ID: '${action.taskGroupId}'
                ACTION_TASK_ID: {$json: {$eval: 'taskId'}}
                ACTION_TASK: {$json: {$eval: 'task'}}
                ACTION_INPUT: {$json: {$eval: 'input'}}
                ACTION_CALLBACK: '${action.cb_name}'
                ACTION_PARAMETERS: {$json: {$eval: 'parameters'}}

        cache:
          level-${repository.level}-checkouts-sparse-v1: /builds/worker/checkouts

        features:
          taskclusterProxy: true
          chainOfTrust: true

        # Note: This task is built server side without the context or tooling that
        # exist in tree so we must hard code the hash
        # XXX Changing this will break Chain of Trust without an associated puppet and
        # scriptworker patch!
        image: 'taskcluster/decision:2.0.0@sha256:4039fd878e5700b326d4a636e28c595c053fbcb53909c1db84ad1f513cf644ef'

        maxRunTime: 1800

        command:
          - /builds/worker/bin/run-task
          - '--vcs-checkout=/builds/worker/checkouts/gecko'
          - '--sparse-profile=build/sparse-profiles/taskgraph'
          - '--'
          - bash
          - -cx
          - $let:
              extraArgs: {$if: 'tasks_for == "cron"', then: '${cron.quoted_args}', else: ''}
            in:
              $if: 'tasks_for == "action"'
              then: >
                cd /builds/worker/checkouts/gecko &&
                ln -s /builds/worker/artifacts artifacts &&
                ./mach --log-no-times taskgraph action-callback
              else: >
                cd /builds/worker/checkouts/gecko &&
                ln -s /builds/worker/artifacts artifacts &&
                ./mach --log-no-times taskgraph decision
                --pushlog-id='${push.pushlog_id}'
                --pushdate='${push.pushdate}'
                --project='${repository.project}'
                --message="$GECKO_COMMIT_MSG"
                --owner='${ownerEmail}'
                --level='${repository.level}'
                --base-repository="$GECKO_BASE_REPOSITORY"
                --head-repository="$GECKO_HEAD_REPOSITORY"
                --head-ref="$GECKO_HEAD_REF"
                --head-rev="$GECKO_HEAD_REV"
                ${extraArgs}

        artifacts:
          'public':
            type: 'directory'
            path: '/builds/worker/artifacts'
            expires: {$fromNow: '1 year'}

      extra:
        $merge:
          - treeherder:
              $merge:
                - machine:
                    platform: gecko-decision
                - $if: 'tasks_for == "hg-push"'
                  then:
                    symbol: D
                  else:
                    $if: 'tasks_for == "action"'
                    then:
                      groupName: 'action-callback'
                      groupSymbol: AC
                      symbol: "${action.symbol}"
                    else:
                      groupSymbol: cron
                      symbol: "${cron.job_symbol}"
          - $if: 'tasks_for == "action"'
            then:
              parent: '${action.taskGroupId}'
              action:
                name: '${action.name}'
                context:
                  taskGroupId: '${action.taskGroupId}'
                  taskId: {$eval: 'taskId'}
                  input: {$eval: 'input'}
                  parameters: {$eval: 'parameters'}