diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2769a2c2749d..1c5330ec25dd6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,8 @@ jobs: - name: Checkout the source code uses: actions/checkout@v4 - name: Calculate the CI job matrix + env: + COMMIT_MESSAGE: ${{ github.event.head_commit.message }} run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT id: jobs job: diff --git a/src/ci/github-actions/calculate-job-matrix.py b/src/ci/github-actions/calculate-job-matrix.py index 1a9d01969b860..cb45111eec4d1 100755 --- a/src/ci/github-actions/calculate-job-matrix.py +++ b/src/ci/github-actions/calculate-job-matrix.py @@ -11,6 +11,7 @@ import json import logging import os +import re import typing from pathlib import Path from typing import List, Dict, Any, Optional @@ -67,6 +68,23 @@ class GitHubCtx: event_name: str ref: str repository: str + commit_message: Optional[str] + + +def get_job_from_commit(ctx: GitHubCtx) -> Optional[str]: + """ + Tries to parse a name of a CI job that should be executed in the form of + ci-job: + from the commit message of the passed GitHub context. + """ + if ctx.commit_message is None: + return None + + regex = re.compile(r"ci-job: (.*)") + match = regex.search(ctx.commit_message) + if match is None: + return None + return match.group(1) def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]: @@ -84,7 +102,8 @@ def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]: try_build = old_bors_try_build or new_bors_try_build if try_build: - return TryRunType() + job_name = get_job_from_commit(ctx) + return TryRunType(job=job_name) if ctx.ref == "refs/heads/auto" and ctx.repository == "rust-lang-ci/rust": return AutoRunType() @@ -96,8 +115,16 @@ def calculate_jobs(run_type: WorkflowRunType, job_data: Dict[str, Any]) -> List[ if isinstance(run_type, PRRunType): return add_base_env(name_jobs(job_data["pr"], "PR"), job_data["envs"]["pr"]) elif isinstance(run_type, TryRunType): - return add_base_env(name_jobs(job_data["try"], "try"), job_data["envs"]["try"]) - elif isinstance(run_type, AutoRunType): + jobs = job_data["try"] + if run_type.job is not None: + jobs = [job for job in job_data["auto"] if job["image"] == run_type.job] + if not jobs: + raise Exception( + f"CI job `{run_type.job}` asked for in the try build does not exist" + ) + + return add_base_env(name_jobs(jobs, "try"), job_data["envs"]["try"]) + elif run_type is AutoRunType: return add_base_env(name_jobs(job_data["auto"], "auto"), job_data["envs"]["auto"]) return [] @@ -111,10 +138,16 @@ def skip_jobs(jobs: List[Dict[str, Any]], channel: str) -> List[Job]: def get_github_ctx() -> GitHubCtx: + event_name = os.environ["GITHUB_EVENT_NAME"] + + commit_message = None + if event_name == "push": + commit_message = os.environ["COMMIT_MESSAGE"] return GitHubCtx( - event_name=os.environ["GITHUB_EVENT_NAME"], + event_name=event_name, ref=os.environ["GITHUB_REF"], - repository=os.environ["GITHUB_REPOSITORY"] + repository=os.environ["GITHUB_REPOSITORY"], + commit_message=commit_message )