torrust-tracker-deployer 0.1.0

Torrust Tracker Deployer - Deployment Infrastructure with Ansible and OpenTofu
Documentation
name: E2E Infrastructure Lifecycle Tests

# This workflow tests infrastructure provisioning and destruction (creating and destroying VMs/containers)
# It does NOT test software configuration/installation to avoid GitHub Actions
# network connectivity issues with LXD VMs.
#
# NOTE: This workflow uses CI-specific approaches like 'sudo chmod 666' on the LXD socket
# and 'sudo' with LXD commands. These approaches are NOT recommended for local development.
# For local use, follow the proper group membership approach documented in templates/tofu/lxd/README.md
#
# NETWORK TUNING: We use smorimoto/tune-github-hosted-runner-network to fix flaky networking
# issues that cause Docker GPG key downloads to fail intermittently in GitHub Actions.
# See: https://github.com/actions/runner-images/issues/1187 and https://github.com/actions/runner-images/issues/2890

on:
  push:
  pull_request:
  workflow_dispatch: # Allow manual triggering

jobs:
  e2e-infrastructure-lifecycle-tests:
    runs-on: ubuntu-latest
    timeout-minutes: 30 # Reduced timeout since we're not installing software

    steps:
      - name: Checkout repository
        uses: actions/checkout@v5

      - name: Tune GitHub-hosted runner network
        uses: smorimoto/tune-github-hosted-runner-network@v1

      - name: Setup Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable

      - name: Cache Rust dependencies
        uses: Swatinem/rust-cache@v2

      - name: Install dependencies
        run: |
          cargo build -p torrust-tracker-deployer-dependency-installer --bin dependency-installer
          cargo run -p torrust-tracker-deployer-dependency-installer --bin dependency-installer -- install

      - name: Verify installations
        run: |
          sudo lxc version
          tofu version
          cargo --version

      - name: Build E2E infrastructure lifecycle tests binary
        run: |
          cargo build --bin e2e-infrastructure-lifecycle-tests --release

      - name: Run E2E infrastructure lifecycle test
        run: |
          # Run the E2E infrastructure lifecycle test with debug logging for better debugging
          # Use sudo -E and preserve PATH to ensure cargo is accessible
          echo "🚀 Starting E2E infrastructure lifecycle test at $(date)"
          sudo -E env "PATH=$PATH" cargo run --bin e2e-infrastructure-lifecycle-tests
          echo "✅ E2E infrastructure lifecycle test completed at $(date)"
        env:
          # Preserve environment variables for the E2E test
          RUST_LOG: debug

      - name: Get test outputs (on success)
        if: success()
        run: |
          echo "=== Infrastructure Outputs ==="
          # Only check outputs if build directory still exists (it may be cleaned up by DestroyCommand)
          if [ -d "build/e2e-infrastructure/tofu/lxd" ]; then
            cd build/e2e-infrastructure/tofu/lxd
            sudo -E tofu output || echo "No outputs available"
          else
            echo "Build directory not found (likely cleaned up by DestroyCommand)"
          fi

          echo "=== Container Status ==="
          sudo lxc list torrust-tracker-vm-e2e-infrastructure || echo "Container not found"

          # Check if the container has an IP address before proceeding
          sudo lxc info torrust-tracker-vm-e2e-infrastructure || echo "Container info not available"

      - name: Debug information (on failure)
        if: failure()
        run: |
          echo "=== LXD Status ==="
          sudo lxc list || echo "LXC list failed"

          echo "=== OpenTofu State ==="
          if [ -d "build/e2e-infrastructure/tofu/lxd" ]; then
            cd build/e2e-infrastructure/tofu/lxd
            sudo -E tofu show || echo "No state to show"
          else
            echo "No OpenTofu state directory found"
          fi

          echo "=== System Resources ==="
          df -h
          free -h

          echo "=== Recent logs ==="
          sudo journalctl --since "10 minutes ago" --no-pager | tail -50 || echo "Journal logs not available"

      - name: Cleanup infrastructure (on failure only)
        if: failure()
        run: |
          echo "Test failed - attempting emergency cleanup..."

          # Try OpenTofu cleanup only if build directory still exists
          if [ -d "build/e2e-infrastructure/tofu/lxd" ]; then
            echo "Found OpenTofu state directory, attempting tofu destroy..."
            cd build/e2e-infrastructure/tofu/lxd
            sudo -E tofu destroy -auto-approve || echo "Tofu destroy failed or nothing to destroy"
          else
            echo "No OpenTofu state directory found (likely cleaned up by DestroyCommand)"
          fi

          # Always attempt LXD cleanup (no working directory dependency)
          echo "Attempting LXD resource cleanup..."
          sudo lxc delete torrust-tracker-vm-e2e-infrastructure --force || echo "Container deletion failed or container doesn't exist"
          sudo lxc profile delete torrust-profile-e2e-infrastructure || echo "Profile deletion failed or profile doesn't exist"

      - name: Final verification
        if: always()
        run: |
          echo "Verifying final cleanup..."
          sudo lxc list

          echo "=== Test Summary ==="
          echo "E2E infrastructure lifecycle test workflow completed"
          if [ "${{ job.status }}" = "success" ]; then
            echo "✅ All infrastructure lifecycle tests passed successfully"
          else
            echo "❌ Some infrastructure lifecycle tests failed - check logs above"
          fi