Pin and update test container image references regularly

Assisted-by: Copilot v1.0.59 (Claude Sonnet 4.6)
Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
This commit is contained in:
Pablo Zmdl
2026-07-02 13:06:16 +02:00
parent 6589878dc6
commit bf473324ba
4 changed files with 119 additions and 4 deletions
+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Update container image digests in configured docker compose files and Dockerfiles.
The script will look for matches for `<imagename>:<tag>@sha256:<digest>` in those files and update the digest,
if a different one is found for `<imagename>:<tag>` at the registry.
Requires: skopeo
"""
import re
import subprocess
import sys
# Change this to add more files to check.
FILES = {
"compose": [
"php/tests/compose.yaml",
],
"dockerfile": [
"php/tests/Containers/composer/Dockerfile",
],
}
PREFIX = {
"compose": "image: ",
"dockerfile": "FROM ",
}
# Matches `<prefix><imagename>:<tag>@sha256:<digest>`
IMAGE_RE = r"{prefix}([^\s@]+:[^\s@]+)@(sha256:[a-f0-9]+)"
if subprocess.run(["which", "skopeo"], capture_output=True).returncode != 0:
sys.exit("Error: skopeo is not installed. Install it from https://github.com/containers/skopeo#installation")
def update_image_digest(content, full_ref, current_digest, file_path):
result = subprocess.run(
[
"skopeo", "inspect",
"--override-os", "linux",
"--no-tags",
"--format", "{{.Digest}}",
f"docker://{full_ref}",
],
capture_output=True, text=True, check=True,
)
latest_digest = result.stdout.strip()
msg_prefix = f"{file_path}: {full_ref}"
if latest_digest == current_digest:
print(f"{msg_prefix}: already up to date.")
return content
old = f"{full_ref}@{current_digest}"
count = content.count(old)
content = content.replace(old, f"{full_ref}@{latest_digest}")
print(f"{msg_prefix}: updated {count} occurrence(s) to {latest_digest}.")
return content
def update_file(file_path, prefix):
with open(file_path) as f:
content = f.read()
images = re.findall(IMAGE_RE.format(prefix=re.escape(prefix)), content)
if not images:
print(f"{file_path}: no pinned image references found.")
return
# Run only once for every pair of file_path and image.
unique_images = list(dict.fromkeys(images))
for full_ref, current_digest in unique_images:
content = update_image_digest(content, full_ref, current_digest, file_path)
with open(file_path, "w") as f:
f.write(content)
def main():
for file_type, paths in FILES.items():
for path in paths:
update_file(path, PREFIX[file_type])
if __name__ == "__main__":
main()
@@ -0,0 +1,28 @@
name: update-test-container-image-references
on:
workflow_dispatch:
schedule:
- cron: '00 5 * * *'
jobs:
update:
name: Update test container image references
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install skopeo
run: sudo apt-get install -y skopeo
- name: Run update script
run: python3 .ci/update-image-reference.py
- name: Create Pull Request
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v7
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "chore(tests): update test container image references"
signoff: true
title: Update test container image references
body: Automated update of node and playwright image digests in php/tests/compose.yaml
labels: dependencies, 3. to review
milestone: next
branch: update-test-container-image-references
+1 -1
View File
@@ -1,4 +1,4 @@
FROM docker.io/library/composer:latest
FROM docker.io/library/composer:2@sha256:7725eb4545c438629ae8bde3ef0bb9a5038ef566126ad878442a69007242d267
RUN pecl bundle -d /usr/src/php/ext apcu \
&& docker-php-ext-install apcu
+3 -3
View File
@@ -59,21 +59,21 @@ services:
- local-code
desec-mock:
image: docker.io/library/node:latest
image: docker.io/library/node:26@sha256:b46a10d964ad15136ebdf9012142131481caa0697d7a4d4eafe4bbabd818f876
volumes:
- ..:/app/php
working_dir: /app
command: node php/tests/desec-mock.mjs 8090 2>&1
npm-installer:
image: docker.io/library/node:latest
image: docker.io/library/node:26@sha256:b46a10d964ad15136ebdf9012142131481caa0697d7a4d4eafe4bbabd818f876
volumes:
- ..:/app
working_dir: /app/tests
command: npm ci --omit=optional
test-runner-base:
image: mcr.microsoft.com/playwright:v1.56.1
image: mcr.microsoft.com/playwright:v1.56.1@sha256:f1e7e01021efd65dd1a2c56064be399f3e4de00fd021ac561325f2bfbb2b837a
volumes:
- ..:/app
working_dir: /app/tests