282 lines
9.9 KiB
YAML
282 lines
9.9 KiB
YAML
name: Release Inventarsystem
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "v*"
|
|
workflow_dispatch:
|
|
inputs:
|
|
bump:
|
|
description: "Version bump type (major stays fixed from latest release)"
|
|
required: false
|
|
default: "patch"
|
|
type: choice
|
|
options:
|
|
- patch
|
|
- minor
|
|
- major
|
|
|
|
permissions:
|
|
contents: write
|
|
packages: write
|
|
|
|
env:
|
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
|
|
|
jobs:
|
|
release-docker:
|
|
# Hinweis: Falls dein lokaler Gitea-Runner ein anderes Label hat (z.B. 'linux' oder 'self-hosted'), passe dies hier an.
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set metadata
|
|
id: meta
|
|
env:
|
|
# Gitea stellt das GITHUB_TOKEN für Kompatibilität mit GitHub Actions automatisch zur Verfügung
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
REPO: ${{ gitea.repository }}
|
|
EVENT_NAME: ${{ gitea.event_name }}
|
|
REF_NAME: ${{ gitea.ref_name }}
|
|
BUMP_TYPE: ${{ gitea.event.inputs.bump || 'patch' }}
|
|
DOCKER_API_VERSION: '1.44'
|
|
run: |
|
|
if [ "$EVENT_NAME" = "push" ] && [ -n "$REF_NAME" ]; then
|
|
TAG="$REF_NAME"
|
|
else
|
|
# Gitea API Endpunkt nutzen, um das aktuellste Release abzufragen
|
|
latest_tag="v0.8.31"
|
|
if meta_json=$(curl -fsSL -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/json" "https://git.invario-software.eu/api/v1/repos/$REPO/releases/latest" 2>/dev/null); then
|
|
tag_name=$(printf "%s" "$meta_json" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n1)
|
|
if [ -n "$tag_name" ]; then
|
|
latest_tag="$tag_name"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$latest_tag" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
|
|
major=${BASH_REMATCH[1]}
|
|
minor=${BASH_REMATCH[2]}
|
|
patch=${BASH_REMATCH[3]}
|
|
else
|
|
major=0; minor=8; patch=31
|
|
fi
|
|
|
|
# Bump strategy: major / minor / patch
|
|
if [ "${BUMP_TYPE:-}" = "major" ]; then
|
|
major=$((major + 1)); minor=0; patch=0
|
|
elif [ "${BUMP_TYPE:-}" = "minor" ]; then
|
|
minor=$((minor + 1)); patch=0
|
|
else
|
|
patch=$((patch + 1))
|
|
fi
|
|
|
|
# Zusammenbau des Tags für den manuellen Run
|
|
TAG="v${major}.${minor}.${patch}"
|
|
fi
|
|
|
|
# Validierung des erzeugten oder übergebenen Tags
|
|
if ! echo "$TAG" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+(-dev(\.[0-9]+)?)?$'; then
|
|
echo "Error: tag '$TAG' is not valid semver (vX.Y.Z)"
|
|
exit 1
|
|
fi
|
|
|
|
git fetch --tags --force
|
|
LATEST_TAG="$(git tag -l 'v*' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1)"
|
|
if [ -z "$LATEST_TAG" ]; then
|
|
LATEST_TAG="v0.8.31"
|
|
fi
|
|
|
|
TAG_MAJOR="${TAG#v}"
|
|
TAG_MAJOR="${TAG_MAJOR%%.*}"
|
|
LATEST_MAJOR="$(echo "$LATEST_TAG" | grep -Eo '^v[0-9]+' | tr -d 'v')"
|
|
if [ -z "$LATEST_MAJOR" ]; then
|
|
LATEST_MAJOR="0"
|
|
fi
|
|
|
|
# If not explicitly bumping major, disallow changing major version
|
|
if [ "${BUMP_TYPE:-}" != "major" ] && [ "$TAG_MAJOR" != "$LATEST_MAJOR" ]; then
|
|
echo "Error: major version must stay v$LATEST_MAJOR.x.x (got $TAG)"
|
|
exit 1
|
|
fi
|
|
|
|
# Ensure tag uniqueness: if tag exists append numeric suffix
|
|
if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then
|
|
i=1
|
|
base="$TAG"
|
|
while git rev-parse -q --verify "refs/tags/${base}.${i}" >/dev/null; do
|
|
i="$((i + 1))"
|
|
done
|
|
TAG="${base}.${i}"
|
|
fi
|
|
|
|
# Docker Images verlangen Kleinbuchstaben. Repository-Namen daher umwandeln.
|
|
LOWER_REPO=$(echo "$REPO" | tr '[:upper:]' '[:lower:]')
|
|
IMAGE="git.invario-software.eu/${LOWER_REPO}:${TAG}"
|
|
|
|
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
|
|
echo "image=$IMAGE" >> "$GITHUB_OUTPUT"
|
|
echo "lower_repo=$LOWER_REPO" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Ensure Docker CLI is available and up to date
|
|
run: |
|
|
install_docker=true
|
|
|
|
# Prüfen, ob Docker existiert und ob die Version ausreicht
|
|
if command -v docker >/dev/null 2>&1; then
|
|
# Extrahiere die Major-Version (z. B. "20" aus "20.10.24" oder "26" aus "26.1.0")
|
|
DOCKER_MAJOR=$(docker --version | grep -oE '[0-9]+' | head -n1)
|
|
|
|
# API 1.44 erfordert mindestens Docker v25
|
|
if [ -n "$DOCKER_MAJOR" ] && [ "$DOCKER_MAJOR" -ge 25 ]; then
|
|
install_docker=false
|
|
fi
|
|
fi
|
|
|
|
if [ "$install_docker" = true ]; then
|
|
echo "Veraltete oder fehlende Docker-Installation erkannt. Führe Update durch..."
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
apt-get update
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y curl
|
|
# Nutzt das offizielle Docker-Skript (installiert docker-ce statt das alte docker.io)
|
|
curl -fsSL https://get.docker.com | sh
|
|
elif command -v apk >/dev/null 2>&1; then
|
|
apk update
|
|
apk add --no-cache docker-cli
|
|
else
|
|
echo "Error: no supported package manager found to install docker"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "Docker CLI ist bereits auf einem aktuellen Stand."
|
|
fi
|
|
|
|
docker --version
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Login to Gitea Container Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: git.invario-software.eu
|
|
username: ${{ gitea.actor }}
|
|
password: ${{ secrets.REGISTRY_TOKEN }}
|
|
|
|
- name: Build and push release image
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
file: ./Dockerfile
|
|
push: true
|
|
tags: |
|
|
${{ steps.meta.outputs.image }}
|
|
git.invario-software.eu/${{ steps.meta.outputs.lower_repo }}:latest
|
|
|
|
- name: Build local image tar for offline deploy
|
|
run: |
|
|
set -euo pipefail
|
|
IMG="${{ steps.meta.outputs.image }}"
|
|
TAG="${{ steps.meta.outputs.tag }}"
|
|
|
|
echo "Pulling freshly pushed image from registry: $IMG"
|
|
docker pull "$IMG"
|
|
|
|
echo "Saving image to offline tar archive..."
|
|
docker save "$IMG" | gzip > "inventarsystem-image-${TAG}.tar.gz"
|
|
|
|
- name: Create release-only docker bundle
|
|
run: |
|
|
mkdir -p release-bundle
|
|
cat > release-bundle/docker-compose.yml <<EOF
|
|
services:
|
|
app:
|
|
image: \${INVENTAR_APP_IMAGE:-${{ steps.meta.outputs.image }}}
|
|
container_name: inventarsystem-app
|
|
restart: unless-stopped
|
|
ports:
|
|
- "\${INVENTAR_HTTP_PORT:-10000}:8000"
|
|
depends_on:
|
|
- mongodb
|
|
- redis
|
|
environment:
|
|
INVENTAR_MONGODB_HOST: mongodb
|
|
INVENTAR_MONGODB_PORT: "27017"
|
|
INVENTAR_MONGODB_DB: Inventarsystem
|
|
INVENTAR_BACKUP_FOLDER: /data/backups
|
|
INVENTAR_LOGS_FOLDER: /data/logs
|
|
expose:
|
|
- "8000"
|
|
volumes:
|
|
- ./config.json:/app/config.json:ro
|
|
- app_uploads:/app/Web/uploads
|
|
- app_thumbnails:/app/Web/thumbnails
|
|
- app_previews:/app/Web/previews
|
|
- app_qrcodes:/app/Web/QRCodes
|
|
- app_backups:/data/backups
|
|
- app_logs:/data/logs
|
|
|
|
mongodb:
|
|
image: mongo:7.0
|
|
container_name: inventarsystem-mongodb
|
|
restart: unless-stopped
|
|
volumes:
|
|
- mongodb_data:/data/db
|
|
healthcheck:
|
|
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: inventarsystem-redis
|
|
restart: unless-stopped
|
|
command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru
|
|
ports:
|
|
- "6379:6379"
|
|
volumes:
|
|
- redis_data:/data
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
volumes:
|
|
mongodb_data:
|
|
app_uploads:
|
|
app_thumbnails:
|
|
app_previews:
|
|
app_qrcodes:
|
|
app_backups:
|
|
app_logs:
|
|
redis_data:
|
|
EOF
|
|
|
|
# Copy runtime scripts and config if present
|
|
for f in start.sh stop.sh restart.sh backup.sh config.json update.sh; do
|
|
if [ -f "$f" ]; then
|
|
cp "$f" "release-bundle/$(basename "$f")"
|
|
fi
|
|
done
|
|
|
|
# Multitenant scripts & docs (optional)
|
|
for f in docker-compose-multitenant.yml manage-tenant.sh run-tenant-cmd.sh MULTITENANT_DEPLOYMENT.md MULTITENANT_PYTHON_API.md; do
|
|
if [ -f "$f" ]; then
|
|
cp "$f" "release-bundle/$(basename "$f")"
|
|
fi
|
|
done
|
|
|
|
# Make any shipped scripts executable
|
|
find release-bundle -maxdepth 1 -type f -name '*.sh' -exec chmod +x {} \; || true
|
|
tar -czf inventarsystem-docker-bundle.tar.gz -C release-bundle .
|
|
|
|
- name: Create or update Gitea Release
|
|
uses: https://gitea.com/actions/gitea-release-action@v1
|
|
with:
|
|
tag_name: ${{ steps.meta.outputs.tag }}
|
|
files: |
|
|
inventarsystem-docker-bundle.tar.gz
|
|
inventarsystem-image-${{ steps.meta.outputs.tag }}.tar.gz |