You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Actions中跨仓库测试无法访问localhost的问题求助

问题:GitHub Actions中NextJS应用与Cucumber/Playwright测试套件连接失败

背景

  • 仓库A:NextJS应用
  • 仓库B:Cucumber+Playwright测试套件
  • 需求:仓库A的Main分支收到Pull Request时,触发GitHub Actions执行以下流程:
    • 拉取PR分支头部的仓库A代码
    • 安装仓库A依赖
    • 构建并启动应用
    • 拉取仓库B测试套件代码
    • 安装测试套件依赖
    • 针对运行中的应用执行测试

当前Workflow配置(第一版)

name: Automated Testing workflow
on:
  pull_request: 
    types: 
      - opened
    branches: 
      - 'github-actions/Test'
  workflow_dispatch:
  
jobs:
  build-and-test:
    name: Build and test app
    runs-on: ubuntu-latest
    env:
      APP_URL: ${{ secrets.APP_URL }}
      USERNAME: ${{ secrets.USERNAME }}
      PASSWORD: ${{ secrets.PASSWORD }}
      ORGANISATION_NAME: ${{ secrets.ORGANISATION_NAME }}
    steps:
      - name: Checkout Git repository A
        uses: actions/checkout@v4
        with:
          path: 'app'

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
        
      - name: Install Node.js dependencies
        working-directory: ${{ github.workspace }}/app
        run: npm ci

      - name: Run application
        working-directory: ${{ github.workspace }}/app
        run: npm run start &

      - name: Checkout Automated Testing suite repo
        uses: actions/checkout@v4
        with:
          repository: orgname/testing-repo-B
          token: ${{ secrets.TOKEN }}
          path: 'tests'
      
      - name: Install dependencies
        working-directory: ${{ github.workspace }}/tests
        run: npm ci

      - name: Install playwright browsers
        working-directory: ${{ github.workspace }}/tests
        run: npx playwright install --with-deps

      - name: Run Testing Suite
        run: export APP_URL=$APP_URL &&
          export USERNAME=$USERNAME &&
          export PASSWORD=$PASSWORD &&
          export ORGANISATION_NAME=$ORGANISATION_NAME &&
          npm test
        working-directory: ${{ github.workspace }}/tests

错误日志

Error: a BeforeAll hook errored, process exiting: file:/home/runner/work/******/******/tests/hooks/hooks.js:36
    at Runtime.runTestRunHooks (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/runtime/run_test_run_hooks.js:22:23)
    at async Runtime.start (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/runtime/index.js:62:9)
    at async runCucumber (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/api/run_cucumber.js:110:21)
    at async Cli.run (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/cli/index.js:56:29)
    at async Object.run [as default] (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/cli/run.js:29:18) {
  [cause]: page.goto: net::ERR_CONNECTION_REFUSED at http://***
  Call log:
    - navigating to "***", waiting until "load"
  
      at Object.<anonymous> (/home/runner/work/******/******/tests/hooks/hooks.js:54:16)
      at async wrapPromiseWithTimeout (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/time.js:57:12)
      at async Object.run (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/user_code_runner.js:64:22)
      at async Runtime.runTestRunHooks (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/runtime/run_test_run_hooks.js:14:31)
      at async Runtime.start (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/runtime/index.js:62:9)
      at async runCucumber (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/api/run_cucumber.js:110:21)
      at async Cli.run (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/cli/index.js:56:29)
      at async Object.run (/home/runner/work/******/******/tests/node_modules/@cucumber/cucumber/lib/cli/run.js:29:18) {
    name: 'Error'
  }
}

已尝试的方法

  • 本地环境运行应用和测试套件,测试正常;
  • 将APP_URL从http://localhost:3000改为127.0.0.1,无效;
  • 尝试将应用作为service运行,配置如下:
name: Automated Testing workflow
on:
  pull_request: 
    types: 
      - opened
    branches: 
      - 'github-actions/Test'
  workflow_dispatch:
  
jobs:
  build-and-test:
    name: Build and test app
    runs-on: ubuntu-latest
    env:
      APP_URL: ${{ secrets.APP_URL}}
      USERNAME: ${{ secrets.USERNAME}}
      PASSWORD: ${{ secrets.PASSWORD}}
      ORGANISATION_NAME: ${{ secrets.ORGANISATION_NAME}}
    container: ubuntu
    services:
      appA:
        image: node:20-alpine
        ports: 
          - 3000:3000
    steps:
      - name: Checkout Git repository
        uses: actions/checkout@v4
        with:
          path: 'app'

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
        
      - name: Install Node.js dependencies
        working-directory: ${{ github.workspace }}/app
        run: npm ci

      - name: Run application
        working-directory: ${{ github.workspace }}/app
        run: npm run start:prod &

      - name: Checkout Automated Testing suite repo
        uses: actions/checkout@v4
        with:
          repository: orgname/testing-repo-B
          token: ${{ secrets.TOKEN }}
          path: 'tests'
      
      - name: Install dependencies
        working-directory: ${{ github.workspace }}/tests
        run: npm ci

      - name: Install playwright browsers
        working-directory: ${{ github.workspace }}/tests
        run: export APP_URL=$APP_URL &&
          export USERNAME=$USERNAME &&
          export PASSWORD=$PASSWORD &&
          export ORGANISATION_NAME=$ORGANISATION_NAME &&
          npm test && npm test
        working-directory: ${{ github.workspace }}/tests

问题排查与解决方案

核心问题分析

  1. 应用未完全就绪就执行测试:用npm run start &后台启动应用后,GitHub Actions会立刻执行后续步骤,此时应用可能还在编译启动中,无法接收请求。
  2. Service配置无效:第二版的Service仅声明了Node镜像,并未在容器内部部署和启动你的NextJS应用,实际应用仍在主Job容器中运行,Service未发挥作用。
  3. 环境变量传递冗余:Job级别的env已定义变量,测试步骤无需重复export。

修正后的Workflow配置

name: Automated Testing workflow
on:
  pull_request: 
    types: [opened, synchronize]  # PR更新时也触发测试
    branches: ['main']  # 匹配需求中的Main分支
  workflow_dispatch:
  
jobs:
  build-and-test:
    name: Build and test app
    runs-on: ubuntu-latest
    env:
      APP_URL: http://localhost:3000  # 本地地址直接声明,无需secret(特殊需求除外)
      USERNAME: ${{ secrets.USERNAME }}
      PASSWORD: ${{ secrets.PASSWORD }}
      ORGANISATION_NAME: ${{ secrets.ORGANISATION_NAME }}
    steps:
      - name: Checkout Git repository A
        uses: actions/checkout@v4
        with:
          path: 'app'

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'  # 缓存依赖,加速安装
          cache-dependency-path: app/package-lock.json

      - name: Install Node.js dependencies
        working-directory: ${{ github.workspace }}/app
        run: npm ci

      - name: Build NextJS app  # 先构建再启动,避免启动时编译延迟
        working-directory: ${{ github.workspace }}/app
        run: npm run build

      - name: Run application in background
        working-directory: ${{ github.workspace }}/app
        run: npm run start:prod &  # 确保package.json中有对应脚本(一般对应next start)

      - name: Wait for app to be ready  # 关键步骤:等待应用完全就绪
        run: |
          timeout 120s bash -c 'until curl -s $APP_URL > /dev/null; do sleep 2; done'
          echo "Application is ready at $APP_URL"

      - name: Checkout Automated Testing suite repo
        uses: actions/checkout@v4
        with:
          repository: orgname/testing-repo-B
          token: ${{ secrets.TOKEN }}
          path: 'tests'

      - name: Install test dependencies
        working-directory: ${{ github.workspace }}/tests
        run: npm ci

      - name: Install playwright browsers
        working-directory: ${{ github.workspace }}/tests
        run: npx playwright install --with-deps

      - name: Run Testing Suite
        working-directory: ${{ github.workspace }}/tests
        run: npm test

关键修复点说明

  • 增加应用就绪等待:用curl轮询检查应用可访问性,最多等待120秒,确保应用完全启动后再执行测试。
  • 先构建再启动生产服务:NextJS的start命令依赖预构建产物,提前build可避免启动时的编译延迟。
  • 优化触发条件:将分支改为main,并增加synchronize类型,PR更新代码时自动触发测试。
  • 缓存依赖:利用Node.js Action的缓存功能,减少重复安装依赖的时间。
  • 简化环境变量使用:Job级别的env会自动传递到所有步骤,无需重复export。

内容的提问来源于stack exchange,提问作者Artik Bharoliya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:30:03