Skip to content

Commit

Permalink
ci: Merge similar try jobs when possible
Browse files Browse the repository at this point in the history
This comes up a lot when triggering wpt-2013 and wpt-2020. Instead of
merging the jobs and triggering both layouts, the try parser will
trigger two separate jobs. Running two of the same builds at once seems
to cause the CI to fail one of them [1]. This fixes that issue.

1. An example of this: https://github.com/servo/servo/actions/runs/7892269495
  • Loading branch information
mrobinson committed Feb 13, 2024
1 parent 07c7096 commit 5bce7ad
Showing 1 changed file with 41 additions and 12 deletions.
53 changes: 41 additions & 12 deletions python/servo/try_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import json
import sys
from typing import Optional
from typing import Optional, Self
import unittest
import logging

Expand Down Expand Up @@ -40,10 +40,10 @@ def to_string(self):


class Workflow(str, Enum):
LINUX = 'linux'
MACOS = 'macos'
WINDOWS = 'windows'
ANDROID = 'android'
LINUX = "linux"
MACOS = "macos"
WINDOWS = "windows"
ANDROID = "android"


@dataclass
Expand All @@ -55,6 +55,16 @@ class JobConfig(object):
unit_tests: bool = False
wpt_tests_to_run: str = ""

def merge(self, other: Self) -> bool:
"""Try to merge another job with this job. Returns True if merging is successful
or False if not. If merging is successful this job will be modified."""
if self.workflow != other.workflow or self.profile != other.profile or \
self.wpt_tests_to_run != other.wpt_tests_to_run:
return False
self.wpt_layout |= other.wpt_layout
self.unit_tests |= other.unit_tests
return True


def handle_preset(s: str) -> Optional[JobConfig]:
s = s.lower()
Expand All @@ -68,15 +78,15 @@ def handle_preset(s: str) -> Optional[JobConfig]:
elif s in ["wpt", "linux-wpt"]:
return JobConfig("Linux WPT", Workflow.LINUX, unit_tests=True, wpt_layout=Layout.all())
elif s in ["wpt-2013", "linux-wpt-2013"]:
return JobConfig("Linux WPT legacy-layout", Workflow.LINUX, wpt_layout=Layout.layout2013)
return JobConfig("Linux WPT", Workflow.LINUX, wpt_layout=Layout.layout2013)
elif s in ["wpt-2020", "linux-wpt-2020"]:
return JobConfig("Linux WPT layout-2020", Workflow.LINUX, wpt_layout=Layout.layout2020)
return JobConfig("Linux WPT", Workflow.LINUX, wpt_layout=Layout.layout2020)
elif s in ["mac-wpt", "wpt-mac"]:
return JobConfig("MacOS WPT", Workflow.MACOS, wpt_layout=Layout.all())
elif s == "mac-wpt-2013":
return JobConfig("MacOS WPT legacy-layout", Workflow.MACOS, wpt_layout=Layout.layout2013)
return JobConfig("MacOS WPT", Workflow.MACOS, wpt_layout=Layout.layout2013)
elif s == "mac-wpt-2020":
return JobConfig("MacOS WPT layout-2020", Workflow.MACOS, wpt_layout=Layout.layout2020)
return JobConfig("MacOS WPT", Workflow.MACOS, wpt_layout=Layout.layout2020)
elif s == "android":
return JobConfig("Android", Workflow.ANDROID)
elif s == "webgpu":
Expand Down Expand Up @@ -122,11 +132,17 @@ def parse(self, input: str):
words.extend(["linux-wpt", "macos", "windows", "android"])
continue # skip over keyword

preset = handle_preset(word)
if preset is None:
job = handle_preset(word)
if job is None:
print(f"Ignoring unknown preset {word}")
else:
self.matrix.append(preset)
self.add_or_merge_job_to_matrix(job)

def add_or_merge_job_to_matrix(self, job: JobConfig):
for existing_job in self.matrix:
if existing_job.merge(job):
return
self.matrix.append(job)

def to_json(self, **kwargs) -> str:
return json.dumps(self, cls=Encoder, **kwargs)
Expand Down Expand Up @@ -192,6 +208,19 @@ def test_empty(self):
}
]})

def test_job_merging(self):
self.assertDictEqual(json.loads(Config("wpt-2020 wpt-2013").to_json()),
{'fail_fast': False,
'matrix': [{
'name': 'Linux WPT',
'profile': 'release',
'unit_tests': False,
'workflow': 'linux',
'wpt_layout': 'all',
'wpt_tests_to_run': ''
}]
})

def test_full(self):
self.assertDictEqual(json.loads(Config("linux-wpt macos windows android").to_json()),
json.loads(Config("").to_json()))
Expand Down

0 comments on commit 5bce7ad

Please sign in to comment.