From 7a7e0bd185d7a68f29c91ebfe13cfc969dc773af Mon Sep 17 00:00:00 2001 From: janis Date: Wed, 20 May 2026 17:27:09 +0000 Subject: [PATCH] .gitea/workflows/delpoy.yml aktualisiert --- .gitea/workflows/delpoy.yml | 445 ++++++++++++++++++++++++++++++++++-- 1 file changed, 426 insertions(+), 19 deletions(-) diff --git a/.gitea/workflows/delpoy.yml b/.gitea/workflows/delpoy.yml index e38fc9e..bd121e7 100644 --- a/.gitea/workflows/delpoy.yml +++ b/.gitea/workflows/delpoy.yml @@ -2,15 +2,243 @@ name: Deploy on: push: - branches: [main] + branches: + - main jobs: + security_scan: + runs-on: ubuntu-latest + + env: + GIT_REPO: jakach/jakach-login + GIT_BRANCH: main + GIT_USER: ${{ vars.GIT_USER }} + GIT_TOKEN: ${{ secrets.GIT_TOKEN }} + SECURITY_SCAN_ENABLED: ${{ vars.SECURITY_SCAN_ENABLED }} + TRIVY_SEVERITY: HIGH,CRITICAL + + steps: + - name: Scan Docker images for vulnerabilities + run: | + set -Eeuo pipefail + + case "${SECURITY_SCAN_ENABLED:-true}" in + false|False|FALSE|0|no|No|NO|off|Off|OFF) + echo "Security scan disabled by SECURITY_SCAN_ENABLED=${SECURITY_SCAN_ENABLED}" + exit 0 + ;; + esac + + : "${GIT_USER:?GIT_USER is required}" + : "${GIT_TOKEN:?GIT_TOKEN is required}" + + if command -v apk >/dev/null 2>&1; then + apk add --no-cache ca-certificates curl git + elif command -v apt-get >/dev/null 2>&1; then + apt-get update + apt-get install -y ca-certificates curl git + elif command -v dnf >/dev/null 2>&1; then + dnf install -y ca-certificates curl git + elif command -v yum >/dev/null 2>&1; then + yum install -y ca-certificates curl git + else + echo "Unsupported package manager" + exit 1 + fi + + if ! command -v trivy >/dev/null 2>&1; then + mkdir -p "$HOME/.local/bin" + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \ + | sh -s -- -b "$HOME/.local/bin" + export PATH="$HOME/.local/bin:$PATH" + fi + + GIT_HOST="${GIT_HOST:-git.jakach.ch}" + REPO_URL="https://${GIT_USER}:${GIT_TOKEN}@${GIT_HOST}/${GIT_REPO}" + + git clone \ + --branch "$GIT_BRANCH" \ + "$REPO_URL" \ + source + + cd source + + COMPOSE_FILE="" + + for file in docker-compose.yml compose.yml compose.yaml; do + if [ -f "$file" ]; then + COMPOSE_FILE="$file" + break + fi + done + + if [ -z "$COMPOSE_FILE" ]; then + echo "No docker compose file found" + exit 0 + fi + + if docker compose version >/dev/null 2>&1; then + docker compose -f "$COMPOSE_FILE" config --images > images.txt + else + awk ' + /^[[:space:]]*image:[[:space:]]*/ { + sub(/^[[:space:]]*image:[[:space:]]*/, "") + gsub(/["\047]/, "") + print + } + ' "$COMPOSE_FILE" > images.txt + fi + + sort -u images.txt -o images.txt + + if [ ! -s images.txt ]; then + echo "No Docker images found to scan" + exit 0 + fi + + TRIVY_IGNORE_ARGS="" + + if [ -f cve_blacklist.txt ]; then + awk ' + /^[[:space:]]*($|#)/ { + next + } + { + print $1 + } + ' cve_blacklist.txt > .trivyignore + + if [ -s .trivyignore ]; then + TRIVY_IGNORE_ARGS="--ignorefile .trivyignore" + echo "Using CVE blacklist from cve_blacklist.txt" + fi + fi + + echo "Scanning Docker images for ${TRIVY_SEVERITY} vulnerabilities:" + cat images.txt + + failed=0 + + while IFS= read -r image; do + [ -n "$image" ] || continue + + echo "" + echo "Scanning ${image}" + + if ! trivy \ + image \ + --exit-code 1 \ + --severity "${TRIVY_SEVERITY}" \ + --ignore-unfixed \ + ${TRIVY_IGNORE_ARGS} \ + --no-progress \ + "${image}"; then + failed=1 + fi + done < images.txt + + if [ "$failed" -ne 0 ]; then + echo "WARNING: High or critical vulnerabilities were found in one or more Docker images. Deployment stopped." + exit 1 + fi + + echo "No high or critical vulnerabilities found" + + code_scan: + runs-on: ubuntu-latest + + env: + GIT_REPO: jakach/jakach-login + GIT_BRANCH: main + GIT_USER: ${{ vars.GIT_USER }} + GIT_TOKEN: ${{ secrets.GIT_TOKEN }} + CODE_SCAN_ENABLED: ${{ vars.CODE_SCAN_ENABLED }} + + steps: + - name: Scan source code + run: | + set -Eeuo pipefail + + case "${CODE_SCAN_ENABLED:-true}" in + false|False|FALSE|0|no|No|NO|off|Off|OFF) + echo "Code scan disabled by CODE_SCAN_ENABLED=${CODE_SCAN_ENABLED}" + exit 0 + ;; + esac + + : "${GIT_USER:?GIT_USER is required}" + : "${GIT_TOKEN:?GIT_TOKEN is required}" + + if command -v apk >/dev/null 2>&1; then + apk add --no-cache ca-certificates curl git python3 py3-pip + elif command -v apt-get >/dev/null 2>&1; then + apt-get update + apt-get install -y ca-certificates curl git python3 python3-pip python3-venv + elif command -v dnf >/dev/null 2>&1; then + dnf install -y ca-certificates curl git python3 python3-pip + elif command -v yum >/dev/null 2>&1; then + yum install -y ca-certificates curl git python3 python3-pip + else + echo "Unsupported package manager" + exit 1 + fi + + if ! command -v semgrep >/dev/null 2>&1; then + python3 -m venv "$HOME/.semgrep-venv" + . "$HOME/.semgrep-venv/bin/activate" + python3 -m pip install --upgrade pip + python3 -m pip install semgrep + fi + + if ! command -v trivy >/dev/null 2>&1; then + mkdir -p "$HOME/.local/bin" + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \ + | sh -s -- -b "$HOME/.local/bin" + export PATH="$HOME/.local/bin:$PATH" + fi + + GIT_HOST="${GIT_HOST:-git.jakach.ch}" + REPO_URL="https://${GIT_USER}:${GIT_TOKEN}@${GIT_HOST}/${GIT_REPO}" + + git clone \ + --branch "$GIT_BRANCH" \ + "$REPO_URL" \ + source + + cd source + + semgrep scan \ + --config p/default \ + --error \ + --metrics=off + + trivy fs \ + --scanners vuln,misconfig,secret \ + --exit-code 1 \ + --severity HIGH,CRITICAL \ + --ignore-unfixed \ + --no-progress \ + . + deploy: runs-on: ubuntu-latest + needs: + - security_scan + - code_scan + + env: + GIT_REPO: jakach/jakach-login + GIT_BRANCH: main + + APP_NAME: template + APP_DOMAIN: auth.jakach.ch + APP_PORT: 447 + steps: - - name: Install SSH client + - name: Install dependencies run: | set -e + if command -v apk >/dev/null 2>&1; then apk add --no-cache openssh-client git bash elif command -v apt-get >/dev/null 2>&1; then @@ -21,55 +249,234 @@ jobs: elif command -v yum >/dev/null 2>&1; then yum install -y openssh-clients git bash else - echo "No supported package manager found" + echo "Unsupported package manager" exit 1 fi - - name: Run deploy + + - name: Deploy application env: SSH_KEY: ${{ secrets.SSH_KEY }} SSH_USER: ${{ vars.SSH_USER }} SSH_IP: ${{ vars.SSH_IP }} + GIT_USER: ${{ vars.GIT_USER }} GIT_TOKEN: ${{ secrets.GIT_TOKEN }} - APP_DIR: /home/deploy/my-app - GIT_REPO: Jakach/my-app.git - GIT_BRANCH: main + run: | - cat > deploy.sh <<'EOF' + cat > deploy.sh <<'OUTER_EOF' #!/usr/bin/env bash set -Eeuo pipefail + : "${SSH_KEY:?SSH_KEY is required}" : "${SSH_USER:?SSH_USER is required}" : "${SSH_IP:?SSH_IP is required}" : "${GIT_USER:?GIT_USER is required}" : "${GIT_TOKEN:?GIT_TOKEN is required}" - APP_DIR="/srv/systems/jakach-login" GIT_HOST="${GIT_HOST:-git.jakach.ch}" - GIT_REPO="jakach/jakach-login.git" - GIT_BRANCH="${GIT_BRANCH:-main}" + + REPO_NAME="$(basename "$GIT_REPO")" + APP_DIR="/srv/systems/${REPO_NAME}" mkdir -p ~/.ssh chmod 700 ~/.ssh + printf '%s\n' "$SSH_KEY" | tr -d '\r' > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key + ssh-keyscan -H "$SSH_IP" >> ~/.ssh/known_hosts 2>/dev/null || true - ssh -i ~/.ssh/deploy_key \ + ssh \ + -i ~/.ssh/deploy_key \ -o StrictHostKeyChecking=yes \ -o IdentitiesOnly=yes \ "$SSH_USER@$SSH_IP" \ - "export APP_DIR='$APP_DIR' GIT_HOST='$GIT_HOST' GIT_REPO='$GIT_REPO' GIT_BRANCH='$GIT_BRANCH' GIT_USER='$GIT_USER' GIT_TOKEN='$GIT_TOKEN'; bash -s" <<'REMOTE' + " + export \ + APP_NAME='${APP_NAME}' \ + APP_DOMAIN='${APP_DOMAIN}' \ + APP_PORT='${APP_PORT}' \ + APP_DIR='${APP_DIR}' \ + GIT_HOST='${GIT_HOST}' \ + GIT_REPO='${GIT_REPO}' \ + GIT_BRANCH='${GIT_BRANCH}' \ + GIT_USER='${GIT_USER}' \ + GIT_TOKEN='${GIT_TOKEN}'; + bash -s + " <<'REMOTE_EOF' + set -Eeuo pipefail + + REPO_URL="https://${GIT_USER}:${GIT_TOKEN}@${GIT_HOST}/${GIT_REPO}" + + PROXY_DIR="/srv/systems/proxy" + NGINX_CONF="${PROXY_DIR}/nginx_conf/nginx.conf" + GET_CERT_SCRIPT="${PROXY_DIR}/get_cert.sh" + RENEW_SCRIPT="${PROXY_DIR}/renew_cert.sh" + FIRST_DEPLOY=0 + PROXY_RESTART_REQUIRED=0 + + # -------------------------------------------------- + # Clone repository if missing + # -------------------------------------------------- + + if [ ! -d "$APP_DIR/.git" ]; then + echo "Repository missing, cloning..." + FIRST_DEPLOY=1 + + mkdir -p "$(dirname "$APP_DIR")" + + git clone \ + --branch "$GIT_BRANCH" \ + "$REPO_URL" \ + "$APP_DIR" + fi + + # -------------------------------------------------- + # Update repository + # -------------------------------------------------- + cd "$APP_DIR" - git remote set-url origin "https://${GIT_USER}:${GIT_TOKEN}@${GIT_HOST}/${GIT_REPO}" + + git remote set-url origin "$REPO_URL" + git fetch origin "$GIT_BRANCH" + git checkout "$GIT_BRANCH" + git pull origin "$GIT_BRANCH" - docker compose down - docker compose up -d --build - REMOTE - EOF + + # -------------------------------------------------- + # Create nginx reverse proxy entry + # -------------------------------------------------- + + if [ "$FIRST_DEPLOY" -eq 1 ]; then + + if ! grep -q "proxy_pass http://192.168.1.109:${APP_PORT}/;" "$NGINX_CONF"; then + echo "Creating nginx entry..." + PROXY_RESTART_REQUIRED=1 + + cat >> "$NGINX_CONF" <> "$RENEW_SCRIPT" <