def create_task_payload(build, base_context):
    build_type = os.path.splitext(os.path.basename(build))[0]

    build_context = defaultValues_build_context()
    with open(build) as src:
        build_context['build'].update(
            yaml.load(src, Loader=yaml.FullLoader)['build'])

    # Be able to use what has been defined in base_context
    # e.g., the {${event.head.branch}}
    build_context = jsone.render(build_context, base_context)
    template_context = {
        'taskcluster': {
            'taskId': as_slugid(build_type)
        },
        'build_type': build_type
    }

    with open(os.path.join(TASKS_ROOT,
                           build_context['build']['template_file'])) as src:
        template = yaml.load(src, Loader=yaml.FullLoader)

    contextes = merge_dicts({}, base_context, template_context, build_context)
    for one_context in glob(os.path.join(TASKS_ROOT, '*.cyml')):
        with open(one_context) as src:
            contextes = merge_dicts(contextes,
                                    yaml.load(src, Loader=yaml.FullLoader))

    return jsone.render(template, contextes)
Example #2
0
def test_jsone_validates(tmp_path, hook_file, payload):
    tmp_hook_file = tmp_path / "hook.json"

    shutil.copyfile(hook_file, tmp_hook_file)

    set_hook(tmp_hook_file, version)

    with open(tmp_hook_file, "r") as f:
        hook_content = json.load(f)

    jsonschema.validate(instance=payload, schema=hook_content["triggerSchema"])

    jsone.render(hook_content, context={"payload": payload})
Example #3
0
def test_jsone_validates(tmp_path):
    payload = {}
    hook_file = os.path.realpath("taskcluster-hook.json")
    assert os.path.exists(hook_file)

    content = open(hook_file).read()
    content = content.replace("CHANNEL", "dev")
    content = content.replace("VERSION", version)

    hook_content = json.loads(content)

    jsonschema.validate(instance=payload, schema=hook_content["triggerSchema"])

    jsone.render(hook_content, context={"payload": payload})
 def test_cron(self):
     context = {
         "tasks_for": "cron",
         "repository": {
             "url": "https://hg.mozilla.org/mozilla-central",
             "project": "mozilla-central",
             "level": 3,
         },
         "push": {
             "revision": "e8aebe488b2f2e567940577de25013d00e818f7c",
             "pushlog_id": -1,
             "pushdate": 0,
             "owner": "cron",
         },
         "cron": {
             "task_id": "<cron task id>",
             "job_name": "test",
             "job_symbol": "T",
             "quoted_args": "abc def",
         },
         "now": current_json_time(),
         "ownTaskId": slugid.nice().encode("ascii"),
     }
     rendered = jsone.render(self.taskcluster_yml, context)
     pprint.pprint(rendered)
     self.assertEqual(rendered["tasks"][0]["metadata"]["name"],
                      "Decision Task for cron job test")
 def test_action(self):
     context = {
         "tasks_for": "action",
         "repository": {
             "url": "https://hg.mozilla.org/mozilla-central",
             "project": "mozilla-central",
             "level": 3,
         },
         "push": {
             "revision": "e8d2d9aff5026ef1f1777b781b47fdcbdb9d8f20",
             "owner": "*****@*****.**",
             "pushlog_id": 1556565286,
             "pushdate": 112957,
         },
         "action": {
             "name": "test-action",
             "title": "Test Action",
             "description": "Just testing",
             "taskGroupId": slugid.nice().encode("ascii"),
             "symbol": "t",
             "repo_scope": "assume:repo:hg.mozilla.org/try:action:generic",
             "cb_name": "test_action",
         },
         "input": {},
         "parameters": {},
         "now": current_json_time(),
         "taskId": slugid.nice().encode("ascii"),
         "ownTaskId": slugid.nice().encode("ascii"),
         "clientId": "testing/testing/testing",
     }
     rendered = jsone.render(self.taskcluster_yml, context)
     pprint.pprint(rendered)
     self.assertEqual(rendered["tasks"][0]["metadata"]["name"],
                      "Action: Test Action")
Example #6
0
def py(when, template, context):
    when = datetime.datetime.utcfromtimestamp(when)
    with freeze_time(when):
        try:
            return jsone.render(template, context)
        except jsone.JSONTemplateError:
            return Exception
def load_config(context):
    path_to_worker_template = os.path.join(os.path.dirname(__file__), "..",
                                           "docker.d", "worker.yml")
    with open(path_to_worker_template, "r") as file:
        worker_template = yaml.safe_load(file)

    return jsone.render(worker_template, context)
Example #8
0
def test_jsone_validates(pipeline_file, task_schema, payload_schema):
    responses.add_passthru("https://community-tc.services.mozilla.com/")

    with open(pipeline_file, "r") as f:
        yaml_content = yaml.safe_load(f.read())

    result = jsone.render(yaml_content, context={"version": "42.0"})
    tasks = result["tasks"]

    all_ids = [task["ID"] for task in tasks]

    # Make sure there are no duplicate IDs.
    assert len(all_ids) == len(set(all_ids))

    # Make sure all dependencies are present.
    for task in tasks:
        assert "dependencies" not in task or all(
            dependency in all_ids for dependency in task["dependencies"])

    for task in tasks:
        if "ID" in task:
            del task["ID"]

        if "dependencies" in task:
            del task["dependencies"]

        jsonschema.validate(instance=task, schema=task_schema)

        jsonschema.validate(instance=task["payload"], schema=payload_schema)
Example #9
0
    def __call__(self, taskgraph, label_to_taskid):
        if not self.templates:
            return taskgraph, label_to_taskid

        for task in taskgraph.tasks.itervalues():
            for template in sorted(self.templates):
                context = {
                    'task': task.task,
                    'taskGroup': None,
                    'taskId': task.task_id,
                    'kind': task.kind,
                    'input': self.templates[template],
                    # The following context differs from action tasks
                    'attributes': task.attributes,
                    'label': task.label,
                    'target_tasks': self.target_tasks,
                }

                template_path = os.path.join(self.template_dir, template + '.yml')
                with open(template_path) as f:
                    template = yaml.load(f)
                result = jsone.render(template, context) or {}
                for attr in ('task', 'attributes'):
                    if attr in result:
                        setattr(task, attr, result[attr])

        return taskgraph, label_to_taskid
Example #10
0
    def _submit(self,
                action=None,
                decision_task_id=None,
                task_id=None,
                input=None,
                static_action_variables=None) -> str:
        context = {
                "taskGroupId": decision_task_id,
                "taskId": task_id or None,
                "input": input,
         }
        context.update(static_action_variables)
        action_kind = action["kind"]

        if action_kind == "hook":
            hook_payload = jsone.render(action["hookPayload"], context)
            hook_id, hook_group_id = action["hookId"], action["hookGroupId"]

            decision_task = self.queue.task(decision_task_id)
            expansion = self.auth.expandScopes({"scopes": decision_task["scopes"]})
            expression = f"in-tree:hook-action:{hook_group_id}/{hook_id}"

            if not satisfiesExpression(expansion["scopes"], expression):
                raise RuntimeError(f"Action is misconfigured: decision task's scopes do not satisfy {expression}")

            result = self.hooks.triggerHook(hook_group_id, hook_id, hook_payload)
            return result["status"]["taskId"]

        raise NotImplementedError(f"Unable to submit actions with '{action_kind}' kind.")
Example #11
0
def trigger_action(action_name, decision_task_id, task_id=None, input={}):
    if not decision_task_id:
        raise ValueError(
            "No decision task. We can't find the actions artifact.")
    actions_json = get_artifact(decision_task_id, "public/actions.json")
    if actions_json["version"] != 1:
        raise RuntimeError("Wrong version of actions.json, unable to continue")

    # These values substitute $eval in the template
    context = {
        "input": input,
        "taskId": task_id,
        "taskGroupId": decision_task_id,
    }
    # https://docs.taskcluster.net/docs/manual/design/conventions/actions/spec#variables
    context.update(actions_json["variables"])
    action = _extract_applicable_action(actions_json, action_name,
                                        decision_task_id, task_id)
    kind = action["kind"]
    if kind == "hook":
        hook_payload = jsone.render(action["hookPayload"], context)
        trigger_hook(action["hookGroupId"], action["hookId"], hook_payload)
    else:
        raise NotImplementedError(
            "Unable to submit actions with {} kind.".format(kind))
Example #12
0
    def retrigger(self, push, times=3):
        """This function implements ability to perform retriggers on tasks"""
        if self._should_retrigger() == "false":
            logger.info(
                "Not retriggering task '{}', task should not be retriggered".
                format(self.tags.get("label")))
            return None

        decision_task = push.decision_task
        retrigger_action = self._get_action(decision_task, "retrigger")

        hook_payload = jsone.render(
            retrigger_action["hookPayload"],
            context={
                "taskId": self.id,
                "taskGroupId": decision_task.id,
                "input": {
                    "times": times
                },
            },
        )

        logger.info("Retriggering task '{}'".format(self.tags.get("label",
                                                                  "")))
        return self._trigger_action(retrigger_action, hook_payload)
Example #13
0
def run_query(name, config, **context):
    """Loads and runs the specified query, yielding the result.

    Given name of a query, this method will first read the query
    from a .query file corresponding to the name.

    After queries are loaded, each query to be run is inspected
    and overridden if the provided context has values for limit.

    The actual call to the ActiveData endpoint is encapsulated
    inside the query_activedata method.

    :param str name: name of the query file to be loaded.
    :param Configuration config: config object.
    :param dict context: dictionary of ActiveData configs.
    :yields str: json-formatted string.
    """
    for query in load_query(name):
        # If limit is in the context, override the queries' value. We do this
        # to keep the results down to a sane level when testing queries.
        if 'limit' in context:
            query['limit'] = context['limit']
        if 'format' in context:
            query['format'] = context['format']
        if config.debug:
            query['meta'] = {"save": True}

        query = jsone.render(query, context)
        query_str = json.dumps(query, indent=2, separators=(',', ':'))
        log.debug("Running query {}:\n{}".format(name, query_str))
        yield query_activedata(query_str, config.url)
Example #14
0
    def __call__(self, taskgraph, label_to_taskid):
        if not self.templates:
            return taskgraph, label_to_taskid

        for task in taskgraph.tasks.itervalues():
            for template in sorted(self.templates):
                context = {
                    'task': task.task,
                    'taskGroup': None,
                    'taskId': task.task_id,
                    'kind': task.kind,
                    'input': self.templates[template],
                    # The following context differs from action tasks
                    'attributes': task.attributes,
                    'label': task.label,
                    'target_tasks': self.target_tasks,
                }

                template = load_yaml(self.template_dir, template + '.yml')
                result = jsone.render(template, context) or {}
                for attr in ('task', 'attributes'):
                    if attr in result:
                        setattr(task, attr, result[attr])

        return taskgraph, label_to_taskid
Example #15
0
def run_query(name, args):
    """Loads and runs the specified query, yielding the result.

    Given name of a query, this method will first read the query
    from a .query file corresponding to the name.

    After queries are loaded, each query to be run is inspected
    and overridden if the provided context has values for limit.

    The actual call to the ActiveData endpoint is encapsulated
    inside the query_activedata method.

    :param str name: name of the query file to be loaded.
    :param Namespace args: namespace of ActiveData configs.
    :return str: json-formatted string.
    """

    context = vars(args)
    query = load_query(name)

    if 'limit' not in query and 'limit' in context:
        query['limit'] = context['limit']
    if 'format' not in query and 'format' in context:
        query['format'] = context['format']
    if config.debug:
        query['meta'] = {"save": True}

    query = jsone.render(query, context)
    query_str = json.dumps(query, indent=2, separators=(',', ':'))

    # translate "all" to a null value (which ActiveData will treat as all)
    query_str = query_str.replace('"all"', 'null')

    log.debug("Running query {}:\n{}".format(name, query_str))
    return query_activedata(query_str, config.url)
Example #16
0
def generate_beetmover_upstream_artifacts(job, platform, locale=None, dependencies=None):
    """Generate the upstream artifacts for beetmover, using the artifact map.

    Currently only applies to beetmover tasks.

    Args:
        job (dict): The current job being generated
        dependencies (list): A list of the job's dependency labels.
        platform (str): The current build platform
        locale (str): The current locale being beetmoved.

    Returns:
        list: A list of dictionaries conforming to the upstream_artifacts spec.
    """
    base_artifact_prefix = get_artifact_prefix(job)
    resolve_keyed_by(job, 'attributes.artifact_map', 'artifact map', platform=platform)
    map_config = load_yaml(*os.path.split(job['attributes']['artifact_map']))
    upstream_artifacts = list()

    if not locale:
        locales = map_config['default_locales']
    else:
        locales = [locale]

    if not dependencies:
        dependencies = job['dependencies'].keys()

    for locale, dep in itertools.product(locales, dependencies):
        paths = list()

        for filename in map_config['mapping']:
            if dep not in map_config['mapping'][filename]['from']:
                continue
            if locale != 'en-US' and not map_config['mapping'][filename]['all_locales']:
                continue

            # The next time we look at this file it might be a different locale.
            file_config = deepcopy(map_config['mapping'][filename])
            resolve_keyed_by(file_config, "source_path_modifier",
                             'source path modifier', locale=locale)
            paths.append(os.path.join(
                base_artifact_prefix,
                jsone.render(file_config['source_path_modifier'], {'locale': locale}),
                filename,
            ))

        if not paths:
            continue

        upstream_artifacts.append({
            "taskId": {
                "task-reference": "<{}>".format(dep)
            },
            "taskType": map_config['tasktype_map'].get(dep),
            "paths": sorted(paths),
            "locale": locale,
        })

    return upstream_artifacts
Example #17
0
def render_action_hook(payload, context, delete_params=[]):
    rendered_payload = jsone.render(payload, context)
    # some parameters contain a lot of entries, so we hit the payload
    # size limit. We don't use this parameter in any case, safe to
    # remove
    for param in delete_params:
        del rendered_payload['decision']['parameters'][param]
    return rendered_payload
Example #18
0
def load_manifest(mtype, context={}):
    """Load the specified yaml file given the specified context"""
    filename = f'{mtype}.yaml'
    manifest_path = os.path.join(ROOT_REPO_DIR, 'k8s', filename)

    with open(manifest_path) as mt:
        manifest_template = yaml.safe_load(mt.read())
        return jsone.render(manifest_template, context)
Example #19
0
def test_verify_taskcluster_yml():
    """Verify that the json-e in the .taskcluster.yml is valid"""
    with open(os.path.join(root, ".taskcluster.yml"), encoding="utf8") as f:
        template = yaml.safe_load(f)

    events = [("pr_event.json", "github-pull-request", "Pull Request"),
              ("master_push_event.json", "github-push", "Push to master")]

    for filename, tasks_for, title in events:
        with open(data_path(filename), encoding="utf8") as f:
            event = json.load(f)

        context = {"tasks_for": tasks_for,
                   "event": event,
                   "as_slugid": lambda x: x}

        jsone.render(template, context)
Example #20
0
def render_action_hook(payload, context, delete_params=[]):
    rendered_payload = jsone.render(payload, context)
    # some parameters contain a lot of entries, so we hit the payload
    # size limit. We don't use this parameter in any case, safe to
    # remove
    for param in delete_params:
        del rendered_payload['decision']['parameters'][param]
    return rendered_payload
Example #21
0
def test_hook_syntax(hook_path, payload):
    """
    Validate the Taskcluster hook syntax
    """
    assert os.path.exists(hook_path)

    with open(hook_path, "r") as f:
        # Patch the hook as in the taskboot deployment
        content = f.read()
        content = content.replace("REVISION", "deadbeef1234")
        content = content.replace("CHANNEL", "test")

        # Now parse it as json
        hook_content = json.loads(content)

    jsonschema.validate(instance=payload, schema=hook_content["triggerSchema"])

    jsone.render(hook_content, context=payload)
Example #22
0
 def test():
     exc, res = None, None
     try:
         res = jsone.render(spec['template'], spec['context'])
     except Exception as e:
         exc = e
     if 'error' in spec:
         assert exc, "expected exception"
     else:
         assert res == spec['result']
def run_query(name, **context):
    for query in load_query(name):
        # If limit is in the context, override the queries' value. We do this
        # to keep the results down to a sane level when testing queries.
        if 'limit' in context:
            query['limit'] = context['limit']
        query = jsone.render(query, context)
        query_str = json.dumps(query, indent=2, separators=(',', ':'))
        log.debug("Running query {}:\n{}".format(name, query_str))
        yield query_activedata(query_str)
Example #24
0
def write_file(template, context, suffix):
    filepath = f"{args.destination}/{context['project_name']}-{suffix}.yaml"
    try:
        f = open(filepath, "x")
        f.write(
            yaml.dump(jsone.render(template, context),
                      default_flow_style=False,
                      width=float("inf")))
        f.close()
    except:
        print(f"failed to write {filepath}")
Example #25
0
def make_decision_task(params, root, symbol, arguments=[]):
    """Generate a basic decision task, based on the root .taskcluster.yml"""
    with open(os.path.join(root, '.taskcluster.yml'), 'rb') as f:
        taskcluster_yml = yaml.safe_load(f)

    push_info = find_hg_revision_push_info(params['repository_url'],
                                           params['head_rev'])

    slugids = {}

    def as_slugid(name):
        # https://github.com/taskcluster/json-e/issues/164
        name = name[0]
        if name not in slugids:
            slugids[name] = slugid.nice()
        return slugids[name]

    # provide a similar JSON-e context to what mozilla-taskcluster provides:
    # https://docs.taskcluster.net/reference/integrations/mozilla-taskcluster/docs/taskcluster-yml
    # but with a different tasks_for and an extra `cron` section
    context = {
        'tasks_for': 'cron',
        'repository': {
            'url': params['repository_url'],
            'project': params['project'],
            'level': params['level'],
        },
        'push': {
            'revision': params['head_rev'],
            # remainder are fake values, but the decision task expects them anyway
            'pushlog_id': push_info['pushid'],
            'pushdate': push_info['pushdate'],
            'owner': 'cron',
            'comment': '',
        },
        'cron': {
            'task_id': os.environ.get('TASK_ID', '<cron task id>'),
            'job_name': params['job_name'],
            'job_symbol': symbol,
            # args are shell-quoted since they are given to `bash -c`
            'quoted_args': ' '.join(pipes.quote(a) for a in arguments),
        },
        'now': current_json_time(),
        'as_slugid': as_slugid,
    }

    rendered = jsone.render(taskcluster_yml, context)
    if len(rendered['tasks']) != 1:
        raise Exception(
            "Expected .taskcluster.yml to only produce one cron task")
    task = rendered['tasks'][0]

    task_id = task.pop('taskId')
    return (task_id, task)
Example #26
0
def try_ami(ami_id, tc_options):
    pool = tc.parse_yaml("worker-pools.yml")["win2016"]
    pool.pop("kind")
    pool = tc.aws_windows(**pool)
    pool = dict(description="", emailOnError=False, owner="*****@*****.**", **pool)

    now = datetime.datetime.now().replace(microsecond=0).isoformat()
    worker_type = "tmp-" + re.sub("[-:T]", "", now)
    pool_id = "proj-servo/" + worker_type

    task = {h["hookId"]: h for h in tc.parse_yaml("hooks.yml")}["daily"]["task"]
    task["metadata"]["name"] = "Trying new Windows image " + ami_id
    task["metadata"]["source"] = \
        "https://github.com/servo/taskcluster-config/blob/master/commands/try-ami.py"
    task["payload"]["env"]["SOURCE"] = task["metadata"]["source"]
    task["payload"]["env"]["TASK_FOR"] = "try-windows-ami"
    task["payload"]["env"]["GIT_REF"] = "refs/heads/try-windows-ami"
    task["payload"]["env"]["NEW_AMI_WORKER_TYPE"] = worker_type
    task["created"] = {"$eval": "now"}
    task = jsone.render(task, {})
    task_id = taskcluster.slugId()

    wm = taskcluster.WorkerManager(tc_options)
    queue = taskcluster.Queue(tc_options)
    wm.createWorkerPool(pool_id, pool)
    try:
        queue.createTask(task_id, task)
        task_view = "https://community-tc.services.mozilla.com/tasks/"
        log("Created " + task_view + task_id)
        while 1:
            time.sleep(2)
            result = queue.status(task_id)
            state = result["status"]["state"]
            if state not in ["unscheduled", "pending", "running"]:
                log("Decision task:", state)
                break

        # The decision task has finished, so any other task should be scheduled now
        while 1:
            tasks = []
            def handler(result):
                for task in result["tasks"]:
                    if task["status"]["taskId"] != task_id:
                        tasks.append((task["status"]["taskId"], task["status"]["state"]))
            queue.listTaskGroup(result["status"]["taskGroupId"], paginationHandler=handler)
            if all(state not in ["unscheduled", "pending"] for _, state in tasks):
                for task, _ in tasks:
                    log("Running " + task_view + task)
                break
            time.sleep(2)
    finally:
        wm.deleteWorkerPool(pool_id)
Example #27
0
def generate_action_task(decision_task_id, action_task_input):
    actions = fetch_actions_json(decision_task_id)
    relpro = find_action("release-promotion", actions)
    context = copy.deepcopy(actions["variables"])  # parameters
    action_task_id = slugid.nice()
    context.update({
        "input": action_task_input,
        "ownTaskId": action_task_id,
        "taskId": None,
        "task": None,
        "taskGroupId": decision_task_id,
    })
    action_task = jsone.render(relpro["task"], context)
    return action_task_id, action_task
Example #28
0
def generate_action_task(decision_task_id, action_task_input):
    actions = fetch_actions_json(decision_task_id)
    relpro = find_action("release-promotion", actions)
    context = copy.deepcopy(actions["variables"])  # parameters
    action_task_id = slugid.nice()
    context.update({
        "input": action_task_input,
        "ownTaskId": action_task_id,
        "taskId": None,
        "task": None,
        "taskGroupId": decision_task_id,
    })
    action_task = jsone.render(relpro["task"], context)
    return action_task_id, action_task
Example #29
0
def main(worker_id_prefix, input, output):
    """Convert JSON/YAML templates into using json-e.

    Accepts JSON or YAML format and outputs using JSON because it is YAML
    compatible.
    """
    config_template = yaml.safe_load(input)
    context = os.environ.copy()
    # special case for workerId, it must be unique and max 38 characters long,
    # according to
    # https://docs.taskcluster.net/docs/reference/platform/queue/api#declareWorker
    worker_id = worker_id_prefix + slugid.nice().lower().replace("_", "").replace("-", "")
    context["WORKER_ID"] = worker_id[:38]
    config = jsone.render(config_template, context)
    json.dump(config, output, indent=2, sort_keys=True)
Example #30
0
def generate_action_task(decision_task_id, action_task_input):
    actions = fetch_actions_json(decision_task_id)
    relpro = find_action("release-promotion", actions)
    context = copy.deepcopy(actions["variables"])  # parameters
    action_task_id = slugid.nice()
    context.update({
        "input": action_task_input,
        "ownTaskId": action_task_id,
        "taskId": None,
        "task": None,
    })
    action_task = jsone.render(relpro["task"], context)
    # override ACTION_TASK_GROUP_ID, so we know the new ID in advance
    action_task["payload"]["env"]["ACTION_TASK_GROUP_ID"] = action_task_id
    return action_task_id, action_task
Example #31
0
def make_decision_task(params):
    """Generate a basic decision task, based on the root .taskcluster.yml"""
    with open(os.path.join(ROOT, '.taskcluster.yml'), 'rb') as f:
        taskcluster_yml = yaml.safe_load(f)

    slugids = {}

    def as_slugid(name):
        if name not in slugids:
            slugids[name] = slugid.nice()
        return slugids[name]

    repository_parts = params['html_url'].split('/')
    repository_full_name = '/'.join(
        (repository_parts[-2], repository_parts[-1]))

    # provide a similar JSON-e context to what taskcluster-github provides
    context = {
        'tasks_for': 'cron',
        'cron': {
            'task_id': params['cron_task_id'],
            'name': params['name'],
        },
        'now': datetime.datetime.utcnow().isoformat()[:23] + 'Z',
        'as_slugid': as_slugid,
        'event': {
            'repository': {
                'html_url': params['html_url'],
                'full_name': repository_full_name,
            },
            'release': {
                'tag_name': params['head_rev'],
                'target_commitish': params['branch'],
            },
            'sender': {
                'login': '******',
            }
        }
    }

    rendered = jsone.render(taskcluster_yml, context)
    if len(rendered['tasks']) != 1:
        raise Exception(
            'Expected .taskcluster.yml to only produce one cron task')
    task = rendered['tasks'][0]

    task_id = task.pop('taskId')
    return task_id, task
Example #32
0
def generate_action_hook(decision_task_id, action_name, actions):
    target_action = find_action(action_name, actions)
    context = copy.deepcopy(actions['variables'])  # parameters
    context.update({
        'input': {},
        'taskGroupId': decision_task_id,
        'taskId': None,
        'task': None,
    })
    hook_payload = jsone.render(target_action['hookPayload'], context)
    return dict(
        hook_group_id=target_action['hookGroupId'],
        hook_id=target_action['hookId'],
        hook_payload=hook_payload,
        context=context,
    )
Example #33
0
def test_jsone_validates(pipeline_file):
    with open(pipeline_file, "r") as f:
        yaml_content = yaml.safe_load(f.read())

    result = jsone.render(yaml_content, context={"version": "42.0"})
    tasks = result["tasks"]

    all_ids = [task["ID"] for task in tasks]

    # Make sure there are no duplicate IDs.
    assert len(all_ids) == len(set(all_ids))

    # Make sure all dependencies are present.
    for task in tasks:
        assert "dependencies" not in task or all(
            dependency in all_ids for dependency in task["dependencies"])
Example #34
0
def run(venv, **kwargs):
    with open(os.path.join(root, ".taskcluster.yml")) as f:
        template = yaml.safe_load(f)

    events = [("pr_event.json", "github-pull-request", "Pull Request"),
              ("master_push_event.json", "github-push", "Push to master")]

    for filename, tasks_for, title in events:
        with open(os.path.join(here, "testdata", filename)) as f:
            event = json.load(f)

        context = {"tasks_for": tasks_for,
                   "event": event,
                   "as_slugid": lambda x: x}

        data = jsone.render(template, context)
        heading = "Got %s tasks for %s" % (len(data["tasks"]), title)
        print(heading)
        print("=" * len(heading))
        for item in data["tasks"]:
            print(json.dumps(item, indent=2))
        print("")
Example #35
0
def render_action_task(task, context):
    action_task = jsone.render(task, context)
    return action_task