1 #!/usr/bin/env powershell
2 # Install Python 3.8 for x64 and x86 in order to build wheels on Windows.
3 
4 Set-StrictMode -Version 2
5 $ErrorActionPreference = 'Stop'
6 # Disable progress bar to avoid getting the
7 # '"Access is denied" 0x5 occurred while reading the console output buffer'
8 # error when running on kokoro (i.e. in non-interactive mode)
9 $global:ProgressPreference = 'SilentlyContinue'
10 
11 trap {
12     $ErrorActionPreference = "Continue"
13     Write-Error $_
14     exit 1
15 }
16 
17 # Avoid "Could not create SSL/TLS secure channel"
18 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
19 
Install-Pythonnull20 function Install-Python {
21     Param(
22         [string]$PythonVersion,
23         [string]$PythonInstaller,
24         [string]$PythonInstallPath,
25         [string]$PythonInstallerHash
26     )
27     $PythonInstallerUrl = "https://www.python.org/ftp/python/$PythonVersion/$PythonInstaller.exe"
28     $PythonInstallerPath = "C:\tools\$PythonInstaller.exe"
29 
30     # Downloads installer
31     Write-Host "Downloading the Python installer: $PythonInstallerUrl => $PythonInstallerPath"
32     Invoke-WebRequest -Uri $PythonInstallerUrl -OutFile $PythonInstallerPath
33 
34     # Validates checksum
35     $HashFromDownload = Get-FileHash -Path $PythonInstallerPath -Algorithm MD5
36     if ($HashFromDownload.Hash -ne $PythonInstallerHash) {
37         throw "Invalid Python installer: failed checksum!"
38     }
39     Write-Host "Python installer $PythonInstallerPath validated."
40 
41     # Installs Python
42     & $PythonInstallerPath /passive InstallAllUsers=1 PrependPath=1 Include_test=0 TargetDir=$PythonInstallPath
43     if (-Not $?) {
44         throw "The Python installation exited with error!"
45     }
46 
47     # NOTE(lidiz) Even if the install command finishes in the script, that
48     # doesn't mean the Python installation is finished. If using "ps" to check
49     # for running processes, you might see ongoing installers at this point.
50     # So, we needs this "hack" to reliably validate that the Python binary is
51     # functioning properly.
52 
53     # Wait for the installer process
54     Wait-Process -Name $PythonInstaller -Timeout 300
55     Write-Host "Installation process exits normally."
56 
57     # Validate Python binary
58     $PythonBinary = "$PythonInstallPath\python.exe"
59     & $PythonBinary -c 'print(42)'
60     Write-Host "Python binary works properly."
61 
62     # Installs pip
63     & $PythonBinary -m ensurepip --user
64 
65     Write-Host "Python $PythonVersion installed by $PythonInstaller at $PythonInstallPath."
66 }
67 
68 # Python 3.8
69 $Python38x86Config = @{
70     PythonVersion = "3.8.10"
71     PythonInstaller = "python-3.8.10"
72     PythonInstallPath = "C:\Python38_32bit"
73     PythonInstallerHash = "b355cfc84b681ace8908ae50908e8761"
74 }
75 Install-Python @Python38x86Config
76 
77 $Python38x64Config = @{
78     PythonVersion = "3.8.10"
79     PythonInstaller = "python-3.8.10-amd64"
80     PythonInstallPath = "C:\Python38"
81     PythonInstallerHash = "62cf1a12a5276b0259e8761d4cf4fe42"
82 }
83 Install-Python @Python38x64Config
84 
85 # Python 3.9
86 $Python39x86Config = @{
87     PythonVersion = "3.9.11"
88     PythonInstaller = "python-3.9.11"
89     PythonInstallPath = "C:\Python39_32bit"
90     PythonInstallerHash = "4210652b14a030517046cdf111c09c1e"
91 }
92 Install-Python @Python39x86Config
93 
94 $Python39x64Config = @{
95     PythonVersion = "3.9.11"
96     PythonInstaller = "python-3.9.11-amd64"
97     PythonInstallPath = "C:\Python39"
98     PythonInstallerHash = "fef52176a572efd48b7148f006b25801"
99 }
100 Install-Python @Python39x64Config
101 
102 # Python 3.10
103 $Python310x86Config = @{
104     PythonVersion = "3.10.3"
105     PythonInstaller = "python-3.10.3"
106     PythonInstallPath = "C:\Python310_32bit"
107     PythonInstallerHash = "6a336cb2aca62dd05805316ab3aaf2b5"
108 }
109 Install-Python @Python310x86Config
110 
111 $Python310x64Config = @{
112     PythonVersion = "3.10.3"
113     PythonInstaller = "python-3.10.3-amd64"
114     PythonInstallPath = "C:\Python310"
115     PythonInstallerHash = "9ea305690dbfd424a632b6a659347c1e"
116 }
117 Install-Python @Python310x64Config
118 
119 # Python 3.11
120 $Python311x86Config = @{
121     PythonVersion = "3.11.0"
122     PythonInstaller = "python-3.11.0rc1"
123     PythonInstallPath = "C:\Python311_32bit"
124     PythonInstallerHash = "d2e5420e53d9e71c82b4a19763dbaa12"
125 }
126 Install-Python @Python311x86Config
127 
128 $Python311x64Config = @{
129     PythonVersion = "3.11.0"
130     PythonInstaller = "python-3.11.0rc1-amd64"
131     PythonInstallPath = "C:\Python311"
132     PythonInstallerHash = "5943d8702e40a5ccd62e5a8d4c8852aa"
133 }
134 Install-Python @Python311x64Config
135