ci: migrate workflows to Gitea Actions
This commit is contained in:
+17
-14
@@ -1,7 +1,7 @@
|
||||
# Deployment mit einem Image aus der Container Registry
|
||||
|
||||
Proxmox AIS wird auf dem Zielserver aus einem bereits veröffentlichten
|
||||
Containerimage gestartet. Der [GitHub-Actions-Workflow](github-actions.md) erstellt dieses Image; auf dem
|
||||
Containerimage gestartet. Der [Gitea-Actions-Workflow](gitea-actions.md) erstellt dieses Image; auf dem
|
||||
Zielserver werden nur Docker Compose und die Betriebskonfiguration benötigt.
|
||||
Diese Anleitung setzt einen erfolgreichen `container-publish`-Job und ein
|
||||
weiterhin abrufbares Image voraus.
|
||||
@@ -42,20 +42,20 @@ Wert führt bereits bei der Konfigurationsprüfung zu einem Fehler.
|
||||
|
||||
## Image und öffentliche Adresse festlegen
|
||||
|
||||
In GitHub unter **Actions** den erfolgreichen Workflow-Lauf mit
|
||||
In Gitea unter **Actions** den erfolgreichen Workflow-Lauf mit
|
||||
`container-publish` öffnen, unter **Artifacts** das Archiv `container-deploy`
|
||||
herunterladen und entpacken. Es enthält `build.env` und `deploy.env`.
|
||||
Die vollständige Zeile `PROVISIONER_IMAGE=…@sha256:…` aus `deploy.env` in die
|
||||
`.env` auf dem Zielserver übernehmen. Der Digest legt genau das veröffentlichte
|
||||
Image fest. Compose liest `deploy.env` nicht automatisch ein.
|
||||
[GitHub-Artefakte herunterladen](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/download-workflow-artifacts).
|
||||
|
||||
Alternativ auf GitHub das zugehörige **Packages**-Paket öffnen und den vollständigen
|
||||
Alternativ in Gitea beim Benutzer `BartelLuis` das zugehörige **Packages**-Paket
|
||||
öffnen und den vollständigen
|
||||
Imagepfad mit einem tatsächlich vorhandenen Versions-Tag kopieren. Der aktuelle
|
||||
Imagepfad der Beispieldatei sieht so aus:
|
||||
|
||||
```dotenv
|
||||
PROVISIONER_IMAGE=ghcr.io/netivra/proxmox-ais:0.1.0
|
||||
PROVISIONER_IMAGE=gitlab.bartelluis.de/bartelluis/proxmox-ais-server:0.1.0
|
||||
PUBLIC_URL=https://provision.example.net
|
||||
MAINTENANCE=false
|
||||
```
|
||||
@@ -64,7 +64,9 @@ MAINTENANCE=false
|
||||
Imagepfad entspricht dem aktuellen Wert der Vorlage; die Verfügbarkeit des
|
||||
Tags `0.1.0` wird damit nicht vorausgesetzt. Maßgeblich sind das
|
||||
Pipeline-Artefakt oder die Registry-Anzeige deines Projekts.
|
||||
Der Registry-Endpunkt ist `ghcr.io`. Für reproduzierbare Deployments den Digest
|
||||
Der Registry-Endpunkt der Vorlage ist `gitlab.bartelluis.de`. Bei einer abweichenden
|
||||
CI-Registry den Host aus `deploy.env` auch für `docker login` verwenden.
|
||||
Für reproduzierbare Deployments den Digest
|
||||
bevorzugen und die bisher verwendeten Digests für spätere Updates aufbewahren.
|
||||
|
||||
`PUBLIC_URL` ist die vollständige HTTPS-Basisadresse ohne zusätzlichen Pfad,
|
||||
@@ -78,19 +80,20 @@ einrichten; `127.0.0.1` bezeichnet dort jeweils das eigene System.
|
||||
|
||||
## An der Registry anmelden und Image laden
|
||||
|
||||
Öffentliche GHCR-Pakete lassen sich ohne Anmeldung herunterladen. Für ein
|
||||
privates Paket einen GitHub Personal Access Token **(classic)** mit dem Scope
|
||||
`read:packages` verwenden. Das zugehörige GitHub-Konto benötigt Lesezugriff auf
|
||||
das Paket; bei Organisations-SSO den Token dafür autorisieren. Der Token wird
|
||||
Öffentliche Gitea-Pakete lassen sich ohne Anmeldung herunterladen. Für ein
|
||||
privates Paket einen Gitea Personal Access Token mit dem Scope
|
||||
`read:package` verwenden. Das zugehörige Gitea-Konto benötigt Lesezugriff auf
|
||||
das Paket. Der Token wird
|
||||
bei der Anmeldung als Passwort verdeckt eingegeben und gehört nicht in `.env`.
|
||||
Das kurzlebige `GITHUB_TOKEN` des CI-Jobs ist kein Deployment-Zugang.
|
||||
[GHCR-Authentifizierung](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-with-a-personal-access-token-classic).
|
||||
Das kurzlebige `GITEA_TOKEN` des CI-Jobs ist kein Deployment-Zugang.
|
||||
[Gitea-Container-Registry](https://docs.gitea.com/usage/packages/container/),
|
||||
[Paketberechtigungen](https://docs.gitea.com/usage/packages/overview/#access-restrictions).
|
||||
|
||||
Nur für private Pakete anmelden und `GITHUB_USERNAME` durch den GitHub-Namen
|
||||
Nur für private Pakete anmelden und `GITEA_USERNAME` durch den Gitea-Namen
|
||||
des Token-Inhabers ersetzen:
|
||||
|
||||
```bash
|
||||
docker login ghcr.io --username GITHUB_USERNAME
|
||||
docker login gitlab.bartelluis.de --username GITEA_USERNAME
|
||||
```
|
||||
|
||||
Konfiguration prüfen und das gewählte Image herunterladen:
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
# Gitea Actions und Container Registry
|
||||
|
||||
Das Projekt liegt auf
|
||||
[Gitea](https://gitlab.bartelluis.de/BartelLuis/Proxmox-AIS-Server).
|
||||
Der [Workflow](../.gitea/workflows/ci.yml) prüft Python und JavaScript, baut
|
||||
das Image und führt den Container-Smoke-Test aus. Bei aktivierter
|
||||
Veröffentlichung lädt er dasselbe getestete Image in die Gitea Container
|
||||
Registry. Der Workflow endet beim Image-Push; die Schritte auf dem Zielserver
|
||||
stehen in der [Deployment-Anleitung](deployment.md).
|
||||
|
||||
## Gitea und Runner einrichten
|
||||
|
||||
In den Repository-Einstellungen **Actions** aktivieren und unter
|
||||
**Settings → Actions → Runners** einen registrierten Runner prüfen oder
|
||||
einrichten. Gitea benötigt einen eigenen Runner-Dienst; ein GitHub-Runner-Label
|
||||
stellt keine Rechenkapazität bereit.
|
||||
[Gitea Actions einrichten](https://docs.gitea.com/usage/actions/quickstart/).
|
||||
|
||||
Alle Jobs verwenden `vars.AIS_RUNNER_LABEL` oder, wenn die Variable nicht gesetzt
|
||||
ist, `ubuntu-latest`. Das ausgewählte Label muss einem für dieses Repository
|
||||
verfügbaren, erreichbaren Linux-amd64-Runner entsprechen. Die Angabe
|
||||
`ubuntu-latest` wählt ein Runner-Label; sie installiert kein Ubuntu-Image.
|
||||
Für ein anderes Label in **Settings → Actions → Variables** beispielsweise
|
||||
`AIS_RUNNER_LABEL=ais-ci` setzen und genau dieses Label am Runner konfigurieren.
|
||||
|
||||
Die tatsächliche Job-Umgebung benötigt Git, Bash, OpenSSL, `ssh-keygen`, Python
|
||||
3.13 mit `venv`, Node.js 24 sowie Docker CLI und Buildx mit Zugriff auf einen
|
||||
laufenden Docker-Daemon. Die Setup-Actions richten Python 3.13 und Node.js 24
|
||||
für ihre jeweiligen Jobs ein. Die Umgebung muss außerdem bereits die
|
||||
JavaScript-Laufzeit zum Ausführen der Actions unterstützen. Bei einem
|
||||
Container-Runner müssen Werkzeuge und Docker-Zugriff im Job-Container verfügbar
|
||||
sein, nicht nur auf dem Host. Ein Standard-Node-Image allein enthält nicht die
|
||||
gesamte Build-Umgebung. Runner-Konfiguration und Label-Zuordnung sind in der
|
||||
[Runner-Anleitung](https://docs.gitea.com/1.26/usage/actions/act-runner/#labels)
|
||||
beschrieben.
|
||||
|
||||
Der Runner muss Gitea, die Registry, die absoluten Action-URLs im Workflow und
|
||||
die Downloadquellen für Python, Node.js, Python-Pakete und das Docker-Basisimage
|
||||
erreichen. Die Actions sind auf vollständige Commit-SHAs festgelegt.
|
||||
Der Artefakt-Upload verwendet die Gitea-kompatible Action
|
||||
`https://gitea.com/actions/gitea-upload-artifact`.
|
||||
|
||||
Diese Build-Umgebung ist unabhängig vom AIS-Host-Runner für die
|
||||
Postinstallation auf Proxmox-Hosts. CI-Code mit Docker-Zugriff auf einer dafür
|
||||
vorgesehenen Build-Maschine ausführen; Änderungen an Workflow und CI-Skripten
|
||||
vor der Übernahme prüfen.
|
||||
|
||||
## Registry und Veröffentlichung einrichten
|
||||
|
||||
Ohne `PUBLISH_IMAGES=true` führen alle Refs ausschließlich Prüfungen durch.
|
||||
In **Settings → Actions → Variables** folgende Repository-Variablen setzen:
|
||||
|
||||
| Variable | Wert und Bedeutung |
|
||||
| --- | --- |
|
||||
| `AIS_RUNNER_LABEL` | Optional: Label eines verfügbaren Runners; Standard `ubuntu-latest` |
|
||||
| `REGISTRY_HOST` | Optional: Registry-Host ohne Schema oder Pfad; Standard `gitlab.bartelluis.de` |
|
||||
| `REGISTRY_USERNAME` | Gitea-Benutzername des Token-Inhabers; für Veröffentlichung erforderlich |
|
||||
| `PUBLISH_IMAGES` | Genau `true`, nachdem Registry-Zugang und Schutzregeln eingerichtet sind |
|
||||
|
||||
Im Gitea-Benutzerkonto einen Personal Access Token mit Paket-Schreibrecht
|
||||
(`write:package`, in der Oberfläche **package: Read & Write**) erstellen.
|
||||
Den Wert unter **Settings → Actions → Secrets** als `REGISTRY_TOKEN` speichern.
|
||||
Das zugehörige Konto muss beim Paketinhaber `BartelLuis` Schreibzugriff besitzen.
|
||||
Das kurzlebige `GITEA_TOKEN` des Jobs unterstützt die Paketveröffentlichung
|
||||
nicht; es ersetzt dieses Secret nicht.
|
||||
[Gitea-Secrets](https://docs.gitea.com/usage/actions/secrets/),
|
||||
[Paketberechtigungen](https://docs.gitea.com/usage/packages/overview/#access-restrictions),
|
||||
[Gitea-Paketautorisierung](https://docs.gitea.com/usage/actions/comparison/#package-repository-authorization).
|
||||
|
||||
Der Imagepfad ist `<REGISTRY_HOST>/<kleingeschriebener Repositoryname>`, hier
|
||||
`gitlab.bartelluis.de/bartelluis/proxmox-ais-server`. Bei einem Fork oder einer
|
||||
Umbenennung ändert sich der Pfad. Pakete gehören in Gitea einem Benutzer oder
|
||||
einer Organisation. Nach dem ersten Push kann das Paket in seinen Einstellungen
|
||||
mit dem Repository verknüpft werden, damit es auch in dessen Paketliste erscheint.
|
||||
[Gitea Container Registry](https://docs.gitea.com/usage/packages/container/).
|
||||
|
||||
## Standardbranch und Release-Tags schützen
|
||||
|
||||
Vor `PUBLISH_IMAGES=true` in den Gitea-Repository-Einstellungen den
|
||||
Standardbranch `main` und die Release-Tags schützen. Für `main` direkte Pushes
|
||||
deaktivieren, Reviews und erfolgreiche Statuschecks verlangen sowie Force-Push
|
||||
und Löschen einschränken.
|
||||
Für `v*` die Erstellung, Änderung und Löschung auf Release-Verantwortliche
|
||||
begrenzen. Release-Tags auf einen geprüften Commit mit passender Projektversion
|
||||
setzen. Die Schutzregeln werden durch den Workflow-Commit nicht angelegt.
|
||||
[Geschützte Branches](https://docs.gitea.com/usage/access-control/protected-branches/),
|
||||
[Geschützte Tags](https://docs.gitea.com/usage/access-control/protected-tags/).
|
||||
|
||||
Nach dem ersten Pull-Request-Lauf die tatsächlich gemeldeten Statuskontexte
|
||||
für `python-tests`, `javascript-check`, `container-policy` und `container-verify`
|
||||
als verpflichtend auswählen. `container-publish` wird bei Pull Requests übersprungen und ist
|
||||
deshalb keine Pflichtprüfung.
|
||||
|
||||
Die CI entscheidet anhand von `PUBLISH_IMAGES`, Ereignis und Ref. Sie fragt
|
||||
keinen Schutzstatus ab: Giteas kompatibler `ref_protected`-Wert ist dafür nicht
|
||||
verwendbar. Die Gitea-Schutzregeln und restriktive Schreibrechte bleiben daher
|
||||
ein eigener Einrichtungsschritt.
|
||||
|
||||
## Auslöser und Image-Tags
|
||||
|
||||
Der Workflow läuft bei Branch- und Tag-Pushes, bei Pull Requests sowie bei
|
||||
manuellem Start über `workflow_dispatch`.
|
||||
|
||||
| Ref und Ereignis | Container-Job | Veröffentlichung |
|
||||
| --- | --- | --- |
|
||||
| `PUBLISH_IMAGES` fehlt oder ist nicht `true` | `container-verify` | Keine |
|
||||
| Pull Request, Feature-Branch oder sonstiger Tag | `container-verify` | Keine |
|
||||
| Standardbranch, Push oder manueller Start, Veröffentlichung aktiviert | `container-publish` | `sha-<vollständiger Commit-SHA>` und `edge` |
|
||||
| Tag `vX.Y.Z`, Push oder manueller Start, Veröffentlichung aktiviert | `container-publish` | `sha-<vollständiger Commit-SHA>` und `X.Y.Z` |
|
||||
|
||||
Release-Tags müssen vollständig dem Muster
|
||||
`v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)` entsprechen. Führende
|
||||
Nullen, Vorabversionen und Build-Zusätze veröffentlichen kein Image.
|
||||
Bei einem zur Veröffentlichung ausgewählten Release muss die Version außerdem
|
||||
exakt `[project].version` in [pyproject.toml](../pyproject.toml) entsprechen;
|
||||
eine Abweichung bricht den Publish-Job ab.
|
||||
|
||||
`edge` ist ein beweglicher Tag. Ein erneuter Lauf eines älteren Commits kann
|
||||
ihn zurücksetzen. SHA-Tags enthalten alle 40 Zeichen des Commits; externe
|
||||
Build-Abhängigkeiten können bei erneuten Builds zu einem anderen Digest führen.
|
||||
Es gibt keinen `latest`-Tag. Im Betrieb den Digest aus `deploy.env` verwenden
|
||||
und bisherige Registry-Versionen für Updates und Rollback aufbewahren.
|
||||
|
||||
## Jobs und Artefakte
|
||||
|
||||
`python-tests` führt über [ci/python-tests.sh](../ci/python-tests.sh) Pytest in
|
||||
einer temporären virtuellen Umgebung aus. `javascript-check` prüft mit
|
||||
`node --check provisioner/static/app.js` die JavaScript-Syntax.
|
||||
`container-policy` wählt den Container-Job aus. Nach erfolgreichen
|
||||
Quellcodeprüfungen läuft genau einer der Jobs `container-verify` und
|
||||
`container-publish`. Beide verwenden [ci/container.sh](../ci/container.sh);
|
||||
das Skript prüft vor einer Veröffentlichung erneut Ereignis, Ref und Opt-in.
|
||||
|
||||
Der [Container-Smoke-Test](../tests/container_smoke.py) prüft das gebaute
|
||||
`linux/amd64`-Image auf TLS, Anmeldung, CSRF, Webdateien und Datenerhalt über
|
||||
einen Dienstneustart. Er läuft als UID 10001 mit schreibgeschütztem Dateisystem,
|
||||
entfernten Linux-Capabilities und temporären Testdaten. Eine Proxmox-Installation
|
||||
ist kein Bestandteil dieses Tests. Der Publish-Job lädt das getestete Image
|
||||
ohne zweiten Build hoch. OCI-Labels enthalten Quellrepository, Commit und
|
||||
Anwendungsversion; Provenance- und SBOM-Attestierungen werden nicht erzeugt.
|
||||
|
||||
| Artefakt im Gitea-Lauf | Inhalt | Angefragte Aufbewahrung |
|
||||
| --- | --- | --- |
|
||||
| `python-test-results` | `reports/pytest.xml`, auch bei fehlgeschlagenen Tests, sofern erzeugt | 7 Tage |
|
||||
| `container-build` | `build.env` nach erfolgreicher Verifikation | 7 Tage |
|
||||
| `container-deploy` | `build.env` und `deploy.env` nach erfolgreicher Veröffentlichung | 30 Tage |
|
||||
|
||||
Die tatsächliche Aufbewahrung unterliegt der Gitea-Instanzkonfiguration.
|
||||
Unter **Actions** den erfolgreichen Lauf öffnen und das gewünschte Artefakt
|
||||
herunterladen. `build.env` enthält den temporären lokalen Image-Tag, Commit
|
||||
und Anwendungsversion. Der lokale `ci-…`-Tag wird nicht veröffentlicht und am
|
||||
Jobende entfernt. `deploy.env` enthält ausschließlich
|
||||
`PROVISIONER_IMAGE=gitlab.bartelluis.de/bartelluis/proxmox-ais-server@sha256:…`
|
||||
beziehungsweise die konfigurierte Registry-Adresse. Beide Dateien enthalten
|
||||
keine Zugangsdaten. Die Image-Zeile in `.env` auf dem Zielserver übernehmen.
|
||||
|
||||
## Erster Lauf und Release
|
||||
|
||||
Nach dem Push unter **Actions** prüfen, dass der Lauf einen Runner erhält und
|
||||
Python-, JavaScript- und Containerprüfungen erfolgreich sind. Nach aktivierter
|
||||
Veröffentlichung muss ein Standardbranch-Lauf außerdem die Image-Tags
|
||||
`sha-<Commit>` und `edge` sowie `container-deploy` mit `deploy.env` liefern.
|
||||
Lokale Tests ersetzen diesen Lauf mit Registry-Anmeldung und Push nicht.
|
||||
|
||||
Für ein Release zuerst `[project].version` ändern und den geprüften Commit
|
||||
übernehmen. Anschließend mit einem berechtigten Konto den passenden Tag
|
||||
erstellen und an den Gitea-Remote pushen. Im vorhandenen Checkout heißt er
|
||||
`origin`; vor dem Push mit `git remote -v` prüfen. Für Projektversion `0.1.0`,
|
||||
sofern der Tag noch nicht existiert:
|
||||
|
||||
```bash
|
||||
git tag -a v0.1.0 -m "Release 0.1.0"
|
||||
git push origin v0.1.0
|
||||
```
|
||||
|
||||
Der Release-Lauf muss den Image-Tag `0.1.0` erzeugen. Für einen manuellen Lauf
|
||||
unter **Actions** den Workflow und den gewünschten Ref auswählen. Auch dabei
|
||||
gelten Opt-in, Standardbranch- beziehungsweise Tag-Regel und Versionsabgleich.
|
||||
Branch-Push und Pull Request können für denselben Quellstand getrennte Läufe
|
||||
erzeugen. Pull Requests veröffentlichen keine Images.
|
||||
|
||||
## Fehlersuche und Deployment
|
||||
|
||||
Bei **Waiting** beziehungsweise **no matching online runner** das angeforderte
|
||||
Label mit den erreichbaren Runnern unter **Settings → Actions → Runners**
|
||||
vergleichen. Der bisherige Workflow verlangte `ubuntu-24.04`; dafür war kein
|
||||
passender Online-Runner verfügbar. `AIS_RUNNER_LABEL` auf ein tatsächlich
|
||||
vorhandenes Label setzen oder einen geeigneten Runner registrieren und starten.
|
||||
Ein Label-Wechsel allein ersetzt keine fehlende Runner-Installation.
|
||||
|
||||
Bei fehlendem Docker-Zugriff `docker info` und `docker buildx version` in der
|
||||
Job-Umgebung prüfen. Bei DNS-, Checkout- oder Artefaktfehlern müssen Giteas
|
||||
öffentliche `ROOT_URL`, die Checkout-Adresse und die vom Runner erreichbare
|
||||
Adresse zusammenpassen. Das Projekt verwendet `gitlab.bartelluis.de`; eine
|
||||
von der Instanz zurückgegebene abweichende Adresse wie `git.bartelluis.de` muss
|
||||
ebenfalls auflösbar und erreichbar sein oder in der Gitea-Konfiguration
|
||||
korrigiert werden.
|
||||
|
||||
Bei übersprungenem Publish-Job `PUBLISH_IMAGES`, Ereignis, Standardbranch und
|
||||
Tagformat prüfen. Bei `denied` oder `unauthorized` Registry-Host, Benutzername,
|
||||
`REGISTRY_TOKEN`, dessen `write:package`-Scope und die Rechte am Paketinhaber
|
||||
kontrollieren. Bei Versionsfehlern Git-Tag und `pyproject.toml` abgleichen.
|
||||
Fehlt `container-deploy`, die Build-, Smoke-, Push- und Upload-Logs prüfen.
|
||||
|
||||
Zum Deployment [compose.yaml](../compose.yaml) und
|
||||
[config/deployment.env.example](../config/deployment.env.example) auf den
|
||||
Zielserver kopieren. Die [Deployment-Anleitung](deployment.md) beschreibt
|
||||
Registry-Anmeldung, Erstinitialisierung, HTTPS-Prüfung, Updates und Rollback.
|
||||
Für private Pakete benötigt das Deploymentkonto einen eigenen Token mit
|
||||
`read:package`; öffentliche Pakete lassen sich anonym laden.
|
||||
+3
-202
@@ -1,203 +1,4 @@
|
||||
# GitHub Actions und Container Registry
|
||||
# CI/CD ist nach Gitea umgezogen
|
||||
|
||||
Der [Workflow](../.github/workflows/ci.yml) führt die Python-Tests aus, prüft die
|
||||
JavaScript-Syntax und baut und testet das Anwendungsimage. Freigegebene Builds
|
||||
werden in die GitHub Container Registry (GHCR) veröffentlicht. Der Workflow
|
||||
endet beim Image-Push und aktualisiert keinen Zielserver. Die anschließenden
|
||||
Betriebsschritte stehen in der [Deployment-Anleitung](deployment.md).
|
||||
|
||||
## Auslöser und Image-Tags
|
||||
|
||||
Der Workflow läuft bei Pushes auf alle Branches und Tags, bei Pull Requests
|
||||
und beim manuellen Start mit `workflow_dispatch`.
|
||||
|
||||
| Ref und Ereignis | Container-Job | Veröffentlichung |
|
||||
| --- | --- | --- |
|
||||
| Pull Request, auch aus einem Fork | `container-verify` | Keine |
|
||||
| Feature-Branch, ungeschützter Ref oder sonstiger Tag | `container-verify` | Keine |
|
||||
| Geschützter Standardbranch bei Push oder manuellem Start | `container-publish` | `sha-<vollständiger Commit-SHA>` und `edge` |
|
||||
| Geschützter Tag `vX.Y.Z` bei Push oder manuellem Start | `container-publish` | `sha-<vollständiger Commit-SHA>` und `X.Y.Z` |
|
||||
|
||||
Release-Tags müssen dem Muster `v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)`
|
||||
vollständig entsprechen. Führende Nullen, Vorabversionen wie `v1.0.0-rc.1` und
|
||||
Build-Zusätze veröffentlichen daher kein Image. Bei einem gültigen geschützten
|
||||
Release-Tag muss dessen Version außerdem exakt `[project].version` in
|
||||
[pyproject.toml](../pyproject.toml) entsprechen; eine Abweichung bricht den Lauf ab.
|
||||
|
||||
Das Image liegt für dieses Repository unter `ghcr.io/netivra/proxmox-ais`.
|
||||
Der Workflow leitet den Pfad aus dem kleingeschriebenen GitHub-Repositorynamen
|
||||
ab; bei einem Fork oder einer Umbenennung ändert sich deshalb der Imagepfad.
|
||||
`edge` bezeichnet den zuletzt veröffentlichten Standardbranch-Build. Ein
|
||||
erneuter Lauf eines älteren Commits kann `edge` zurücksetzen. SHA-Tags enthalten
|
||||
alle 40 Zeichen des Commits; erneute Builds desselben Quellstands können durch
|
||||
externe Build-Abhängigkeiten einen anderen Digest ergeben. Es gibt keinen
|
||||
`latest`-Tag. Im Betrieb den Digest aus `deploy.env` verwenden und die
|
||||
zugehörigen Registry-Versionen für Updates und Rollback aufbewahren.
|
||||
|
||||
## Jobs und Artefakte
|
||||
|
||||
`python-tests` und `javascript-check` prüfen den Quellstand. Das Skript
|
||||
[ci/python-tests.sh](../ci/python-tests.sh) installiert `.[dev]` in einer
|
||||
eigenen temporären virtuellen Umgebung, führt Pytest aus und entfernt die
|
||||
Umgebung anschließend. Die JavaScript-Prüfung verwendet
|
||||
`node --check provisioner/static/app.js`; sie ist kein Browsertest.
|
||||
`container-policy` bestimmt anhand des GitHub-Ereignisses, des Ref-Schutzes
|
||||
und des Branch- beziehungsweise Tag-Namens, welcher Container-Job laufen darf.
|
||||
|
||||
Nach erfolgreichen Python- und JavaScript-Prüfungen läuft genau einer der
|
||||
Jobs `container-verify` und `container-publish`. Beide bauen über
|
||||
[ci/container.sh](../ci/container.sh) ein `linux/amd64`-Image und prüfen es
|
||||
mit dem [Container-Smoke-Test](../tests/container_smoke.py). Der Publish-Job
|
||||
lädt genau das bereits getestete Image hoch, ohne einen zweiten Build.
|
||||
Die Veröffentlichung wird im Skript erneut auf Ereignis und Ref geprüft;
|
||||
dort erfolgt auch der Abgleich mit der Projektversion.
|
||||
|
||||
Publish-Jobs teilen eine Warteschlange mit `queue: max` und laufen einzeln.
|
||||
Bis zu 100 Jobs können warten; ein laufender Publish-Job wird durch neue
|
||||
Commits nicht abgebrochen. Die Reihenfolge richtet sich nach dem Eintritt in
|
||||
die Warteschlange, nicht zwingend nach dem Alter der Commits. Bei Pull Requests
|
||||
und ungeschützten Refs ersetzt ein neuer Lauf den vorherigen Lauf desselben Refs.
|
||||
[GitHub-Parallelität und Warteschlangen](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency).
|
||||
|
||||
Der Smoke-Test prüft TLS, Anmeldung, CSRF, ausgelieferte Webdateien und
|
||||
Datenerhalt über einen Dienstneustart. Er läuft als UID 10001 mit
|
||||
schreibgeschütztem Dateisystem, entfernten Linux-Capabilities und temporären
|
||||
Testdaten. Eine Proxmox-Installation ist kein Bestandteil dieses Tests.
|
||||
|
||||
Der Build verwendet `--provenance=false --sbom=false` und veröffentlicht
|
||||
keine Provenance- oder SBOM-Attestierungen. Die OCI-Labels für Quellrepository,
|
||||
Commit und Anwendungsversion bleiben erhalten.
|
||||
|
||||
| Artefakt in GitHub Actions | Inhalt | Aufbewahrung |
|
||||
| --- | --- | --- |
|
||||
| `python-test-results` | `reports/pytest.xml` als JUnit-Datei, auch nach fehlgeschlagenen Tests, sofern erzeugt | 7 Tage |
|
||||
| `container-build` | `build.env` nach erfolgreichem Verify-Job | 7 Tage |
|
||||
| `container-deploy` | `build.env` und `deploy.env` nach erfolgreichem Publish-Job | 30 Tage |
|
||||
|
||||
Die Aufbewahrung wird im Workflow mit `retention-days` gesetzt und ist durch
|
||||
die übergeordneten GitHub-Einstellungen begrenzt. Die JUnit-Datei wird als
|
||||
Download bereitgestellt; der Workflow installiert keinen zusätzlichen
|
||||
Testberichtsdienst. Auf der Übersicht des jeweiligen Laufs unter **Artifacts**
|
||||
das gewünschte Archiv herunterladen und entpacken.
|
||||
[Workflow-Artefakte](https://docs.github.com/en/actions/tutorials/store-and-share-data),
|
||||
[Artefakte herunterladen](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/download-workflow-artifacts).
|
||||
|
||||
`build.env` enthält den temporären lokalen Image-Tag, Commit und
|
||||
Anwendungsversion. Dieser `ci-…`-Tag wird nicht veröffentlicht und beim
|
||||
Jobende lokal entfernt. `deploy.env` enthält ausschließlich die
|
||||
Deploymentreferenz `PROVISIONER_IMAGE=ghcr.io/netivra/proxmox-ais@sha256:…`.
|
||||
Die Dateien enthalten keine Zugangsdaten. `deploy.env` wird auf dem Zielserver
|
||||
nicht automatisch eingelesen; seine Image-Zeile in die dortige `.env` übernehmen.
|
||||
|
||||
## GitHub einrichten
|
||||
|
||||
Ein eigener CI-Runner ist nicht erforderlich. Alle Jobs verwenden
|
||||
GitHub-gehostete Linux-amd64-Runner mit `ubuntu-24.04`. Der Workflow richtet
|
||||
Python 3.13 über `actions/setup-python` und Node.js 24 über `actions/setup-node`
|
||||
ein. Docker und Buildx werden vom Runner bereitgestellt und vor dem Build
|
||||
geprüft. Bash, OpenSSL und der OpenSSH-Client werden dort ebenfalls verwendet.
|
||||
Diese Build-Umgebung ist
|
||||
unabhängig vom AIS-Host-Runner für die Postinstallation auf Proxmox-Hosts.
|
||||
[GitHub-gehostete Runner](https://docs.github.com/en/actions/reference/runners/github-hosted-runners).
|
||||
|
||||
Im Repository unter **Settings → Actions → General** GitHub Actions aktivieren
|
||||
und die im Workflow verwendeten Actions von `actions/*` zulassen. Diese sind
|
||||
im Workflow auf vollständige Commit-SHAs festgelegt. Es werden
|
||||
keine selbst angelegten Repository-Secrets oder CI-Variablen benötigt.
|
||||
Der Workflow verwendet standardmäßig `contents: read`; nur
|
||||
`container-publish` erhält zusätzlich `packages: write` und verwendet das
|
||||
automatisch bereitgestellte `GITHUB_TOKEN` für die Anmeldung an `ghcr.io`.
|
||||
[Actions-Einstellungen](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository).
|
||||
|
||||
GHCR-Pakete sind bei der ersten Veröffentlichung standardmäßig privat. Ein
|
||||
bereits existierendes Paket muss mit diesem Repository verbunden sein und
|
||||
dessen Actions Schreibzugriff haben. In den Paketeinstellungen unter
|
||||
**Manage Actions access** gegebenenfalls `Netivra/Proxmox-AIS` mit Schreibrecht
|
||||
hinzufügen. Dort auch die gewünschte Paketsichtbarkeit festlegen.
|
||||
[GHCR und GITHUB_TOKEN](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-in-a-github-actions-workflow),
|
||||
[Paketzugriff und Sichtbarkeit](https://docs.github.com/en/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility).
|
||||
|
||||
## Standardbranch und Release-Tags schützen
|
||||
|
||||
**Vor der ersten Veröffentlichung müssen aktive Schutzregeln für die
|
||||
veröffentlichten Refs eingerichtet sein.** Der Workflow und das Skript
|
||||
verlangen `github.ref_protected == true`. GitHub setzt dieses Merkmal, wenn
|
||||
Branchschutz oder ein passendes Ruleset für den auslösenden Ref konfiguriert
|
||||
ist. Ohne Schutz wird nur geprüft.
|
||||
[GitHub-Ref-Kontext](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#github-context).
|
||||
|
||||
Unter den Repository-Einstellungen für Rulesets zwei Regeln anlegen und
|
||||
jeweils **Enforcement status: Active** wählen:
|
||||
|
||||
| Ruleset | Ziel | Vorgesehene Regeln |
|
||||
| --- | --- | --- |
|
||||
| Standardbranch | **Include default branch**, etwa `main` | Pull Request und Review verlangen; Löschen und Force-Push verhindern; erfolgreiche Statuschecks verlangen |
|
||||
| Releases | Tags mit dem Muster `v*` | Erstellung, Aktualisierung und Löschung beschränken; nur Release-Verantwortliche in die Bypass-Liste aufnehmen |
|
||||
|
||||
Für Pull Requests die Statuschecks `python-tests`, `javascript-check`,
|
||||
`container-policy` und `container-verify` nach ihrem ersten Lauf als
|
||||
verpflichtend auswählen. `container-publish` ist bei Pull Requests absichtlich
|
||||
übersprungen und wird deshalb nicht als Pflichtprüfung eingerichtet.
|
||||
Das Tag-Ruleset schützt alle `v*`-Tags; die engere Versionsprüfung übernimmt
|
||||
zusätzlich das CI-Skript. Release-Verantwortliche setzen Tags auf einen
|
||||
geprüften Commit mit der passenden Projektversion. Ein Tag auf einem Commit
|
||||
des geschützten Standardbranches ist selbst noch kein geschützter Tag.
|
||||
[Rulesets anlegen](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/creating-rulesets-for-a-repository),
|
||||
[Verfügbare Schutzregeln](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets).
|
||||
|
||||
Die Regeln und Paketberechtigungen im GitHub-Projekt sind Teil der Einrichtung;
|
||||
sie werden durch den Commit der Workflow-Datei nicht automatisch angelegt.
|
||||
Welche Rulesets verfügbar sind, hängt von Repository-Sichtbarkeit und
|
||||
GitHub-Tarif ab. Die CI-Abfragen ersetzen keine restriktiven Schreibrechte
|
||||
auf Repository und Paket; Änderungen an Workflow und CI-Skripten im Review prüfen.
|
||||
[Ruleset-Verfügbarkeit](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/creating-rulesets-for-a-repository).
|
||||
|
||||
## Erster Lauf und Release
|
||||
|
||||
Nach dem Push der Workflow-Datei unter **Actions** den Lauf öffnen.
|
||||
Python- und JavaScript-Prüfung sowie der passende Container-Job müssen
|
||||
erfolgreich sein. Für einen geschützten Standardbranch zusätzlich prüfen,
|
||||
dass das GHCR-Paket `sha-<Commit>` und `edge` enthält und das Artefakt
|
||||
`container-deploy` mit `deploy.env` bereitsteht. Ein lokaler Test ersetzt
|
||||
diesen ersten GitHub-Lauf samt GHCR-Anmeldung und Push nicht.
|
||||
|
||||
Für ein Release zuerst `[project].version` auf die gewünschte Version setzen
|
||||
und den geprüften Commit übernehmen. Anschließend durch ein für das
|
||||
Release-Ruleset berechtigtes Konto den passenden Tag erstellen und pushen.
|
||||
Im vorhandenen Checkout heißt der GitHub-Remote `GH-AIS`; in anderen Checkouts
|
||||
den Namen mit `git remote -v` prüfen und im Befehl entsprechend ersetzen.
|
||||
Für Projektversion `0.1.0`, sofern der Tag noch nicht existiert:
|
||||
|
||||
```bash
|
||||
git tag -a v0.1.0 -m "Release 0.1.0"
|
||||
git push GH-AIS v0.1.0
|
||||
```
|
||||
|
||||
Der Release-Lauf muss zusätzlich den Image-Tag `0.1.0` erzeugen. Für einen
|
||||
manuellen Branch-Lauf unter **Actions** den Workflow und **Run workflow**
|
||||
wählen. Dafür muss die Workflow-Datei bereits auf dem Standardbranch liegen.
|
||||
Ein manueller Lauf veröffentlicht nur, wenn dieselben Ref-Schutz- und
|
||||
Versionsbedingungen erfüllt sind.
|
||||
[Workflow manuell starten](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manually-run-a-workflow).
|
||||
|
||||
Branch-Push und Pull Request können für denselben Quellstand getrennte Läufe
|
||||
erzeugen. Pull Requests werden im Merge-Kontext geprüft; ihre Tests führen
|
||||
keinen Registry-Push aus. Die Jobs laden keine produktiven Deployment-Zugänge.
|
||||
|
||||
## Fehlersuche und Deployment
|
||||
|
||||
Bei übersprungenem Publish-Job zuerst Ereignis, Standardbranch, Tagformat und
|
||||
aktive Schutzregeln prüfen. Bei einer Versionsabweichung müssen Git-Tag und
|
||||
`pyproject.toml` aufeinander abgestimmt werden. Bei `denied` oder `unauthorized`
|
||||
im Publish-Job die Organisationsrichtlinien, `packages: write` und den
|
||||
Actions-Zugriff auf das GHCR-Paket kontrollieren. Fehlt `container-deploy`,
|
||||
die Logs des Build-, Smoke- und Push-Schritts prüfen; vor erfolgreicher
|
||||
Veröffentlichung steht kein Deployment-Digest bereit.
|
||||
|
||||
Zum Deployment [compose.yaml](../compose.yaml) und
|
||||
[config/deployment.env.example](../config/deployment.env.example) auf den
|
||||
Zielserver kopieren und die Image-Zeile aus `deploy.env` verwenden.
|
||||
Die [Deployment-Anleitung](deployment.md) beschreibt GHCR-Anmeldung,
|
||||
Erstinitialisierung, HTTPS-Prüfung, Updates und Rollback. Für private Pakete
|
||||
benötigt das Deploymentkonto einen Personal Access Token (classic) mit
|
||||
`read:packages`; öffentliche Pakete lassen sich anonym laden.
|
||||
Die aktuelle Anleitung steht unter [Gitea Actions und Container Registry](gitea-actions.md).
|
||||
Der Workflow liegt in [.gitea/workflows/ci.yml](../.gitea/workflows/ci.yml).
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Betrieb und Wiederherstellung
|
||||
|
||||
Für die Installation aus der GitHub Container Registry (GHCR) siehe
|
||||
Für die Installation aus der Gitea Container Registry siehe
|
||||
[Deployment-Anleitung](deployment.md). Alle `docker compose`-Befehle unten
|
||||
werden im Deployment-Verzeichnis mit `compose.yaml` und `.env` ausgeführt.
|
||||
`PROVISIONER_IMAGE` verweist auf das veröffentlichte Image, vorzugsweise per Digest.
|
||||
|
||||
+23
-4
@@ -1,11 +1,30 @@
|
||||
# Softwaretestbericht
|
||||
|
||||
Stand: 13. September 2026. Die hier dokumentierten Softwaretests führen keine
|
||||
Die hier dokumentierten Softwaretests führen keine
|
||||
Proxmox-Installation aus und verändern keine Hostdatenträger, Paketquellen oder
|
||||
Produktivdienste. Die noch offenen praktischen Prüfungen stehen in der
|
||||
[Kompatibilitätsmatrix](compatibility.md).
|
||||
|
||||
## Automatisierte Prüfungen
|
||||
## Gitea-Migration: 14. September 2026
|
||||
|
||||
Der aktuelle [Workflow](../.gitea/workflows/ci.yml) und die
|
||||
[Einrichtungsanleitung](gitea-actions.md) verwenden Gitea Actions und die
|
||||
Gitea Container Registry. Die Prüfung unter Windows mit Python 3.13.15 ergab:
|
||||
|
||||
- 120 CI-Skripttests bestanden: Veröffentlichungs-Opt-in, Ereignis- und Ref-Regeln,
|
||||
Versionsabgleich, Registry-Adressen und Paket-Token sowie Build-, Smoke-,
|
||||
Push- und Aufräumfehler. Der konstante Gitea-Wert `ref_protected=false`
|
||||
verhindert bei gesetztem Opt-in keine Veröffentlichung mehr.
|
||||
- 47 Anwendungstests bestanden; zwei Tests zur nativen Linux-Prozessüberwachung
|
||||
wurden unter Windows übersprungen.
|
||||
- Workflow-YAML, Shell-Syntax und JavaScript-Syntax wurden erfolgreich geprüft.
|
||||
|
||||
Ein neuer Linux-Containerbuild und ein vollständiger Gitea-Lauf einschließlich
|
||||
Registry-Push sind noch offen. Der vorhandene Gitea-Lauf wartet auf einen
|
||||
Online-Runner mit passendem Label; die Repository-Runnerliste ist leer.
|
||||
Die folgenden Ergebnisse dokumentieren den Stand vor dieser Migration.
|
||||
|
||||
## Automatisierte Prüfungen: 13. September 2026
|
||||
|
||||
Die 49 Anwendungstests wurden unter Windows mit Python 3.14 ausgeführt:
|
||||
47 Tests bestanden; zwei Linux-spezifische Prozesstests wurden dort übersprungen.
|
||||
@@ -86,9 +105,9 @@ TLS-Reverse-Proxy, reale Provisionierungsnetze, Medienboot, Initialisierung und
|
||||
Wiederherstellung in der späteren Betriebsumgebung müssen zusätzlich geprüft werden.
|
||||
Ein erfolgreicher Image-Build allein ist keine Betriebsfreigabe.
|
||||
|
||||
## GitHub Actions und GHCR
|
||||
## GitHub Actions und GHCR: historischer Stand
|
||||
|
||||
Der [Workflow](../.github/workflows/ci.yml) verwendet GitHub-gehostete
|
||||
Der damalige Workflow verwendete GitHub-gehostete
|
||||
Ubuntu-24.04-Runner, Python 3.13 und Node.js 24. Python- und JavaScript-Prüfung
|
||||
müssen erfolgreich sein, bevor das Containerimage gebaut und getestet wird.
|
||||
Die [Einrichtungsanleitung](github-actions.md) beschreibt Schutzregeln,
|
||||
|
||||
Reference in New Issue
Block a user