Commit 14f660c2 authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

docs: forbid parallel:matrix keyword

parent 7b673cb6
Loading
Loading
Loading
Loading
+77 −2
Original line number Diff line number Diff line
@@ -191,8 +191,8 @@ It is highly important - when designing your template - to separate the command-

| Who controls the option?       | Description | Guidelines |
| ------------------------------ | ----------- | ---------- |
| :lock: **template controlled** | Options you (as the template developer) want to control because they are part of the proper implementation of the template | • Must be **enforced** and **hard-coded** in your job implementation. |
| :unlock: **user controlled**   | Options that the user will be allowed to customize (project specific preferences) | • **Documented** and **customizable** by the user.<br>• You should decide [what are the **good default**?](#sensible-defaults) (_90% of the time, the tool defaults are fine_). |
| :lock: **template controlled** | Options you (as the template developer) want to control<br>because they are part of the proper implementation of the template | • Must be **enforced** and **hard-coded** in your job implementation. |
| :unlock: **user controlled**   | Options that the user will be allowed to customize<br>(project specific preferences) | • **Documented** and **customizable** by the user.<br>• You should decide [what are the **good default**?](#sensible-defaults) (_90% of the time, the tool defaults are fine_). |

Example with a unit-testing tool:

@@ -205,3 +205,78 @@ Example with a unit-testing tool:
    - the tests to launch, as a glob pattern (with TBC default `**/*.test.xyz`)
    - logging level (with tool's defaults)
    - parallelization / retry policy (with tool's defaults)

## Allow multiple template instantiation

In order to allow users to [multi-instantiate them](../usage.md#multiple-template-instantiation-advanced-usage) (using the 
`parallel:matrix` keyword), our templates have to comply to some constraints explained in the following chapters.

### Ensure output artifacts segregation

Every job producing output artifacts (ex: build artifacts, report files...) must make sure there will be 
no name/path collision between those output artifacts when the template is multi-instantiated.

#### How to segregate output files?

For example, a unit testing job generating an output JUnit report `$CI_PROJECT_DIR/reports/xyz.xunit.xml` will cause collisions if the template is multi-instantiated, because the report path is absolute.

This problem can be fixed by introducing some variable part (namespacing) that will be used when the template is multi-instantiated.

For example `$CI_PROJECT_DIR/$XYZ_PROJECT_DIR/reports/xyz.xunit.xml`, as `$XYZ_PROJECT_DIR` will have different values in each matrix instance.

#### How to segregate output environment variables?

The same occurs with output environment variables, propagated via [dotenv reports](https://docs.gitlab.com/ci/yaml/artifacts_reports/#artifactsreportsdotenv).

If your job computes and propagates a variable `XYZ_COMPUTED_VARIABLE`, then you have to pay attention to two things::

1. you have to segregate the dotenv report file itself (see [previous chapter](#how-to-segregate-output-files)),
2. but you also have to segregate variable names too (two instances of your template will produce the same `XYZ_COMPUTED_VARIABLE` variable)...

This problem can be fixed by introducing some (optional) namespacing part that will be inserted into output variable names 
when the template is multi-instantiated.

For example, if `$JOB_MATRIX_NAMESPACE` is defined (optional), produce instead an output variable `XYZ_${JOB_MATRIX_NAMESPACE}_COMPUTED_VARIABLE`. Then those variables can be used safely when multi-instanting your template.

### Forbid `parallel:matrix` keyword

Basically because if a user uses the `parallel:matrix` keyword, it will break your template implementation.
Instead, prefer defining a job prototype and explicit inheritance as many times as required.

Example:

```yaml
a-job-i-want-multiple-times:
  script:
    - echo "this is $MYVAR"
  parallel:
    matrix:
      - MYVAR: case1
      - MYVAR: case2
      - MYVAR: case3
```

Can be easily replaced with:

```yaml
.job-prototype:
  script:
    - echo "this is $MYVAR"

job-case1:
  extends: .job-prototype
  variables:
    MYVAR: case1

job-case2:
  extends: .job-prototype
  variables:
    MYVAR: case2

job-case3:
  extends: .job-prototype
  variables:
    MYVAR: case3
```

This is obviously longer, but preserves the ability for the user to [multi-instantiate](../usage.md#multiple-template-instantiation-advanced-usage) your template.