name: Deploy on: push: branches: - master - stage jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Resolve environment run: | set -euo pipefail # Тег образа зависит только от коммита (одинаков для stage и prod) echo "IMAGE_TAG=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV" if [[ "${{ gitea.ref_name }}" == "stage" ]]; then { echo "ENV_NAME=stage" echo "CONTAINER_SUFFIX=-stage" echo "APP_PORT=8004" echo "POSTGRES_PORT=5433" echo "REDIS_PORT=6380" echo "COMPOSE_PROJECT=g2s-aggregator-stage" echo "DEPLOY_DIR=/home/deploy/g2s-aggregator-stage" } >> "$GITHUB_ENV" else { echo "ENV_NAME=prod" echo "CONTAINER_SUFFIX=" echo "APP_PORT=8003" echo "POSTGRES_PORT=5432" echo "REDIS_PORT=6379" echo "COMPOSE_PROJECT=g2s-aggregator" echo "DEPLOY_DIR=/home/deploy/g2s-aggregator" } >> "$GITHUB_ENV" fi - name: Build and push image run: | docker login gitea.p4r4dls.ru \ -u ${{ secrets.REGISTRY_USER }} \ -p ${{ secrets.REGISTRY_TOKEN }} IMG=gitea.p4r4dls.ru/yusupal1ev/g2s-aggregator:${IMAGE_TAG} if docker manifest inspect "$IMG" >/dev/null 2>&1; then echo "Образ $IMG уже есть в реестре — сборка пропущена" else docker buildx rm multibuilder 2>/dev/null || true docker buildx create --use --name multibuilder --driver-opt network=host docker buildx build \ --platform linux/amd64 \ --load \ -t "$IMG" \ . docker push "$IMG" fi - name: Setup SSH run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key ssh-keyscan 194.58.121.203 >> ~/.ssh/known_hosts - name: Render and copy configs env: ALL_SECRETS: ${{ toJSON(secrets) }} run: | set -euo pipefail # Экспортируем все секреты как env-переменные while IFS= read -r -d '' entry; do key="${entry%%=*}" value="${entry#*=}" export "$key=$value" done < <(echo "$ALL_SECRETS" | jq -j 'to_entries[] | "\(.key)=\(.value)\u0000"') # Для stage подменяем базовые имена секретов на STAGE_-версии: # STAGE_FOO -> FOO if [[ "$ENV_NAME" == "stage" ]]; then while IFS= read -r -d '' entry; do key="${entry%%=*}" value="${entry#*=}" if [[ "$key" == STAGE_* ]]; then export "${key#STAGE_}=$value" fi done < <(echo "$ALL_SECRETS" | jq -j 'to_entries[] | "\(.key)=\(.value)\u0000"') fi render() { local src=$1 dst=$2 vars=$(grep -oP '\$\{\K[^}]+' "$src") for var in $vars; do if [[ -z "${!var+x}" ]]; then echo "Error: $var не задан в Gitea Secrets" >&2 exit 1 fi done perl -pe 's/\$\{(\w+)\}/exists $ENV{$1} ? $ENV{$1} : ""/ge' "$src" > "$dst" } render config.template.yaml config.rendered.yaml render docker-compose.template.yml docker-compose.rendered.yml scp -i ~/.ssh/deploy_key config.rendered.yaml \ deploy@194.58.121.203:$DEPLOY_DIR/config.yaml scp -i ~/.ssh/deploy_key docker-compose.rendered.yml \ deploy@194.58.121.203:$DEPLOY_DIR/docker-compose.yml - name: Deploy run: | ssh -i ~/.ssh/deploy_key deploy@194.58.121.203 " cd $DEPLOY_DIR && docker login gitea.p4r4dls.ru \ -u ${{ secrets.REGISTRY_USER }} \ -p ${{ secrets.REGISTRY_TOKEN }} && docker compose -p $COMPOSE_PROJECT pull && docker compose -p $COMPOSE_PROJECT up -d "