From c055e8b4563f2fb0f71970a0a9e0043a16e7c43e Mon Sep 17 00:00:00 2001 From: Jonathan Schwender <55576758+jschwe@users.noreply.github.com> Date: Thu, 7 Aug 2025 07:13:36 +0200 Subject: [PATCH] ci: Move runner-timeout to composite action (#38503) We are hitting the limit of 20 workflow references in servo. To help mitigate this somewhat, we migrate the timeout job to a composite action, which should be able to support our needs just as well. Testing: [try run of this PR](https://github.com/servo/servo/actions/runs/16783916103/job/47529580725). [try run with unconditional cancel](https://github.com/servo/servo/actions/runs/16784074213/job/47530099654). This reduces our workflow count by one, slightly helping to address #36143 Signed-off-by: Jonathan Schwender --- .github/actions/runner-timeout/action.yml | 37 ++++++++++++++++++ .github/workflows/linux.yml | 17 +++++--- .github/workflows/mac.yml | 17 +++++--- .../workflows/self-hosted-runner-timeout.yml | 39 ------------------- .github/workflows/windows.yml | 17 +++++--- 5 files changed, 73 insertions(+), 54 deletions(-) create mode 100644 .github/actions/runner-timeout/action.yml delete mode 100644 .github/workflows/self-hosted-runner-timeout.yml diff --git a/.github/actions/runner-timeout/action.yml b/.github/actions/runner-timeout/action.yml new file mode 100644 index 00000000000..707867f74ed --- /dev/null +++ b/.github/actions/runner-timeout/action.yml @@ -0,0 +1,37 @@ +# In the unlikely event a self-hosted runner was selected and reserved but it +# goes down before the workload starts, cancel the workflow run. +name: Detect self-hosted runner assigment timeout +description: "Cancel the workflow run if a self-hosted runner was selected, but the job failed to start" +inputs: + unique-id: + required: true + description: "Unique ID of the runner" + github_token: + required: true + description: "Must be able to do github API calls and cancel jobs." + +runs: + using: "composite" + steps: + - name: Wait a bit + shell: bash + run: sleep 120 + + - name: Cancel if workload job is still queued + shell: bash + run: | + run_url=/repos/${{ github.repository }}/actions/runs/${{ github.run_id }} + export GH_TOKEN=${{ inputs.github_token }} + + if [ "$(gh api "$run_url/jobs" \ + | jq -er --arg id '${{ inputs.unique-id }}' \ + '.jobs[] | select(.name | contains("[" + $id + "]")) | .status' + )" = queued ]; then + echo 'Timeout waiting for runner assignment!' + echo 'Hint: does this repo have permission to access the runner group?' + echo 'Hint: https://github.com/organizations/servo/settings/actions/runner-groups' + echo + echo 'Cancelling workflow run' + gh api "$run_url/cancel" --method POST + exit 1 + fi diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index b47f1906160..3f4c06c3e22 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -111,11 +111,18 @@ jobs: runner-timeout: needs: - runner-select - uses: ./.github/workflows/self-hosted-runner-timeout.yml - secrets: inherit - with: - unique-id: ${{ needs.runner-select.outputs.unique-id }} - is-self-hosted: ${{ fromJSON(needs.runner-select.outputs.is-self-hosted) }} + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + sparse-checkout: '.github' + - name: Runner timeout + uses: ./.github/actions/runner-timeout + if: ${{ fromJSON(needs.runner-select.outputs.is-self-hosted) }} + with: + github_token: '${{ secrets.GITHUB_TOKEN }}' + unique-id: '${{ needs.runner-select.outputs.unique-id }}' build: needs: diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 4c19def57d2..8a83d247fea 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -94,11 +94,18 @@ jobs: runner-timeout: needs: - runner-select - uses: ./.github/workflows/self-hosted-runner-timeout.yml - secrets: inherit - with: - unique-id: ${{ needs.runner-select.outputs.unique-id }} - is-self-hosted: ${{ fromJSON(needs.runner-select.outputs.is-self-hosted) }} + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + sparse-checkout: '.github' + - name: Runner timeout + uses: ./.github/actions/runner-timeout + if: ${{ fromJSON(needs.runner-select.outputs.is-self-hosted) }} + with: + github_token: '${{ secrets.GITHUB_TOKEN }}' + unique-id: '${{ needs.runner-select.outputs.unique-id }}' build: needs: diff --git a/.github/workflows/self-hosted-runner-timeout.yml b/.github/workflows/self-hosted-runner-timeout.yml deleted file mode 100644 index 0cc8bc46631..00000000000 --- a/.github/workflows/self-hosted-runner-timeout.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Detect Self-hosted Runner Timeout -on: - workflow_call: - inputs: - unique-id: - required: true - type: string - is-self-hosted: - required: true - type: boolean - -jobs: - # In the unlikely event a self-hosted runner was selected and reserved but it - # goes down before the workload starts, cancel the workflow run. - runner-timeout: - if: ${{ inputs.is-self-hosted }} - name: Detect Runner Timeout - runs-on: ubuntu-latest - steps: - - name: Wait a bit - run: sleep 120 - - - name: Cancel if workload job is still queued - run: | - run_url=/repos/${{ github.repository }}/actions/runs/${{ github.run_id }} - export GH_TOKEN=${{ secrets.GITHUB_TOKEN }} - - if [ "$(gh api "$run_url/jobs" \ - | jq -er --arg id '${{ inputs.unique-id }}' \ - '.jobs[] | select(.name | contains("[" + $id + "]")) | .status' - )" = queued ]; then - echo 'Timeout waiting for runner assignment!' - echo 'Hint: does this repo have permission to access the runner group?' - echo 'Hint: https://github.com/organizations/servo/settings/actions/runner-groups' - echo - echo 'Cancelling workflow run' - gh api "$run_url/cancel" --method POST - exit 1 - fi diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 850db0f063d..c6aa3dc7445 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -85,11 +85,18 @@ jobs: runner-timeout: needs: - runner-select - uses: ./.github/workflows/self-hosted-runner-timeout.yml - secrets: inherit - with: - unique-id: ${{ needs.runner-select.outputs.unique-id }} - is-self-hosted: ${{ fromJSON(needs.runner-select.outputs.is-self-hosted) }} + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + sparse-checkout: '.github' + - name: Runner timeout + uses: ./.github/actions/runner-timeout + if: ${{ fromJSON(needs.runner-select.outputs.is-self-hosted) }} + with: + github_token: '${{ secrets.GITHUB_TOKEN }}' + unique-id: '${{ needs.runner-select.outputs.unique-id }}' build: needs: