name: CI/CD on: pull_request: push: branches: - main - master concurrency: group: ci-${{ gitea.workflow }}-${{ gitea.ref }} cancel-in-progress: true jobs: backend: name: Backend runs-on: ubuntu-latest defaults: run: working-directory: backend steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Go uses: actions/setup-go@v5 with: go-version: "1.24.x" cache-dependency-path: backend/go.sum - name: Download dependencies run: go mod download - name: Vet run: go vet ./... - name: Test run: go test -race -count=1 ./... frontend: name: Frontend runs-on: ubuntu-latest defaults: run: working-directory: frontend steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version: "22" cache: npm cache-dependency-path: frontend/package-lock.json - name: Install dependencies run: npm ci - name: Build run: npm run build build-and-push: name: Build & Push runs-on: ubuntu-latest needs: [backend, frontend] if: ${{ gitea.ref == 'refs/heads/main' || gitea.ref == 'refs/heads/master' }} steps: - name: Checkout uses: actions/checkout@v4 - name: Login to Gitea Container Registry run: | REGISTRY_HOST=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||') echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "$REGISTRY_HOST" -u "${{ secrets.REGISTRY_USER }}" --password-stdin - name: Build & Push Backend API run: | REGISTRY_HOST=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||') REPO="${{ gitea.repository }}" docker build -f backend/Dockerfile --target api \ -t "$REGISTRY_HOST/$REPO/backend-api:${{ gitea.sha }}" \ -t "$REGISTRY_HOST/$REPO/backend-api:latest" \ . docker push "$REGISTRY_HOST/$REPO/backend-api" --all-tags - name: Build & Push Backend Worker run: | REGISTRY_HOST=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||') REPO="${{ gitea.repository }}" docker build -f backend/Dockerfile --target worker \ -t "$REGISTRY_HOST/$REPO/backend-worker:${{ gitea.sha }}" \ -t "$REGISTRY_HOST/$REPO/backend-worker:latest" \ . docker push "$REGISTRY_HOST/$REPO/backend-worker" --all-tags - name: Build & Push Frontend run: | REGISTRY_HOST=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||') REPO="${{ gitea.repository }}" docker build -f frontend/Dockerfile \ -t "$REGISTRY_HOST/$REPO/frontend:${{ gitea.sha }}" \ -t "$REGISTRY_HOST/$REPO/frontend:latest" \ . docker push "$REGISTRY_HOST/$REPO/frontend" --all-tags deploy: name: Deploy runs-on: ubuntu-latest needs: [build-and-push] if: ${{ gitea.ref == 'refs/heads/main' || gitea.ref == 'refs/heads/master' }} steps: - name: Checkout uses: actions/checkout@v4 - name: Setup SSH run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/vloop-deploy chmod 600 ~/.ssh/vloop-deploy - name: Copy nginx.prod.conf to server run: | scp -o StrictHostKeyChecking=no -i ~/.ssh/vloop-deploy \ frontend/nginx.prod.conf \ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/opt/vloop/nginx.prod.conf - name: Pull images & restart services run: | ssh -o StrictHostKeyChecking=no -i ~/.ssh/vloop-deploy \ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} \ "cd /opt/vloop && \ sed -i 's/^TAG=.*/TAG=${{ gitea.sha }}/' .env && \ docker compose -f docker-compose.prod.yml pull && \ docker compose -f docker-compose.prod.yml up -d --remove-orphans && \ docker image prune -f"