mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 11:46:35 +00:00
feat(ci): keep GitHub-hosted runner labels current through the updater
The workflows pin `runs-on: ubuntu-NN.NN`, so no job moves to a new Ubuntu release behind our back, but nothing raised the pin either. A sixth job of `🔄 Update versions` closes that: `utils/update/runner.py` reads the image table of actions/runner-images, takes the newest x64 Ubuntu label whose image carries no preview or beta badge, and raises every older bare `runs-on: ubuntu-NN.NN` to it; arch-suffixed labels stay untouched. The job opens the change as one PR over `.github/workflows`, so its CI run tests the new image before it reaches main. This commit carries the updater's first result: every job now runs on ubuntu-26.04 (49 `runs-on`). actionlint 1.7.12, the newest release, does not know `ubuntu-26.04` yet (rhysd/actionlint#682, fix proposed in rhysd/actionlint#743), so `.github/actionlint.yaml` declares the label until a release knows it. act maps each `ubuntu-NN.NN` label the workflows use to the local platform image, derived from `.github/workflows`, instead of a fixed list that did not know ubuntu-26.04. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
52ad8549e0
commit
b055eece05
36 files changed
+307
-55
No files matched your search
@@ -0,0 +1,77 @@
|
||||
"""Bump the pinned GitHub-hosted Ubuntu runner label of every workflow job.
|
||||
|
||||
GitHub lists its hosted images in the runner-images README; the newest x64
|
||||
Ubuntu label whose image carries no preview or beta badge is the target.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pathlib import Path
|
||||
|
||||
IMAGES_README = "https://raw.githubusercontent.com/actions/runner-images/main/README.md"
|
||||
|
||||
_LABEL = re.compile(r"`ubuntu-(\d{2})\.(\d{2})`")
|
||||
_RUNS_ON = re.compile(r"(runs-on:\s*)ubuntu-(\d{2})\.(\d{2})(?![\w.-])")
|
||||
_PRERELEASE = re.compile(r"preview|beta", re.IGNORECASE)
|
||||
|
||||
|
||||
def newest_ubuntu_label(readme: str) -> str | None:
|
||||
"""Return the newest GA x64 Ubuntu label listed in the images table.
|
||||
|
||||
Args:
|
||||
readme: text of the runner-images README.
|
||||
"""
|
||||
versions: list[tuple[int, int]] = []
|
||||
for row in readme.splitlines():
|
||||
cells = [cell.strip() for cell in row.split("|")]
|
||||
if len(cells) < 5 or not cells[1].startswith("Ubuntu"):
|
||||
continue
|
||||
if _PRERELEASE.search(cells[1]) or cells[2] != "x64":
|
||||
continue
|
||||
versions += [
|
||||
(int(major), int(minor)) for major, minor in _LABEL.findall(cells[3])
|
||||
]
|
||||
if not versions:
|
||||
return None
|
||||
major, minor = max(versions)
|
||||
return f"ubuntu-{major:02d}.{minor:02d}"
|
||||
|
||||
|
||||
def bump_text(text: str, label: str) -> str:
|
||||
"""Raise every older ``runs-on: ubuntu-NN.NN`` in *text* to *label*.
|
||||
|
||||
Args:
|
||||
text: workflow source.
|
||||
label: target label, ``ubuntu-NN.NN``.
|
||||
"""
|
||||
target = tuple(int(part) for part in label.removeprefix("ubuntu-").split("."))
|
||||
|
||||
def _raise(match: re.Match[str]) -> str:
|
||||
if (int(match.group(2)), int(match.group(3))) < target:
|
||||
return match.group(1) + label
|
||||
return match.group(0)
|
||||
|
||||
return _RUNS_ON.sub(_raise, text)
|
||||
|
||||
|
||||
def bump_workflows(workflows_dir: Path, label: str) -> list[Path]:
|
||||
"""Rewrite the workflows under *workflows_dir* to *label*; return the changed files.
|
||||
|
||||
Args:
|
||||
workflows_dir: directory holding the workflow YAML files.
|
||||
label: target label, ``ubuntu-NN.NN``.
|
||||
"""
|
||||
changed: list[Path] = []
|
||||
for path in sorted(workflows_dir.glob("*.y*ml")):
|
||||
text = path.read_text( # nocheck: cache-read — read-then-write of the same file; cached read would go stale
|
||||
encoding="utf-8"
|
||||
)
|
||||
bumped = bump_text(text, label)
|
||||
if bumped != text:
|
||||
path.write_text(bumped, encoding="utf-8")
|
||||
changed.append(path)
|
||||
return changed
|
||||
Reference in new issue
Block a user