In high-concurrency scenarios, a runner can sometimes be “stolen” by a job other than the one that launched it, potentially leading to jobs no longer having a runner available or runners timing out before executing a job.
To ensure a runner is only assigned to the job that launched it, you can pin it to that job by adding a job pinning discriminator to the label.
This discriminator is unique and shared by both the job and its runner and ensures they are always matched together. The easiest way to do this would have been to use the job’s unique ID, but unfortunately, GitHub doesn’t let you access that from within the workflow yml. We can however achieve the same result by combining various job attributes, depending on whether the job is a regular job or a matrix job.
The following attributes uniquely identify a regular job:
Attribute | Description |
---|---|
github.run_id |
The unique ID of the current workflow run. |
github.run_attempt |
The attempt number of the current workflow run. |
job_name | The name of the current job. |
For a regular job named test-job, the job pinning discriminator would then be:
${{ github.run_id }}-${{ github.run_attempt }}-test-job
The following attributes uniquely identify a matrix job:
Attribute | Description |
---|---|
github.run_id |
The unique ID of the current workflow run. |
github.run_attempt |
The attempt number of the current workflow run. |
job_name | The name of the current job. |
strategy.job-index |
The position of the job within the matrix. |
For a matrix job named test-matrix-job, the job pinning discriminator would then be:
${{ github.run_id }}-${{ github.run_attempt }}-test-matrix-job-${{ strategy.job-index }}
To activate job pinning, simply add the job pinning discriminator to the job’s labels.
You can either add it as an additional label:
runs-on:
- sprinters:aws:ubuntu-latest
- ${{ github.run_id }}-${{ github.run_attempt }}-test-matrix-job-${{ strategy.job-index }}
or inline:
runs-on: sprinters/${{ github.run_id }}-${{ github.run_attempt }}-test-job:aws:ubuntu-latest
GitHub will then replace all variables before passing the labels to Sprinters.