## Custom User CI stages
```{warning} Outdated Documentation!
    This documentation version is out of date. Please check the [latest version 2026.1](https://hog.readthedocs.io/en/latest/).
```
From Hog2021.1, users can add custom CI jobs to the *Merge Request* pipeline. These jobs can be added in three different stages:

- **user_pre**, running before the *Generation* stage
- **user_proj**, running after the *Generation* stage
- **user_post**, running after the *Collect* stage

The custom jobs can be defined inside your `.gitlab-ci.yml` file or in another file inside the repository included in the main `.gitlab-ci.yml`.

```{warning}
Custom User CI Stages are not supported by Hog dynamic CI.
```

### Default Hog settings
In general any jobs with any settings can be added to the yml file, even settings that differ from Hog default jobs.

To run the users jobs with the same settings as the default Hog-CI jobs, users can add these lines in their `yml` file.

```yaml
.tag-hog: &tag-hog
  tags:
     - hog

.tag-sr: &tag-sr
  tags:
     - docker

.only-default: &only-default
  only:
    refs:
      - merge_requests
      - master # or name of the default official branch
  except:
    variables:
      - $CI_COMMIT_REF_NAME =~ /^test\/.*$/i
      - $CI_MERGE_REQUEST_TITLE =~ /^Draft:.*$/ && $CI_COMMIT_MESSAGE !~ /^RESOLVE_WIP:/
```

The `.tag-hog` section, configures the user jobs to run on the virtual machine. Otherwise, the `.tag-sr` section can be used to run on shared runners.

The `.only-default` specifies that the jobs will run only merge_request's commits, which are not in a *Draft* status. Users can customise this section, also for their custom jobs, for example to use the **RESOLVE_WIP** keyword, to activate the pipeline.

Extra variables can be set with in the `variables` section of your job. For instance, if you wish your job to checkout also the submodules in the repository, you must set:

```yaml
variables:
  GIT_STRATEGY: clone
  GIT_SUBMODULE_STRATEGY: recursive
```

Note that, by default user jobs will not checkout your submodules, to speed-up the CI workflow. 

### Writing a Custom job
A custom job can be instantiated with the following code:

```yaml
  <job_name>:
    <<: *only-default
    <<: *tag-hog #Remove to run this job on a shared runner
    # <<: *tag-sr #Uncomment to run on a shared runner
    stage: <stage_name>
    script:
      - <user_script>
    variables:
      GIT_STRATEGY: clone
      GIT_SUBMODULE_STRATEGY: recursive # Remove if you don't need to checkout the submodules
    artifacts:
      name: <job_name>
      when: always
      paths:
        - $CI_PROJECT_DIR/bin
        - <custom_dir>
      expire_in: 30 day
```

Where `<job_name>` is the name of the job, `<stage_name>` is the desired user stage (`user_pre, user_proj, user_post`), and `<custom_dir>` is the folder to be saved in the Gitlab artifacts.

:::{tip}
If you wish the artifacts to be saved in the official releases, just save them in a folder called `bin`.
:::

<img style="float: middle;" width="900" src="../figures/stages_order.png">

Users can also create a job template, to run multiple jobs in the same stage, without code duplication. A template can be instantiated in this way:

```yaml
.<template_name>: &<template_name>
    <<: *only-default
    <<: *tag-hog #Remove to run this job on a shared runner
    # <<: *tag-sr #Uncomment to run on a shared runner
    stage: <stage_name>
    script:
      - <user_script>
    variables:
      GIT_STRATEGY: clone
      GIT_SUBMODULE_STRATEGY: recursive # Remove if you don't need to checkout the submodules
    artifacts:
      name: <template_name>
      when: always
      paths:
        - $CI_PROJECT_DIR/bin
        - <custom_dir>
      expire_in: 30 day
```

And finally add the template call:

```yaml
<template_name>:<job_name>:
    extends: .projjob
    variables:
      extends: .vars
      <VARIABLE_NAME>:<variable>
```

Here `<template_name>` is the same defined in the template, `<job_name>` is the specific job name.

If you need to define specific variables in a user job, replace `<VARIABLE_NAME>:<variable>` in the template above.

:::{tip}
You can use more than one custom variable in your template script. Just be sure to declare all of them in the template call. 
:::
