124 lines
4.1 KiB
YAML
124 lines
4.1 KiB
YAML
name: Notification Service – CI/CD
|
||
|
||
on:
|
||
workflow_dispatch:
|
||
push:
|
||
paths:
|
||
- notification_service/**
|
||
- .github/workflows/notification-service.yml
|
||
pull_request:
|
||
branches: [main]
|
||
paths:
|
||
- notification_service/**
|
||
- .github/workflows/notification-service.yml
|
||
|
||
jobs:
|
||
# ── 1. Build & test ──────────────────────────────────────────────────────────
|
||
ci:
|
||
name: Build & test
|
||
runs-on: ubuntu-latest
|
||
defaults:
|
||
run:
|
||
working-directory: notification_service
|
||
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Setup Java 17
|
||
uses: actions/setup-java@v4
|
||
with:
|
||
java-version: 17
|
||
distribution: temurin
|
||
cache: maven
|
||
|
||
- name: Run tests
|
||
run: mvn verify -q
|
||
|
||
# ── 2. Docker build & push ───────────────────────────────────────────────────
|
||
docker:
|
||
name: Docker build & push
|
||
runs-on: ubuntu-latest
|
||
needs: ci
|
||
if: github.ref == 'refs/heads/main'
|
||
outputs:
|
||
sha_tag: ${{ steps.tag.outputs.sha }}
|
||
|
||
permissions:
|
||
contents: read
|
||
packages: write
|
||
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Compute image tags
|
||
id: tag
|
||
run: |
|
||
OWNER="${{ github.repository_owner }}"
|
||
IMAGE_LC="ghcr.io/${OWNER,,}/notification-service"
|
||
echo "image=${IMAGE_LC}" >> $GITHUB_OUTPUT
|
||
echo "sha=${IMAGE_LC}:${{ github.sha }}" >> $GITHUB_OUTPUT
|
||
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
|
||
echo "extra=${IMAGE_LC}:latest" >> $GITHUB_OUTPUT
|
||
else
|
||
BRANCH="${{ github.head_ref || github.ref_name }}"
|
||
echo "extra=${IMAGE_LC}:branch-${BRANCH//\//-}" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
- name: Login to GHCR
|
||
uses: docker/login-action@v3
|
||
with:
|
||
registry: ghcr.io
|
||
username: ${{ github.actor }}
|
||
password: ${{ secrets.GITHUB_TOKEN }}
|
||
|
||
- name: Build & push
|
||
uses: docker/build-push-action@v5
|
||
with:
|
||
context: notification_service
|
||
push: true
|
||
tags: |
|
||
${{ steps.tag.outputs.sha }}
|
||
${{ steps.tag.outputs.extra }}
|
||
|
||
# ── 3. Deploy to physical server (SSH) ───────────────────────────────────────
|
||
deploy:
|
||
name: Deploy
|
||
runs-on: ubuntu-latest
|
||
needs: docker
|
||
if: github.ref == 'refs/heads/main'
|
||
|
||
steps:
|
||
- name: SSH deploy
|
||
env:
|
||
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||
SSH_CERT: ${{ secrets.SSH_CERTIFICATE }}
|
||
SHA_TAG: ${{ needs.docker.outputs.sha_tag }}
|
||
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
||
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||
AIR_QUALITY_API_URL: ${{ secrets.AIR_QUALITY_API_URL }}
|
||
API_USERNAME: ${{ secrets.API_USERNAME }}
|
||
API_PASSWORD: ${{ secrets.API_PASSWORD }}
|
||
run: |
|
||
echo "$SSH_KEY" > /tmp/deploy_key
|
||
echo "$SSH_CERT" > /tmp/deploy_key-cert.pub
|
||
chmod 600 /tmp/deploy_key
|
||
ssh -i /tmp/deploy_key \
|
||
-p ${{ secrets.SSH_PORT }} \
|
||
-o StrictHostKeyChecking=no \
|
||
-o IdentitiesOnly=yes \
|
||
${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} \
|
||
"sudo -iu e << 'EOF'
|
||
docker pull $SHA_TAG
|
||
docker stop notification-service 2>/dev/null || true
|
||
docker rm notification-service 2>/dev/null || true
|
||
docker run -d --name notification-service --restart unless-stopped \
|
||
-e TELEGRAM_BOT_TOKEN=$TELEGRAM_BOT_TOKEN \
|
||
-e TELEGRAM_CHAT_ID=$TELEGRAM_CHAT_ID \
|
||
-e AIR_QUALITY_API_URL=$AIR_QUALITY_API_URL \
|
||
-e API_USERNAME=$API_USERNAME \
|
||
-e API_PASSWORD=$API_PASSWORD \
|
||
-e MOCK_MODE=false \
|
||
$SHA_TAG
|
||
EOF"
|
||
rm /tmp/deploy_key /tmp/deploy_key-cert.pub
|