name: Build Hugo on: push: branches: [ "main" ] env: REGISTRY: tea.ahmza.com IMAGE_NAME: ${{ gitea.repository }} jobs: build: runs-on: ubuntu-latest permissions: contents: read packages: write attestations: write id-token: write steps: - name: Checkout Repo uses: actions/checkout@v4 - name: Login to Gitea Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ gitea.repository_owner }} password: ${{ secrets.GITEATOKEN }} - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push uses: docker/build-push-action@v6 with: context: . platforms: linux/arm64, linux/amd64 push: true build-args: | BUILDKIT_CONTEXT_KEEP_GIT_DIR=true tags: | ${{ env.REGISTRY }}/${{ gitea.repository_owner }}/blog-ahmza-com:latest ${{ env.REGISTRY }}/${{ gitea.repository_owner }}/blog-ahmza-com:${{ gitea.event.head_commit.id }} cache-from: type=gha cache-to: type=gha,mode=max deploy: runs-on: ubuntu-latest needs: build steps: - name: Debug Netbird connectivity env: NB_URL: ${{ secrets.NETBIRD_URL }} NB_KEY: ${{ secrets.NETBIRD_SETUP_KEY }} run: | echo "=== Secret presence (values are masked) ===" echo "NETBIRD_URL length: ${#NB_URL}" echo "NETBIRD_SETUP_KEY length: ${#NB_KEY}" if [ -z "$NB_URL" ]; then echo "WARNING: NETBIRD_URL is EMPTY"; fi if [ -z "$NB_KEY" ]; then echo "WARNING: NETBIRD_SETUP_KEY is EMPTY"; fi # Derive host from the URL without printing the full URL. host="$(printf '%s' "$NB_URL" | sed -E 's#^[a-zA-Z]+://##; s#[:/].*$##')" echo "Derived management host: ${host:-}" echo "=== DNS resolution ===" getent hosts "$host" || nslookup "$host" || echo "DNS resolution FAILED for $host" # This deployment multiplexes management + signal + dashboard # behind Traefik on :443 (gRPC-over-HTTP/2). There is no separate # :10000 signal port. The data plane is WireGuard on 51820/udp and # STUN on 3478/udp -- those are the ports that actually matter for # 'netbird up' to complete the tunnel handshake. echo "=== Control plane: HTTPS :443 (mgmt + signal via Traefik) ===" curl -sS -o /dev/null -w "HTTP %{http_code} connect=%{time_connect}s total=%{time_total}s\n" \ --max-time 15 "https://${host}/" || echo "curl to :443 FAILED" ip="$(getent hosts "$host" | awk '{print $1; exit}')" echo "Resolved IP: ${ip:-}" echo "=== Data plane: WireGuard 51820/udp (nc UDP probe) ===" if command -v nc >/dev/null 2>&1; then nc -zu -w 5 "$host" 51820 \ && echo "UDP 51820 appears OPEN/reachable" \ || echo "UDP 51820 probe returned non-zero (may be filtered/blocked -- prime suspect)" else echo "nc not available; installing..." (apt-get update -qq && apt-get install -y -qq netcat-openbsd) >/dev/null 2>&1 || true nc -zu -w 5 "$host" 51820 \ && echo "UDP 51820 appears OPEN/reachable" \ || echo "UDP 51820 probe returned non-zero (may be filtered/blocked -- prime suspect)" fi echo "=== STUN 3478/udp (nc UDP probe) ===" nc -zu -w 5 "$host" 3478 \ && echo "UDP 3478 appears OPEN/reachable" \ || echo "UDP 3478 probe returned non-zero (may be filtered/blocked)" echo "=== Outbound UDP allowed at all? (probe public STUN) ===" nc -zu -w 5 stun.l.google.com 19302 \ && echo "General outbound UDP works (reached Google STUN)" \ || echo "General outbound UDP may be BLOCKED on this runner network" echo "=== done (this step never fails the build) ===" continue-on-error: true - name: Netbird Connect uses: Alemiz112/netbird-connect@v1 with: setup-key: ${{ secrets.NETBIRD_SETUP_KEY }} hostname: 'gitea-actions-blog' management-url: ${{ secrets.NETBIRD_URL }} - name: Deploy to RPIC-Cluster uses: appleboy/ssh-action@v1 with: host: ${{ secrets.RPIC_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.RPIC_KEY }} port: ${{ secrets.SSH_PORT }} script: 'kubectl rollout restart deployment blog -n blog-ahmza-com' - name: Deploy to Gimli uses: appleboy/ssh-action@v1 with: host: ${{ secrets.GIMLI_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.GIMLI_KEY }} port: ${{ secrets.SSH_PORT }} script: 'docker compose down && docker compose pull && docker compose up -d'