Prepare v1.0.0 with rebuilt runtimes and HD coverage note

This commit is contained in:
raptorreplica committed 2026-10-21 18:30:15 +11:00
1 parent ea6e937b91
commit cd31949383
18 files changed
+357 -42

No files matched your search

+51
View File
@@ -97,5 +97,56 @@ class FrozenDraftUploadTests(unittest.TestCase):
upload.DraftExporter(package, state, root / 'single')
class ConfigurableReleaseTargetTests(unittest.TestCase):
def test_stable_and_preview_guards_require_the_explicit_expected_state(self):
stable = upload.ReleaseTarget('c' * 40, 'v1.0.0', 12345, False)
release = {'id': 12345, 'tag_name': 'v1.0.0', 'target_commitish': 'c' * 40,
'draft': True, 'prerelease': False}
upload.checked_release(release, stable)
with self.assertRaises(ValueError):
upload.checked_release(dict(release, prerelease=True), stable)
with self.assertRaises(ValueError):
upload.checked_release(release) # Legacy preview defaults cannot match stable.
reference = {'ref': 'refs/tags/v1.0.0', 'object': {'type': 'commit', 'sha': 'c' * 40}}
upload.checked_tag(reference, target=stable)
with self.assertRaises(ValueError):
upload.checked_tag(dict(reference, object={'type': 'commit', 'sha': upload.COMMIT}), target=stable)
def test_invalid_exact_release_inputs_fail_before_any_directory_or_upload(self):
for values in (("main", 'v1.0.0', 123, False), ('A' * 40, 'v1.0.0', 123, False),
('c' * 40, '../v1', 123, False), ('c' * 40, 'v1/other', 123, False),
('c' * 40, 'v1.0.0', 0, False), ('c' * 40, 'v1.0.0', True, False),
('c' * 40, 'v1.0.0', 123, 'false')):
with self.subTest(values=values), self.assertRaises(ValueError):
upload.ReleaseTarget(*values)
def test_explicit_release_routes_api_and_upload_to_its_exact_id_and_tag(self):
target = upload.ReleaseTarget('c' * 40, 'v1.0.0', 12345, False)
with tempfile.TemporaryDirectory() as temp:
root = Path(temp)
package = root / 'frozen'
package.mkdir()
controller = upload.DraftExporter(package, root / 'state', root / 'single', target)
reference = {'ref': 'refs/tags/v1.0.0', 'object': {'type': 'commit', 'sha': 'c' * 40}}
release = {'id': 12345, 'tag_name': 'v1.0.0', 'target_commitish': 'c' * 40,
'draft': True, 'prerelease': False, 'assets': []}
with patch.object(controller, 'api', side_effect=[reference, release]) as api:
self.assertEqual(controller.release(), release)
self.assertEqual(api.call_args_list[0].args[0], 'repos/Quintine/RustRaptor/git/ref/tags/v1.0.0')
self.assertEqual(api.call_args_list[1].args[0], 'repos/Quintine/RustRaptor/releases/12345')
archive = root / 'single/one.zip'
archive.write_bytes(b'fixture')
wrong = {'name': 'one.zip', 'size': archive.stat().st_size, 'state': 'uploaded', 'digest': 'sha256:' + '0' * 64}
with patch.object(controller, 'snapshot'), patch.object(controller, 'release', return_value=release), \
patch.object(controller, 'log'), patch.object(upload.subprocess, 'run') as run:
run.return_value.returncode = 0
run.return_value.stdout = json.dumps(wrong)
run.return_value.stderr = ''
with self.assertRaises(ValueError):
controller.upload(archive, 'one.zip', upload.digest(archive), archive.stat().st_size)
self.assertIn('/releases/12345/assets?name=one.zip', run.call_args.args[0][4])
self.assertTrue(archive.exists())
if __name__ == '__main__':
unittest.main()
+50 -23
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Export the frozen preview to its existing empty draft; never publish it."""
"""Export an exact frozen release to its existing empty draft; never publish it."""
import argparse
import hashlib
import json
@@ -9,16 +9,37 @@ import subprocess
import sys
import time
from pathlib import Path
from dataclasses import dataclass
from urllib.parse import quote
REPO = 'Quintine/RustRaptor'
TAG = 'v0.1.0-preview.20261020'
COMMIT = '7ecaa42b29ff0db5d2f7cdfe6da0a3221dfea555'
RELEASE_ID = 418286902
UPLOAD_URL = f'https://uploads.github.com/repos/{REPO}/releases/{RELEASE_ID}/assets'
FLOOR = 1_800_000_000
@dataclass(frozen=True)
class ReleaseTarget:
commit: str = COMMIT
tag: str = TAG
release_id: int = RELEASE_ID
prerelease: bool = True
def __post_init__(self):
if not isinstance(self.commit, str) or not re.fullmatch('[0-9a-f]{40}', self.commit):
raise ValueError('release commit must be an exact lowercase 40-character SHA')
if not isinstance(self.tag, str) or not re.fullmatch(r'v[0-9A-Za-z._-]+', self.tag):
raise ValueError('release tag must be a safe exact version tag')
if type(self.release_id) is not int or self.release_id <= 0:
raise ValueError('release ID must be a positive integer')
if type(self.prerelease) is not bool:
raise ValueError('prerelease expectation must be a boolean')
PREVIEW_TARGET = ReleaseTarget()
def digest(path):
with Path(path).open('rb') as stream:
return hashlib.file_digest(stream, 'sha256').hexdigest()
@@ -30,24 +51,24 @@ def write_json(path, value):
stream.write('\n')
def checked_release(release):
if (release.get('id') != RELEASE_ID or release.get('tag_name') != TAG
or release.get('target_commitish') != COMMIT or release.get('draft') is not True
or release.get('prerelease') is not True):
def checked_release(release, target=PREVIEW_TARGET):
if (release.get('id') != target.release_id or release.get('tag_name') != target.tag
or release.get('target_commitish') != target.commit or release.get('draft') is not True
or release.get('prerelease') is not target.prerelease):
raise ValueError('existing release ID/tag/target/draft state differs')
return release
def checked_tag(reference, annotated=None):
if reference.get('ref') != 'refs/tags/' + TAG:
def checked_tag(reference, annotated=None, target=PREVIEW_TARGET):
if reference.get('ref') != 'refs/tags/' + target.tag:
raise ValueError('wrong frozen tag reference')
obj = reference.get('object', {})
if obj.get('type') == 'tag':
if (not isinstance(annotated, dict) or annotated.get('sha') != obj.get('sha')
or annotated.get('tag') != TAG):
or annotated.get('tag') != target.tag):
raise ValueError('annotated tag identity differs')
obj = annotated.get('object', {})
if obj.get('type') != 'commit' or obj.get('sha') != COMMIT:
if obj.get('type') != 'commit' or obj.get('sha') != target.commit:
raise ValueError('frozen tag no longer points to the tested commit')
@@ -70,7 +91,8 @@ def checked_receipt(plan, plan_sha, asset, receipt):
class DraftExporter:
def __init__(self, package, state, temporary):
def __init__(self, package, state, temporary, target=PREVIEW_TARGET):
self.target = target
self.package = package.resolve(strict=True)
self.state = state.absolute()
self.temporary = temporary.absolute()
@@ -98,7 +120,7 @@ class DraftExporter:
return json.loads(subprocess.check_output(['gh', 'api', endpoint], cwd=self.package))
def release(self):
reference = self.api(f'repos/{REPO}/git/ref/tags/{TAG}')
reference = self.api(f'repos/{REPO}/git/ref/tags/{self.target.tag}')
obj = reference.get('object', {})
annotated = None
if obj.get('type') == 'tag':
@@ -106,14 +128,14 @@ class DraftExporter:
if not re.fullmatch('[0-9a-f]{40}', sha):
raise ValueError('unsafe annotated tag SHA')
annotated = self.api(f'repos/{REPO}/git/tags/{sha}')
checked_tag(reference, annotated)
return checked_release(self.api(f'repos/{REPO}/releases/{RELEASE_ID}'))
checked_tag(reference, annotated, self.target)
return checked_release(self.api(f'repos/{REPO}/releases/{self.target.release_id}'), self.target)
def snapshot(self):
actual = {'commit': subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=self.package, text=True).strip(),
'runtime_manifest_sha256': digest(self.package / 'runtime-manifest.json'),
'windows_manifest_sha256': digest(self.package / 'runtime-windows-manifest.json')}
if actual['commit'] != COMMIT or subprocess.check_output(
if actual['commit'] != self.target.commit or subprocess.check_output(
['git', 'status', '--porcelain', '--untracked-files=all'], cwd=self.package):
raise ValueError('frozen source commit or cleanliness differs')
if hasattr(self, 'plan') and actual != self.plan['snapshot']:
@@ -138,7 +160,7 @@ class DraftExporter:
or digest(path) != expected_sha):
raise ValueError('local upload no longer matches authenticated receipt')
self.log('uploading', asset=name, bytes=expected_size, sha256=expected_sha)
result = subprocess.run(['gh', 'api', '--method', 'POST', UPLOAD_URL + '?name=' + quote(name, safe=''),
result = subprocess.run(['gh', 'api', '--method', 'POST', f'https://uploads.github.com/repos/{REPO}/releases/{self.target.release_id}/assets?name=' + quote(name, safe=''),
'--input', str(path), '-H', 'Content-Type: application/octet-stream'],
cwd=self.package, capture_output=True, text=True)
(self.state / (name + '.upload.stdout')).write_text(result.stdout)
@@ -163,12 +185,12 @@ class DraftExporter:
raise ValueError('draft must be completely empty before this one-pass export')
write_json(self.state / 'initial-empty-draft.json', initial)
subprocess.run([sys.executable, '-B', str(self.exporter), 'plan', '--package', str(self.package),
'--expected-commit', COMMIT, '--output', str(self.plan_path)], check=True, cwd=self.package)
'--expected-commit', self.target.commit, '--output', str(self.plan_path)], check=True, cwd=self.package)
self.plan = json.loads(self.plan_path.read_text())
plan_sha = digest(self.plan_path)
if (len(self.plan['assets']) != 9 or self.plan['snapshot']['commit'] != COMMIT
if (len(self.plan['assets']) != 9 or self.plan['snapshot']['commit'] != self.target.commit
or sorted(asset['kind'] for asset in self.plan['assets']) != ['linux'] + ['shared-data'] * 7 + ['windows']):
raise ValueError('frozen preview no longer has exactly the expected nine ZIPs')
raise ValueError('frozen release no longer has exactly the expected nine ZIPs')
for asset in self.plan['assets']:
self.snapshot()
self.remote_members(self.release())
@@ -188,15 +210,15 @@ class DraftExporter:
manifest = self.state / 'release-manifest.json'
subprocess.run([sys.executable, '-B', str(self.exporter), 'checksums', '--plan', str(self.plan_path),
'--receipts', str(self.receipts), '--output', str(sums),
'--manifest-output', str(manifest), '--tag', TAG], check=True, cwd=self.package)
'--manifest-output', str(manifest), '--tag', self.target.tag], check=True, cwd=self.package)
for path in (sums, manifest, self.package / 'release/Install-Linux.sh', self.package / 'release/Install-Windows.ps1'):
self.upload(path, path.name, digest(path), path.stat().st_size)
final = self.release()
self.remote_members(final)
if len(final['assets']) != 13:
raise ValueError('complete preview must contain nine ZIPs plus four companion assets')
raise ValueError('complete release must contain nine ZIPs plus four companion assets')
write_json(self.state / 'final-13-assets-draft-still-unpublished.json', final)
self.log('COMPLETE_THIRTEEN_REMOTE_ASSETS_VERIFIED_DRAFT_NOT_PUBLISHED', checkpoint=COMMIT)
self.log('COMPLETE_THIRTEEN_REMOTE_ASSETS_VERIFIED_DRAFT_NOT_PUBLISHED', checkpoint=self.target.commit)
def main():
@@ -204,8 +226,13 @@ def main():
parser.add_argument('--package', type=Path, required=True)
parser.add_argument('--state', type=Path, required=True)
parser.add_argument('--temporary', type=Path, required=True)
parser.add_argument('--commit', default=COMMIT)
parser.add_argument('--tag', default=TAG)
parser.add_argument('--release-id', type=int, default=RELEASE_ID)
parser.add_argument('--prerelease', choices=('true', 'false'), default='true')
args = parser.parse_args()
DraftExporter(args.package, args.state, args.temporary).run()
target = ReleaseTarget(args.commit, args.tag, args.release_id, args.prerelease == 'true')
DraftExporter(args.package, args.state, args.temporary, target).run()
if __name__ == '__main__':