1 #! /usr/bin/env python3
2 # -*- coding: utf-8 -*-
5 # Copyright © 2021 Shlomi Fish < https://www.shlomifish.org/ >
7 # Licensed under the terms of the MIT license.
10 CI-testing/translate-travis.yml-to-github-actions.py :
12 This program translates fc-solve's .travis.yml to GitHub actions
13 and ACT workflows ( https://github.com/nektos/act ).
15 While ostensibly FOSS, it most probably is not generic enough
25 def _add_condition_while_excluding_gh_actions(job_dict, is_act):
29 https://github.com/actions/runner/issues/480
31 Workflow level `env` does not work properly in all fields. · Issue #480
36 "${{ ! contains(env.ACT_SKIP, matrix.env.WHAT) }}"
39 def generate(output_path, is_act):
40 """docstring for main"""
43 def _process_env(env):
47 '\\A([A-Za-z0-9_]+)=([A-Za-z0-9_]+)\\Z',
55 with open("./.travis.yml", "rt") as infh:
56 data = yaml.safe_load(infh)
59 "uses": ("actions/checkout@v2"),
67 ("cd workflow ; (ls -lrtA ; false)"), })
71 ("cd . ; (ls -lrtA ; false)"), })
72 steps.append({"run": ("sudo apt-get update -qq"), })
74 "run": ("sudo apt-get --no-install-recommends install -y " +
75 " ".join(["eatmydata"])
80 "run": ("sudo eatmydata apt-get --no-install-recommends install -y " +
81 " ".join(data['addons']['apt']['packages'])
85 local_lib_shim = 'local_lib_shim() { eval "$(perl ' + \
86 '-Mlocal::lib=$HOME/' + \
87 'perl_modules)"; } ; local_lib_shim ; '
88 for arr in ['before_install', 'install', 'script']:
89 steps += [{"run": local_lib_shim + x} for x in data[arr]]
91 o = {'jobs': {job: {'runs-on': 'ubuntu-latest',
93 'name': 'use-github-actions', 'on': ['push', ], }
95 if 'include' in data['matrix']:
96 o['jobs'][job]['strategy'] = {'matrix': {'include': [
97 {'env': _process_env(x['env']), }
98 for x in data['matrix']['include']
100 o['jobs'][job]['env'] = {
101 x: "${{ matrix.env." + x + " }}"
104 _add_condition_while_excluding_gh_actions(
105 job_dict=o['jobs'][job],
110 with open(output_path, "wt") as outfh:
111 # yaml.safe_dump(o, outfh)
112 yaml.safe_dump(o, stream=outfh, canonical=False, indent=4, )
115 def generate_windows_yaml(plat, output_path, is_act):
116 """docstring for main"""
119 def _process_env(env):
123 '\\A([A-Za-z0-9_]+)=([A-Za-z0-9_]+)\\Z',
127 assert key not in ret
131 with open("./.appveyor.yml", "rt") as infh:
132 data = yaml.safe_load(infh)
133 with open("./CI-testing/gh-actions--" +
134 "windows-yml--from-p5-UV.yml", "rt") as infh:
135 skel = yaml.safe_load(infh)
136 steps = skel['jobs']['perl']['steps']
137 while steps[-1]['name'] != 'perl -V':
141 "run": "git config --global core.autocrlf input",
146 "uses": "cygwin/cygwin-install-action@master",
149 "packages": "docbook-xml docbook-xsl libxml2 libxslt",
154 "name": "install cpanm and mult modules",
155 "uses": "perl-actions/install-with-cpanm@v1",
157 steps.append(cpanm_step)
158 # if True: # plat == 'x86':
162 "name": "Set up MinGW",
163 "uses": "egor-tensin/setup-mingw@v2",
172 # https://github.com/sithlord48/blackchocobo/actions/runs/1207252836/workflow#L100
173 # https://github.community/t/windows-actions-suddenly-fail-needing-a-nuspec-file/199483
175 "if": "runner.os == 'Windows'",
176 "name": "Remove Chocolatey's CPack",
177 "run": "Remove-Item -Path " +
178 "C:\\ProgramData\\Chocolatey\\bin\\cpack.exe -Force",
180 cpack_fix_needed = False
182 steps.append(cpack_fix)
184 def _calc_batch_code(cmds):
185 cmds = [(x['cmd'] if isinstance(x, dict) else x) for x in cmds]
187 batch += "@echo on\n"
188 for k, v in sorted(data['environment']['global'].items()):
189 # batch += "SET " + k + "=\"" + v + "\"\n"
190 batch += "SET " + k + "=" + v + "\n"
193 cmds.insert(idx, "SET CXX=c++")
194 cmds.insert(idx, "SET CC=cc")
197 idx, "c:\\msys64\\usr\\bin\\bash -lc "
198 "\"pacman --noconfirm -Sy mingw-w64-x86_64-libsystre\"")
201 if cmd.startswith("copy C:\\msys64\\mingw64\\bin" +
202 "\\mingw32-make.exe "):
204 if cmd.startswith("C:\\cygwin64\\setup"):
206 cmd = cmd.replace("cygwin64", "cygwin")
207 cmd = cmd.replace("MSYS Makefiles", "MinGW Makefiles")
208 if cmd.startswith("cpanm "):
209 words = cmd.split(' ')[1:]
212 if not w.startswith("-"):
215 cpanm_step['with'] = {"install": "\n".join(dw), }
217 if re.search("copy.*?python\\.exe", cmd):
219 if "strawberry" in cmd:
221 cmd = re.sub("\\S*CMAKE_MAKE_PROGRAM\\S*", "", cmd)
222 if "choco install strawberryperl" not in cmd:
225 "curl\\s+-o\\s+(\\S+)\\s+(\\S+)",
226 "lwp-download \\2 \\1",
229 if cmd.startswith("perl ../source/run-tests.pl"):
239 # https://serverfault.com/questions/157173
241 if not (r.lower().startswith("set ")):
242 shim = " || ( echo Failed & exit /B 1 )"
243 batch += r + shim + "\n"
247 steps.append({'name': "install code", "run": _calc_batch_code(
248 cmds=data['install']), "shell": "cmd", })
250 'name': "install and test_script code",
251 "run": _calc_batch_code(
252 cmds=(data['install']+data['test_script'])
258 is32 = ("\\pkg-build\\" in path)
259 return (is32 if plat == 'x86' else (not is32))
260 skel['name'] = ("windows-x86" if plat == 'x86' else 'windows-x64')
261 skel['on'] = ['push']
262 with open(output_path, "wt") as outfh:
263 # yaml.safe_dump(o, outfh)
265 "# This file is GENERATED BY\n" +
267 "translate-travis.yml-to-github-actions.py\n")
268 yaml.safe_dump(skel, stream=outfh, canonical=False, indent=4, )
273 output_path=".github/workflows/use-github-actions.yml",
277 output_path=".act-github/workflows/use-github-actions.yml",
281 generate_windows_yaml(
283 output_path=".github/workflows/windows-x86.yml",
286 generate_windows_yaml(
288 output_path=".github/workflows/windows-x64.yml",
293 if __name__ == "__main__":