Changes
This commit is contained in:
@@ -98,6 +98,8 @@ jobs:
|
|||||||
restore-keys: product-vamp-conan-${{ runner.os }}-
|
restore-keys: product-vamp-conan-${{ runner.os }}-
|
||||||
- name: Configure native release
|
- name: Configure native release
|
||||||
run: python3 modulus.py configure --target x86_64_gcc12_release --update
|
run: python3 modulus.py configure --target x86_64_gcc12_release --update
|
||||||
|
- name: Check package tooling
|
||||||
|
run: python3 -m unittest discover -s tests -p 'test_publish_package.py'
|
||||||
- name: Check code style
|
- name: Check code style
|
||||||
run: |
|
run: |
|
||||||
python3 -m pip install --no-cache-dir -r build/build_tools/docker/format-requirements.txt
|
python3 -m pip install --no-cache-dir -r build/build_tools/docker/format-requirements.txt
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ PACKAGE_REGISTRY_TOKEN=<token> \
|
|||||||
python3 package/scripts/publish_latest_generic_package.py
|
python3 package/scripts/publish_latest_generic_package.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Artifacts are published to the khodo generic package registry's required `latest` slot. Publish the updated Modulus tooling before running Product Vamp CI so packaging and publishing agree on the stable filenames.
|
Artifacts are published to the khodo generic package registry's required `latest` slot. Publish the updated Modulus tooling before running Product Vamp CI so packaging and publishing agree on the stable filenames. CI checks this contract immediately after configure using a tiny fixture archive, without compiling or contacting the registry. A failure here means the exported Modulus packager needs updating; rerun the full workflow after publishing Modulus, not just the upload step.
|
||||||
|
|
||||||
## Score Assets
|
## Score Assets
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,10 @@ def discover_artifacts(dist_dir, package_name, targets):
|
|||||||
artifacts.extend((archive, archive.with_name(archive.name + ".sha256")))
|
artifacts.extend((archive, archive.with_name(archive.name + ".sha256")))
|
||||||
missing = [path for path in artifacts if not path.is_file()]
|
missing = [path for path in artifacts if not path.is_file()]
|
||||||
if missing:
|
if missing:
|
||||||
raise SystemExit("missing artifact files: " + ", ".join(str(path) for path in missing))
|
found = sorted(path.name for path in dist_dir.glob(f"{package_name}-*.tar.gz*") if path.is_file())
|
||||||
|
raise SystemExit("missing artifact files: " + ", ".join(str(path) for path in missing)
|
||||||
|
+ "\nFound: " + (", ".join(found) or "none")
|
||||||
|
+ "\nPublish the current Modulus tooling, run configure --update, and recreate the package so the builder and publisher use the same filenames.")
|
||||||
return artifacts
|
return artifacts
|
||||||
|
|
||||||
def upload_file(registry_url, package_name, path, auth):
|
def upload_file(registry_url, package_name, path, auth):
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import hashlib
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tarfile
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -6,6 +10,37 @@ from unittest.mock import patch
|
|||||||
from package.scripts import publish_latest_generic_package
|
from package.scripts import publish_latest_generic_package
|
||||||
|
|
||||||
class PackagePublishingTests(unittest.TestCase):
|
class PackagePublishingTests(unittest.TestCase):
|
||||||
|
def test_configured_packager_matches_publisher(self):
|
||||||
|
root = Path(__file__).resolve().parents[1]
|
||||||
|
runtime = root / 'build/build_common/modulus'
|
||||||
|
if not (runtime / 'modulus/cli.py').is_file():
|
||||||
|
self.skipTest('Configure first to check the exported Modulus packager')
|
||||||
|
with patch.object(sys, 'path', [str(runtime), *sys.path]):
|
||||||
|
import modulus.cli
|
||||||
|
import modulus.config
|
||||||
|
with tempfile.TemporaryDirectory() as temporary:
|
||||||
|
directory = Path(temporary)
|
||||||
|
context = modulus.cli.build_context(directory, modulus.config.load_repo_config(root))
|
||||||
|
name, registry, targets = publish_latest_generic_package.read_config(root / 'modulus.json')
|
||||||
|
def fake_build(context, command, **kwargs):
|
||||||
|
if command[:2] == ['cmake', '--install']:
|
||||||
|
stage = Path(command[2]).parent / 'stage'
|
||||||
|
(stage / 'manifest.json').write_text('{}\n')
|
||||||
|
return 0
|
||||||
|
with patch.object(modulus.cli, 'in_docker', return_value=True), \
|
||||||
|
patch.object(modulus.cli, 'run', side_effect=fake_build), \
|
||||||
|
patch.object(modulus.cli, 'run_capture', return_value=subprocess.CompletedProcess([], 0, stdout='fixture\n', stderr='')), \
|
||||||
|
patch.object(modulus.cli, 'upload_generic_artifact') as upload:
|
||||||
|
self.assertEqual(modulus.cli.package_artifacts(context, ['--no-remote']), 0)
|
||||||
|
upload.assert_not_called()
|
||||||
|
try:
|
||||||
|
artifacts = publish_latest_generic_package.discover_artifacts(directory / 'build/packages', name, targets)
|
||||||
|
except SystemExit as error:
|
||||||
|
self.fail(str(error))
|
||||||
|
for archive, checksum in zip(artifacts[::2], artifacts[1::2]):
|
||||||
|
self.assertEqual(checksum.read_text(), f'{hashlib.sha256(archive.read_bytes()).hexdigest()} {archive.name}\n')
|
||||||
|
with tarfile.open(archive) as package:
|
||||||
|
self.assertIn('manifest.json', package.getnames())
|
||||||
def test_only_configured_target_archives_and_checksums_are_uploaded(self):
|
def test_only_configured_target_archives_and_checksums_are_uploaded(self):
|
||||||
with tempfile.TemporaryDirectory() as temporary:
|
with tempfile.TemporaryDirectory() as temporary:
|
||||||
root = Path(temporary)
|
root = Path(temporary)
|
||||||
@@ -20,6 +55,15 @@ class PackagePublishingTests(unittest.TestCase):
|
|||||||
archive.unlink()
|
archive.unlink()
|
||||||
with self.assertRaisesRegex(SystemExit, 'missing artifact files'):
|
with self.assertRaisesRegex(SystemExit, 'missing artifact files'):
|
||||||
publish_latest_generic_package.discover_artifacts(root, 'product-vamp', ['arm_64_gcc12_release'])
|
publish_latest_generic_package.discover_artifacts(root, 'product-vamp', ['arm_64_gcc12_release'])
|
||||||
|
def test_mismatched_filenames_report_actual_artifacts_without_uploading(self):
|
||||||
|
with tempfile.TemporaryDirectory() as temporary, patch.object(publish_latest_generic_package, 'request') as request:
|
||||||
|
archive = Path(temporary) / 'product-vamp-abc123-arm_64_gcc12_release.tar.gz'
|
||||||
|
archive.write_bytes(b'fixture')
|
||||||
|
with self.assertRaises(SystemExit) as error:
|
||||||
|
publish_latest_generic_package.main(['--dist-dir', temporary, '--user', 'user', '--token', 'test-token'])
|
||||||
|
self.assertIn(f'Found: {archive.name}', str(error.exception))
|
||||||
|
self.assertIn('Publish the current Modulus tooling', str(error.exception))
|
||||||
|
request.assert_not_called()
|
||||||
def test_missing_artifacts_do_not_touch_the_registry(self):
|
def test_missing_artifacts_do_not_touch_the_registry(self):
|
||||||
with tempfile.TemporaryDirectory() as temporary, patch.object(publish_latest_generic_package, 'request') as request:
|
with tempfile.TemporaryDirectory() as temporary, patch.object(publish_latest_generic_package, 'request') as request:
|
||||||
with self.assertRaisesRegex(SystemExit, 'missing artifact files'):
|
with self.assertRaisesRegex(SystemExit, 'missing artifact files'):
|
||||||
|
|||||||
Reference in New Issue
Block a user