.taskcluster.yml
author Nika Layzell <nika@thelayzells.com>
Tue, 25 Sep 2018 17:34:53 +0200
changeset 507828 5e6dae0c1e5a4939ccd406f14607f7fafffd45a7
parent 507534 4b8c2df35461931ee0eaa2f9e7fad1c2d41acb6c
child 507755 e75b3f5571fe4127b09b468cc8c7dacb6d822863
permissions -rw-r--r--
Bug 1448426 - Wrap windows.h to avoid problematic define statements, r=froydnj,glandium By default, windows.h exposes a large number of problematic define statements which are UpperCamelCase, such as a define from `CreateWindow` to `CreateWindow{A,W}`. As many of these names are generic (e.g. CreateFile, CreateWindow), they can mess up Gecko code that may legitimately have its own methods with the same names. The header also defines some traditional SCREAMING_SNAKE_CASE defines which can mess up our code by conflicting with local values. This patch adds a simple code generator which generates wrappers for these defines, and uses them to wrap the windows.h wrapper using the `stl_wrappers` mechanism, allowing us to use windows.h in more places. Differential Revision: https://phabricator.services.mozilla.com/D10932

# 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:
  # NOTE: support for actions in ci-admin requires that the `tasks` property be an array *before* JSON-e rendering
  # takes place.
  - $if: 'tasks_for in ["hg-push", "action", "cron"]'
    then:
      $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'}}
        # Hardcode cron push info for now, so that we can transition to using real values without breaking callers of Chain of Trust
        _pushId: {$if: 'tasks_for == "cron"', then: '-1', else: {$eval: 'push.pushlog_id'}}
        # action tasks can fail because of no pushdate or push comment information in context, so include them in
        # hardcodes (even though they don't use these variables)
        _pushDate: {$if: 'tasks_for == "cron" || tasks_for == "action"', then: '0', else: {$eval: 'push.pushdate'}}
        _pushComment: {$if: 'tasks_for == "cron" || tasks_for == "action"', then: '', else: {$eval: 'push.comment'}}
      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}"
            kind: decision-task
          else:
            $if: 'tasks_for == "action"'
            then:
              createdForUser: '${ownerEmail}'
              kind: 'action-callback'
            else:
              $if: 'tasks_for == "cron"'
              then:
                kind: cron-task

        routes:
          $flatten:
            - "tc-treeherder.v2.${repository.project}.${push.revision}.${_pushId}"
            - $if: 'tasks_for == "hg-push"'
              then:
                - "index.gecko.v2.${repository.project}.latest.taskgraph.decision"
                - "index.gecko.v2.${repository.project}.revision.${push.revision}.taskgraph.decision"
                - "index.gecko.v2.${repository.project}.pushlog-id.${_pushId}.decision"
                - "notify.email.${ownerEmail}.on-failed"
                - "notify.email.${ownerEmail}.on-exception"
                # Send a notification email if the push comes from try
                - $if: 'repository.project == "try"'
                  then:
                    "notify.email.${ownerEmail}.on-completed"
                # BUG 1500166 Notify ciduty by email if a nightly hook fails
                - "notify.email.ciduty+failedcron@mozilla.com.on-failed"
                - "notify.email.ciduty+exceptioncron@mozilla.com.on-exception"
                - "notify.email.sheriffs+failedcron@mozilla.com.on-failed"
                - "notify.email.sheriffs+exceptioncron@mozilla.com.on-exception"
                # These are the old index routes for the decision task.
                # They are still here so external tools that referenced them continue to work.
                - "index.gecko.v2.${repository.project}.latest.firefox.decision"
                - "index.gecko.v2.${repository.project}.revision.${push.revision}.firefox.decision"
              else:
                $if: 'tasks_for == "action"'
                then:
                - "notify.email.taskcluster-notifications+action-task@mozilla.com.on-failed"
                - "notify.email.taskcluster-notifications+action-task@mozilla.com.on-exception"
                - "index.gecko.v2.${repository.project}.pushlog-id.${_pushId}.actions.${ownTaskId}"
                else:  # cron
                - "index.gecko.v2.${repository.project}.latest.taskgraph.decision-${cron.job_name}"
                # list each cron task on this revision, so actions can find them
                - 'index.gecko.v2.${repository.project}.revision.${push.revision}.cron.${as_slugid("decision")}'
                # These are the old index routes for the decision task.
                - "index.gecko.v2.${repository.project}.latest.firefox.decision-${cron.job_name}"

        scopes:
          $if: 'tasks_for == "hg-push"'
          then:
            - 'assume:repo:${repoUrl[8:]}:branch:default'
            - 'queue:route:notify.email.${ownerEmail}.*'
            - 'in-tree:hook-action:project-gecko/in-tree-action-${repository.level}-*'
          else:
            $if: 'tasks_for == "action"'
            then:
              # when all actions are hooks, we can calculate this directly rather than using a variable
              - '${action.repo_scope}'
            else:
              - 'assume:repo:${repoUrl[8:]}:cron:${cron.job_name}'

        dependencies: []
        requires: all-completed

        priority:
          # Most times, there is plenty of worker capacity so everything runs
          # quickly, but sometimes a storm of action tasks lands.  Then we
          # want, from highest to lowest:
          # - cron tasks (time-sensitive) (low)
          # - action tasks (avoid interfering with the other two) (very-low)
          # - decision tasks (minimize user-visible delay) (lowest)
          # SCM levels all use different workerTypes, so there is no need for priority
          # between levels; "low" is the highest priority available at all levels, and
          # nothing runs at any higher priority on these workerTypes.
          $if: "tasks_for == 'cron'"
          then: low
          else:
            $if: "tasks_for == 'action'"
            then: very-low
            else: lowest  # tasks_for == 'hg-push'
        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: '${_pushComment}'}
                HG_STORE_PATH: /builds/worker/checkouts/hg-store
                TASKCLUSTER_CACHES: /builds/worker/checkouts
              - $if: 'tasks_for == "action"'
                then:
                  ACTION_TASK_GROUP_ID: '${action.taskGroupId}'     # taskGroupId of the target task
                  ACTION_TASK_ID: {$json: {$eval: 'taskId'}} # taskId of the target task (JSON-encoded)
                  ACTION_INPUT: {$json: {$eval: 'input'}}
                  ACTION_CALLBACK: '${action.cb_name}'
                  ACTION_PARAMETERS: {$json: {$eval: 'parameters'}}

          cache:
            level-${repository.level}-checkouts-sparse-v2: /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
          image: 'taskcluster/decision:2.1.0@sha256:6db3b697d7a3c7aba440d72f04199331b872111cefff57206b8b8b1d53230360'

          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='${_pushId}'
                  --pushdate='${_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'}
            - $if: 'tasks_for == "cron"'
              then:
                cron: {$json: {$eval: 'cron'}}
            - tasks_for: '${tasks_for}'
            # Email format for try pushes
            - $if: 'tasks_for == "hg-push" && repository.project == "try"'
              then:
                notify:
                  email:
                    subject: "Thank you for your try submission of ${push.revision}. It's the best!"
                    content: "Your try push has been submitted. It's the best! Use the link to view the status of your jobs."
                    link:
                      text: "Treeherder Jobs"
                      href: "https://treeherder.mozilla.org/#/jobs?repo=${repository.project}&revision=${push.revision}"