name: mesh-isp-config-ci

on:
  pull_request:
    paths:
      - "inventory/**"
      - "roles/**"
      - "templates/**"
      - "playbooks/**"
      - "firmware/**"
  push:
    branches:
      - main

env:
  COMMUNITY_ASN: "4242421099"
  MGMT_DOMAIN: "noc.rivermesh.local"
  CONFIG_OUTPUT: "build/rendered"

jobs:
  validate:
    name: Validate network source data
    runs-on: ubuntu-24.04

    steps:
      - uses: actions/checkout@v4

      - name: Install tooling
        run: |
          sudo apt-get update
          sudo apt-get install -y yamllint jq python3-pip
          pip3 install ansible-core netaddr jsonschema

      - name: Lint YAML inventory
        run: yamllint inventory group_vars host_vars

      - name: Validate node registry schema
        run: |
          python3 tools/validate_nodes.py \
            --schema schemas/node-registry.schema.json \
            --nodes inventory/nodes.yml

      - name: Check IP allocations
        run: |
          python3 tools/check_allocations.py \
            --ipv4-prefix 10.109.0.0/16 \
            --ipv6-prefix fd42:1099::/48 \
            --nodes inventory/nodes.yml

  render-router-configs:
    name: Render router configs
    runs-on: ubuntu-24.04
    needs: validate

    steps:
      - uses: actions/checkout@v4

      - name: Install Ansible
        run: pip3 install ansible-core jmespath netaddr

      - name: Render edge and relay configs
        run: |
          mkdir -p "$CONFIG_OUTPUT"
          ansible-playbook playbooks/render.yml \
            -i inventory/hosts.yml \
            -e output_dir="$CONFIG_OUTPUT" \
            -e community_asn="$COMMUNITY_ASN"

      - name: Verify BIRD syntax
        run: |
          docker run --rm \
            -v "$PWD/$CONFIG_OUTPUT:/configs:ro" \
            ghcr.io/rivermesh/bird2-check:2.15 \
            /configs

      - name: Verify WireGuard peers
        run: |
          python3 tools/check_wireguard_peers.py \
            --config-dir "$CONFIG_OUTPUT" \
            --min-mtu 1280 \
            --max-endpoints-per-node 6

      - name: Upload rendered configs
        uses: actions/upload-artifact@v4
        with:
          name: rendered-router-configs
          path: build/rendered
          retention-days: 14

  firmware:
    name: Build OpenWrt site image
    runs-on: ubuntu-24.04
    needs: validate

    steps:
      - uses: actions/checkout@v4

      - name: Build imagebuilder profile
        run: |
          docker build \
            --file firmware/Dockerfile.imagebuilder \
            --tag rivermesh-openwrt-builder:ci \
            firmware

      - name: Generate node images
        run: |
          docker run --rm \
            -v "$PWD:/work" \
            rivermesh-openwrt-builder:ci \
            ./firmware/build-site-images.sh \
              --nodes inventory/nodes.yml \
              --profile ath79-generic \
              --release 23.05.5

      - name: Upload firmware artifacts
        uses: actions/upload-artifact@v4
        with:
          name: openwrt-site-images
          path: firmware/output/*.bin
          retention-days: 7

  deploy-staging:
    name: Deploy staging mesh services
    runs-on: ubuntu-24.04
    needs:
      - render-router-configs
      - firmware
    if: github.ref == 'refs/heads/main'

    environment:
      name: staging
      url: https://staging-noc.rivermesh.net

    steps:
      - uses: actions/checkout@v4

      - name: Download rendered configs
        uses: actions/download-artifact@v4
        with:
          name: rendered-router-configs
          path: build/rendered

      - name: Install deployment tools
        run: pip3 install ansible-core netaddr

      - name: Deploy to staging gateways
        env:
          ANSIBLE_HOST_KEY_CHECKING: "true"
          SSH_AUTH_SOCK: /tmp/ssh-agent.sock
        run: |
          ansible-playbook playbooks/deploy-staging.yml \
            -i inventory/staging.yml \
            -e rendered_config_dir=build/rendered \
            --limit gateway_staging

      - name: Run post-deploy health checks
        run: |
          python3 tools/mesh_healthcheck.py \
            --prometheus https://prometheus.staging-noc.rivermesh.net \
            --require-bgp-sessions-up \
            --require-dns \
            --max-packet-loss 2.5