GitLab - Define and write jobs’ specifications
Tags: gitlab, cicd, devops, gitlabci
Published: 2023-10-03 15:00:42

## The “specs” attribute?

The “specs” attribute has been introduced in GitLab CI since the release 15.11 of GitLab (as mentioned in this blog post).

This attribute allows you to invalidate CI when one field typed as “important” is missing.

## When should I use the specs attribute?

To illustrate one benefit of using this attribute, let me explain with an example. This simple command allows you to deploy a Cloud Run service based on a Docker image called `my-image`.

```
gcloud run deploy my-service --image my-image
```

This works, but if I want to optimize this script and use it for other services, I can replace the names of my service and my image by variables, like this:

```
gcloud run deploy $MY_SERVICE --image $MY_IMAGE

```

To integrate this command into a GitLab CI job, I can simply include it in a `script` attribute within a job: 

```
deploy-cloud-run-services:
[...]
script: 
gcloud run deploy $MY_SERVICE --image $MY_IMAGE
```

Before GitLab 15.11 release or without the `specs` attribute, how can I call this script?  

If all jobs are defined in the same .gitlab-ci.yml file, I can add a `variables` attribute: 

```
variables: 
  MY_SERVICE: my-service-1
  MY_IMAGE: my-image-1

deploy-cloud-run-services:
[...]
script: 
gcloud run deploy $MY_SERVICE --image $MY_IMAGE

```

In most “real life” cases, not all your jobs are in the same file. Well, I hope so 😅. By using the `include` attribute, you can link files and your variables will automatically be sent to the included jobs. 

.gitlab-ci.yml file : 

```
stages:
  - deploy 

variables: 
  MY_SERVICE: my-service-2
  MY_IMAGE: my-image-2

include:
  - local: jobs-deploy.yml

```
 
jobs-deploy.yml

```
deploy-cloud-run-services:
  stage: deploy
  script: 
    - echo $MY_SERVICE " - " $MY_IMAGE

```

By using an included file, you can quickly see that knowing which parameters I should send to each job I call can be complicated. Of course every job included in your pipeline needs to be checked. But when a job adds a variable, all the impacts may be hard to find.

The only way to verify the impacts in your pipelines is to execute them. However you will be informed a bit late if something goes wrong.

This is why the `specs` attribute can save your life time.

Within the `specs` attribute, a `yaml invalid` error will appear immediately in your pipeline if a variable is missing.



The `specs`attribute allows you to create reusable jobs, avoiding you to duplicate jobs and most important, to catch errors earlier. With this attribute, you can easily have a description of all the parameters for a job and identify which ones are essential.  

To sum up our example, with the `specs` attribute you start by defining all your parameters in a `spec.inputs`structure:

```
spec:
  inputs:
    my-service:
    my-image: 
---
```

With this specification, written at the beginning of your yaml file, users can easily see all parameters. In this case, these two parameters have to be set, or an error will appear in your pipeline.

You can specify a default value for your parameters. Jobs that call your job can not define `my-image`variable.

```
spec:
  inputs:
    my-service:
    my-image: 
      default: "my-image:latest"
---
```

In jobs, a new way to use your variable is to enclose it within two square brackets like `$[[ inputs.my-service ]]`.

```
deploy-cloud-run-services:
[...]
script: 
gcloud run deploy $[[ inputs.my-service ]]" --image $[[ inputs.my-image ]]"
```

Pipelines including this example job can use it and customize with their own variables with this syntax: 

```
include:
  - local: jobs-deploy.yml
    inputs:
       MY_SERVICE: my-service-2
       MY_IMAGE: my-image-2
```


_Edit 2023-12-18_

💡 You can have rules on your jobs containing variables from `spec` attribute, you have to wrap the input block by a quote

```
rules:
    - if: '"$[[ inputs.my-image ]]" == "a type of image"'
``` 

## A CI/CD Catalog

This new feature is the first step of a significant epic, the [CI/CD Catalog](https://gitlab.com/groups/gitlab-org/-/epics/7462). You can find all the information and thoughts in this epic. This feature is in its early stages but the primary goal is to provide templates that can be easily used in many projects without too much effort. Every component has to be isolated, reusable, versioned, resolvable and focused on a single objective while being as small as possible. 

This feature has already been explored. I am thinking in particular of R2DevOps (who is a partner with GitLab) and Orange with this project to-be-continuous. 

GitLab is working on its own catalog but some challenges exist and are hard to resolve: how do you document templates? How do you version them? How do you maintain these templates? For further informations, you can refer to this page: https://docs.gitlab.com/ee/architecture/blueprints/ci_pipeline_components/