name: Deploy to production on: push: branches: - main concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: detect-changes: runs-on: ubuntu-latest name: Detect changed components permissions: contents: read outputs: frontend: ${{ steps.filter.outputs.frontend }} backend: ${{ steps.filter.outputs.backend }} stops-script: ${{ steps.filter.outputs.stops-script }} steps: - uses: actions/checkout@v6 - uses: dorny/paths-filter@v3 id: filter with: filters: | frontend: - 'src/frontend/**' backend: - 'src/Costasdev.Busurbano.Backend/**' - 'src/common/**' stops-script: - 'src/gtfs_perstop_report/**' build-frontend: runs-on: ubuntu-latest name: Build frontend artifact needs: detect-changes if: needs.detect-changes.outputs.frontend == 'true' environment: Production steps: - uses: actions/checkout@v6 with: submodules: true lfs: false - uses: actions/setup-node@v6 with: node-version: lts/* cache: "npm" cache-dependency-path: src/frontend/package-lock.json - name: Install frontend dependencies working-directory: src/frontend run: npm ci - name: Build frontend working-directory: src/frontend run: npm run build - name: Prepare artifact directory run: | rm -rf dist mkdir -p dist/frontend cp -R src/frontend/build/client/. dist/frontend/ - name: Archive Production Artifact uses: actions/upload-artifact@v5 with: name: production path: dist retention-days: 7 build-backend: runs-on: ubuntu-latest name: Build backend artifact needs: detect-changes if: needs.detect-changes.outputs.backend == 'true' environment: Production permissions: contents: read steps: - uses: actions/checkout@v6 with: submodules: true lfs: false - uses: actions/setup-dotnet@v5 with: dotnet-version: '9.0.x' - name: Build backend run: dotnet publish -c Release -r linux-arm64 --self-contained false src/Costasdev.Busurbano.Backend/Costasdev.Busurbano.Backend.csproj -o dist/backend - name: Archive Backend Artifact uses: actions/upload-artifact@v5 with: name: backend path: dist/backend retention-days: 7 build-stops-script: runs-on: ubuntu-latest name: Build stop report script needs: detect-changes if: needs.detect-changes.outputs.stops-script == 'true' environment: Production permissions: contents: read steps: - uses: actions/checkout@v6 with: submodules: true lfs: false - name: Archive Stop Report Script Artifact uses: actions/upload-artifact@v5 with: name: stop_report path: src/gtfs_perstop_report/ deploy: runs-on: ubuntu-latest needs: [detect-changes, build-frontend, build-backend, build-stops-script] if: | always() && needs.detect-changes.result == 'success' && (needs.build-frontend.result == 'success' || needs.build-backend.result == 'success' || needs.build-stops-script.result == 'success') name: Deploy to production server environment: Production steps: - name: Download Frontend Artifact if: needs.detect-changes.outputs.frontend == 'true' uses: actions/download-artifact@v6 with: name: production path: dist - name: Download Backend Artifact if: needs.detect-changes.outputs.backend == 'true' uses: actions/download-artifact@v6 with: name: backend path: dist/backend - name: Download Stop Report Script Artifact if: needs.detect-changes.outputs.stops-script == 'true' uses: actions/download-artifact@v6 with: name: stop_report path: dist/stop_report - name: Connect to tailnet uses: tailscale/github-action@v4 with: oauth-client-id: ${{ secrets.TAILSCALE_CLIENT_ID }} oauth-secret: ${{ secrets.TAILSCALE_CLIENT_SECRET }} tags: tag:ci - name: Wait for reachability run: | until tailscale ping --until-direct=false ${{ secrets.TARGET_HOST }}; do echo "Waiting for Tailscale to connect..." sleep 2 done - name: Add SSH Key run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keyscan -H ${{ secrets.TARGET_HOST }} >> ~/.ssh/known_hosts - name: Deploy frontend if: needs.detect-changes.outputs.frontend == 'true' run: | scp -r dist/frontend/* ${{ secrets.TARGET_USER }}@${{ secrets.TARGET_HOST }}:${{ secrets.TARGET_PATH }}/ - name: Stop service if: needs.detect-changes.outputs.backend == 'true' run: ssh ${{ secrets.TARGET_USER }}@${{ secrets.TARGET_HOST }} "echo ${{ secrets.TARGET_PASSWORD }} | sudo -S /usr/bin/systemctl stop busurbano" - name: Upload backend if: needs.detect-changes.outputs.backend == 'true' run: scp -r dist/backend/* app@${{ secrets.TARGET_HOST }}:/opt/busurbano/ - name: Allow execution if: needs.detect-changes.outputs.backend == 'true' run: ssh ${{ secrets.TARGET_USER }}@${{ secrets.TARGET_HOST }} "chmod +x /opt/busurbano/Costasdev.Busurbano.Backend" - name: Start service if: needs.detect-changes.outputs.backend == 'true' run: ssh ${{ secrets.TARGET_USER }}@${{ secrets.TARGET_HOST }} "echo ${{ secrets.TARGET_PASSWORD }} | sudo -S /usr/bin/systemctl start busurbano" - name: Deploy stop report script if: needs.detect-changes.outputs.stops-script == 'true' run: | scp -r dist/stop_report/* ${{ secrets.TARGET_USER }}@${{ secrets.TARGET_HOST }}:/opt/gtfs_perstop_report/