Mercurial > hg
comparison contrib/automation/hgautomation/windows.py @ 44772:5e788dc7fb5d stable
automation: support building Python 3 MSI installers
This is very similar to what we just did for Inno.
Differential Revision: https://phab.mercurial-scm.org/D8484
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Fri, 24 Apr 2020 12:37:43 -0700 |
parents | 802ee93c205d |
children | d1ce0ffdd3ce |
comparison
equal
deleted
inserted
replaced
44771:802ee93c205d | 44772:5e788dc7fb5d |
---|---|
93 if ($LASTEXITCODE -ne 0) {{ | 93 if ($LASTEXITCODE -ne 0) {{ |
94 throw "process exited non-0: $LASTEXITCODE" | 94 throw "process exited non-0: $LASTEXITCODE" |
95 }} | 95 }} |
96 ''' | 96 ''' |
97 | 97 |
98 BUILD_WIX = r''' | 98 BUILD_WIX_PYTHON3 = r''' |
99 $Env:RUSTUP_HOME = "C:\hgdev\rustup" | |
100 $Env:CARGO_HOME = "C:\hgdev\cargo" | |
101 Set-Location C:\hgdev\src | |
102 C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --pyoxidizer-target {pyoxidizer_target} --version {version} | |
103 if ($LASTEXITCODE -ne 0) {{ | |
104 throw "process exited non-0: $LASTEXITCODE" | |
105 }} | |
106 ''' | |
107 | |
108 BUILD_WIX_PYTHON2 = r''' | |
99 Set-Location C:\hgdev\src | 109 Set-Location C:\hgdev\src |
100 $python = "C:\hgdev\python27-{arch}\python.exe" | 110 $python = "C:\hgdev\python27-{arch}\python.exe" |
101 C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --python $python {extra_args} | 111 C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --python $python {extra_args} |
102 if ($LASTEXITCODE -ne 0) {{ | 112 if ($LASTEXITCODE -ne 0) {{ |
103 throw "process exited non-0: $LASTEXITCODE" | 113 throw "process exited non-0: $LASTEXITCODE" |
120 | 130 |
121 EXE_FILENAME_PYTHON2_X86 = 'Mercurial-{version}-x86-python2.exe' | 131 EXE_FILENAME_PYTHON2_X86 = 'Mercurial-{version}-x86-python2.exe' |
122 EXE_FILENAME_PYTHON2_X64 = 'Mercurial-{version}-x64-python2.exe' | 132 EXE_FILENAME_PYTHON2_X64 = 'Mercurial-{version}-x64-python2.exe' |
123 EXE_FILENAME_PYTHON3_X86 = 'Mercurial-{version}-x86.exe' | 133 EXE_FILENAME_PYTHON3_X86 = 'Mercurial-{version}-x86.exe' |
124 EXE_FILENAME_PYTHON3_X64 = 'Mercurial-{version}-x64.exe' | 134 EXE_FILENAME_PYTHON3_X64 = 'Mercurial-{version}-x64.exe' |
125 X86_MSI_FILENAME = 'mercurial-{version}-x86-python2.msi' | 135 |
126 X64_MSI_FILENAME = 'mercurial-{version}-x64-python2.msi' | 136 MSI_FILENAME_PYTHON2_X86 = 'mercurial-{version}-x86-python2.msi' |
137 MSI_FILENAME_PYTHON2_X64 = 'mercurial-{version}-x64-python2.msi' | |
138 MSI_FILENAME_PYTHON3_X86 = 'mercurial-{version}-x86.msi' | |
139 MSI_FILENAME_PYTHON3_X64 = 'mercurial-{version}-x64.msi' | |
127 | 140 |
128 MERCURIAL_SCM_BASE_URL = 'https://mercurial-scm.org/release/windows' | 141 MERCURIAL_SCM_BASE_URL = 'https://mercurial-scm.org/release/windows' |
129 | 142 |
130 X86_USER_AGENT_PATTERN = '.*Windows.*' | 143 X86_USER_AGENT_PATTERN = '.*Windows.*' |
131 X64_USER_AGENT_PATTERN = '.*Windows.*(WOW|x)64.*' | 144 X64_USER_AGENT_PATTERN = '.*Windows.*(WOW|x)64.*' |
145 ) | 158 ) |
146 EXE_PYTHON3_X64_DESCRIPTION = ( | 159 EXE_PYTHON3_X64_DESCRIPTION = ( |
147 'Mercurial {version} Inno Setup installer - x64 Windows (Python 3) ' | 160 'Mercurial {version} Inno Setup installer - x64 Windows (Python 3) ' |
148 '- does not require admin rights' | 161 '- does not require admin rights' |
149 ) | 162 ) |
150 X86_MSI_DESCRIPTION = ( | 163 MSI_PYTHON2_X86_DESCRIPTION = ( |
151 'Mercurial {version} MSI installer - x86 Windows ' '- requires admin rights' | 164 'Mercurial {version} MSI installer - x86 Windows (Python 2) ' |
152 ) | 165 '- requires admin rights' |
153 X64_MSI_DESCRIPTION = ( | 166 ) |
154 'Mercurial {version} MSI installer - x64 Windows ' '- requires admin rights' | 167 MSI_PYTHON2_X64_DESCRIPTION = ( |
168 'Mercurial {version} MSI installer - x64 Windows (Python 2) ' | |
169 '- requires admin rights' | |
170 ) | |
171 MSI_PYTHON3_X86_DESCRIPTION = ( | |
172 'Mercurial {version} MSI installer - x86 Windows (Python 3) ' | |
173 '- requires admin rights' | |
174 ) | |
175 MSI_PYTHON3_X64_DESCRIPTION = ( | |
176 'Mercurial {version} MSI installer - x64 Windows (Python 3) ' | |
177 '- requires admin rights' | |
155 ) | 178 ) |
156 | 179 |
157 | 180 |
158 def get_vc_prefix(arch): | 181 def get_vc_prefix(arch): |
159 if arch == 'x86': | 182 if arch == 'x86': |
373 run_powershell(winrm_client, ps) | 396 run_powershell(winrm_client, ps) |
374 copy_latest_dist(winrm_client, '*.whl', dest_path) | 397 copy_latest_dist(winrm_client, '*.whl', dest_path) |
375 | 398 |
376 | 399 |
377 def build_wix_installer( | 400 def build_wix_installer( |
378 winrm_client, arch: str, dest_path: pathlib.Path, version=None | 401 winrm_client, |
402 python_version: int, | |
403 arch: str, | |
404 dest_path: pathlib.Path, | |
405 version=None, | |
379 ): | 406 ): |
380 """Build the WiX installer on a remote machine. | 407 """Build the WiX installer on a remote machine. |
381 | 408 |
382 Using a WinRM client, remote commands are executed to build a WiX installer. | 409 Using a WinRM client, remote commands are executed to build a WiX installer. |
383 """ | 410 """ |
384 print('Building WiX installer for %s' % arch) | 411 print('Building WiX installer for Python %d %s' % (python_version, arch)) |
385 extra_args = [] | 412 |
386 if version: | 413 if python_version == 3: |
387 extra_args.extend(['--version', version]) | 414 # TODO fix this limitation in packaging code |
388 | 415 if not version: |
389 ps = get_vc_prefix(arch) + BUILD_WIX.format( | 416 raise Exception( |
390 arch=arch, extra_args=' '.join(extra_args) | 417 "version string is required when building for Python 3" |
391 ) | 418 ) |
419 | |
420 if arch == "x86": | |
421 target_triple = "i686-pc-windows-msvc" | |
422 elif arch == "x64": | |
423 target_triple = "x86_64-pc-windows-msvc" | |
424 else: | |
425 raise Exception("unhandled arch: %s" % arch) | |
426 | |
427 ps = BUILD_WIX_PYTHON3.format( | |
428 pyoxidizer_target=target_triple, version=version, | |
429 ) | |
430 else: | |
431 extra_args = [] | |
432 if version: | |
433 extra_args.extend(['--version', version]) | |
434 | |
435 ps = get_vc_prefix(arch) + BUILD_WIX_PYTHON2.format( | |
436 arch=arch, extra_args=' '.join(extra_args) | |
437 ) | |
438 | |
392 run_powershell(winrm_client, ps) | 439 run_powershell(winrm_client, ps) |
393 copy_latest_dist(winrm_client, '*.msi', dest_path) | 440 copy_latest_dist(winrm_client, '*.msi', dest_path) |
394 | 441 |
395 | 442 |
396 def run_tests(winrm_client, python_version, arch, test_flags=''): | 443 def run_tests(winrm_client, python_version, arch, test_flags=''): |
437 dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version), | 484 dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version), |
438 dist_path / EXE_FILENAME_PYTHON2_X86.format(version=version), | 485 dist_path / EXE_FILENAME_PYTHON2_X86.format(version=version), |
439 dist_path / EXE_FILENAME_PYTHON2_X64.format(version=version), | 486 dist_path / EXE_FILENAME_PYTHON2_X64.format(version=version), |
440 dist_path / EXE_FILENAME_PYTHON3_X86.format(version=version), | 487 dist_path / EXE_FILENAME_PYTHON3_X86.format(version=version), |
441 dist_path / EXE_FILENAME_PYTHON3_X64.format(version=version), | 488 dist_path / EXE_FILENAME_PYTHON3_X64.format(version=version), |
442 dist_path / X86_MSI_FILENAME.format(version=version), | 489 dist_path / MSI_FILENAME_PYTHON2_X86.format(version=version), |
443 dist_path / X64_MSI_FILENAME.format(version=version), | 490 dist_path / MSI_FILENAME_PYTHON2_X64.format(version=version), |
491 dist_path / MSI_FILENAME_PYTHON3_X86.format(version=version), | |
492 dist_path / MSI_FILENAME_PYTHON3_X64.format(version=version), | |
444 ) | 493 ) |
445 | 494 |
446 | 495 |
447 def generate_latest_dat(version: str): | 496 def generate_latest_dat(version: str): |
448 python2_x86_exe_filename = EXE_FILENAME_PYTHON2_X86.format(version=version) | 497 python2_x86_exe_filename = EXE_FILENAME_PYTHON2_X86.format(version=version) |
449 python2_x64_exe_filename = EXE_FILENAME_PYTHON2_X64.format(version=version) | 498 python2_x64_exe_filename = EXE_FILENAME_PYTHON2_X64.format(version=version) |
450 python3_x86_exe_filename = EXE_FILENAME_PYTHON3_X86.format(version=version) | 499 python3_x86_exe_filename = EXE_FILENAME_PYTHON3_X86.format(version=version) |
451 python3_x64_exe_filename = EXE_FILENAME_PYTHON3_X64.format(version=version) | 500 python3_x64_exe_filename = EXE_FILENAME_PYTHON3_X64.format(version=version) |
452 x86_msi_filename = X86_MSI_FILENAME.format(version=version) | 501 python2_x86_msi_filename = MSI_FILENAME_PYTHON2_X86.format(version=version) |
453 x64_msi_filename = X64_MSI_FILENAME.format(version=version) | 502 python2_x64_msi_filename = MSI_FILENAME_PYTHON2_X64.format(version=version) |
503 python3_x86_msi_filename = MSI_FILENAME_PYTHON3_X86.format(version=version) | |
504 python3_x64_msi_filename = MSI_FILENAME_PYTHON3_X64.format(version=version) | |
454 | 505 |
455 entries = ( | 506 entries = ( |
456 ( | 507 ( |
457 '10', | 508 '10', |
458 version, | 509 version, |
483 ), | 534 ), |
484 ( | 535 ( |
485 '10', | 536 '10', |
486 version, | 537 version, |
487 X86_USER_AGENT_PATTERN, | 538 X86_USER_AGENT_PATTERN, |
488 '%s/%s' % (MERCURIAL_SCM_BASE_URL, x86_msi_filename), | 539 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_msi_filename), |
489 X86_MSI_DESCRIPTION.format(version=version), | 540 MSI_PYTHON3_X86_DESCRIPTION.format(version=version), |
490 ), | 541 ), |
491 ( | 542 ( |
492 '10', | 543 '10', |
493 version, | 544 version, |
494 X64_USER_AGENT_PATTERN, | 545 X64_USER_AGENT_PATTERN, |
495 '%s/%s' % (MERCURIAL_SCM_BASE_URL, x64_msi_filename), | 546 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_msi_filename), |
496 X64_MSI_DESCRIPTION.format(version=version), | 547 MSI_PYTHON3_X64_DESCRIPTION.format(version=version), |
548 ), | |
549 ( | |
550 '9', | |
551 version, | |
552 X86_USER_AGENT_PATTERN, | |
553 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x86_msi_filename), | |
554 MSI_PYTHON2_X86_DESCRIPTION.format(version=version), | |
555 ), | |
556 ( | |
557 '9', | |
558 version, | |
559 X64_USER_AGENT_PATTERN, | |
560 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x64_msi_filename), | |
561 MSI_PYTHON2_X64_DESCRIPTION.format(version=version), | |
497 ), | 562 ), |
498 ) | 563 ) |
499 | 564 |
500 lines = ['\t'.join(e) for e in entries] | 565 lines = ['\t'.join(e) for e in entries] |
501 | 566 |