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

GitHub Actions默认runner不可用时,如何自动切换至自托管runner?

解决GitHub Actions自动切换自托管Runner的方案

我们平时用GitHub Actions默认的ubuntu-latest runner,但遇到付费限制时需要切换到自托管实例。你当前靠仓库topics判断runner的方案存在两个问题:无法自动检测runner状态、重跑作业时上下文里的topics不会更新。下面给几个可行的解决办法:

方案一:自动检测自托管Runner状态(完全自动化)

通过前置作业实时查询仓库里的自托管runner是否在线,动态决定后续作业使用的runner。重跑时这个检测会重新执行,完美解决上下文不更新的问题。

jobs:
  check-runner-status:
    runs-on: ubuntu-latest  # 这个轻量检测用默认runner即可,消耗极小
    outputs:
      target-runner: ${{ steps.detect.outputs.runner }}
    steps:
      - name: 检测在线自托管Runner
        id: detect
        run: |
          # 查询仓库所有runner,过滤出状态为online且带self-hosted标签的
          HAS_ONLINE_SELF_HOSTED=$(gh api repos/${{ github.repository }}/runners --jq '.runners[] | select(.status == "online") | .labels[].name' | grep -q "self-hosted" && echo "true" || echo "false")
          if [ "$HAS_ONLINE_SELF_HOSTED" = "true" ]; then
            echo "runner=self-hosted" >> $GITHUB_OUTPUT
          else
            echo "runner=ubuntu-latest" >> $GITHUB_OUTPUT
          fi
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  main-job:
    name: 核心作业
    needs: check-runner-status
    runs-on: ${{ needs.check-runner-status.outputs.target-runner }}
    steps:
      - name: 执行作业内容
        run: echo "当前运行在: ${{ runner.name }}"

注意事项

  • 默认的GITHUB_TOKEN已经具备读取仓库runner状态的权限,不需要额外配置
  • 如果你的自托管runner用了自定义标签(比如self-hosted-linux),把grep的内容改成对应的标签名称即可

方案二:手动指定Runner(灵活干预)

通过工作流的手动触发选项,允许你直接选择要使用的runner,重跑作业时也能重新选择,彻底绕开上下文缓存的问题。

name: 可选择Runner的工作流
on:
  push:  # 代码推送时默认用ubuntu-latest
  workflow_dispatch:  # 手动触发时可选择runner
    inputs:
      runner-type:
        description: 选择运行的Runner
        required: true
        default: 'ubuntu-latest'
        type: choice
        options:
          - ubuntu-latest
          - self-hosted

jobs:
  main-job:
    name: 核心作业
    runs-on: ${{ github.event.inputs.runner-type || 'ubuntu-latest' }}
    steps:
      - name: 执行作业内容
        run: echo "当前运行在: ${{ runner.name }}"

使用方式

  • 日常推送代码自动用默认runner
  • 需要切换自托管时,在GitHub仓库的Actions页面手动触发该工作流,选择self-hosted
  • 重跑失败作业时,在重跑界面可以重新选择runner类型

方案三:修复原Topics方案的重跑问题

如果你想保留用仓库topics控制的逻辑,可以通过前置作业实时拉取最新的topics,而不是依赖触发时的github.event缓存数据。

jobs:
  fetch-latest-topics:
    runs-on: ubuntu-latest
    outputs:
      use-self-hosted: ${{ steps.check.outputs.result }}
    steps:
      - name: 获取最新仓库Topics
        id: check
        run: |
          # 查询仓库当前的topics列表,判断是否包含self-hosted
          TOPICS_CONTAINS=$(gh api repos/${{ github.repository }} --jq '.topics | contains(["self-hosted"])')
          echo "result=$TOPICS_CONTAINS" >> $GITHUB_OUTPUT
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  main-job:
    name: 核心作业
    needs: fetch-latest-topics
    runs-on: ${{ needs.fetch-latest-topics.outputs.use-self-hosted == 'true' && 'self-hosted' || 'ubuntu-latest' }}
    steps:
      - name: 执行作业内容
        run: echo "当前运行在: ${{ runner.name }}"

这个方案重跑时会重新拉取最新的topics状态,解决了原方案重跑时上下文不更新的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 17:11:10