能否为GitHub Actions的runs-on配置「或」逻辑而非「与」逻辑?
实现GitHub Actions
runs-on的「或」逻辑(优先托管, fallback到自托管) 要实现你需要的「优先使用GitHub托管运行器,无可用容量时 fallback到自托管运行器」的逻辑,官方的runs-on数组(与逻辑)无法直接满足,但可以通过并发组(Concurrency)+ 双作业的方式实现,具体方案如下:
核心思路
创建两个并行作业:一个绑定GitHub托管的ubuntu-latest,另一个绑定自托管的my-ubuntu-latest,将它们放入同一个并发组并开启「取消进行中任务」的配置。由于托管运行器启动速度远快于你的自托管临时运行器(带队列延迟),托管作业会先抢占执行权,此时GitHub Actions会自动取消同一并发组内的自托管作业;若托管运行器因容量不足等原因未及时启动,自托管作业则会正常执行。
完整配置示例
name: Fallback Runner Workflow on: [push, pull_request] concurrency: group: runner-fallback-${{ github.ref }} cancel-in-progress: true jobs: run-on-hosted: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Execute your task run: | # 这里替换为你的实际任务命令 echo "Running on GitHub hosted runner" run-on-self-hosted: runs-on: my-ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Execute your task run: | # 这里替换为你的实际任务命令 echo "Running on self-hosted runner"
配置说明
- 并发组(
concurrency):通过runner-fallback-${{ github.ref }}为每个分支/标签创建独立的并发组,避免不同分支的任务互相干扰;cancel-in-progress: true确保同一组内只有一个作业能执行,其他待处理或进行中的作业会被取消。 - 双作业设计:两个作业逻辑完全一致,仅
runs-on标签不同。托管作业启动更快,会优先抢占执行,自托管作业因启动延迟,在准备就绪时会发现已被取消,从而跳过任务执行,完美契合你自托管运行器的队列机制。 - 任务一致性:确保两个作业的步骤完全相同,无论最终在哪个运行器执行,任务逻辑都保持一致。
额外优化(可选)
如果希望仅当托管作业未启动(而非失败)时才触发自托管作业,可以通过needs和if条件调整:
jobs: run-on-hosted: runs-on: ubuntu-latest continue-on-error: true # 允许托管作业失败,不影响后续判断 steps: - name: Checkout code uses: actions/checkout@v4 - name: Execute your task run: | echo "Running on GitHub hosted runner" run-on-self-hosted: needs: run-on-hosted if: needs.run-on-hosted.result == 'skipped' || needs.run-on-hosted.result == 'cancelled' runs-on: my-ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Execute your task run: | echo "Running on self-hosted runner"
这种方式下,自托管作业仅在托管作业被跳过或取消时才执行,若托管作业执行失败,不会触发自托管作业(可根据你的需求调整if条件)。
内容的提问来源于stack exchange,提问作者Shawn
相关产品推荐
相关产品推荐

