Add scratch OS support#578
Open
bschwedler wants to merge 16 commits into
Open
Conversation
Test Results1 733 tests +22 1 732 ✅ +21 8m 11s ⏱️ -36s For more details on these failures, see this check. Results for commit 094db41. ± Comparison against base commit ddaf099. ♻️ This comment has been updated with latest results. |
ianpittwood
requested changes
Jun 11, 2026
ianpittwood
left a comment
Contributor
There was a problem hiding this comment.
A lot of this is making sense, but the branch seems like it was polluted with another change
Introduce `_OSLESS_NAMES` (containing "scratch") in `shared.py`. The `default_factory` lambdas for `ExtensionField` and `TagDisplayNameField` now return `""` when the OS name is in that set. The `pattern` validators are relaxed from `+` (one-or-more) to `*` (zero-or-more) so explicitly-supplied empty strings are also accepted.
Move the inline name→BuildOS resolution logic from the field validator into a module-level function so Task 3 can reuse it without duplication. No behavior change; all existing tests pass.
Adds an optional `artifactOs` field to `ImageVersionOS` for dev versions that use a scratch OS but need to resolve artifact download URLs against a real OS (e.g. ubuntu-24.04). The `artifact_build_os` property returns the resolved `BuildOS` for `artifactOs` when set, falling back to `buildOS` otherwise. Also fixes trailing-hyphen stripping in `_resolve_name_to_build_os` so that hyphenated OS names like "ubuntu-24.04" resolve correctly, and restores the comment explaining int conversion before max() for numeric ordering.
The assertion `Containerfile.{previous_os.extension}` produced
`Containerfile.` when scratch OS has an empty extension field.
Fall back to the lowercased OS name when extension is empty, matching
the actual rendered filename (`Containerfile.scratch`).
Consolidates the four duplicated OS validators from version.py, dev_version/base.py, and matrix.py into a single mixin with generic messages. Adds a fifth validator, error_untaggable_os, which must run after make_single_os_primary (declaration order enforces this) to catch non-primary OSes with an empty tagDisplayName.
Wire OSValidatorMixin into ImageVersion, BaseImageDevelopmentVersion,
and ImageMatrix, removing the four duplicate @field_validator("os")
methods from each class body.
- Add sourceType to the mixin's name-guard so dev version classes
(which have no name/namePattern field) still trigger warnings and
errors correctly
- Update all test message assertions to match the mixin's generic
messages ("image configuration" instead of class-specific strings)
- Add three new tests for error_untaggable_os behaviour on scratch OS
build() called self.image_os.platforms directly at the docker.build call site, crashing with AttributeError when image_os is None. build_platforms was already computed safely with a null guard two lines earlier — use it consistently. Adds two tests: - scratch OS (empty extension) + no variant produces a plain Containerfile - build() uses DEFAULT_PLATFORMS instead of crashing when image_os is None
Replace the three buildOS call sites in get_version(), get_url_by_os(), and _resolve_os_urls() with artifact_build_os. This ensures scratch OS entries (which have family=UNKNOWN) delegate artifact resolution to their configured artifactOs instead of failing.
The scratch OS now uses empty extension/tagDisplayName, producing a bare Containerfile (no suffix) and OS-unsuffixed tags (only version and :latest, no :scratch or :1.0.0-scratch). - Rename Containerfile.scratch → Containerfile and Containerfile.scratch.jinja2 → Containerfile.jinja2 in the barebones fixture - Update test_config.py assertions to use bare Containerfile instead of Containerfile.scratch - Drop OS-suffix tags from get/tags/barebones expected JSON - Add multiversion context and default matrix testdata
Commit 456788a2 updated the barebones bakery.yaml to use empty extension for Scratch OS and renamed the Containerfile, but the bake plan JSON fixtures still referenced Containerfile.scratch and included OS-suffix tags (1.0.0-scratch, scratch). Update the three bake testdata fixtures to match the new Scratch OS behavior.
- test_dgoss_environment: use full dict equality after delenv(GITHUB_ACTIONS)
so extra keys (e.g. GH_TOKEN leaking in CI) cannot go undetected
- test_resolve_os_urls_uses_artifact_os_for_scratch: capture _resolve_os_urls()
return value and assert artifactDownloadURL was set, not just that the mock
was called with the right BuildOS
- Rename fail-fast Containerfile.scratch.{min,std} to Containerfile.{min,std}
so bakery finds them now that Scratch OS defaults to empty extension; fixes
test_building_images_from_a_project_using_sequential_build_with_failfast
failing with BakeryFileError under just test-all
Python 3.14 raises DeprecationWarning for invalid escape sequences processed through Jinja2's unicode-escape codec. The string literal '\d' inside the Jinja2 template triggers this; '\\d' makes Jinja2 decode it to \d correctly without the warning.
Move _OSLESS_NAMES and the scratch-aware default_factory out of shared.py into version_os.py. The shared ExtensionField/ TagDisplayNameField are used by ImageVariant too; keeping the scratch check there would silently produce empty extension/ tagDisplayName for any variant named "scratch", risking tag and Containerfile collisions. - shared.py: restore original default_factory and + patterns - version_os.py: own _OSLESS_NAMES and * patterns locally
d221142 to
a46ea62
Compare
Lines 76 and 91 of version_os.py had inline pattern strings for extension and tagDisplayName validation. Extract them to named constants in const.py alongside the existing tag-suffix pattern.
Duplicate OS entries that share the same name/extension/tagDisplayName but have different artifactOs values represent a config conflict — the set-based deduplication in deduplicate_os would silently drop one, producing incorrect artifact URL resolution. Detect this case and raise a ValueError instead of collapsing silently.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Enables images that don't vary by OS — no OS suffix in tags or Containerfile names. The
artifactOsfield handles the dev-channel case where the channel API has no scratch-native artifact entries.