4

I have 2 branches prod and dev and I need to create a self-hosted runner for each so that I can use GitHub actions to auto-deploy the branches to the respective server.

I already made the YAML file for actions on both branches that are different and now I don't know to separate the runners for them. I did research but I am unable to find any documentation for that.

alirasheed
  • 43
  • 1
  • 7
  • 1
    You can set up different runners and then utilize `run-on` in the workflow definition to choose the right runner to use, https://docs.github.com/en/actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow#using-self-hosted-runners-in-a-workflow – Lex Li Sep 08 '21 at 06:46
  • 3
    Could you share your workflow so we could refer to it with solution? – Krzysztof Madej Sep 08 '21 at 14:56
  • @LexLi I have to use another OS to accomplish this and that's not what I want. I think GitHub does not have support for labels. It should add a label to select the runner you want to run for a particular action. – alirasheed Sep 18 '21 at 18:44
  • 1
    @alirasheed take a look at this question: https://stackoverflow.com/questions/69986612/github-self-hosted-runners-per-branch – frennky Dec 11 '21 at 16:28

2 Answers2

1

It's easy to do, actually, but finding out how is oddly difficult.

The documentation is marvelous at telling you all the options, but not always great for giving examples.

So the trick is, in your workflow, do this:

  setup-dns:
    name: Setup dynamic DNS
    runs-on: prod

Assuming, of course, that your label is 'prod'. (BTW, don't make Prod use dynamic DNS). According to the docs and common sense, this should work:

  setup-dns:
    name: Setup dynamic DNS
    runs-on: [self-hosted, prod]

But it does not; the runner never runs. As long as you don't create a self-hosted runner with a label (not name) of 'ubuntu-latest' (or other GitHub hosted runner O/S versions) you won't have a problem!

When you think about it logically, putting in your own label requires that it's a self-hosted runner, so the two values for "runs-on" are somewhat redundant. My guess is that you could still use two self-hosted runner labels, and the routine would run on whichever one was available. We didn't go that route as we needed patches run on multiple production servers deterministically, so we literally have prod1, prod2, prod2, etc.

Now here's where it gets interesting. Let's say that you have a callable workflow - better known as a "Subroutine". In that case, you cannot use "runs-on" in the caller; only the callee.

So here's what you do, in your callable workflow:

on:
   workflow_call:
      inputs:
         target_runner_label:
                type: string
                description: 'Target GitHub Runner'
                required: true

   # not strictly needed, but great for testing your callable workflow
   workflow_dispatch:
      inputs:
         target_runner_label:
                type: string
                description: 'Target GitHub Runner'
                required: true

 jobs:
   report_settings:
      name: Report Settings
      runs-on: ${{ inputs.target_runner_label || github.event.inputs.target_runner_label }}

Now - you might wonder at the || statement in the middle. It turns out, the syntax for referring to workflow_call inputs and workflow_dispatch inputs are completely different, so the concat ensures that, if it's called via workflow_dispatch OR workflow_call, the inputs are received. The other input will be ignored. You have to do this doubling up everywhere. WET code, sigh.

Another gotcha: The 'name' of the runner is completely superfluous, because it's the label, not the name, that the workflow uses to trigger it. In the below example, you wouldn't use "erpnext_erpdev" to trigger the workflow, you'd use "erp_fix"

Self-hosted runner example

J. Gwinner
  • 931
  • 10
  • 15
0

github runner

Click on the runner and settings icon to create a label, in the attached image the label created is dev

In your workflow do this:

runs-on: dev
Peter Moses
  • 1,997
  • 1
  • 19
  • 22