fix(ci): stage complete reproducible infra inputs
lint / lint (push) Successful in 43s
test / stage-firecracker-inputs (pull_request) Successful in 14s
tracker-policy-pr / check-pr (pull_request) Successful in 12s
test / integration-docker (pull_request) Successful in 22s
test / unit (pull_request) Successful in 34s
test / build-infra (pull_request) Successful in 3m32s
test / integration-firecracker (pull_request) Successful in 1m41s
test / coverage (pull_request) Failing after 57s
test / publish-infra (pull_request) Has been skipped

This commit is contained in:
2026-07-19 22:25:45 +00:00
parent 701f5bf5e3
commit 4252ca3562
5 changed files with 43 additions and 1 deletions
+23
View File
@@ -40,13 +40,36 @@ on:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
stage-firecracker-inputs:
runs-on: [self-hosted, kvm]
steps:
- name: Stage the provisioned static dropbear
run: |
mkdir -p firecracker-inputs
cp /var/cache/bot-bottle-fc/dropbear firecracker-inputs/dropbear
- name: Upload Firecracker build inputs
uses: actions/upload-artifact@v3
with:
name: firecracker-inputs
path: firecracker-inputs/
build-infra: build-infra:
needs: stage-firecracker-inputs
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Download Firecracker build inputs
uses: actions/download-artifact@v3
with:
name: firecracker-inputs
path: firecracker-inputs
- name: Build infra candidate from this checkout - name: Build infra candidate from this checkout
env:
BOT_BOTTLE_FC_DROPBEAR: ${{ github.workspace }}/firecracker-inputs/dropbear
run: python3 -m bot_bottle.backend.firecracker.publish_infra --output infra-candidate run: python3 -m bot_bottle.backend.firecracker.publish_infra --output infra-candidate
- name: Upload infra candidate - name: Upload infra candidate
@@ -87,6 +87,9 @@ def infra_artifact_version(init_script: str, *, repo_root: Path = _REPO_ROOT) ->
h.update((repo_root / name).read_bytes()) h.update((repo_root / name).read_bytes())
h.update(b"pyproject.toml\0") h.update(b"pyproject.toml\0")
h.update((repo_root / "pyproject.toml").read_bytes()) h.update((repo_root / "pyproject.toml").read_bytes())
h.update(b"dropbear\0")
dropbear = util.dropbear_path()
h.update(dropbear.read_bytes() if dropbear.is_file() else b"<missing>")
h.update(b"init\0") h.update(b"init\0")
h.update(init_script.encode()) h.update(init_script.encode())
return h.hexdigest()[:16] return h.hexdigest()[:16]
@@ -197,6 +197,7 @@ def main(argv: list[str] | None = None) -> int:
print(f"built infra rootfs candidate {version}") print(f"built infra rootfs candidate {version}")
return 0 return 0
assert args.publish_dir is not None
version = _publish_bundle(args.publish_dir, token) version = _publish_bundle(args.publish_dir, token)
print(f"published infra rootfs {version}") print(f"published infra rootfs {version}")
return 0 return 0
+14
View File
@@ -105,6 +105,20 @@ class TestVersionInputs(unittest.TestCase):
after = ia.infra_artifact_version("init", repo_root=root) after = ia.infra_artifact_version("init", repo_root=root)
self.assertNotEqual(before, after) self.assertNotEqual(before, after)
def test_dropbear_change_bumps_version(self) -> None:
with tempfile.TemporaryDirectory() as d:
root = Path(d)
self._fake_repo(root)
dropbear = root / "dropbear"
dropbear.write_bytes(b"dropbear-v1")
with mock.patch.dict(os.environ, {
"BOT_BOTTLE_FC_DROPBEAR": str(dropbear),
}):
before = ia.infra_artifact_version("init", repo_root=root)
dropbear.write_bytes(b"dropbear-v2")
after = ia.infra_artifact_version("init", repo_root=root)
self.assertNotEqual(before, after)
def test_non_python_file_change_bumps_version(self) -> None: def test_non_python_file_change_bumps_version(self) -> None:
with tempfile.TemporaryDirectory() as d: with tempfile.TemporaryDirectory() as d:
root = Path(d) root = Path(d)
+2 -1
View File
@@ -7,6 +7,7 @@ read it into memory. Network is mocked; no Docker, no real build.
from __future__ import annotations from __future__ import annotations
import hashlib import hashlib
from email.message import Message
import tempfile import tempfile
import unittest import unittest
import urllib.error import urllib.error
@@ -88,7 +89,7 @@ class TestPublishBundle(unittest.TestCase):
with tempfile.TemporaryDirectory() as d: with tempfile.TemporaryDirectory() as d:
root = Path(d) root = Path(d)
self._bundle(root, "v1") self._bundle(root, "v1")
missing = urllib.error.HTTPError("u", 404, "missing", {}, None) missing = urllib.error.HTTPError("u", 404, "missing", Message(), None)
with mock.patch.object( with mock.patch.object(
pub.infra_artifact, "infra_artifact_version", return_value="v1" pub.infra_artifact, "infra_artifact_version", return_value="v1"
), mock.patch.object( ), mock.patch.object(