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
|
#!/usr/bin/env python
import shlex
import textwrap
import jinja2
import yaml
class GithubActionsYamlLoader(yaml.SafeLoader):
@staticmethod
def _unsupported(kind, token):
return SyntaxError(
"Github Actions does not support %s:\n%s" % (kind, token.start_mark)
)
def fetch_alias(self):
super().fetch_alias()
raise self._unsupported("aliases", self.tokens[0])
def fetch_anchor(self):
super().fetch_anchor()
raise self._unsupported("anchors", self.tokens[0])
environment = jinja2.Environment(
block_start_string="<%",
block_end_string="%>",
variable_start_string="<@",
variable_end_string="@>",
comment_start_string="<#",
comment_end_string="#>",
lstrip_blocks=True,
trim_blocks=True,
)
with open(".github/workflows/ci/workflow_context.yml") as fp:
context = yaml.load(fp, Loader=yaml.SafeLoader)
with open(".github/workflows/ci/workflow_template.yml") as fp:
template = environment.from_string(fp.read())
for j in context["jobs"]:
base_type = j["type"].split("_")[0]
j["id"] = "%s_%s" % (
base_type,
j["variant"].lower().replace(" ", "_").replace(".", ""),
)
j["name"] = "%s (%s)" % (base_type.capitalize(), j["variant"])
j["needs"] = j.get("needs", [])
j["reqs"] = ["reqs/%s.txt" % r for r in j["reqs"]]
j["cache_extra_deps"] = j.get("cache_extra_deps", [])
if "python" not in j:
j["python"] = context["default_python"]
if context["skippy_enabled"]:
# Path to the "skip_cache" file.
j["skip_cache_path"] = ".skip_cache_{id}".format(**j)
# Name of the "skip_cache" (name + tree SHA1 = key).
j["skip_cache_name"] = "skip_{id}_py-{python}_{platform}".format(
cache_epoch=context["cache_epoch"], **j
)
shell_definition = []
for k, v in sorted(j.items()):
if isinstance(v, list):
v = "(" + " ".join(map(shlex.quote, v)) + ")"
else:
v = shlex.quote(v)
shell_definition.append("job_%s=%s" % (k, v))
j["shell_definition"] = "; ".join(shell_definition)
# Render template.
workflow = template.render(context)
# Save result.
with open(".github/workflows/ci.yml", "w") as fp:
fp.write(
textwrap.dedent(
"""
#
# DO NOT MODIFY! AUTO-GENERATED FROM:
# .github/workflows/ci/workflow_template.yml
#
"""
).lstrip()
)
fp.write(workflow)
# Ensure the generated file ends with a trailing newline.
fp.write("\n")
# And try parsing it to check it's valid YAML,
# and ensure anchors/aliases are not used.
GithubActionsYamlLoader(workflow).get_single_data()
|