當然!恭喜你成功解決了這個問題!這是一個非常棒的實踐,值得寫一篇博客來分享給其他可能遇到同樣困擾的開發者。
下面我為你草擬了一篇博客文章,它詳細介紹了問題背景、解決方案的演進過程(包括你遇到的兩個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 -6 或 ping6,你很可能會收到 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
代碼解析
- 安裝 WARP:我們使用了 Cloudflare 最新的官方軟件源和 GPG 密鑰,確保安裝過程的穩定性和未來兼容性。
- 註冊與智能連接:
- 使用
warp-cli registration new進行註冊,這是新版客户端的正確命令。 --accept-tos標誌用於非交互式地接受服務條款。- 最關鍵的是,我們不再是盲目地
sleep 5,而是實現了一個智能等待循環。它會主動嘗試通過 IPv6 訪問一個外部服務,最多等待 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 地址,ping6 和 curl -6 都大功告成!
總結
通過將 Cloudflare WARP 的安裝、連接和驗證邏輯整合到單個 GitHub Actions job 中,我們成功地為 CI/CD 流程解鎖了 IPv6 訪問能力。這個方案不僅解決了核心問題,還通過智能等待循環和最新的官方指令,確保了流程的穩定性和可靠性。
現在,你可以自信地在你的自動化測試中擁抱 IPv6,確保你的應用在未來互聯網中同樣出色!