Skip to content

Commit 7e74664

Browse files
author
Release Manager
committed
gh-36435: Retrieve upstream tarballs from GitHub release assets <!-- ^^^^^ Please provide a concise, informative and self-explanatory title. Don't put issue numbers in there, do this in the PR body below. For example, instead of "Fixes #1234" use "Introduce new method to calculate 1+1" --> <!-- Describe your changes here in detail --> We propose to add GitHub release assets as a source from which upstream tarballs can be retrieved. This would take priority over trying the Sage mirrors, thus reducing the reliance of the project on self-maintained file servers. https://docs.github.com/en/repositories/releasing- projects-on-github/about-releases#storage-and-bandwidth-quotas For the purpose of testing this PR, one tarball missing on the mirrors (#36381 (comment)) has been uploaded to https://github.com/sagemath/sage/releases/tag/10.1 Creating GitHub releases and depositing the upstream tarballs can later be automated in a GH Actions workflow, e.g., using https://github.com/softprops/action-gh-release. As we don't make GitHub releases for beta versions, the previous stable release can be used. <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes #12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> <!-- Feel free to remove irrelevant items. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation accordingly. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - #12345: short description why this is a dependency - #34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> URL: #36435 Reported by: Matthias Köppe Reviewer(s): Dima Pasechnik, John H. Palmieri, Matthias Köppe
2 parents dcaf556 + 423e48a commit 7e74664

File tree

7 files changed

+95
-16
lines changed

7 files changed

+95
-16
lines changed

.upstream.d/10-SAGE_SERVER

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# When SAGE_SERVER is set, it should be an https/https server in the format of Sage mirrors.
2+
${SAGE_SERVER}/spkg/upstream/${SPKG}/
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Upstream packages as uploaded as GitHub release assets.
2+
# This file is automatically updated by the sage-update-version script.
3+
https://github.com/sagemath/sage/releases/download/10.1/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://www.sagemath.org/mirror_list

build/bin/write-dockerfile.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ $ADD src/Pipfile.m4 src/pyproject.toml.m4 src/requirements.txt.m4 src/setup.cfg.
226226
$ADD m4 ./m4
227227
$ADD pkgs pkgs
228228
$ADD build ./build
229+
$ADD .upstream.d ./.upstream.d
229230
ARG BOOTSTRAP=./bootstrap
230231
$RUN sh -x -c "\${BOOTSTRAP}" $ENDRUN
231232

build/sage_bootstrap/download/mirror_list.py

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
log = logging.getLogger()
2020

2121
from sage_bootstrap.compat import urllib, urlparse
22-
from sage_bootstrap.env import SAGE_DISTFILES
22+
from sage_bootstrap.env import SAGE_DISTFILES, SAGE_ROOT
2323

2424
from fcntl import flock, LOCK_SH, LOCK_EX
2525
from errno import ENOLCK
@@ -41,17 +41,66 @@ class MirrorListException(RuntimeError):
4141
pass
4242

4343

44-
MIRRORLIST_FILENAME = os.path.join(SAGE_DISTFILES, 'mirror_list')
44+
class MirrorList(object):
4545

46+
def __init__(self):
47+
self.sources = []
48+
upstream_d = os.path.join(SAGE_ROOT, '.upstream.d')
49+
for fname in sorted(os.listdir(upstream_d)):
50+
if '~' in fname or '#' in fname:
51+
# Ignore auto-save and backup files
52+
continue
53+
try:
54+
with open(os.path.join(upstream_d, fname), 'r') as f:
55+
for line in f:
56+
line = line.strip()
57+
if line.startswith('#'):
58+
continue
59+
if not line:
60+
continue
61+
line = line.replace('${SAGE_ROOT}', SAGE_ROOT)
62+
line = line.replace('${SAGE_DISTFILES}', SAGE_DISTFILES)
63+
if '${SAGE_SERVER}' in line:
64+
SAGE_SERVER = os.environ.get("SAGE_SERVER", "")
65+
if not SAGE_SERVER:
66+
continue
67+
line = line.replace('${SAGE_SERVER}', SAGE_SERVER)
68+
if line.endswith('mirror_list'):
69+
cache_filename = os.path.join(SAGE_DISTFILES, line.rpartition('/')[2])
70+
self.sources.append(MirrorList_from_url(line, cache_filename))
71+
else:
72+
self.sources.append([line])
73+
except IOError:
74+
# Silently ignore files that do not exist
75+
pass
4676

47-
class MirrorList(object):
77+
def __iter__(self):
78+
"""
79+
Iterate through the list of mirrors.
80+
81+
This is the main entry point into the mirror list. Every
82+
script should just use this function to try mirrors in order
83+
of preference. This will not just yield the official mirrors,
84+
but also urls for packages that are currently being tested.
85+
"""
86+
for source in self.sources:
87+
for mirror in source:
88+
yield mirror
89+
90+
91+
class MirrorList_from_url(object):
4892

49-
URL = 'http://www.sagemath.org/mirror_list'
5093
MAXAGE = 24*60*60 # seconds
5194

52-
def __init__(self):
53-
self.filename = MIRRORLIST_FILENAME
54-
self.mirrors = None
95+
def __init__(self, url, filename):
96+
self.url = url
97+
self.filename = filename
98+
self._mirrors = None
99+
100+
@property
101+
def mirrors(self):
102+
if self._mirrors is not None:
103+
return self._mirrors
55104

56105
try:
57106
self.mirrorfile = open(self.filename, 'r+t')
@@ -67,8 +116,10 @@ def __init__(self):
67116
# process while we waited for the lock? Check again.
68117
if self._must_refresh():
69118
self._refresh()
70-
if self.mirrors is None:
71-
self.mirrors = self._load()
119+
if self._mirrors is None:
120+
self._mirrors = self._load()
121+
122+
return self._mirrors
72123

73124
def _load(self, mirror_list=None):
74125
"""
@@ -147,7 +198,7 @@ def _rank_mirrors(self):
147198
log.info('Cannot time mirrors via proxy, using default order')
148199
else:
149200
timed_mirrors.sort()
150-
self.mirrors = [m[1] for m in timed_mirrors]
201+
self._mirrors = [m[1] for m in timed_mirrors]
151202
log.info('Fastest mirror: ' + self.fastest)
152203

153204
def _age(self):
@@ -176,12 +227,12 @@ def _refresh(self):
176227
"""
177228
log.info('Downloading the Sage mirror list')
178229
try:
179-
with contextlib.closing(urllib.urlopen(self.URL)) as f:
230+
with contextlib.closing(urllib.urlopen(self.url)) as f:
180231
mirror_list = f.read().decode("ascii")
181232
except IOError:
182233
log.critical('Downloading the mirror list failed, using cached version')
183234
else:
184-
self.mirrors = self._load(mirror_list)
235+
self._mirrors = self._load(mirror_list)
185236
self._rank_mirrors()
186237
self._save()
187238

@@ -199,9 +250,9 @@ def __iter__(self):
199250
except KeyError:
200251
pass
201252
for mirror in self.mirrors:
202-
yield mirror
203-
# If all else fails: Try the packages we host ourselves
204-
yield 'http://sagepad.org/'
253+
if not mirror.endswith('/'):
254+
mirror += '/'
255+
yield mirror + '/'.join(['spkg', 'upstream', '${SPKG}'])
205256

206257
@property
207258
def fastest(self):

build/sage_bootstrap/tarball.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,10 @@ def download(self, allow_upstream=False):
159159
successful_download = False
160160
log.info('Attempting to download package {0} from mirrors'.format(self.filename))
161161
for mirror in MirrorList():
162-
url = mirror + '/'.join(['spkg', 'upstream', self.package.name, self.filename])
162+
url = mirror.replace('${SPKG}', self.package.name)
163+
if not url.endswith('/'):
164+
url += '/'
165+
url += self.filename
163166
log.info(url)
164167
try:
165168
Download(url, destination).run()

src/bin/sage-update-version

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,23 @@ EOF
8787
# Create a top-level VERSION.txt file, which some external utilities rely on
8888
echo "$SAGE_VERSION_BANNER" > "$SAGE_ROOT/VERSION.txt"
8989

90+
# Add version to the front of GitHub release assets URLs.
91+
SAGE_MINOR_VERSION=${SAGE_VERSION//.alpha*/}
92+
SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.beta*/}
93+
SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.dev*/}
94+
SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.post*/}
95+
SAGE_MINOR_VERSION=${SAGE_MINOR_VERSION//.rc*/}
96+
( echo "https://github.com/sagemath/sage/releases/download/$SAGE_MINOR_VERSION/"
97+
sed '/^#/d' "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases"
98+
) | uniq | head -n 3 > "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases.tmp"
99+
( cat <<EOF
100+
# Upstream packages as uploaded as GitHub release assets.
101+
# This file is automatically updated by the sage-update-version script.
102+
EOF
103+
cat "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases.tmp"
104+
) > "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases"
105+
rm -f "$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases.tmp"
106+
90107
# Regenerate auto-generated files tarball
91108
"$SAGE_ROOT/bootstrap" -s
92109

@@ -106,6 +123,7 @@ git commit -m "Updated SageMath version to $SAGE_VERSION" -- \
106123
"$SAGE_ROOT/build/pkgs/configure/package-version.txt" \
107124
"$SAGE_ROOT/build/pkgs/*/install-requires.txt" \
108125
"$SAGE_ROOT"/pkgs/*/VERSION.txt \
126+
"$SAGE_ROOT/.upstream.d/20-github.com-sagemath-sage-releases" \
109127
|| die "Error committing to the repository."
110128

111129
git tag -a "$SAGE_VERSION" -m "$SAGE_VERSION_BANNER" \

0 commit comments

Comments
 (0)