Skip to content

Commit 596dd04

Browse files
committed
Add parallel update path for prereleases.
1 parent 780374b commit 596dd04

File tree

4 files changed

+54
-16
lines changed

4 files changed

+54
-16
lines changed

_msbuild.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def main_exe(name):
102102
ItemDefinition('Link',
103103
SubSystem='CONSOLE',
104104
DelayLoadDLLs=f'{DLL_NAME}.dll;ole32.dll;shell32.dll;advapi32.dll',
105-
DisableSpecificWarnings=Prepend('4199;'),
105+
AdditionalOptions=Prepend('/IGNORE:4199 '),
106106
),
107107
INCLUDE_TMPDIR,
108108
Manifest('default.manifest'),
@@ -124,7 +124,7 @@ def mainw_exe(name):
124124
ItemDefinition('Link',
125125
SubSystem='WINDOWS',
126126
DelayLoadDLLs=f'{DLL_NAME}.dll;ole32.dll;shell32.dll;advapi32.dll',
127-
DisableSpecificWarnings=Prepend('4199;'),
127+
AdditionalOptions=Prepend('/IGNORE:4199 '),
128128
),
129129
INCLUDE_TMPDIR,
130130
ItemDefinition('ClCompile', PreprocessorDefinitions=Prepend(f'EXE_NAME=L"{name}";')),
@@ -296,6 +296,12 @@ def _make_xyzw_version(v, sep="."):
296296
return sep.join(map(str, (v.major, v.minor, micro, 0)))
297297

298298

299+
def _is_prerelease(v):
300+
from packaging.version import parse
301+
v = parse(v)
302+
return bool(v.pre)
303+
304+
299305
def _patch_appx_identity(source, dest, **new):
300306
from xml.etree import ElementTree as ET
301307
NS = {}
@@ -335,7 +341,7 @@ def update_file(file, content):
335341
def init_METADATA():
336342
import os, re
337343
_, sep, version = os.getenv("BUILD_SOURCEBRANCH", os.getenv("GITHUB_REF", "")).rpartition("/")
338-
if sep and "." in version:
344+
if "." in version:
339345
from packaging.version import parse
340346
try:
341347
# Looks like a version tag
@@ -359,6 +365,8 @@ def init_PACKAGE(tag=None):
359365
tmpdir = get_current_build_state().temp_dir
360366
INCLUDE_TMPDIR.options["AdditionalIncludeDirectories"] = Prepend(f"{tmpdir};")
361367

368+
pre = _is_prerelease(METADATA["Version"])
369+
362370
# GENERATE _version MODULE
363371
ver_py = tmpdir / "_version.py"
364372
update_file(ver_py, f"__version__ = {METADATA['Version']!r}")
@@ -384,6 +392,9 @@ def init_PACKAGE(tag=None):
384392

385393
appinstaller = tmpdir / "pymanager.appinstaller"
386394
_patch_appinstaller(PACKAGE.find("pymanager.appinstaller").source, appinstaller,
395+
# Prerelease builds use a separate online appinstaller file
396+
# Release builds upload to both files, to move beta users onto final
397+
AppInstallerName="pymanager-preview" if pre else "pymanager",
387398
Version=appx_version,
388399
Publisher=appx_publisher,
389400
Url=appx_url,

ci/upload.py

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
UPLOAD_URL_PREFIX = os.getenv("UPLOAD_URL_PREFIX", "https://www.python.org/ftp/")
99
UPLOAD_PATH_PREFIX = os.getenv("UPLOAD_PATH_PREFIX", "/srv/www.python.org/ftp/")
1010
UPLOAD_URL = os.getenv("UPLOAD_URL")
11-
UPLOAD_DIR = os.getenv("UPLOAD_DIR")
11+
UPLOAD_DIR = os.getenv("UPLOAD_DIR", "dist")
1212
UPLOAD_HOST = os.getenv("UPLOAD_HOST", "")
1313
UPLOAD_HOST_KEY = os.getenv("UPLOAD_HOST_KEY", "")
1414
UPLOAD_KEYFILE = os.getenv("UPLOAD_KEYFILE", "")
@@ -126,6 +126,25 @@ def url2path(url):
126126
return UPLOAD_PATH_PREFIX + url[len(UPLOAD_URL_PREFIX) :]
127127

128128

129+
def appinstaller_uri_matches(file, name):
130+
NS = {}
131+
with open(file, "r", encoding="utf-8") as f:
132+
NS = dict(e for _, e in ET.iterparse(f, events=("start-ns",)))
133+
for k, v in NS.items():
134+
ET.register_namespace(k, v)
135+
NS["x"] = NS[""]
136+
137+
with open(file, "r", encoding="utf-8") as f:
138+
xml = ET.parse(f)
139+
140+
self_uri = xml.find(".[@Uri]", NS).get("Uri")
141+
if not self_uri:
142+
print("##[error]Empty Uri attribute in appinstaller file")
143+
sys.exit(2)
144+
145+
return self_uri.rpartition("/")[2].casefold() == name.casefold()
146+
147+
129148
def validate_appinstaller(file, uploads):
130149
NS = {}
131150
with open(file, "r", encoding="utf-8") as f:
@@ -141,10 +160,8 @@ def validate_appinstaller(file, uploads):
141160
if not self_uri:
142161
print("##[error]Empty Uri attribute in appinstaller file")
143162
sys.exit(2)
144-
if not any(
145-
u.casefold() == self_uri.casefold() and f == file
146-
for f, u, _ in uploads
147-
):
163+
upload_targets = [u for f, u, _ in uploads if f == file]
164+
if not any(u.casefold() == self_uri.casefold() for u in upload_targets):
148165
print("##[error]Uri", self_uri, "in appinstaller file is not where "
149166
"the appinstaller file is being uploaded.")
150167
sys.exit(2)
@@ -164,6 +181,8 @@ def validate_appinstaller(file, uploads):
164181
print(file, "checked:")
165182
print("-", package_uri, "is part of this upload")
166183
print("-", self_uri, "is the destination of this file")
184+
if len(upload_targets) > 1:
185+
print(" - other destinations:", *(set(upload_targets) - set([self_uri])))
167186
print()
168187

169188

@@ -185,20 +204,29 @@ def purge(url):
185204
u = UPLOAD_URL + f.name
186205
UPLOADS.append((f, u, url2path(u)))
187206
else:
188-
for pat in ("python-manager-*.msix", "python-manager-*.msi", "pymanager.appinstaller"):
207+
for pat in ("python-manager-*.msix", "python-manager-*.msi"):
189208
for f in UPLOAD_DIR.glob(pat):
190209
u = UPLOAD_URL + f.name
191210
UPLOADS.append((f, u, url2path(u)))
192211

212+
# pymanager.appinstaller may be uploaded to either the preview URL or both.
213+
f = UPLOAD_DIR / "pymanager.appinstaller"
214+
if f.is_file():
215+
u = UPLOAD_URL + "pymanager-preview.appinstaller"
216+
UPLOADS.append((f, u, url2path(u)))
217+
218+
if not appinstaller_uri_matches(f, "pymanager-preview.appinstaller"):
219+
u = UPLOAD_URL + f.name
220+
UPLOADS.append((f, u, url2path(u)))
221+
193222
print("Planned uploads:")
194223
for f, u, p in UPLOADS:
195224
print(f"{f} -> {p}")
196225
print(f" Final URL: {u}")
197226
print()
198227

199-
for f, *_ in UPLOADS:
200-
if f.match("*.appinstaller"):
201-
validate_appinstaller(f, UPLOADS)
228+
for f in {f for f, *_ in UPLOADS if f.match("*.appinstaller")}:
229+
validate_appinstaller(f, UPLOADS)
202230

203231
for f, u, p in UPLOADS:
204232
print("Upload", f, "to", p)

make.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@
2121

2222
ref = "none"
2323
try:
24-
if os.getenv("BUILD_SOURCEBRANCH"):
25-
ref = os.getenv("BUILD_SOURCEBRANCH")
26-
else:
24+
ref = os.getenv("BUILD_SOURCEBRANCH", os.getenv("GITHUB_REF", ""))
25+
if not ref:
2726
with subprocess.Popen(
2827
["git", "describe", "HEAD", "--tags"],
2928
stdout=subprocess.PIPE,

src/pymanager/pymanager.appinstaller

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<AppInstaller
33
xmlns="http://schemas.microsoft.com/appx/appinstaller/2018"
44
Version="${Version}"
5-
Uri="${Url}/pymanager.appinstaller">
5+
Uri="${Url}/${AppInstallerName}.appinstaller">
66

77
<MainPackage
88
Name="PythonSoftwareFoundation.PythonManager"

0 commit comments

Comments
 (0)