GitHub: Enhancing Runner Selection in GitHub Actions
Problem Statement:
In GitHub Actions workflows, selecting specific runners is essential for ensuring builds and deployments execute on the intended machines with the required configuration. Traditionally, the runs-on syntax allows specifying runners using labels like.
[self-hosted, Windows, tag1, tag2]
However, when a pool of self-hosted runners shares overlapping labels, the system may occasionally pick a different runner than the one explicitly intended. This misassignment can lead to deployments occurring on an unintended runner, causing inconsistencies or failures due to mismatched environments.
Additionally, the traditional syntax doesn’t effectively support multi-runner deployments. For workflows requiring simultaneous deployment across multiple specific runners, static configurations are cumbersome and error-prone. This necessitated a more dynamic and precise approach to runner selection.
Traditional Approach (Old Configuration):
The old method involved specifying all runner labels explicitly in the runs-on directive. While straightforward, this approach lacked flexibility when matrix-based deployments were needed. Here is an example:
deploy-Prod-Environment:
runs-on: [self-hosted, Windows, tag1, tag2]
if: github.ref == 'refs/heads/master' && inputs.environment == 'Proc-Prod'
needs: build
strategy:
matrix:
runner: [ ae-1, ae-2, ae-5 ]
environment: Proc-Prod
Limitations:
- The runs-on directive is static and does not dynamically integrate with the matrix strategy.
- Workflows may randomly select any available runner with matching labels, which can lead to tasks being executed on unintended machines.
New Approach:
To address these limitations, the runs-on directive can be enhanced by integrating matrix variables directly into the runner selection. This ensures each job in the matrix strategy executes on a specific runner dynamically, improving clarity and control over deployments.
New Configuration:
deploy-GeoProc-Prod:
if: github.ref == 'refs/heads/master' && inputs.environment == 'Proc-Prod'
needs: build
strategy:
matrix:
runner: [ ae-1, ae-2, ae-5 ]
environment: Proc-Prod
runs-on:
- self-hosted
- Windows
- tag1
- tag2
- ${{ matrix.runner }}
Improvements:
- Dynamic Runner Assignment: By incorporating ${{ matrix.runner }}, each job in the matrix executes on a specific runner (e.g., ae-1, ae-2, or ae-5).
- Enhanced Flexibility: The workflow dynamically adapts to the runners defined in the matrix, reducing the risk of jobs running on unintended machines.
- Scalability: This approach scales better for larger workflows with diverse runner requirements.
Resolution:
The new configuration resolves the limitations of static runner selection by:
- Leveraging matrix variables for precise runner targeting.
- Ensuring compatibility with self-hosted runner pools.
- Providing a robust and scalable solution for deployment workflows.
Conclusion:
Transitioning from a static to a dynamic runner selection approach in GitHub Actions workflows simplifies runner management and enhances deployment precision. By integrating matrix variables into the runs-on directive, workflows become more adaptable, maintainable, and aligned with modern CI/CD practices. This shift is particularly beneficial for projects requiring multiple self-hosted runners with specific roles or configurations.