|
4 | 4 | # v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
5 | 5 | # obtain one at http://mozilla.org/MPL/2.0/.
|
6 | 6 |
|
| 7 | +import asyncio |
7 | 8 | import datetime
|
| 9 | +import functools |
8 | 10 | import hashlib
|
9 | 11 | import textwrap
|
10 | 12 |
|
@@ -48,69 +50,59 @@ def should_hash(project):
|
48 | 50 | else:
|
49 | 51 | return False
|
50 | 52 |
|
| 53 | + # hash the value of this .taskcluster.yml. Note that this must match the |
| 54 | + # hashing in taskgraph/actions/registry.py |
| 55 | + def hash(val): |
| 56 | + return hashlib.sha256(val).hexdigest()[:10] |
| 57 | + |
51 | 58 | tcyml_projects = list(filter(should_hash, projects))
|
52 | 59 | futures = []
|
| 60 | + rv = {} |
53 | 61 | for p in tcyml_projects:
|
54 |
| - branch_futures = {} |
55 |
| - for b in p.branches: |
| 62 | + rv[p.alias] = {} |
| 63 | + |
| 64 | + for b in set([b.name for b in p.branches] + [p.default_branch]): |
56 | 65 | # Can't fetch a .taskcluster.yml for a globbed branch
|
57 | 66 | # TODO: perhaps we should do this for partly globbed branches,
|
58 | 67 | # eg: release* ?
|
59 | 68 | # we'd have to fetch that list from the server to do that
|
60 |
| - if "*" not in b.name: |
61 |
| - branch_futures[b.name] = tcyml.get( |
62 |
| - p.repo, repo_type=p.repo_type, default_branch=b.name |
| 69 | + if "*" not in b: |
| 70 | + |
| 71 | + def process(project, branch_name, task): |
| 72 | + tcy = task.result() |
| 73 | + |
| 74 | + # some ancient projects have no .taskcluster.yml |
| 75 | + if not tcy: |
| 76 | + return |
| 77 | + |
| 78 | + # some old projects have .taskcluster.yml's that are not valid YAML |
| 79 | + # (back in the day, mozilla-taskcluster used mustache to templatize |
| 80 | + # the text before parsing it..). Ignore those projects. |
| 81 | + try: |
| 82 | + parsed = yaml.safe_load(tcy) |
| 83 | + except Exception: |
| 84 | + return |
| 85 | + |
| 86 | + # some slightly less old projects have |
| 87 | + # {tasks: $let: .., in: [..]} instead of the expected |
| 88 | + # {tasks: [{$let: .., in: ..}]}. Those can be ignored too. |
| 89 | + if not isinstance(parsed["tasks"], list): |
| 90 | + return |
| 91 | + |
| 92 | + rv[project.alias][branch_name] = { |
| 93 | + "parsed": parsed, |
| 94 | + "hash": hash(tcy), |
| 95 | + "level": project.get_level(branch_name), |
| 96 | + "alias": project.alias, |
| 97 | + } |
| 98 | + |
| 99 | + future = asyncio.ensure_future( |
| 100 | + tcyml.get(p.repo, repo_type=p.repo_type, default_branch=b) |
63 | 101 | )
|
| 102 | + future.add_done_callback(functools.partial(process, p, b)) |
| 103 | + futures.append(future) |
64 | 104 |
|
65 |
| - if p.default_branch not in branch_futures: |
66 |
| - branch_futures[p.default_branch] = tcyml.get( |
67 |
| - p.repo, repo_type=p.repo_type, default_branch=p.default_branch |
68 |
| - ) |
69 |
| - |
70 |
| - futures.append(branch_futures) |
71 |
| - |
72 |
| - tcymls = [] |
73 |
| - for branches in futures: |
74 |
| - branch_tcymls = {} |
75 |
| - for b in branches: |
76 |
| - branch_tcymls[b] = await branches[b] |
77 |
| - |
78 |
| - tcymls.append(branch_tcymls) |
79 |
| - |
80 |
| - # hash the value of this .taskcluster.yml. Note that this must match the |
81 |
| - # hashing in taskgraph/actions/registry.py |
82 |
| - def hash(val): |
83 |
| - return hashlib.sha256(val).hexdigest()[:10] |
84 |
| - |
85 |
| - rv = {} |
86 |
| - for project, branch_tcymls in zip(tcyml_projects, tcymls): |
87 |
| - for branch_name, tcy in branch_tcymls.items(): |
88 |
| - # some ancient projects have no .taskcluster.yml |
89 |
| - if not tcy: |
90 |
| - continue |
91 |
| - |
92 |
| - # some old projects have .taskcluster.yml's that are not valid YAML |
93 |
| - # (back in the day, mozilla-taskcluster used mustache to templatize |
94 |
| - # the text before parsing it..). Ignore those projects. |
95 |
| - try: |
96 |
| - parsed = yaml.safe_load(tcy) |
97 |
| - except Exception: |
98 |
| - continue |
99 |
| - |
100 |
| - # some slightly less old projects have {tasks: $let: .., in: [..]} instead |
101 |
| - # of the expected {tasks: [{$let: .., in: ..}]}. Those can be ignored too. |
102 |
| - if not isinstance(parsed["tasks"], list): |
103 |
| - continue |
104 |
| - |
105 |
| - if project.alias not in rv: |
106 |
| - rv[project.alias] = {} |
107 |
| - |
108 |
| - rv[project.alias][branch_name] = { |
109 |
| - "parsed": parsed, |
110 |
| - "hash": hash(tcy), |
111 |
| - "level": project.get_level(branch_name), |
112 |
| - "alias": project.alias, |
113 |
| - } |
| 105 | + await asyncio.gather(*futures) |
114 | 106 | return rv
|
115 | 107 |
|
116 | 108 |
|
@@ -352,6 +344,10 @@ async def update_resources(resources):
|
352 | 344 | continue
|
353 | 345 | if project.trust_domain != action.trust_domain:
|
354 | 346 | continue
|
| 347 | + if branch_name not in hashed_tcymls[project.alias]: |
| 348 | + # Branch didn't exist, or doesn't have a parseable tcyml |
| 349 | + continue |
| 350 | + |
355 | 351 | content, hash = (
|
356 | 352 | hashed_tcymls[project.alias][branch_name]["parsed"],
|
357 | 353 | hashed_tcymls[project.alias][branch_name]["hash"],
|
|
0 commit comments