# Деплой на сервер по SSH после пуша тега v* или вручную (в т.ч. откат на старый тег). name: Deploy on: push: tags: - "v*" workflow_dispatch: inputs: ref: description: "main, v1.7.0 или 1.7.0 (без v подставится автоматически)." required: true default: "main" jobs: deploy: runs-on: ubuntu-latest steps: - name: Определить ревизию id: pick env: RAW_REF: ${{ inputs.ref }} run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then R=$(printf '%s' "$RAW_REF" | tr -d '\r\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') # Теги в git: v1.7.0; если ввели 1.7.0 — подставляем v (иначе checkout не находит ref). if echo "$R" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then echo "::notice::Указано $R без префикса v — деплой на v${R}" R="v${R}" fi echo "ref=$R" >> "$GITHUB_OUTPUT" else echo "ref=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" fi # Без секретов appleboy/ssh-action падает с «missing server host» — даём явную подсказку. - name: Проверить секреты деплоя env: DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} DEPLOY_USER: ${{ secrets.DEPLOY_USER }} DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }} DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }} run: | ok=0 [ -n "$DEPLOY_HOST" ] || { echo "::error::Секрет DEPLOY_HOST пустой. Forgejo → репозиторий → Настройки → Actions → Secrets."; ok=1; } [ -n "$DEPLOY_USER" ] || { echo "::error::Секрет DEPLOY_USER пустой."; ok=1; } [ -n "$DEPLOY_PATH" ] || { echo "::error::Секрет DEPLOY_PATH пустой (каталог клона на сервере, напр. /opt/onGuard24)."; ok=1; } [ -n "$DEPLOY_SSH_KEY" ] || { echo "::error::Секрет DEPLOY_SSH_KEY пустой (приватный SSH-ключ целиком, PEM)."; ok=1; } exit "$ok" - name: SSH — fetch, checkout, docker compose uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.DEPLOY_HOST }} port: "22" username: ${{ secrets.DEPLOY_USER }} key: ${{ secrets.DEPLOY_SSH_KEY }} script_stop: true command_timeout: 20m script: | set -euo pipefail REF="${{ steps.pick.outputs.ref }}" cd "${{ secrets.DEPLOY_PATH }}" echo "=== deploy REF=$REF ===" git fetch origin --tags --prune git checkout "$REF" # Теги не дают refs/remotes/origin/<тег> — только ветки; для v* срабатывает else. if git show-ref --verify --quiet "refs/remotes/origin/$REF"; then git reset --hard "origin/$REF" else git reset --hard "$REF" fi echo "=== git HEAD ===" git log -1 --oneline echo "=== docker compose version ===" docker compose version echo "=== docker compose build ===" docker compose build --progress=plain echo "=== docker compose up ===" docker compose up -d docker compose ps