feat(update): leave an image pin to the version source it declares

A pin that names its own upstream in an update: block was still collected
by the image updater, which raises it to the newest tag of its registry.
For a component of a release bundle that tag is not the bundle's, so the
two updaters would propose different versions for the same line and such
a pin had to carry nocheck: docker-version.

The image updater now skips a version that declares a source for itself.
The source resolver alone bumps it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5.5 committed 2026-10-08 10:30:48 +02:00
1 parent 759a1aa4d0
commit 75460b95cd
4 files changed
+81 -2

No files matched your search

+41 -1
View File
@@ -5,7 +5,33 @@ import unittest
from pathlib import Path
from utils.cache.files import read_text
from utils.update.docker import _registry_cursor, update_config_versions
from utils.roles.mapping import ROLE_FILE_META_SERVICES
from utils.update.docker import (
_registry_cursor,
collect_entries,
sourced_services,
update_config_versions,
)
SOURCED = """bundled:
image: example/app
version: v1.0.0
update:
type: http_regex
url: https://example.invalid/bundle
pattern: "app:(v[0-9.]+)"
tracked:
image: example/side
version: v2.0.0
other_version: v3.0.0
update:
- key: other_version
type: git_tags
repository: https://example.invalid/side.git
plain:
image: example/plain
version: v4.0.0
"""
class TestRegistryCursor(unittest.TestCase):
@@ -16,6 +42,20 @@ class TestRegistryCursor(unittest.TestCase):
self.assertIsNone(_registry_cursor("19.1.1"))
class TestDeclaredSource(unittest.TestCase):
def test_a_version_with_its_own_source_is_left_to_that_source(self) -> None:
root = Path(tempfile.mkdtemp())
config = root / "roles" / "web-app-example" / ROLE_FILE_META_SERVICES
config.parent.mkdir(parents=True)
config.write_text(SOURCED, encoding="utf-8")
self.assertEqual(sourced_services(config), {"bundled"})
self.assertEqual(
sorted(entry.service for entry in collect_entries(root)),
["plain", "tracked"],
)
class TestUpdateDocker(unittest.TestCase):
def test_update_config_versions_updates_only_target_services(self) -> None:
original = """moodle: