948f9800d5
Build & Deploy Tippspiel / build (push) Successful in 17s
Statt Credentials im Workflow hardcoden: - Compose-File und Env-Vars werden zur Laufzeit aus Portainer gelesen - Einziges Secret im Workflow: PORTAINER_TOKEN - Keine sensiblen Daten mehr in git-versionierten Dateien Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
99 lines
3.6 KiB
YAML
99 lines
3.6 KiB
YAML
name: Build & Deploy Tippspiel
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: self-hosted
|
|
steps:
|
|
- name: Setup tools
|
|
run: apk add --no-cache curl python3
|
|
|
|
- name: Checkout
|
|
run: |
|
|
rm -rf workspace && mkdir workspace
|
|
GIT_TERMINAL_PROMPT=0 git clone \
|
|
--depth 1 \
|
|
--branch main \
|
|
http://x-token:${{ secrets.DEPLOY_TOKEN }}@gitea:3000/mwf975_git/tippspiel.git \
|
|
workspace
|
|
|
|
- name: Create build context
|
|
run: |
|
|
cd workspace
|
|
tar cf /tmp/tippspiel-ci.tar \
|
|
--exclude='.git' \
|
|
--exclude='node_modules' \
|
|
--exclude='*.docx' \
|
|
--exclude='prototyp_*.html' \
|
|
.
|
|
echo "Build context size: $(du -sh /tmp/tippspiel-ci.tar | cut -f1)"
|
|
|
|
- name: Build Docker Image via Portainer
|
|
run: |
|
|
echo "Starting Docker build on NAS..."
|
|
curl -s -k -X POST \
|
|
"https://192.168.1.60:9444/api/endpoints/2/docker/build?t=wm2026-tippspiel:latest&dockerfile=./Dockerfile" \
|
|
-H "X-API-Key: ${{ secrets.PORTAINER_TOKEN }}" \
|
|
-H "Content-Type: application/x-tar" \
|
|
--data-binary @/tmp/tippspiel-ci.tar \
|
|
--max-time 600 \
|
|
| grep -E '(Successfully built|Successfully tagged|error|Error)' || true
|
|
echo "Build completed."
|
|
|
|
- name: Redeploy Stack via Portainer
|
|
run: |
|
|
echo "Fetching current stack config from Portainer..."
|
|
|
|
# Aktuelles Compose-File aus Portainer lesen
|
|
STACK_FILE=$(curl -s -k \
|
|
"https://192.168.1.60:9444/api/stacks/115/file" \
|
|
-H "X-API-Key: ${{ secrets.PORTAINER_TOKEN }}" \
|
|
| python3 -c "import sys,json; print(json.load(sys.stdin).get('StackFileContent',''))")
|
|
|
|
# Aktuelle Env-Vars aus Portainer lesen (enthält die echten Werte)
|
|
ENV_VARS=$(curl -s -k \
|
|
"https://192.168.1.60:9444/api/stacks/115" \
|
|
-H "X-API-Key: ${{ secrets.PORTAINER_TOKEN }}" \
|
|
| python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin).get('Env', [])))")
|
|
|
|
# Stack mit bestehender Konfiguration neu deployen (keine Credentials im Workflow)
|
|
PAYLOAD=$(python3 -c "
|
|
import json, sys
|
|
stack_file = '''$STACK_FILE'''
|
|
env_vars = $ENV_VARS
|
|
print(json.dumps({
|
|
'stackFileContent': stack_file,
|
|
'env': env_vars,
|
|
'prune': True,
|
|
'pullImage': False
|
|
}))
|
|
")
|
|
|
|
echo "Redeploying stack wm2026-tippspiel..."
|
|
curl -s -k -X PUT \
|
|
"https://192.168.1.60:9444/api/stacks/115?endpointId=2" \
|
|
-H "X-API-Key: ${{ secrets.PORTAINER_TOKEN }}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$PAYLOAD" \
|
|
| python3 -c "import sys,json; d=json.load(sys.stdin); print('Stack redeployed:', d.get('Name'), '| Status:', d.get('Status'))" \
|
|
|| echo "Stack redeploy triggered."
|
|
echo "Deployment complete!"
|
|
|
|
- name: Verify deployment
|
|
run: |
|
|
sleep 15
|
|
STATUS=$(curl -s http://192.168.1.60:3301/health | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('status'))" 2>/dev/null || echo "unreachable")
|
|
echo "Health check: $STATUS"
|
|
if [ "$STATUS" = "ok" ]; then
|
|
echo "✅ Deployment successful! App running at http://192.168.1.60:3301"
|
|
else
|
|
echo "⚠️ Health check inconclusive (container may be restarting)"
|
|
fi
|
|
|
|
- name: Cleanup
|
|
if: always()
|
|
run: rm -rf workspace /tmp/tippspiel-ci.tar
|