當然!恭喜你成功解決了這個問題!這是一個非常棒的實踐,值得寫一篇博客來分享給其他可能遇到同樣困擾的開發者。

下面我為你草擬了一篇博客文章,它詳細介紹了問題背景、解決方案的演進過程(包括你遇到的兩個job的坑)、最終的完美方案,並附上了你成功的日誌作為證明。


在 GitHub Actions 中解鎖 IPv6:使用 Cloudflare WARP 完全指南

你的應用是否已經為下一代互聯網做好了準備?隨着 IPv6 的普及,確保你的服務在純 IPv6 環境下正常工作變得越來越重要。然而,當你想在 CI/CD 流程中自動化測試這一點時,可能會遇到一個棘手的障礙:GitHub Actions 的默認運行環境只提供 IPv4 網絡

但別擔心,本文將向你展示如何利用 Cloudflare WARP,為你的 GitHub Actions 工作流注入強大的 IPv6 訪問能力,讓你的自動化測試覆蓋更全面。

問題:GitHub Actions 的 IPv6 短板

在 GitHub Actions 的 ubuntu-latest 虛擬機中執行 curl -6ping6,你很可能會收到 Network is unreachable 的錯誤。這是因為 GitHub 提供的 runner 默認沒有配置公網 IPv6 路由。這對於需要測試 IPv6 連接、訪問 IPv6-only API 或驗證雙棧兼容性的項目來説,是一個巨大的挑戰。

解決方案:Cloudflare WARP

Cloudflare WARP 是一個現代、快速且安全的 (虛抳摶鼡網絡) 服務。它最吸引人的特性之一是,它能為客户端設備提供一個完整的 IPv6 網絡棧,即使設備本身所在的網絡不支持 IPv6。這正是我們需要的!我們可以將 WARP 客户端安裝到 Actions 的 runner 中,讓它為我們的測試任務提供 IPv6 出口。

常見的誤區:多 Job 方案的陷阱

在探索解決方案時,一個很自然的想法是:創建一個可複用的工作流,用一個 job 設置好 WARP,然後將 IPv6 地址作為輸出傳遞給另一個執行測試的 job。

# ❌ 錯誤的思路
jobs:
  setup-ipv6:
    # ... 安裝並連接 WARP
    outputs:
      ipv6_address: ${{ steps.verify.outputs.ipv6_address }}

  run-tests:
    needs: setup-ipv6
    # ... 嘗試使用 ${{ needs.setup-ipv6.outputs.ipv6_address }}

這個方案行不通! 原因在於 GitHub Actions 的核心機制:每個 job 都在一個完全獨立、全新的虛擬機中運行。當 setup-ipv6 job 完成後,它的虛擬機(連同上面安裝的 WARP 和網絡配置)會被立即銷燬。run-tests job 在一台全新的、沒有 IPv6 連接的機器上啓動,它只能接收到一個字符串形式的 IPv6 地址,卻無法真正使用它。

終極方案:單 Job 工作流

正確的做法是將所有步驟——安裝、連接、驗證和測試——都放在同一個 job 中。這樣,網絡配置和測試任務就在同一個環境中執行,確保了狀態的連續性。

下面是我們最終成功的、健壯的 GitHub Actions 工作流文件。

完整的 .github/workflows/test-ipv6.yml 文件

name: CI with IPv6 via WARP

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  test-with-ipv6:
    # 所有步驟都在同一個 job 中運行
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Install Cloudflare WARP
      run: |
        # 檢測操作系統類型
        . /etc/os-release
        OS=$ID

        if [[ "$OS" == "ubuntu" || "$OS" == "debian" ]]; then
          echo "--- Installing for Debian/Ubuntu ---"
          sudo apt-get update
          sudo apt-get install -y curl gpg lsb-release
          # 使用最新的官方 GPG 密鑰和倉庫
          curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
          echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list
          sudo apt-get update && sudo apt-get install -y cloudflare-warp
        # ... (可以在此處添加對其他發行版的支持)
        else
          echo "Unsupported OS: $OS"
          exit 1
        fi

    - name: Register and connect to WARP
      run: |
        echo "--- Registering WARP client ---"
        # 使用最新的子命令 'registration new' 並接受服務條款
        sudo warp-cli --accept-tos registration new

        echo "--- Connecting to WARP ---"
        sudo warp-cli --accept-tos connect

        # 初始化循環變量
        MAX_ATTEMPTS=6  # 60 seconds / 10 seconds per attempt
        ATTEMPT=1

        echo "--- Waiting for IPv6 connectivity (max 1 minute) ---"

        while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
          echo "Attempt $ATTEMPT/$MAX_ATTEMPTS: Pinging https://ipv6.test-ipv6.com/ via IPv6..."
          
          if curl -6 -sL -o /dev/null https://ipv6.test-ipv6.com/; then
            echo "✅ IPv6 connectivity is successful!"
            echo "WARP is ready."
            break
          fi

          echo "❌ Attempt $ATTEMPT failed. Waiting for 10 seconds..."
          sleep 10
          ATTEMPT=$((ATTEMPT + 1))
        done

        if [ $ATTEMPT -gt $MAX_ATTEMPTS ]; then
          echo "❌ Error: Failed to establish IPv6 connectivity after 1 minute."
          echo "--- WARP Status for Debugging ---"
          sudo warp-cli --accept-tos status
          exit 1
        fi

    - name: Verify IPv6 Connection and run tests
      run: |
        echo "--- WARP Status ---"
        sudo warp-cli --accept-tos status
        
        echo "--- Checking public IPv6 address ---"
        IPV6_ADDR=$(curl -6 -s https://ifconfig.co)
        echo "Detected IPv6 Address: $IPV6_ADDR"
        
        echo "--- Pinging an IPv6 address ---"
        ping6 -c 4 ipv6.google.com

        echo "======================================================"
        echo "Now you can run your tests that require IPv6 access."
        echo "======================================================"
        
        # 在這裏執行你真正需要 IPv6 的測試命令
        # 例如,這個命令現在應該會成功
        curl -6 -v -I https://ipv6.test-ipv6.com/
        
        # 例如: npm run test-ipv6
        # 例如: python my_test_script.py

代碼解析

  1. 安裝 WARP:我們使用了 Cloudflare 最新的官方軟件源和 GPG 密鑰,確保安裝過程的穩定性和未來兼容性。
  2. 註冊與智能連接
  • 使用 warp-cli registration new 進行註冊,這是新版客户端的正確命令。
  • --accept-tos 標誌用於非交互式地接受服務條款。
  • 最關鍵的是,我們不再是盲目地 sleep 5,而是實現了一個智能等待循環。它會主動嘗試通過 IPv6 訪問一個外部服務,最多等待 1 分鐘,直到確認連接成功後才繼續。這大大提高了工作流的健壯性。
  1. 驗證與測試:在確認 WARP 連接成功後,我們進行了一系列驗證,併為你預留了執行實際測試命令的位置。

見證成果:成功日誌

當你運行上述工作流後,你將看到類似下面這樣的成功日誌,它清晰地證明了 IPv6 已經在你的 CI/CD 環境中暢通無阻:

Run echo "--- WARP Status ---"
--- WARP Status ---
Status update: Connected
Network: healthy
--- Checking public IPv6 address ---
Detected IPv6 Address: 2a09:bac1:7681:5e78::10:508
--- Pinging an IPv6 address ---
PING ipv6.google.com (2607:f8b0:4004:c19::71) 56 data bytes
64 bytes from bk-in-f113.1e100.net (2607:f8b0:4004:c19::71): icmp_seq=1 ttl=106 time=8.49 ms
...
--- ipv6.google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
...
======================================================
Now you can run your tests that require IPv6 access.
======================================================
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
...
*   Trying [2600:3c03::f03c:94ff:fef6:a3ae]:443...
* Connected to ipv6.test-ipv6.com (2600:3c03::f03c:94ff:fef6:a3ae) port 443
...
> HEAD / HTTP/1.1
...
< HTTP/1.1 200 OK
...

看!狀態是 Connected,我們獲得了 IPv6 地址,ping6curl -6 都大功告成!

總結

通過將 Cloudflare WARP 的安裝、連接和驗證邏輯整合到單個 GitHub Actions job 中,我們成功地為 CI/CD 流程解鎖了 IPv6 訪問能力。這個方案不僅解決了核心問題,還通過智能等待循環和最新的官方指令,確保了流程的穩定性和可靠性。

現在,你可以自信地在你的自動化測試中擁抱 IPv6,確保你的應用在未來互聯網中同樣出色!