Skip to content

Commit 18f3d80

Browse files
authored
Add import and non-sparse parameter functionality to job matrix generation (Azure#18660)
1 parent ffe8dc6 commit 18f3d80

File tree

6 files changed

+600
-108
lines changed

6 files changed

+600
-108
lines changed

eng/scripts/job-matrix/Create-JobMatrix.ps1

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,23 @@ param (
1212
[Parameter(Mandatory=$True)][string] $ConfigPath,
1313
[Parameter(Mandatory=$True)][string] $Selection,
1414
[Parameter(Mandatory=$False)][string] $DisplayNameFilter,
15-
[Parameter(Mandatory=$False)][array] $Filters
15+
[Parameter(Mandatory=$False)][array] $Filters,
16+
[Parameter(Mandatory=$False)][array] $NonSparseParameters
1617
)
1718

1819
. $PSScriptRoot/job-matrix-functions.ps1
1920

2021
$config = GetMatrixConfigFromJson (Get-Content $ConfigPath)
22+
# Strip empty string filters in order to be able to use azure pipelines yaml join()
23+
$Filters = $Filters | Where-Object { $_ }
24+
25+
[array]$matrix = GenerateMatrix `
26+
-config $config `
27+
-selectFromMatrixType $Selection `
28+
-displayNameFilter $DisplayNameFilter `
29+
-filters $Filters `
30+
-nonSparseParameters $NonSparseParameters
2131

22-
[array]$matrix = GenerateMatrix $config $Selection $DisplayNameFilter $Filters
2332
$serialized = SerializePipelineMatrix $matrix
2433

2534
Write-Output $serialized.pretty

eng/scripts/job-matrix/README.md

Lines changed: 203 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@
22

33
* [Usage in a pipeline](#usage-in-a-pipeline)
44
* [Matrix config file syntax](#matrix-config-file-syntax)
5-
* [Fields](#fields)
6-
* [matrix](#matrix)
7-
* [include](#include)
8-
* [exclude](#exclude)
9-
* [displayNames](#displaynames)
5+
* [Fields](#fields)
6+
* [matrix](#matrix)
7+
* [include](#include)
8+
* [exclude](#exclude)
9+
* [displayNames](#displaynames)
10+
* [$IMPORT](#import)
1011
* [Matrix Generation behavior](#matrix-generation-behavior)
11-
* [all](#all)
12-
* [sparse](#sparse)
13-
* [include/exclude](#includeexclude)
14-
* [displayNames](#displaynames-1)
15-
* [Filters](#filters)
16-
* [Under the hood](#under-the-hood)
12+
* [all](#all)
13+
* [sparse](#sparse)
14+
* [include/exclude](#includeexclude)
15+
* [displayNames](#displaynames-1)
16+
* [Filters](#filters)
17+
* [NonSparseParameters](#nonsparseparameters)
18+
* [Under the hood](#under-the-hood)
1719
* [Testing](#testing)
1820

1921

@@ -38,13 +40,14 @@ jobs:
3840
- Name: base_product_matrix
3941
Path: /eng/pipelines/matrix.json
4042
Selection: sparse
41-
GenerateVMJobs: true
43+
NonSparseParameters: <csv of parameter names for which all combinations should be included>
44+
GenerateVMJobs: true
4245
- Name: sdk_specific_matrix
4346
Path: /sdk/foobar/matrix.json
4447
Selection: all
45-
GenerateContainerJobs: true
46-
steps:
47-
- pwsh:
48+
GenerateContainerJobs: true
49+
steps:
50+
- pwsh:
4851
...
4952
```
5053

@@ -58,14 +61,14 @@ type is useful for when 2 or more parameters need to be grouped together, but wi
5861
"<parameter1 name>": [ <values...> ],
5962
"<parameter2 name>": [ <values...> ],
6063
"<parameter set>": {
61-
"<parameter set 1 name>": {
62-
"<parameter set 1 value 1": "value",
63-
"<parameter set 1 value 2": "<value>",
64-
},
65-
"<parameter set 2 name>": {
66-
"<parameter set 2 value 1": "value",
67-
"<parameter set 2 value 2": "<value>",
68-
}
64+
"<parameter set 1 name>": {
65+
"<parameter set 1 value 1": "value",
66+
"<parameter set 1 value 2": "<value>",
67+
},
68+
"<parameter set 2 name>": {
69+
"<parameter set 2 value 1": "value",
70+
"<parameter set 2 value 2": "<value>",
71+
}
6972
}
7073
}
7174
"include": [ <matrix>, <matrix>, ... ],
@@ -144,6 +147,150 @@ readable value here. For example:
144147
}
145148
```
146149

150+
#### $IMPORT
151+
152+
Matrix configs can also import another matrix config. The effect of this is the imported matrix will be generated,
153+
and then the importing config will be combined with that matrix (as if each entry of the imported matrix was a parameter).
154+
To import a matrix, add a parameter with the key `$IMPORT`:
155+
156+
```
157+
"matrix": {
158+
"$IMPORT": "path/to/matrix.json",
159+
"JavaVersion": [ "1.8", "1.11" ]
160+
}
161+
```
162+
163+
Importing can be useful, for example, in cases where there is a shared base matrix, but there is a need to run it
164+
once for each instance of a language version.
165+
166+
The processing order is as follows:
167+
168+
Given a matrix and import matrix like below:
169+
```
170+
{
171+
"matrix": {
172+
"$IMPORT": "example-matrix.json",
173+
"endpointType": [ "storage", "cosmos" ],
174+
"JavaVersion": [ "1.8", "1.11" ]
175+
},
176+
"include": [
177+
{
178+
"operatingSystem": "windows",
179+
"mode": "TestFromSource",
180+
"JavaVersion": "1.8"
181+
}
182+
]
183+
}
184+
185+
### example-matrix.json to import
186+
{
187+
"matrix": {
188+
"operatingSystem": [ "windows", "linux" ],
189+
"client": [ "netty", "okhttp" ]
190+
},
191+
"include": [
192+
{
193+
"operatingSystem": "mac",
194+
"client": "netty"
195+
}
196+
]
197+
}
198+
```
199+
200+
1. The base matrix is generated (sparse in this example):
201+
```
202+
{
203+
"storage_18": {
204+
"endpointType": "storage",
205+
"JavaVersion": "1.8"
206+
},
207+
"cosmos_111": {
208+
"endpointType": "cosmos",
209+
"JavaVersion": "1.11"
210+
}
211+
}
212+
```
213+
1. The imported base matrix is generated (sparse in this example):
214+
```
215+
{
216+
"windows_netty": {
217+
"operatingSystem": "windows",
218+
"client": "netty"
219+
},
220+
"linux_okhttp": {
221+
"operatingSystem": "linux",
222+
"client": "okhttp"
223+
}
224+
}
225+
```
226+
1. Includes/excludes from the imported matrix get applied to the imported matrix
227+
```
228+
{
229+
"windows_netty": {
230+
"operatingSystem": "windows",
231+
"client": "netty"
232+
},
233+
"linux_okhttp": {
234+
"operatingSystem": "linux",
235+
"client": "okhttp"
236+
},
237+
"mac_netty": {
238+
"operatingSystem": "mac",
239+
"client": "netty"
240+
}
241+
}
242+
```
243+
1. The base matrix is multipled by the imported matrix (in this case, the base matrix has 2 elements, and the imported
244+
matrix has 3 elements, so the product is a matrix with 6 elements:
245+
```
246+
"storage_18_windows_netty": {
247+
"endpointType": "storage",
248+
"JavaVersion": "1.8",
249+
"operatingSystem": "windows",
250+
"client": "netty"
251+
},
252+
"storage_18_linux_okhttp": {
253+
"endpointType": "storage",
254+
"JavaVersion": "1.8",
255+
"operatingSystem": "linux",
256+
"client": "okhttp"
257+
},
258+
"storage_18_mac_netty": {
259+
"endpointType": "storage",
260+
"JavaVersion": "1.8",
261+
"operatingSystem": "mac",
262+
"client": "netty"
263+
},
264+
"cosmos_111_windows_netty": {
265+
"endpointType": "cosmos",
266+
"JavaVersion": "1.11",
267+
"operatingSystem": "windows",
268+
"client": "netty"
269+
},
270+
"cosmos_111_linux_okhttp": {
271+
"endpointType": "cosmos",
272+
"JavaVersion": "1.11",
273+
"operatingSystem": "linux",
274+
"client": "okhttp"
275+
},
276+
"cosmos_111_mac_netty": {
277+
"endpointType": "cosmos",
278+
"JavaVersion": "1.11",
279+
"operatingSystem": "mac",
280+
"client": "netty"
281+
}
282+
}
283+
```
284+
1. Includes/excludes from the top-level matrix get applied to the multiplied matrix, so the below element will be added
285+
to the above matrix, for an output matrix with 7 elements:
286+
```
287+
"windows_TestFromSource_18": {
288+
"operatingSystem": "windows",
289+
"mode": "TestFromSource",
290+
"JavaVersion": "1.8"
291+
}
292+
```
293+
147294
## Matrix Generation behavior
148295
149296
#### all
@@ -220,7 +367,7 @@ The logic for generating display names works like this:
220367
- Join parameter values by "_"
221368
a. If the parameter value exists as a key in `displayNames` in the matrix config, replace it with that value.
222369
b. For each name value, strip all non-alphanumeric characters (excluding "_").
223-
c. If the name is greater than 100 characters, truncate it.
370+
c. If the name is greater than 100 characters, truncate it.
224371
225372
#### Filters
226373
@@ -242,6 +389,38 @@ named "ExcludedKey", a framework variable containing either "461" or "5.0", and
242389
-Filters @("ExcludedKey=^$", "framework=(461|5\.0)", "SupportedClouds=^$|.*Public.*")
243390
```
244391
392+
#### NonSparseParameters
393+
394+
Sometimes it may be necessary to generate a sparse matrix, but keep the full combination of a few parameters. The
395+
NonSparseParameters argument allows for more fine-grained control of matrix generation. For example:
396+
397+
```
398+
./Create-JobMatrix.ps1 `
399+
-ConfigPath /path/to/matrix.json `
400+
-Selection sparse `
401+
-NonSparseParameters @("JavaTestVersion")
402+
```
403+
404+
Given a matrix like below with `JavaTestVersion` marked as a non-sparse parameter:
405+
406+
```
407+
{
408+
"matrix": {
409+
"Agent": {
410+
"windows-2019": { "OSVmImage": "MMS2019", "Pool": "azsdk-pool-mms-win-2019-general" },
411+
"ubuntu-1804": { "OSVmImage": "MMSUbuntu18.04", "Pool": "azsdk-pool-mms-ubuntu-1804-general" },
412+
"macOS-10.15": { "OSVmImage": "macOS-10.15", "Pool": "Azure Pipelines" }
413+
},
414+
"JavaTestVersion": [ "1.8", "1.11" ],
415+
"AZURE_TEST_HTTP_CLIENTS": "netty",
416+
"ArmTemplateParameters": [ "@{endpointType='storage'}", "@{endpointType='cosmos'}" ]
417+
}
418+
}
419+
```
420+
421+
A matrix with 6 entries will be generated: A sparse matrix of Agent, AZURE_TEST_HTTP_CLIENTS and ArmTemplateParameters
422+
(3 total entries) will be multipled by the two `JavaTestVersion` parameters `1.8` and `1.11`.
423+
245424
#### Under the hood
246425
247426
The script generates an N-dimensional matrix with dimensions equal to the parameter array lengths. For example,

0 commit comments

Comments
 (0)