feat: ci-python CI-Basis-Image + Build-Workflow
Build ci-python image / build (push) Failing after 2m53s
Build ci-python image / build (push) Failing after 2m53s
Vorgebackenes Python-CI-Image (debian:bookworm-slim + uv, gepinnte CPython 3.12.13, ruff 0.16.1, pytest 9.1.1) fuer Gitea Actions. Basis + uv per Digest gepinnt, Versionen zentral im Dockerfile-Kopf. Build-Workflow pusht :latest + :<sha> in die Gitea-Registry (sko/ci-python), woechentlicher Rebuild. Lokal verifiziert: Build gruen, 397 MB, uv sync --frozen + Exporter-Imports OK. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
name: Build ci-python image
|
||||
|
||||
# Baut das ci-python-Image und pusht es in die Gitea-Container-Registry.
|
||||
# Tags: :latest (mitlaufend) + :<sha> (unveränderlich, zum Pinnen in Workflows).
|
||||
#
|
||||
# Voraussetzungen im Runner:
|
||||
# - Docker verfügbar (Socket oder DinD) — Image-Bau braucht einen Docker-Daemon.
|
||||
# - Secrets: REGISTRY_USER (Gitea-User) + REGISTRY_TOKEN (PAT, Scope package:write).
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'python/Dockerfile'
|
||||
- '.gitea/workflows/build-ci-python.yml'
|
||||
schedule:
|
||||
- cron: '0 3 * * 1' # wöchentlicher Rebuild für Basis-Sicherheitsupdates
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: gitea.inmedias.it
|
||||
IMAGE: sko/ci-python
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Gitea registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Build & push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: python
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE }}:latest
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ github.sha }}
|
||||
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE }}:buildcache
|
||||
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE }}:buildcache,mode=max
|
||||
@@ -0,0 +1,2 @@
|
||||
*.log
|
||||
.DS_Store
|
||||
@@ -0,0 +1,54 @@
|
||||
# ci-images
|
||||
|
||||
Vorgebackene CI-Basis-Images für Gitea Actions. Ziel: schneller Cold-Start und
|
||||
reproduzierbare Läufe, statt Werkzeuge bei jedem Lauf per `curl | sh` /
|
||||
`pip install` nachzuladen (siehe Recherche „CI/CD-Optimierung mit Docker & Ansible").
|
||||
|
||||
## Images
|
||||
|
||||
| Image | Registry-Pfad | Inhalt |
|
||||
|-------|---------------|--------|
|
||||
| `ci-python` | `gitea.inmedias.it/sko/ci-python` | `debian:bookworm-slim` + uv + gepinnte CPython, ruff, pytest |
|
||||
|
||||
Weitere Stacks (z. B. `ci-node`) kommen als eigene Unterordner nach demselben
|
||||
Muster dazu, sobald der Python-Pilot trägt.
|
||||
|
||||
## Versionen pflegen (eine Quelle der Wahrheit)
|
||||
|
||||
Alle Versionen stehen als `ARG` bzw. gepinnter Digest oben im jeweiligen
|
||||
`Dockerfile` (z. B. `python/Dockerfile`). Ändern → auf `main` pushen → der
|
||||
Workflow `build-ci-python` baut und pusht neu.
|
||||
|
||||
Digests auffrischen:
|
||||
|
||||
```bash
|
||||
docker buildx imagetools inspect debian:bookworm-slim
|
||||
docker buildx imagetools inspect ghcr.io/astral-sh/uv:0.12.1
|
||||
```
|
||||
|
||||
## Verwendung in einem Repo (Weg B: `container:`, kein Runner-Eingriff)
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
container: gitea.inmedias.it/sko/ci-python:latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: uv sync --frozen # repo-eigene Deps aus uv.lock
|
||||
- run: ruff check .
|
||||
- run: pytest
|
||||
```
|
||||
|
||||
Zum reproduzierbaren Pinnen statt `:latest` einen unveränderlichen `:<sha>`-Tag
|
||||
verwenden.
|
||||
|
||||
Registry-Login für den Pull passiert im Runner über einen `container.credentials`-
|
||||
Block oder `docker/login-action` gegen `gitea.inmedias.it` (PAT, Scope `package:read`).
|
||||
|
||||
## Build lokal testen
|
||||
|
||||
```bash
|
||||
docker build -t ci-python:test python
|
||||
docker run --rm ci-python:test python --version
|
||||
```
|
||||
@@ -0,0 +1,60 @@
|
||||
# ci-python — vorgebackenes CI-Image für Python-Repos (Gitea Actions)
|
||||
#
|
||||
# Basis: debian:bookworm-slim (firmenweite Distro-Linie), Toolchain über uv.
|
||||
# Ziel: schneller Cold-Start + reproduzierbare Läufe (kein `curl | sh` / kein
|
||||
# `pip install` zur Laufzeit mehr). Repo-eigene Deps kommen weiterhin per
|
||||
# `uv sync --frozen` aus dem jeweiligen uv.lock — dieses Image liefert nur die
|
||||
# Toolchain (Python, uv, ruff, pytest).
|
||||
#
|
||||
# Versionen stehen ausschliesslich hier (eine Quelle der Wahrheit). Aktualisieren
|
||||
# heisst: ARG/Digest anpassen -> Push -> Build-Workflow baut & pusht neu.
|
||||
|
||||
# Basis per Digest gepinnt (reproduzierbar). Auflösen mit:
|
||||
# docker buildx imagetools inspect debian:bookworm-slim
|
||||
FROM debian:bookworm-slim@sha256:7b140f374b289a7c2befc338f42ebe6441b7ea838a042bbd5acbfca6ec875818
|
||||
|
||||
# --- zentrale Versionsliste ---------------------------------------------------
|
||||
ARG PYTHON_VERSION=3.12.13
|
||||
ARG RUFF_VERSION=0.16.1
|
||||
ARG PYTEST_VERSION=9.1.1
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
# 1) Selten ändernde Systemschicht zuerst -> Cache greift lange.
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 2) uv aus dem offiziellen, digest-gepinnten uv-Image kopieren.
|
||||
# Digest auflösen mit: docker buildx imagetools inspect ghcr.io/astral-sh/uv:0.12.1
|
||||
COPY --from=ghcr.io/astral-sh/uv:0.12.1@sha256:cf4eedcaa81655197f625739489effcbe71b61ceb1506f332c3facae5deceded \
|
||||
/uv /uvx /usr/local/bin/
|
||||
|
||||
# 3) uv systemweit verdrahten: managed Python, keine Suche nach System-Python,
|
||||
# Tool-Bins landen in /usr/local/bin (auf PATH).
|
||||
ENV UV_PYTHON_INSTALL_DIR=/opt/uv/python \
|
||||
UV_TOOL_DIR=/opt/uv/tools \
|
||||
UV_TOOL_BIN_DIR=/usr/local/bin \
|
||||
UV_PYTHON_PREFERENCE=only-managed \
|
||||
UV_LINK_MODE=copy \
|
||||
UV_NO_PROGRESS=1
|
||||
|
||||
# 4) Gepinnte CPython einbacken und als Default `python`/`python3` verdrahten.
|
||||
RUN uv python install "${PYTHON_VERSION}" \
|
||||
&& ln -sf "$(uv python find "${PYTHON_VERSION}")" /usr/local/bin/python3 \
|
||||
&& ln -sf /usr/local/bin/python3 /usr/local/bin/python
|
||||
|
||||
# 5) Lint-/Test-Tools global (schnelle CI ohne per-Repo-Install).
|
||||
RUN uv tool install "ruff==${RUFF_VERSION}" \
|
||||
&& uv tool install "pytest==${PYTEST_VERSION}"
|
||||
|
||||
# 6) Smoke-Test beim Bau: bricht den Build ab, falls etwas nicht auf PATH liegt.
|
||||
RUN python --version \
|
||||
&& uv --version \
|
||||
&& ruff --version \
|
||||
&& pytest --version
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
Reference in New Issue
Block a user