Search code examples
gitlabcontinuous-integrationcross-platform

How to skip job in gitlab-ci.yml base on different runner?


I am using the gitlab as my CI/CD system. And I need setup my own runner. I have two runner both 'windows' with 'powershell' and 'macos' with 'shell'. I want either of them can run my build job. The 'macos' is a laptop so it not always online. So I write two version of build jobs, and hope just execute one of them for different runner.

When I use the runner tags, both of the job will execute. And the build will execute twice. If my 'macos' is offline, the build-mac will stuck.

build-win:
  stage: build
  tags:
    - windows
  script: powershell command...

build-mac:
  stage: build
  tags:
    - macos
  script: shell command...

So I think I need 'skip' the job but not select a runner. So I am trying to use only or rules to skip the job. I find the linkage: https://gitlab.com/gitlab-org/gitlab/-/issues/21860 But as the issues said, the CI_RUNNER_EXECUTABLE_ARCH can not use in only, except and rules.

build-win:
  stage: build
  script: powershell command...
  rules:
    - if: $CI_RUNNER_EXECUTABLE_ARCH =~ /^windows.*/

build-mac:
  stage: build
  script: shell command...
  rules:
    - if: $CI_RUNNER_EXECUTABLE_ARCH =~ /^(darwin|linux).*/

I think both of the solution is not suitable. Is there any better way to do this? Thank you~


Solution

  • Not seeing any options in predefined variables for anything like runner online status.

    If you want to base a run rule by runner status, you will probably have to leverage a personal token (or maybe a project token) to hit the runners api for status. You could do something like this:

    stages:
      - check-runner
      - run
    
    image: python
    
    check runner:
      stage: check-runner
      script:
        - curl --header "PRIVATE-TOKEN:$READ_RUNNERS_TOKEN" "$CI_API_V4_URL/runners?tag_list=unreliable"
        - |
          echo RUNNER_STATUS=$(\
          curl --header "PRIVATE-TOKEN:$READ_RUNNERS_TOKEN" "$CI_API_V4_URL/runners?tag_list=macos" \
          | python -c "import sys, json; print(json.load(sys.stdin)[0]['status'])" \
          ) >> .env
      artifacts:
        reports:
          dotenv: .env
    
    use tagged runner:
      stage: run
      script:
        - echo $RUNNER_STATUS
      dependencies:
        - check runner
      rules:
        - if: '$RUNNER_STATUS == "online"'
      tags:
        - macos
    
    user other runner:
      stage: run
      script:
        - echo "used runner"
      dependencies:
        - check runner
      rules:
        - if: '$RUNNER_STATUS != "online"'
      tags:
        - windows