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

如何让GitHub Action在未找到运行器时超时失败?

解决GitHub Action自托管运行器等待超时自动失败的问题

原来的timeout-minutes参数只在作业成功分配到运行器并开始执行后才会生效,等待运行器的阶段不会被计入超时,所以无法满足你的需求。目前可以通过以下两种方式实现“等待运行器超时自动失败”的效果:

方法一:前置作业检测运行器可用性(推荐)

创建一个依赖GitHub托管运行器的前置作业,通过GitHub API循环检查目标自托管运行器的在线状态,设置超时时间,超时后直接失败;主作业依赖这个前置作业,只有前置作业成功才会启动,避免无限等待。

示例工作流代码:

jobs:
  # 前置作业:检测目标自托管运行器是否在线
  check-runner-status:
    runs-on: ubuntu-latest  # 使用GitHub官方托管的运行器,不依赖自托管节点
    outputs:
      runner_ready: ${{ steps.check.outputs.result }}
    steps:
      - name: 检查自托管运行器状态
        id: check
        uses: actions/github-script@v6
        with:
          script: |
            const targetRunner = '${{ matrix.runner_name }}';
            const maxWaitMinutes = 15;  # 设置你想要的超时时间
            const checkInterval = 30;   # 每隔30秒检查一次
            const timeoutTimestamp = Date.now() + maxWaitMinutes * 60 * 1000;

            while (Date.now() < timeoutTimestamp) {
              // 调用GitHub API获取仓库下的自托管运行器列表
              const runnersRes = await github.rest.actions.listSelfHostedRunnersForRepo({
                owner: context.repo.owner,
                repo: context.repo.repo,
              });

              // 查找是否存在在线的目标运行器
              const availableRunner = runnersRes.data.runners.find(r => 
                r.name === targetRunner && r.status === 'online'
              );

              if (availableRunner) {
                console.log(`运行器 ${targetRunner} 已在线,可分配`);
                return true;
              }

              console.log(`运行器 ${targetRunner} 未在线,${checkInterval}秒后重试...`);
              await new Promise(resolve => setTimeout(resolve, checkInterval * 1000));
            }

            console.log(`超时:等待运行器 ${targetRunner} 超过${maxWaitMinutes}分钟,自动失败`);
            return false;

      - name: 检测失败则终止流程
        if: steps.check.outputs.result == 'false'
        run: exit 1

  # 你的主作业,依赖前置检测作业
  main-task:
    needs: check-runner-status
    runs-on: ${{ matrix.runner_name }}
    timeout-minutes: 15  # 这个是作业执行后的超时,依然保留
    strategy:
      matrix:
        runner_name: [runner-01, runner-02, runner-03]  # 你的自托管运行器列表
    steps:
      - name: 执行你的任务
        run: echo "开始在自托管运行器上执行任务"

方法二:利用工作流的超时限制(间接方式)

如果你的工作流整体有固定的执行时间上限,可以设置整个工作流的timeout-minutes,这样不管是等待运行器还是执行作业,只要总时间超过设定值就会终止整个工作流。不过这种方式不够精准,会影响其他正常作业,仅适合对整体时间有严格限制的场景。

示例代码:

name: 你的工作流名称
on:
  schedule:
    - cron: '0 */6 * * *'  # 每日多次运行
timeout-minutes: 20  # 整个工作流的总超时时间,包含等待运行器的阶段

jobs:
  main-job:
    runs-on: ${{ matrix.runners }}
    timeout-minutes: 15
    strategy:
      matrix:
        runners: [runner-01, runner-02]
    steps:
      - name: 执行任务
        run: echo "运行任务"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 16:52:29