mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
Seven roles pin several images at one shared version, because those images are one product: the four Jitsi components, six GitLab CNG images, eight BigBlueButton services, three Penpot, plus Mastodon, Funkwhale and Nextcloud Talk. The bump job walks entries one by one and takes each image's own newest tag, so a run landing between upstream's first and last push raises the components already there and leaves the rest behind. What deploys afterwards is a mixed set, and for Jitsi a mixed set breaks video. The window is real rather than theoretical. Measured on Docker Hub, 'stable-9457' exists for jitsi/prosody, jitsi/jicofo and jitsi/jvb but not for jitsi/web, one build out of sixty. Candidates are now grouped by role and current version, and the group is held to the newest tag the intersection of all their tag lists still offers. A group with nothing newer in common yields no update at all rather than a partial one. A lone entry passes through untouched, so nothing changes for the large majority. The key is deliberately the role and the version, not the image namespace. A namespace rule does not survive the data: prom/* carries four components at four different versions, opentalk/* three, and minio, taigaio and markoshust each two. Grouping by namespace would hold back pins that are correctly independent. Five of the seven roles have carried this exposure all along; the channel grammar in the previous commit added the sixth by making Jitsi orderable at all. This closes all of them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
114 lines
3.6 KiB
Python
114 lines
3.6 KiB
Python
"""Several images of one role at one version move together or not at all.
|
|
|
|
Upstream does not push a release group atomically. Measured on Docker Hub:
|
|
``jitsi/prosody``, ``jitsi/jicofo`` and ``jitsi/jvb`` all publish
|
|
``stable-9457`` while ``jitsi/web`` does not, so a bump run landing in that
|
|
window would raise three components and leave the fourth behind.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from utils.update.docker import (
|
|
DockerImageVersionEntry,
|
|
DockerImageVersionUpdate,
|
|
_held_to_release_groups,
|
|
)
|
|
|
|
JITSI = ("web", "prosody", "jicofo", "jvb")
|
|
|
|
|
|
def _entry(role: str, service: str, image: str, version: str):
|
|
return DockerImageVersionEntry(
|
|
role=role,
|
|
service=service,
|
|
image=image,
|
|
version=version,
|
|
config_path=Path("meta/services.yml"),
|
|
)
|
|
|
|
|
|
def _jitsi_updates(version: str, latest: str):
|
|
return [
|
|
DockerImageVersionUpdate(
|
|
entry=_entry("web-app-jitsi", name, f"jitsi/{name}", version),
|
|
latest=latest,
|
|
)
|
|
for name in JITSI
|
|
]
|
|
|
|
|
|
class TestReleaseGroupsMoveTogether(unittest.TestCase):
|
|
def test_a_partial_publish_holds_the_whole_group_back(self):
|
|
tags = {
|
|
"jitsi/web": ["stable-9400", "stable-9646"],
|
|
"jitsi/prosody": ["stable-9400", "stable-9646", "stable-9700"],
|
|
"jitsi/jicofo": ["stable-9400", "stable-9646", "stable-9700"],
|
|
"jitsi/jvb": ["stable-9400", "stable-9646", "stable-9700"],
|
|
}
|
|
updates = _jitsi_updates("stable-9400", "stable-9700")
|
|
|
|
held = _held_to_release_groups(updates, tags)
|
|
|
|
self.assertEqual({update.latest for update in held}, {"stable-9646"})
|
|
self.assertEqual(len(held), 4)
|
|
|
|
def test_a_group_all_publish_moves_to_the_head(self):
|
|
tags = {
|
|
f"jitsi/{name}": ["stable-9400", "stable-9700"] for name in JITSI
|
|
}
|
|
updates = _jitsi_updates("stable-9400", "stable-9700")
|
|
|
|
held = _held_to_release_groups(updates, tags)
|
|
|
|
self.assertEqual({update.latest for update in held}, {"stable-9700"})
|
|
|
|
def test_a_group_with_nothing_in_common_is_dropped(self):
|
|
tags = {
|
|
"jitsi/web": ["stable-9400", "stable-9701"],
|
|
"jitsi/prosody": ["stable-9400", "stable-9702"],
|
|
"jitsi/jicofo": ["stable-9400", "stable-9703"],
|
|
"jitsi/jvb": ["stable-9400", "stable-9704"],
|
|
}
|
|
updates = _jitsi_updates("stable-9400", "stable-9704")
|
|
|
|
self.assertEqual(_held_to_release_groups(updates, tags), [])
|
|
|
|
def test_a_lone_entry_is_untouched(self):
|
|
update = DockerImageVersionUpdate(
|
|
entry=_entry("web-app-fider", "fider", "getfider/fider", "v0.35.0"),
|
|
latest="v0.36.0",
|
|
)
|
|
|
|
held = _held_to_release_groups([update], {"getfider/fider": ["v0.36.0"]})
|
|
|
|
self.assertEqual(held, [update])
|
|
|
|
def test_two_roles_on_one_version_are_not_one_group(self):
|
|
tags = {
|
|
"jitsi/web": ["stable-9400", "stable-9700"],
|
|
"other/thing": ["stable-9400"],
|
|
}
|
|
updates = [
|
|
DockerImageVersionUpdate(
|
|
entry=_entry("web-app-jitsi", "web", "jitsi/web", "stable-9400"),
|
|
latest="stable-9700",
|
|
),
|
|
DockerImageVersionUpdate(
|
|
entry=_entry("web-app-other", "thing", "other/thing", "stable-9400"),
|
|
latest="stable-9400",
|
|
),
|
|
]
|
|
|
|
held = _held_to_release_groups(updates, tags)
|
|
|
|
self.assertEqual(
|
|
[update.latest for update in held], ["stable-9700", "stable-9400"]
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|