lean-runtime 2.8.0__tar.gz → 2.9.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/CHANGELOG.md +21 -0
- {lean_runtime-2.8.0/lean_runtime.egg-info → lean_runtime-2.9.1}/PKG-INFO +9 -3
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/README.md +8 -2
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/cli.md +17 -4
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/getting-started.md +5 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/local-projects.md +4 -1
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/portable-copies.md +51 -4
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/project-publishing.md +9 -2
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/__init__.py +6 -1
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/cli.py +87 -12
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/errors.py +70 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/oci.py +346 -27
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/project_execution.py +125 -31
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/projects.py +26 -12
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/runtime.py +48 -28
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/schema_resources.py +1 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1/lean_runtime.egg-info}/PKG-INFO +9 -3
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime.egg-info/SOURCES.txt +1 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/pyproject.toml +1 -1
- lean_runtime-2.9.1/schemas/publication-v1.schema.json +70 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_bundles.py +260 -1
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_cli.py +127 -1
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_project_publish.py +45 -2
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_projects.py +53 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_schema_resources.py +1 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_schemas.py +58 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/LICENSE +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/MANIFEST.in +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/catalog/environments.toml +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/catalog/locks/core-v4.32.2.lock.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/catalog/locks/leancert-v4.30.0.5.lock.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/catalog/locks/leancert-v4.31.0.lock.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/catalog/locks/leancert-v4.32.2.4.lock.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/catalog/locks/leancert-v4.33.0.lock.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/catalog/locks/mathlib-v4.30.0.lock.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/catalog/locks/mathlib-v4.31.0.lock.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/catalog/locks/mathlib-v4.32.2.lock.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/catalog/locks/mathlib-v4.33.0.lock.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/compatibility/README.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/compatibility/lake-artifact-cache-4.33.0.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/compatibility/mathlib-4.32.2.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/compatibility/mathlib-4.32.2.toml +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/compatibility/mathlib-4.33.0.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/compatibility/mathlib-4.33.0.toml +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/architecture.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/captures.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/case-study-v1.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/development.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/environments.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/index.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/lake-artifact-cache-design.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/python-api.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/ready-programs.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/standalone-files.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/trust-and-limitations.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/docs/v1-precision.md +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/examples/mathlib.toml +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/__main__.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/_git.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/_paths.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/backends.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/bundles.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/capsules.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/comparison.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/console.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/decisions.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/diagnostics.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/__init__.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/analyzer.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/api.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/candidate.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/catalog.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/catalog_build.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/catalog_cli.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/catalog_manifest.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/data/catalog.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/defaults.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/engine.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/errors.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/module_inventory.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/planner.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/policy.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/probe.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/py.typed +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/result.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/schema_resources.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/schemas/catalog-v1.schema.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/schemas/plan-v1.schema.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/discovery/schemas/result-v1.schema.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/environments.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/events.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/facade.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/frontmatter.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/header_cache.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/health.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/identifier_resolver.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/lake.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/lake_cache.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/lockfiles.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/locking.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/matrix.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/models.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/oci_protocol.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/packs.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/policies.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/profiling.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/programs.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/project_sharing.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/publisher_verification.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/py.typed +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/references.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/resolver.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/run_cli.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/serialization.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/shared_projects.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/specs.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/store.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/timings.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/toolchain_oci.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/toolchain_slim.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/toolchains.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/verification.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime/wire.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime.egg-info/dependency_links.txt +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime.egg-info/entry_points.txt +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime.egg-info/requires.txt +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/lean_runtime.egg-info/top_level.txt +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/mkdocs.yml +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/schemas/cleanup-v1.schema.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/schemas/comparison-v1.schema.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/schemas/execution-v1.schema.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/schemas/inspect-v1.schema.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/schemas/matrix-v1.schema.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/schemas/profile-v1.schema.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/schemas/verify-v1.schema.json +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/scripts/announcement_gate.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/scripts/lake_cache_gate.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/scripts/registry_preflight.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/scripts/run_compatibility.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/scripts/run_v1_case_study.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/scripts/smoke_wheel.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/setup.cfg +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/conftest.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/discovery/e2e/test_real_discovery.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/discovery/test_analyzer.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/discovery/test_catalog.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/discovery/test_catalog_build.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/discovery/test_discovery_schema_resources.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/discovery/test_engine.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/discovery/test_planner.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/discovery/test_policy.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_backend.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_capsules.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_console.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_diagnostics.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_environment_integration.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_events_health.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_facade.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_frontmatter.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_git.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_header_cache.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_identifier_resolver.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_interactive.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_lake_cache.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_lockfiles.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_models.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_multifile.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_oci_protocol.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_packs.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_paths.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_prebuilt_policy.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_programs.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_references.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_run_cli.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_runtime.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_signatures.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_specs.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_store.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_toolchain_oci.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_toolchain_slim.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_toolchains.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_v1_precision.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_verification_inventory.py +0 -0
- {lean_runtime-2.8.0 → lean_runtime-2.9.1}/tests/test_verification_probe.py +0 -0
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 2.9.1 - 2026-08-15
|
|
6
|
+
|
|
7
|
+
- Make GHCR credential discovery a single bounded GitHub CLI status read so a
|
|
8
|
+
transient identity lookup cannot silently downgrade an authenticated account
|
|
9
|
+
to anonymous; add a validated `lean-runtime.publication/v1` envelope behind
|
|
10
|
+
`publish environment --json`.
|
|
11
|
+
|
|
12
|
+
## 2.9.0 - 2026-08-15
|
|
13
|
+
|
|
14
|
+
- Make environment publication fail closed: verify registry push access before
|
|
15
|
+
building, report the selected credential source, remotely verify every
|
|
16
|
+
manifest, emit an explicit terminal failure event, and reserve exit codes 3,
|
|
17
|
+
4, and 5 for permission, retryable transport, and partial/indeterminate
|
|
18
|
+
publication failures respectively.
|
|
19
|
+
- Make standalone `check FILE` failures point directly to `--toolchain`, and
|
|
20
|
+
have project checks ask Lake to materialize a missing local import before one
|
|
21
|
+
automatic retry.
|
|
22
|
+
- Accept any fetchable Git origin for immutable project locks and local exports,
|
|
23
|
+
including self-hosted and local bare repositories; GitHub origins retain
|
|
24
|
+
their canonical `github:` convenience reference.
|
|
25
|
+
|
|
5
26
|
## 2.8.0 - 2026-08-14
|
|
6
27
|
|
|
7
28
|
- Cut repeated project-check latency with capability-probed Lean header snapshots;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lean-runtime
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9.1
|
|
4
4
|
Summary: Run Lean 4 proofs from Python or standalone files
|
|
5
5
|
Author: Alejandro Radisic
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -258,11 +258,17 @@ Environment libraries may be public or private. For example:
|
|
|
258
258
|
|
|
259
259
|
```bash
|
|
260
260
|
lean-runtime --library ghcr.io/owner/lean-environments download environment.lock.json
|
|
261
|
-
lean-runtime
|
|
261
|
+
lean-runtime publish environment environment.lock.json \
|
|
262
262
|
--publish-to ghcr.io/owner/lean-environments
|
|
263
263
|
```
|
|
264
264
|
|
|
265
|
-
|
|
265
|
+
Publication verifies push access before doing an expensive build and reports
|
|
266
|
+
which credential source it selected. Run `lean-runtime publish environment
|
|
267
|
+
--publish-to ghcr.io/owner/lean-environments --check-access` to test access by
|
|
268
|
+
itself. A registry denial is a nonzero, machine-distinct failure; success is not
|
|
269
|
+
reported until the remote manifest digest is read back and verified.
|
|
270
|
+
|
|
271
|
+
To publish an existing clean Git-backed Lean project, inspect it and
|
|
266
272
|
generate the maintained multi-platform workflow:
|
|
267
273
|
|
|
268
274
|
```bash
|
|
@@ -222,11 +222,17 @@ Environment libraries may be public or private. For example:
|
|
|
222
222
|
|
|
223
223
|
```bash
|
|
224
224
|
lean-runtime --library ghcr.io/owner/lean-environments download environment.lock.json
|
|
225
|
-
lean-runtime
|
|
225
|
+
lean-runtime publish environment environment.lock.json \
|
|
226
226
|
--publish-to ghcr.io/owner/lean-environments
|
|
227
227
|
```
|
|
228
228
|
|
|
229
|
-
|
|
229
|
+
Publication verifies push access before doing an expensive build and reports
|
|
230
|
+
which credential source it selected. Run `lean-runtime publish environment
|
|
231
|
+
--publish-to ghcr.io/owner/lean-environments --check-access` to test access by
|
|
232
|
+
itself. A registry denial is a nonzero, machine-distinct failure; success is not
|
|
233
|
+
reported until the remote manifest digest is read back and verified.
|
|
234
|
+
|
|
235
|
+
To publish an existing clean Git-backed Lean project, inspect it and
|
|
230
236
|
generate the maintained multi-platform workflow:
|
|
231
237
|
|
|
232
238
|
```bash
|
|
@@ -77,6 +77,8 @@ lean-runtime --library ghcr.io/owner/lean-environments download environment.lock
|
|
|
77
77
|
lean-runtime copy save research-stack --output research-stack.lean-environment
|
|
78
78
|
lean-runtime --home /tmp/fresh copy open research-stack.lean-environment --name research-stack
|
|
79
79
|
lean-runtime publish environment environment.lock.json --publish-to ghcr.io/owner/lean-environments
|
|
80
|
+
lean-runtime publish environment --publish-to ghcr.io/owner/lean-environments --check-access
|
|
81
|
+
lean-runtime publish environment --publish-to ghcr.io/owner/lean-environments --check-access --json
|
|
80
82
|
lean-runtime check research-stack Main.lean --json
|
|
81
83
|
lean-runtime inspect research-stack --packages
|
|
82
84
|
lean-runtime environments
|
|
@@ -225,6 +227,15 @@ controls whether ready-to-use environments are downloaded or built locally.
|
|
|
225
227
|
`LEAN_RUNTIME_LIBRARIES` accepts a comma-separated equivalent and
|
|
226
228
|
`LEAN_RUNTIME_AVAILABILITY` sets the default policy.
|
|
227
229
|
|
|
230
|
+
Environment publishing probes repository push access before opening or building
|
|
231
|
+
the lock. `--check-access` runs only that content-free preflight and needs no
|
|
232
|
+
lock. GHCR publishers can use an authenticated `gh` session; explicit
|
|
233
|
+
`LEAN_RUNTIME_REGISTRY_USERNAME` and `LEAN_RUNTIME_REGISTRY_PASSWORD` values take
|
|
234
|
+
precedence. Publication exits `3` for authentication/permission denial, `4` for
|
|
235
|
+
retryable transport or registry failures, and `5` when remote state is partial
|
|
236
|
+
or indeterminate. Success is emitted only after the published manifest is read
|
|
237
|
+
back and its digest is verified. See [Portable copies](portable-copies.md#publishing).
|
|
238
|
+
|
|
228
239
|
## Publish an existing project
|
|
229
240
|
|
|
230
241
|
```bash
|
|
@@ -235,10 +246,12 @@ lean-runtime project init-publish . --module MyProject \
|
|
|
235
246
|
--library ghcr.io/owner/my-project-environments
|
|
236
247
|
```
|
|
237
248
|
|
|
238
|
-
`inspect` is read-only. The other commands require a clean root
|
|
239
|
-
whose exact HEAD commit is available from
|
|
240
|
-
|
|
241
|
-
|
|
249
|
+
`inspect` is read-only. The other commands require a clean root Git project
|
|
250
|
+
whose exact HEAD commit is available from its configured origin. GitHub,
|
|
251
|
+
self-hosted HTTPS/SSH, and local bare repositories are supported.
|
|
252
|
+
`init-publish` creates a small caller for the maintained multi-platform
|
|
253
|
+
publication and clean-consumer workflow. See
|
|
254
|
+
[Publishing a Lean project](project-publishing.md).
|
|
242
255
|
|
|
243
256
|
Use global `--publisher_verification required --trusted-publisher ID --trusted-issuer ISSUER`
|
|
244
257
|
to require a verified publisher. `build-and-publish --sign` records the trusted
|
|
@@ -115,6 +115,11 @@ lean-run Main.lean
|
|
|
115
115
|
then lets Lean determine which candidate accepts the source. Use
|
|
116
116
|
`--lock-out environment.lock.json` to pin the successful environment.
|
|
117
117
|
|
|
118
|
+
The lower-level `lean-runtime check Main.lean` command does not guess a
|
|
119
|
+
toolchain for a standalone file. Pass one explicitly, for example
|
|
120
|
+
`lean-runtime check Main.lean --toolchain v4.33.0`, or use `lean-run` for
|
|
121
|
+
catalog discovery.
|
|
122
|
+
|
|
118
123
|
Strict TOML frontmatter remains available when the context is already known:
|
|
119
124
|
|
|
120
125
|
```lean
|
|
@@ -29,7 +29,10 @@ lean-runtime check ./my-project/MyProject/Main.lean
|
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
The actual project-relative file is passed to `lake env lean`, so imports of
|
|
32
|
-
local modules retain normal Lake semantics.
|
|
32
|
+
local modules retain normal Lake semantics. A successful file check does not
|
|
33
|
+
itself write that file's `.olean`; if another checked file imports a local
|
|
34
|
+
module whose artifact is missing, Lean Runtime asks Lake to build that module's
|
|
35
|
+
`leanArts` target and retries once. Checking a source string writes a
|
|
33
36
|
uniquely named disposable file under `.lake/lean-runtime/` and removes it after
|
|
34
37
|
execution:
|
|
35
38
|
|
|
@@ -113,25 +113,72 @@ Signature failure is an integrity failure and never triggers source fallback.
|
|
|
113
113
|
|
|
114
114
|
## Publishing
|
|
115
115
|
|
|
116
|
+
Check push access without building or uploading an environment:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
lean-runtime publish environment \
|
|
120
|
+
--publish-to ghcr.io/alerad/leancert-runtime \
|
|
121
|
+
--check-access
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Add `--json` for the versioned `lean-runtime.publication/v1` success or failure
|
|
125
|
+
envelope. The process exit code retains the classification below.
|
|
126
|
+
|
|
127
|
+
For GHCR, credentials are selected in this order: the
|
|
128
|
+
`LEAN_RUNTIME_REGISTRY_USERNAME` / `LEAN_RUNTIME_REGISTRY_PASSWORD` pair, an
|
|
129
|
+
authenticated GitHub CLI session, then anonymous access. The access report names
|
|
130
|
+
the selected account and source but never prints the token. Lean Runtime does not
|
|
131
|
+
implicitly read Docker's credential store. To give the GitHub CLI package access,
|
|
132
|
+
run:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
gh auth refresh -s write:packages,read:packages
|
|
136
|
+
```
|
|
137
|
+
|
|
116
138
|
Publish the current platform after ensuring the lock:
|
|
117
139
|
|
|
118
140
|
```bash
|
|
119
141
|
export LEAN_RUNTIME_REGISTRY_USERNAME=alerad
|
|
120
142
|
export LEAN_RUNTIME_REGISTRY_PASSWORD="$GHCR_TOKEN"
|
|
121
143
|
|
|
122
|
-
lean-runtime
|
|
144
|
+
lean-runtime publish environment environment.lock.json \
|
|
123
145
|
--publish-to ghcr.io/alerad/leancert-runtime \
|
|
124
146
|
--tag v4.32.2.4 \
|
|
125
147
|
--sign --attest
|
|
126
148
|
```
|
|
127
149
|
|
|
128
|
-
The
|
|
129
|
-
|
|
130
|
-
|
|
150
|
+
The same push-access probe runs automatically before the environment is built,
|
|
151
|
+
so a missing scope fails in seconds instead of after export. The probe starts
|
|
152
|
+
and immediately cancels an empty OCI upload session; it publishes no manifest or
|
|
153
|
+
index. The publisher then checks for existing blobs, uploads only missing
|
|
154
|
+
content, publishes the platform manifest by digest, and updates the canonical
|
|
155
|
+
`lock_<sha>` index tag last. Every manifest is fetched back and its digest is
|
|
156
|
+
verified before success is reported. Human tags are aliases to that same index.
|
|
157
|
+
This follows the
|
|
131
158
|
[OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/main/spec.md)
|
|
132
159
|
and uses an [OCI image index](https://github.com/opencontainers/image-spec/blob/main/image-index.md)
|
|
133
160
|
for platform selection.
|
|
134
161
|
|
|
162
|
+
Publication has stable failure codes for CI:
|
|
163
|
+
|
|
164
|
+
| Exit | Meaning | Retry? |
|
|
165
|
+
|---:|---|---|
|
|
166
|
+
| `2` | Invalid invocation or local input | Fix the invocation |
|
|
167
|
+
| `3` | Registry authentication or permission denial | Fix credentials/scopes first |
|
|
168
|
+
| `4` | Retryable network, throttling, or registry 5xx failure | Yes, with backoff |
|
|
169
|
+
| `5` | Partial or indeterminate publication state | Inspect the terminal state, then retry safely |
|
|
170
|
+
|
|
171
|
+
An unpublished failure explicitly states that no manifest or index was
|
|
172
|
+
finalized; already uploaded content-addressed blobs are unreferenced and safe to
|
|
173
|
+
reuse on retry. Once a manifest write has been attempted, any failure that
|
|
174
|
+
cannot prove the resulting remote state is reported as partial/indeterminate;
|
|
175
|
+
it is never reported as success. Registries do not use status codes
|
|
176
|
+
uniformly: in particular, GHCR can return 403 for missing permissions as well as
|
|
177
|
+
an inaccessible or not-yet-created package namespace, so diagnostics describe
|
|
178
|
+
these as likely causes rather than certainties. Automation can consume the same
|
|
179
|
+
state from the terminal `library.publish_failed` or `library.published` runtime
|
|
180
|
+
event.
|
|
181
|
+
|
|
135
182
|
Repository authors can use the bundled composite action after checking out the
|
|
136
183
|
repository and generating or retaining a lock:
|
|
137
184
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Publishing a Lean project
|
|
2
2
|
|
|
3
|
-
Lean Runtime can freeze a clean
|
|
3
|
+
Lean Runtime can freeze a clean Git-backed Lean project into an exact lock,
|
|
4
4
|
build it on each supported computer type, and publish verified ready-to-use
|
|
5
5
|
environments through an OCI-compatible library. Consumers import the project's
|
|
6
6
|
public module without cloning or building the project.
|
|
@@ -24,7 +24,8 @@ Add `--check-remote` to prove that the exact HEAD commit is available from
|
|
|
24
24
|
- a root `lakefile.toml` or `lakefile.lean` with an importable Lean library;
|
|
25
25
|
- the Lake project at the Git repository root;
|
|
26
26
|
- a clean checkout;
|
|
27
|
-
- a
|
|
27
|
+
- a fetchable `origin` (GitHub, self-hosted HTTPS/SSH, `file://`, or a local
|
|
28
|
+
bare repository); and
|
|
28
29
|
- a HEAD commit available from that remote.
|
|
29
30
|
|
|
30
31
|
If `lakefile.lean` must be translated, its pinned toolchain must already be
|
|
@@ -40,6 +41,12 @@ The default output is `environment.lock.json` in the project root. The lock
|
|
|
40
41
|
contains the exact project commit, complete Lake dependency graph, toolchain,
|
|
41
42
|
and selected public module.
|
|
42
43
|
|
|
44
|
+
GitHub HTTPS and SSH origins are canonicalized to the portable HTTPS form and
|
|
45
|
+
receive a `github:OWNER/REPOSITORY@COMMIT` convenience reference. Other origins
|
|
46
|
+
are preserved as exact Git sources. Relative local paths become absolute
|
|
47
|
+
`file://` URLs, which is useful for offline export but intentionally remains
|
|
48
|
+
machine-local unless the resulting capsule is distributed.
|
|
49
|
+
|
|
43
50
|
## Export this computer
|
|
44
51
|
|
|
45
52
|
A portable capsule is useful for transferring the current computer's
|
|
@@ -21,6 +21,8 @@ from .errors import (
|
|
|
21
21
|
MaterializationError,
|
|
22
22
|
PolicyError,
|
|
23
23
|
ProjectError,
|
|
24
|
+
PublicationError,
|
|
25
|
+
RegistryRequestError,
|
|
24
26
|
ResolutionError,
|
|
25
27
|
SpecificationError,
|
|
26
28
|
ToolchainError,
|
|
@@ -49,7 +51,7 @@ from .models import (
|
|
|
49
51
|
PhaseTiming,
|
|
50
52
|
ProjectProvenance,
|
|
51
53
|
)
|
|
52
|
-
from .oci import DEFAULT_ENVIRONMENT_LIBRARIES, PublicationInfo
|
|
54
|
+
from .oci import DEFAULT_ENVIRONMENT_LIBRARIES, PublicationAccess, PublicationInfo
|
|
53
55
|
from .policies import ExecutionPolicy
|
|
54
56
|
from .profiling import ProfileReport
|
|
55
57
|
from .programs import ProgramDescription, ProgramInfo, ReadyProgram
|
|
@@ -142,6 +144,9 @@ __all__ = [
|
|
|
142
144
|
"PreparedEnvironment",
|
|
143
145
|
"PolicyError",
|
|
144
146
|
"PublicationInfo",
|
|
147
|
+
"PublicationAccess",
|
|
148
|
+
"PublicationError",
|
|
149
|
+
"RegistryRequestError",
|
|
145
150
|
"DownloadUnavailable",
|
|
146
151
|
"ProjectError",
|
|
147
152
|
"ResolutionError",
|
|
@@ -15,7 +15,13 @@ from typing import Any, cast
|
|
|
15
15
|
|
|
16
16
|
from .console import styler_for
|
|
17
17
|
from .environments import ExecutionCapture
|
|
18
|
-
from .errors import
|
|
18
|
+
from .errors import (
|
|
19
|
+
LeanRuntimeError,
|
|
20
|
+
MaterializationError,
|
|
21
|
+
ProjectError,
|
|
22
|
+
PublicationError,
|
|
23
|
+
ResolutionError,
|
|
24
|
+
)
|
|
19
25
|
from .events import RuntimeEvent
|
|
20
26
|
from .health import DoctorReport
|
|
21
27
|
from .lake import ROOT_MODULE
|
|
@@ -49,6 +55,7 @@ def _schema_for(command: str) -> str:
|
|
|
49
55
|
"matrix": "lean-runtime.matrix/v1",
|
|
50
56
|
"clean": "lean-runtime.cleanup/v1",
|
|
51
57
|
"inspect": "lean-runtime.inspect/v1",
|
|
58
|
+
"build-and-publish": "lean-runtime.publication/v1",
|
|
52
59
|
}.get(command, "lean-runtime.execution/v1")
|
|
53
60
|
|
|
54
61
|
|
|
@@ -276,6 +283,31 @@ def _print_operation_failure(exc: ResolutionError | MaterializationError, *, ver
|
|
|
276
283
|
print(exc.output.rstrip(), file=sys.stderr)
|
|
277
284
|
|
|
278
285
|
|
|
286
|
+
def _print_publication_failure(exc: PublicationError) -> None:
|
|
287
|
+
status = f" (HTTP {exc.status_code})" if exc.status_code is not None else ""
|
|
288
|
+
print(
|
|
289
|
+
f"✗ Publication failed at {exc.registry} during {exc.phase}{status}",
|
|
290
|
+
file=sys.stderr,
|
|
291
|
+
)
|
|
292
|
+
print(f" {exc}", file=sys.stderr)
|
|
293
|
+
identity = exc.username or "anonymous"
|
|
294
|
+
print(
|
|
295
|
+
f" Authentication: {identity} (source: {exc.credential_source})",
|
|
296
|
+
file=sys.stderr,
|
|
297
|
+
)
|
|
298
|
+
if exc.partial:
|
|
299
|
+
print(
|
|
300
|
+
" No verified final release was produced; immutable platform content may exist.",
|
|
301
|
+
file=sys.stderr,
|
|
302
|
+
)
|
|
303
|
+
print(" Safe to retry the publication; verified content will be reused.", file=sys.stderr)
|
|
304
|
+
else:
|
|
305
|
+
print(" Nothing was published: no manifest or index was finalized.", file=sys.stderr)
|
|
306
|
+
print(" Safe to retry; completed blobs will be reused.", file=sys.stderr)
|
|
307
|
+
if exc.hint:
|
|
308
|
+
print(f" Fix: {exc.hint}", file=sys.stderr)
|
|
309
|
+
|
|
310
|
+
|
|
279
311
|
def _cli_source_name(path: Path) -> str:
|
|
280
312
|
if path.is_absolute():
|
|
281
313
|
return path.name
|
|
@@ -400,7 +432,7 @@ Run `lean-runtime COMMAND --help` for examples and options.""",
|
|
|
400
432
|
publish = commands.add_parser("publish", help="publish an environment, toolchain, or program")
|
|
401
433
|
publish_kinds = publish.add_subparsers(dest="publish_kind", required=True)
|
|
402
434
|
publish_environment = publish_kinds.add_parser("environment")
|
|
403
|
-
publish_environment.add_argument("lock", type=Path)
|
|
435
|
+
publish_environment.add_argument("lock", nargs="?", type=Path)
|
|
404
436
|
publish_environment.add_argument("--publish-to", required=True)
|
|
405
437
|
publish_environment.add_argument("--tag", action="append", default=[])
|
|
406
438
|
publish_environment.add_argument("--name")
|
|
@@ -409,6 +441,14 @@ Run `lean-runtime COMMAND --help` for examples and options.""",
|
|
|
409
441
|
publish_environment.add_argument("--accelerate", action="store_true")
|
|
410
442
|
publish_environment.add_argument("--sign", action="store_true")
|
|
411
443
|
publish_environment.add_argument("--attest", action="store_true")
|
|
444
|
+
publish_environment.add_argument(
|
|
445
|
+
"--json", action="store_true", help="emit a versioned JSON envelope"
|
|
446
|
+
)
|
|
447
|
+
publish_environment.add_argument(
|
|
448
|
+
"--check-access",
|
|
449
|
+
action="store_true",
|
|
450
|
+
help="verify registry push access without building or publishing",
|
|
451
|
+
)
|
|
412
452
|
publish_toolchain = publish_kinds.add_parser("toolchain")
|
|
413
453
|
publish_toolchain.add_argument("toolchain")
|
|
414
454
|
publish_toolchain.add_argument("--library", required=True)
|
|
@@ -464,7 +504,7 @@ Run `lean-runtime COMMAND --help` for examples and options.""",
|
|
|
464
504
|
push = commands.add_parser(
|
|
465
505
|
"build-and-publish", help="build an exact environment and publish it to a library"
|
|
466
506
|
)
|
|
467
|
-
push.add_argument("lock", type=Path)
|
|
507
|
+
push.add_argument("lock", nargs="?", type=Path)
|
|
468
508
|
push.add_argument("--publish-to", required=True)
|
|
469
509
|
push.add_argument("--tag", action="append", default=[])
|
|
470
510
|
push.add_argument("--name")
|
|
@@ -490,6 +530,12 @@ Run `lean-runtime COMMAND --help` for examples and options.""",
|
|
|
490
530
|
push.add_argument(
|
|
491
531
|
"--attest", action="store_true", help="publish a signed source/probe attestation"
|
|
492
532
|
)
|
|
533
|
+
push.add_argument("--json", action="store_true", help="emit a versioned JSON envelope")
|
|
534
|
+
push.add_argument(
|
|
535
|
+
"--check-access",
|
|
536
|
+
action="store_true",
|
|
537
|
+
help="verify registry push access without building or publishing",
|
|
538
|
+
)
|
|
493
539
|
|
|
494
540
|
publish_index = commands.add_parser(
|
|
495
541
|
"finalize-publication", help="combine computer-specific publication results"
|
|
@@ -777,7 +823,7 @@ Run `lean-runtime COMMAND --help` for examples and options.""",
|
|
|
777
823
|
install.add_argument("toolchain")
|
|
778
824
|
|
|
779
825
|
project = commands.add_parser(
|
|
780
|
-
"project", help="inspect, freeze, or export a pinned
|
|
826
|
+
"project", help="inspect, freeze, or export a pinned Git-backed Lean project"
|
|
781
827
|
)
|
|
782
828
|
project_commands = project.add_subparsers(dest="project_command", required=True)
|
|
783
829
|
project_inspect = project_commands.add_parser(
|
|
@@ -1144,21 +1190,37 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1144
1190
|
_json(environment.inspect().to_dict())
|
|
1145
1191
|
return 0
|
|
1146
1192
|
if args.command == "build-and-publish":
|
|
1193
|
+
access = runtime.check_publication_access(args.publish_to)
|
|
1194
|
+
if args.check_access:
|
|
1195
|
+
_json(
|
|
1196
|
+
envelope(_schema_for(args.command), ok=True, data=access.to_dict())
|
|
1197
|
+
if args.json
|
|
1198
|
+
else access.to_dict()
|
|
1199
|
+
)
|
|
1200
|
+
return 0
|
|
1201
|
+
if args.lock is None:
|
|
1202
|
+
raise ValueError("publish environment requires LOCK unless --check-access is used")
|
|
1147
1203
|
environment = runtime.open_exact(
|
|
1148
1204
|
EnvironmentLock.load(args.lock),
|
|
1149
1205
|
name=args.name,
|
|
1150
1206
|
build_timeout=args.timeout,
|
|
1151
1207
|
accelerate=args.accelerate,
|
|
1152
1208
|
)
|
|
1209
|
+
publication = runtime.publish_environment(
|
|
1210
|
+
environment.id,
|
|
1211
|
+
args.publish_to,
|
|
1212
|
+
tags=args.tag,
|
|
1213
|
+
finalize=not args.platform_only,
|
|
1214
|
+
sign=args.sign,
|
|
1215
|
+
attest=args.attest,
|
|
1216
|
+
).to_dict()
|
|
1217
|
+
publication["consumer_command"] = (
|
|
1218
|
+
f"lean-runtime --library {args.publish_to} download {args.lock}"
|
|
1219
|
+
)
|
|
1153
1220
|
_json(
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
tags=args.tag,
|
|
1158
|
-
finalize=not args.platform_only,
|
|
1159
|
-
sign=args.sign,
|
|
1160
|
-
attest=args.attest,
|
|
1161
|
-
).to_dict()
|
|
1221
|
+
envelope(_schema_for(args.command), ok=True, data=publication)
|
|
1222
|
+
if args.json
|
|
1223
|
+
else publication
|
|
1162
1224
|
)
|
|
1163
1225
|
return 0
|
|
1164
1226
|
if args.command == "finalize-publication":
|
|
@@ -1631,6 +1693,19 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1631
1693
|
else:
|
|
1632
1694
|
_print_operation_failure(exc, verbose=args.verbose)
|
|
1633
1695
|
return 2
|
|
1696
|
+
except PublicationError as exc:
|
|
1697
|
+
if getattr(args, "json", False):
|
|
1698
|
+
_json(
|
|
1699
|
+
envelope(
|
|
1700
|
+
_schema_for(args.command),
|
|
1701
|
+
ok=False,
|
|
1702
|
+
data=exc.to_dict(),
|
|
1703
|
+
errors=[error("publication_failed", str(exc), details=exc.to_dict())],
|
|
1704
|
+
)
|
|
1705
|
+
)
|
|
1706
|
+
else:
|
|
1707
|
+
_print_publication_failure(exc)
|
|
1708
|
+
return exc.exit_code
|
|
1634
1709
|
except (LeanRuntimeError, OSError, UnicodeError, ValueError, json.JSONDecodeError) as exc:
|
|
1635
1710
|
if getattr(args, "json", False):
|
|
1636
1711
|
_json(
|
|
@@ -64,6 +64,76 @@ class DownloadUnavailable(EnvironmentError):
|
|
|
64
64
|
"""A prebuilt cache had no usable artifact or could not be reached."""
|
|
65
65
|
|
|
66
66
|
|
|
67
|
+
class RegistryRequestError(DownloadUnavailable):
|
|
68
|
+
"""An OCI registry request failed with machine-readable retry semantics."""
|
|
69
|
+
|
|
70
|
+
def __init__(
|
|
71
|
+
self,
|
|
72
|
+
message: str,
|
|
73
|
+
*,
|
|
74
|
+
operation: str,
|
|
75
|
+
status_code: int | None = None,
|
|
76
|
+
retryable: bool = False,
|
|
77
|
+
) -> None:
|
|
78
|
+
super().__init__(message)
|
|
79
|
+
self.operation = operation
|
|
80
|
+
self.status_code = status_code
|
|
81
|
+
self.retryable = retryable
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class PublicationError(EnvironmentError):
|
|
85
|
+
"""A required publication did not reach a remotely verified terminal state."""
|
|
86
|
+
|
|
87
|
+
def __init__(
|
|
88
|
+
self,
|
|
89
|
+
message: str,
|
|
90
|
+
*,
|
|
91
|
+
phase: str,
|
|
92
|
+
registry: str,
|
|
93
|
+
status_code: int | None = None,
|
|
94
|
+
retryable: bool = False,
|
|
95
|
+
published: bool = False,
|
|
96
|
+
partial: bool = False,
|
|
97
|
+
credential_source: str = "anonymous",
|
|
98
|
+
username: str | None = None,
|
|
99
|
+
hint: str | None = None,
|
|
100
|
+
) -> None:
|
|
101
|
+
super().__init__(message)
|
|
102
|
+
self.phase = phase
|
|
103
|
+
self.registry = registry
|
|
104
|
+
self.status_code = status_code
|
|
105
|
+
self.retryable = retryable
|
|
106
|
+
self.published = published
|
|
107
|
+
self.partial = partial
|
|
108
|
+
self.credential_source = credential_source
|
|
109
|
+
self.username = username
|
|
110
|
+
self.hint = hint
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
def exit_code(self) -> int:
|
|
114
|
+
if self.partial:
|
|
115
|
+
return 5
|
|
116
|
+
if self.status_code in {401, 403}:
|
|
117
|
+
return 3
|
|
118
|
+
if self.retryable:
|
|
119
|
+
return 4
|
|
120
|
+
return 5
|
|
121
|
+
|
|
122
|
+
def to_dict(self) -> dict[str, object]:
|
|
123
|
+
return {
|
|
124
|
+
"phase": self.phase,
|
|
125
|
+
"registry": self.registry,
|
|
126
|
+
"status_code": self.status_code,
|
|
127
|
+
"retryable": self.retryable,
|
|
128
|
+
"published": self.published,
|
|
129
|
+
"partial": self.partial,
|
|
130
|
+
"credential_source": self.credential_source,
|
|
131
|
+
"username": self.username,
|
|
132
|
+
"hint": self.hint,
|
|
133
|
+
"message": str(self),
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
67
137
|
class DownloadLimitExceeded(EnvironmentError):
|
|
68
138
|
"""An acquisition needs more bytes than the configured download limit.
|
|
69
139
|
|