blob: 491df80be1e9b042960edc17a4e696b1f3ce869c [file] [log] [blame]
Steve Dowere1c54f42018-05-30 22:13:43 -07001<#
2.Synopsis
3 Uploads from a VSTS release build layout to python.org
4.Description
5 Given the downloaded/extracted build artifact from a release
6 build run on python.visualstudio.com, this script uploads
7 the files to the correct locations.
8.Parameter build
9 The location on disk of the extracted build artifact.
10.Parameter user
11 The username to use when logging into the host.
12.Parameter server
13 The host or PuTTY session name.
14.Parameter target
15 The subdirectory on the host to copy files to.
16.Parameter tests
17 The path to run download tests in.
18.Parameter skipupload
19 Skip uploading
20.Parameter skippurge
21 Skip purging the CDN
22.Parameter skiptest
23 Skip the download tests
24.Parameter skiphash
25 Skip displaying hashes
26#>
27param(
28 [Parameter(Mandatory=$true)][string]$build,
29 [Parameter(Mandatory=$true)][string]$user,
30 [string]$server="python-downloads",
31 [string]$target="/srv/www.python.org/ftp/python",
32 [string]$tests=${env:TEMP},
33 [switch]$skipupload,
34 [switch]$skippurge,
35 [switch]$skiptest,
36 [switch]$skiphash
37)
38
39if (-not $build) { throw "-build option is required" }
40if (-not $user) { throw "-user option is required" }
41
Steve Dowera486a472018-10-13 10:10:42 -070042$tools = $script:MyInvocation.MyCommand.Path | Split-Path -parent;
43
Steve Dower74e4aee2018-06-27 08:11:13 -070044if (-not ((Test-Path "$build\win32\python-*.exe") -or (Test-Path "$build\amd64\python-*.exe"))) {
45 throw "-build argument does not look like a 'build' directory"
46}
47
Steve Dowere1c54f42018-05-30 22:13:43 -070048function find-putty-tool {
49 param ([string]$n)
50 $t = gcm $n -EA 0
51 if (-not $t) { $t = gcm ".\$n" -EA 0 }
52 if (-not $t) { $t = gcm "${env:ProgramFiles}\PuTTY\$n" -EA 0 }
53 if (-not $t) { $t = gcm "${env:ProgramFiles(x86)}\PuTTY\$n" -EA 0 }
54 if (-not $t) { throw "Unable to locate $n.exe. Please put it on $PATH" }
55 return gi $t.Path
56}
57
58$p = gci -r "$build\python-*.exe" | `
59 ?{ $_.Name -match '^python-(\d+\.\d+\.\d+)((a|b|rc)\d+)?-.+' } | `
60 select -first 1 | `
61 %{ $Matches[1], $Matches[2] }
62
63"Uploading version $($p[0]) $($p[1])"
64" from: $build"
65" to: $($server):$target/$($p[0])"
Steve Dowere1c54f42018-05-30 22:13:43 -070066""
67
68if (-not $skipupload) {
69 # Upload files to the server
70 $pscp = find-putty-tool "pscp"
71 $plink = find-putty-tool "plink"
72
Steve Dower74e4aee2018-06-27 08:11:13 -070073 "Upload using $pscp and $plink"
74 ""
75
Steve Dowere1c54f42018-05-30 22:13:43 -070076 pushd $build
77 $doc = gci python*.chm, python*.chm.asc
78 popd
79
80 $d = "$target/$($p[0])/"
Steve Dowereeb99bd2018-06-12 14:35:11 -070081 & $plink -batch $user@$server mkdir $d
82 & $plink -batch $user@$server chgrp downloads $d
83 & $plink -batch $user@$server chmod g-x,o+rx $d
Steve Dowere1c54f42018-05-30 22:13:43 -070084 & $pscp -batch $doc.FullName "$user@${server}:$d"
85
86 foreach ($a in gci "$build" -Directory) {
87 "Uploading files from $($a.FullName)"
88 pushd "$($a.FullName)"
89 $exe = gci *.exe, *.exe.asc, *.zip, *.zip.asc
90 $msi = gci *.msi, *.msi.asc, *.msu, *.msu.asc
91 popd
92
93 & $pscp -batch $exe.FullName "$user@${server}:$d"
94
95 $sd = "$d$($a.Name)$($p[1])/"
Steve Dowereeb99bd2018-06-12 14:35:11 -070096 & $plink -batch $user@$server mkdir $sd
97 & $plink -batch $user@$server chgrp downloads $sd
98 & $plink -batch $user@$server chmod g-x,o+rx $sd
Steve Dowere1c54f42018-05-30 22:13:43 -070099 & $pscp -batch $msi.FullName "$user@${server}:$sd"
Steve Dowereeb99bd2018-06-12 14:35:11 -0700100 & $plink -batch $user@$server chgrp downloads $sd*
101 & $plink -batch $user@$server chmod g-x,o+r $sd*
Steve Dowere1c54f42018-05-30 22:13:43 -0700102 }
103
Steve Dowereeb99bd2018-06-12 14:35:11 -0700104 & $plink -batch $user@$server chgrp downloads $d*
105 & $plink -batch $user@$server chmod g-x,o+r $d*
Steve Dowere1c54f42018-05-30 22:13:43 -0700106}
107
108if (-not $skippurge) {
109 # Run a CDN purge
Steve Dowera486a472018-10-13 10:10:42 -0700110 py $tools\purge.py "$($p[0])$($p[1])"
Steve Dowere1c54f42018-05-30 22:13:43 -0700111}
112
113if (-not $skiptest) {
114 # Use each web installer to produce a layout. This will download
115 # each referenced file and validate their signatures/hashes.
116 gci "$build\*-webinstall.exe" -r -File | %{
117 $d = mkdir "$tests\$($_.BaseName)" -Force
118 gci $d -r -File | del
119 $ic = copy $_ $d -PassThru
120 "Checking layout for $($ic.Name)"
121 Start-Process -wait $ic "/passive", "/layout", "$d\layout", "/log", "$d\log\install.log"
122 if (-not $?) {
123 Write-Error "Failed to validate layout of $($inst.Name)"
124 }
125 }
126}
127
128if (-not $skiphash) {
129 # Display MD5 hash and size of each downloadable file
130 pushd $build
Steve Dowera486a472018-10-13 10:10:42 -0700131 $hashes = gci python*.chm, *\*.exe, *\*.zip | `
Steve Dowere1c54f42018-05-30 22:13:43 -0700132 Sort-Object Name | `
Steve Dowera486a472018-10-13 10:10:42 -0700133 Format-Table Name, @{Label="MD5"; Expression={(Get-FileHash $_ -Algorithm MD5).Hash}}, Length -AutoSize | `
134 Out-String -Width 4096
135 $hashes | clip
136 $hashes
Steve Dowere1c54f42018-05-30 22:13:43 -0700137 popd
138}