diff --git a/.gitea/known_hosts b/.gitea/known_hosts new file mode 100644 index 0000000..c12b454 --- /dev/null +++ b/.gitea/known_hosts @@ -0,0 +1,2 @@ +100.127.13.115 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC7xaGuqQN2FIGM/dhnulSiqFVUfsfulIUY1yTYoJrhB +10.10.2.80 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDd7LYWCbMt1hl7f4ttNL3J8Ich3v/SRWXc9X8inn5Sv diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..6918a67 --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,95 @@ +name: CI and Deploy + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +jobs: + test-build-deploy: + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Repository auschecken + uses: actions/checkout@v4 + + - name: Hefekalibrierung testen + run: node tests/yeast-calibration.test.js + + - name: JavaScript-Syntax prüfen + run: | + python3 - <<'PY' + from pathlib import Path + html = Path('index.html').read_text(encoding='utf-8') + start = html.index('', start) + Path('/tmp/teig-terminal.js').write_text(html[start:end], encoding='utf-8') + PY + node --check /tmp/teig-terminal.js + + - name: Statisches Release bauen + run: | + rm -rf dist + install -d -m 0755 dist + install -m 0644 index.html dist/index.html + test -s dist/index.html + grep -q 'TEIG//TERMINAL' dist/index.html + sha256sum dist/index.html + + - name: Deploymentzugang vorbereiten + if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} + env: + TEIG_DEPLOY_KEY: ${{ secrets.TEIG_DEPLOY_KEY }} + run: | + install -d -m 0700 "$HOME/.ssh" + printf '%s\n' "$TEIG_DEPLOY_KEY" > "$HOME/.ssh/teig_deploy" + chmod 0600 "$HOME/.ssh/teig_deploy" + install -m 0644 .gitea/known_hosts "$HOME/.ssh/known_hosts" + cat > "$HOME/.ssh/config" <<'EOF' + Host deploy-jump + HostName 100.127.13.115 + User gitea-jump + IdentityFile ~/.ssh/teig_deploy + IdentitiesOnly yes + StrictHostKeyChecking yes + UserKnownHostsFile ~/.ssh/known_hosts + RequestTTY no + + Host teig-production + HostName 10.10.2.80 + User teig-deploy + IdentityFile ~/.ssh/teig_deploy + IdentitiesOnly yes + ProxyJump deploy-jump + StrictHostKeyChecking yes + UserKnownHostsFile ~/.ssh/known_hosts + RequestTTY no + EOF + chmod 0600 "$HOME/.ssh/config" + + - name: Nach VM220 deployen + if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} + run: | + set -o pipefail + tar -C dist -czf - index.html | ssh teig-production "deploy $GITHUB_SHA" + + - name: Live-Deployment verifizieren + if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} + run: | + expected="$(sha256sum dist/index.html | cut -d' ' -f1)" + for attempt in $(seq 1 12); do + if curl -fsSL --max-time 20 https://teig.deploybar.de/ -o /tmp/teig-live.html; then + actual="$(sha256sum /tmp/teig-live.html | cut -d' ' -f1)" + if [ "$actual" = "$expected" ]; then + printf 'Live-Deployment verifiziert: %s\n' "$actual" + exit 0 + fi + fi + sleep 5 + done + printf 'Erwarteter SHA-256: %s\n' "$expected" >&2 + printf 'Live SHA-256: %s\n' "${actual:-nicht abrufbar}" >&2 + exit 1 diff --git a/README.md b/README.md index bdf7346..3db3def 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,13 @@ Aktuelle Version: **v1.1** - Rezept-Link über URL-Hash Live: https://teig.deploybar.de/ + +## CI/CD + +Gitea Actions prüft bei jedem Push und Pull Request automatisch: + +- Regressionstests der Hefekalibrierung +- JavaScript-Syntax der Single-File-App +- Erstellung des statischen Release-Artefakts + +Pushes auf `main` werden nach erfolgreichen Prüfungen automatisch nach VM220 deployt. Der Webserver erhält ausschließlich das geprüfte `dist/index.html`; anschließend vergleicht die Pipeline den SHA-256-Hash der Live-Seite mit dem gebauten Artefakt.