Skip to content

Commit 21a92f8

Browse files
authored
Implement Windows release builds in Azure Pipelines (pythonGH-14065)
1 parent f0749da commit 21a92f8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1691
-166
lines changed

.azure-pipelines/windows-release.yml

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Release_$(Build.SourceBranchName)_$(SourceTag)_$(Date:yyyyMMdd)$(Rev:.rr)
2+
3+
# QUEUE TIME VARIABLES
4+
# variables:
5+
# GitRemote: python
6+
# SourceTag:
7+
# DoPGO: true
8+
# SigningCertificate: 'Python Software Foundation'
9+
# SigningDescription: 'Built: $(Build.BuildNumber)'
10+
# DoLayout: true
11+
# DoMSIX: true
12+
# DoNuget: true
13+
# DoEmbed: true
14+
# DoMSI: true
15+
# DoPublish: false
16+
17+
trigger: none
18+
pr: none
19+
20+
stages:
21+
- stage: Build
22+
displayName: Build binaries
23+
jobs:
24+
- template: windows-release/stage-build.yml
25+
26+
- stage: Sign
27+
displayName: Sign binaries
28+
dependsOn: Build
29+
jobs:
30+
- template: windows-release/stage-sign.yml
31+
32+
- stage: Layout
33+
displayName: Generate layouts
34+
dependsOn: Sign
35+
jobs:
36+
- template: windows-release/stage-layout-full.yml
37+
- template: windows-release/stage-layout-embed.yml
38+
- template: windows-release/stage-layout-nuget.yml
39+
40+
- stage: Pack
41+
dependsOn: Layout
42+
jobs:
43+
- template: windows-release/stage-pack-nuget.yml
44+
45+
- stage: Test
46+
dependsOn: Pack
47+
jobs:
48+
- template: windows-release/stage-test-embed.yml
49+
- template: windows-release/stage-test-nuget.yml
50+
51+
- stage: Layout_MSIX
52+
displayName: Generate MSIX layouts
53+
dependsOn: Sign
54+
condition: and(succeeded(), eq(variables['DoMSIX'], 'true'))
55+
jobs:
56+
- template: windows-release/stage-layout-msix.yml
57+
58+
- stage: Pack_MSIX
59+
displayName: Package MSIX
60+
dependsOn: Layout_MSIX
61+
jobs:
62+
- template: windows-release/stage-pack-msix.yml
63+
64+
- stage: Build_MSI
65+
displayName: Build MSI installer
66+
dependsOn: Sign
67+
condition: and(succeeded(), eq(variables['DoMSI'], 'true'))
68+
jobs:
69+
- template: windows-release/stage-msi.yml
70+
71+
- stage: Test_MSI
72+
displayName: Test MSI installer
73+
dependsOn: Build_MSI
74+
jobs:
75+
- template: windows-release/stage-test-msi.yml
76+
77+
- stage: PublishPyDotOrg
78+
displayName: Publish to python.org
79+
dependsOn: ['Test_MSI', 'Test']
80+
condition: and(succeeded(), eq(variables['DoPublish'], 'true'))
81+
jobs:
82+
- template: windows-release/stage-publish-pythonorg.yml
83+
84+
- stage: PublishNuget
85+
displayName: Publish to nuget.org
86+
dependsOn: Test
87+
condition: and(succeeded(), eq(variables['DoPublish'], 'true'))
88+
jobs:
89+
- template: windows-release/stage-publish-nugetorg.yml
90+
91+
- stage: PublishStore
92+
displayName: Publish to Store
93+
dependsOn: Pack_MSIX
94+
condition: and(succeeded(), eq(variables['DoPublish'], 'true'))
95+
jobs:
96+
- template: windows-release/stage-publish-store.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
parameters:
2+
ShouldPGO: false
3+
4+
steps:
5+
- template: ./checkout.yml
6+
7+
- powershell: |
8+
$d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }};
9+
Write-Host "##vso[task.setvariable variable=VersionText]$($d.PythonVersion)"
10+
Write-Host "##vso[task.setvariable variable=VersionNumber]$($d.PythonVersionNumber)"
11+
Write-Host "##vso[task.setvariable variable=VersionHex]$($d.PythonVersionHex)"
12+
Write-Host "##vso[task.setvariable variable=VersionUnique]$($d.PythonVersionUnique)"
13+
Write-Host "##vso[build.addbuildtag]$($d.PythonVersion)"
14+
Write-Host "##vso[build.addbuildtag]$($d.PythonVersion)-$(Name)"
15+
displayName: 'Extract version numbers'
16+
17+
- ${{ if eq(parameters.ShouldPGO, 'false') }}:
18+
- powershell: |
19+
$env:SigningCertificate = $null
20+
.\PCbuild\build.bat -v -p $(Platform) -c $(Configuration)
21+
displayName: 'Run build'
22+
env:
23+
IncludeUwp: true
24+
Py_OutDir: '$(Build.BinariesDirectory)\bin'
25+
26+
- ${{ if eq(parameters.ShouldPGO, 'true') }}:
27+
- powershell: |
28+
$env:SigningCertificate = $null
29+
.\PCbuild\build.bat -v -p $(Platform) --pgo
30+
displayName: 'Run build with PGO'
31+
env:
32+
IncludeUwp: true
33+
Py_OutDir: '$(Build.BinariesDirectory)\bin'
34+
35+
- powershell: |
36+
$kitroot = (gp 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\').KitsRoot10
37+
$tool = (gci -r "$kitroot\Bin\*\x64\signtool.exe" | sort FullName -Desc | select -First 1)
38+
if (-not $tool) {
39+
throw "SDK is not available"
40+
}
41+
Write-Host "##vso[task.prependpath]$($tool.Directory)"
42+
displayName: 'Add WinSDK tools to path'
43+
44+
- powershell: |
45+
$env:SigningCertificate = $null
46+
.\python.bat PC\layout -vv -t "$(Build.BinariesDirectory)\catalog" --catalog "${env:CAT}.cdf" --preset-default
47+
makecat "${env:CAT}.cdf"
48+
del "${env:CAT}.cdf"
49+
if (-not (Test-Path "${env:CAT}.cat")) {
50+
throw "Failed to build catalog file"
51+
}
52+
displayName: 'Generate catalog'
53+
env:
54+
CAT: $(Build.BinariesDirectory)\bin\$(Arch)\python
55+
56+
- task: PublishBuildArtifacts@1
57+
displayName: 'Publish binaries'
58+
condition: and(succeeded(), not(and(eq(variables['Configuration'], 'Release'), variables['SigningCertificate'])))
59+
inputs:
60+
PathtoPublish: '$(Build.BinariesDirectory)\bin\$(Arch)'
61+
ArtifactName: bin_$(Name)
62+
63+
- task: PublishBuildArtifacts@1
64+
displayName: 'Publish binaries for signing'
65+
condition: and(succeeded(), and(eq(variables['Configuration'], 'Release'), variables['SigningCertificate']))
66+
inputs:
67+
PathtoPublish: '$(Build.BinariesDirectory)\bin\$(Arch)'
68+
ArtifactName: unsigned_bin_$(Name)
69+
70+
- task: CopyFiles@2
71+
displayName: 'Layout Artifact: symbols'
72+
inputs:
73+
sourceFolder: $(Build.BinariesDirectory)\bin\$(Arch)
74+
targetFolder: $(Build.ArtifactStagingDirectory)\symbols\$(Name)
75+
flatten: true
76+
contents: |
77+
**\*.pdb
78+
79+
- task: PublishBuildArtifacts@1
80+
displayName: 'Publish Artifact: symbols'
81+
inputs:
82+
PathToPublish: '$(Build.ArtifactStagingDirectory)\symbols'
83+
ArtifactName: symbols
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
parameters:
2+
depth: 3
3+
4+
steps:
5+
- checkout: none
6+
7+
- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(SourceTag) --single-branch https://github.com/$(GitRemote)/cpython.git .
8+
displayName: 'git clone ($(GitRemote)/$(SourceTag))'
9+
condition: and(succeeded(), and(variables['GitRemote'], variables['SourceTag']))
10+
11+
- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(SourceTag) --single-branch $(Build.Repository.Uri) .
12+
displayName: 'git clone (<default>/$(SourceTag))'
13+
condition: and(succeeded(), and(not(variables['GitRemote']), variables['SourceTag']))
14+
15+
- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(Build.SourceBranchName) --single-branch https://github.com/$(GitRemote)/cpython.git .
16+
displayName: 'git clone ($(GitRemote)/<default>)'
17+
condition: and(succeeded(), and(variables['GitRemote'], not(variables['SourceTag'])))
18+
19+
- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(Build.SourceBranchName) --single-branch $(Build.Repository.Uri) .
20+
displayName: 'git clone'
21+
condition: and(succeeded(), and(not(variables['GitRemote']), not(variables['SourceTag'])))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Locate the Windows SDK and add its binaries directory to PATH
2+
#
3+
# `toolname` can be overridden to use a different marker file.
4+
5+
parameters:
6+
toolname: signtool.exe
7+
8+
steps:
9+
- powershell: |
10+
$kitroot = (gp 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\').KitsRoot10
11+
$tool = (gci -r "$kitroot\Bin\*\${{ parameters.toolname }}" | sort FullName -Desc | select -First 1)
12+
if (-not $tool) {
13+
throw "SDK is not available"
14+
}
15+
Write-Host "##vso[task.prependpath]$($tool.Directory)"
16+
Write-Host "Adding $($tool.Directory) to PATH"
17+
displayName: 'Add WinSDK tools to path'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
steps:
2+
- powershell: >
3+
Write-Host (
4+
'##vso[task.setvariable variable=LayoutCmd]&
5+
"{0}"
6+
"{1}\PC\layout"
7+
-vv
8+
--source "{1}"
9+
--build "{2}"
10+
--temp "{3}"
11+
--include-cat "{2}\python.cat"
12+
--doc-build "{4}"'
13+
-f (
14+
"$(PYTHON)",
15+
"$(Build.SourcesDirectory)",
16+
(Split-Path -Parent "$(PYTHON)"),
17+
"$(Build.BinariesDirectory)\layout-temp",
18+
"$(Build.BinariesDirectory)\doc"
19+
))
20+
displayName: 'Set LayoutCmd'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
parameters:
2+
DllToolOpt: -m i386:x86-64
3+
#DllToolOpt: -m i386 --as-flags=--32
4+
5+
steps:
6+
- powershell: |
7+
git clone https://github.com/python/cpython-bin-deps --branch binutils --single-branch --depth 1 --progress -v "binutils"
8+
gci "bin\$(Arch)\python*.dll" | %{
9+
& "binutils\gendef.exe" $_ | Out-File -Encoding ascii tmp.def
10+
& "binutils\dlltool.exe" --dllname $($_.BaseName).dll --def tmp.def --output-lib "$($_.Directory)\lib$($_.BaseName).a" ${{ parameters.DllToolOpt }}
11+
}
12+
displayName: 'Generate MinGW import library'
13+
workingDirectory: $(Build.BinariesDirectory)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
steps:
2+
- template: ./checkout.yml
3+
4+
- task: DownloadBuildArtifacts@0
5+
displayName: 'Download artifact: doc'
6+
inputs:
7+
artifactName: doc
8+
downloadPath: $(Build.BinariesDirectory)
9+
10+
- task: CopyFiles@2
11+
displayName: 'Merge documentation files'
12+
inputs:
13+
sourceFolder: $(Build.BinariesDirectory)\doc
14+
targetFolder: $(Build.SourcesDirectory)\Doc\build
15+
contents: |
16+
htmlhelp\*.chm
17+
18+
- task: DownloadBuildArtifacts@0
19+
displayName: 'Download artifact: bin_win32'
20+
inputs:
21+
artifactName: bin_win32
22+
downloadPath: $(Build.BinariesDirectory)
23+
24+
- task: DownloadBuildArtifacts@0
25+
displayName: 'Download artifact: bin_win32_d'
26+
inputs:
27+
artifactName: bin_win32_d
28+
downloadPath: $(Build.BinariesDirectory)
29+
30+
- task: CopyFiles@2
31+
displayName: 'Merge win32 debug files'
32+
inputs:
33+
sourceFolder: $(Build.BinariesDirectory)\bin_win32_d
34+
targetFolder: $(Build.BinariesDirectory)\bin_win32
35+
contents: |
36+
**\*_d.*
37+
38+
- task: DownloadBuildArtifacts@0
39+
displayName: 'Download artifact: bin_amd64'
40+
inputs:
41+
artifactName: bin_amd64
42+
downloadPath: $(Build.BinariesDirectory)
43+
44+
- task: DownloadBuildArtifacts@0
45+
displayName: 'Download artifact: bin_amd64_d'
46+
inputs:
47+
artifactName: bin_amd64_d
48+
downloadPath: $(Build.BinariesDirectory)
49+
50+
- task: CopyFiles@2
51+
displayName: 'Merge amd64 debug files'
52+
inputs:
53+
sourceFolder: $(Build.BinariesDirectory)\bin_amd64_d
54+
targetFolder: $(Build.BinariesDirectory)\bin_amd64
55+
contents: |
56+
**\*_d.*
57+
58+
- task: DownloadBuildArtifacts@0
59+
displayName: 'Download artifact: tcltk_lib_win32'
60+
inputs:
61+
artifactName: tcltk_lib_win32
62+
downloadPath: $(Build.BinariesDirectory)
63+
64+
- task: DownloadBuildArtifacts@0
65+
displayName: 'Download artifact: tcltk_lib_amd64'
66+
inputs:
67+
artifactName: tcltk_lib_amd64
68+
downloadPath: $(Build.BinariesDirectory)
69+
70+
- script: |
71+
ren bin_win32 win32
72+
ren bin_amd64 amd64
73+
displayName: 'Correct artifact directory names'
74+
workingDirectory: $(Build.BinariesDirectory)
75+
76+
- script: |
77+
call Tools\msi\get_externals.bat
78+
call PCbuild\find_python.bat
79+
echo ##vso[task.setvariable variable=PYTHON]%PYTHON%
80+
call PCbuild/find_msbuild.bat
81+
echo ##vso[task.setvariable variable=MSBUILD]%MSBUILD%
82+
displayName: 'Get external dependencies'
83+
84+
- script: |
85+
%PYTHON% -m pip install blurb
86+
%PYTHON% -m blurb merge -f Misc\NEWS
87+
displayName: 'Merge NEWS file'
88+
89+
- script: |
90+
%MSBUILD% Tools\msi\launcher\launcher.wixproj
91+
displayName: 'Build launcher installer'
92+
env:
93+
Platform: x86
94+
Py_OutDir: $(Build.BinariesDirectory)
95+
96+
- script: |
97+
%MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true /p:BuildForRelease=true
98+
%MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false /p:BuildForRelease=true
99+
displayName: 'Build win32 installer'
100+
env:
101+
Platform: x86
102+
Py_OutDir: $(Build.BinariesDirectory)
103+
PYTHON: $(Build.BinariesDirectory)\win32\python.exe
104+
PYTHONHOME: $(Build.SourcesDirectory)
105+
TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_win32
106+
107+
- script: |
108+
%MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true /p:BuildForRelease=true
109+
%MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false /p:BuildForRelease=true
110+
displayName: 'Build amd64 installer'
111+
env:
112+
Platform: x64
113+
Py_OutDir: $(Build.BinariesDirectory)
114+
PYTHON: $(Build.BinariesDirectory)\amd64\python.exe
115+
PYTHONHOME: $(Build.SourcesDirectory)
116+
TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_amd64
117+
118+
- task: CopyFiles@2
119+
displayName: 'Assemble artifact: msi (1/2)'
120+
inputs:
121+
sourceFolder: $(Build.BinariesDirectory)\win32\en-us
122+
targetFolder: $(Build.ArtifactStagingDirectory)\msi\win32
123+
contents: |
124+
*.msi
125+
*.cab
126+
*.exe
127+
128+
- task: CopyFiles@2
129+
displayName: 'Assemble artifact: msi (2/2)'
130+
inputs:
131+
sourceFolder: $(Build.BinariesDirectory)\amd64\en-us
132+
targetFolder: $(Build.ArtifactStagingDirectory)\msi\amd64
133+
contents: |
134+
*.msi
135+
*.cab
136+
*.exe
137+
138+
- task: PublishBuildArtifacts@1
139+
displayName: 'Publish MSI'
140+
inputs:
141+
PathtoPublish: '$(Build.ArtifactStagingDirectory)\msi'
142+
ArtifactName: msi

0 commit comments

Comments
 (0)