General CI Details

CI Job Token

Each CI job has associated with it a unique CI/CD Job token that can be used by the user to gain read access to project and support basic API interactions with the associated GitLab instance. This token is scoped to the user and available only for the duration of the job itself. The server takes step to mask the token so it can not be seen from the web ui.

Regardless of the steps taken by the server to secure the token there are ways it can be miss handled in multi-tenant environments.

The following subsections each detail suggested workflows that should be used in your CI to best handle the provided token. Please note that usage of these is completely optional and in some cases, depending on the target test environment, may be unnecessary.

Git

Traditional GitLab documentation has you passing the CI_JOB_TOKEN via the command line in Git commands. This is potentially unwise if performed on a multi-tenant environment. As such the runner will properly set the GIT_ASKPASS environmental variable and generate the associated file.

$ git clone https://gitlab-ci-token@gitlab.example.com/group/project.git
Cloning into 'project' ...

In the above example the project repository is private but stored in the same GitLab instance as the job itself. By specifying the gitlab-ci-token user we are able to easily clone the repository without being forced to supply the token via a command line argument.

Note

Do not confuse CI_JOB_TOKEN with Personal Access Token (PAT). Use cases for both are completely different.

CI Job Scheduling

CI job pipelines can be triggered under a number of conditions, including but not limited to; commits, merge requests, and schedules. Pipeline schedules can be configured to ensure execution of specific pipelines occur on project defined intervals. Such scheduling could be useful for teams that wish to establish nightly regression testing for instance. For more details on how to setup a pipeline schedule please see the official documentation.

CI Rules

GitLab offers a number of potential mechanisms by which we can trigger a pipeline (e.g. via the web, on a scheduler, by a merge request, etc.). We can even choose to use this in how we may limit which jobs should be run. For example:

example-job:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web" || $CI_PIPELINE_SOURCE == "schedule"'
      when: always
  script:
    - test

A good use case for rules may include reasons not to create artifacts if it is not a merge event, or let a specific job run only if it is manually triggered, or run a job if the branch contains a keyword.

stages:
    - test
    - build

test-1:
    stage: test
    tags: [shell]
    script:
        - echo "Yes" > ${CI_PROJECT_DIR}/test-file
        - env |grep -i branch
    artifacts:
        paths:
            - ${CI_PROJECT_DIR}/test-file

build-1:
    stage: build
    tags: [shell]
    rules:
        - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"'
          when: always
        - if: '$CI_COMMIT_BRANCH =~ /^feature/'
          when: manual
    script:
        - |
            if [ "$(cat ${CI_PROJECT_DIR}/test-file)" == "Yes" ];
            then
                gcc main.c -o ${CI_PROJECT_DIR}/binary-file
            fi
        - echo "done"
    artifacts:
        paths:
            - ${CI_PROJECT_DIR}/binary-file

In the above example, the binary file (binary-file) would be created only when certain conditions are met, the first one is when merging a branch into the main branch, and the second is when desired after manual intervention if the branch’s name starts with “feature”.

Reasons to use rules in pipelines depend on the desired results of the different stages of the CI job, but as pipelines become more complex to accommodate a project’s needs, not all stages might be required to run every single time, like every single commit push onto the repo for example.

Additionally, rules can be set to trigger jobs on conditions like only after commits are pushed, or only when the pipeline is triggered by a schedule, or only after a previous failure, etc.

Rules was introduced in GitLab server version 12.3. It allow us to define when jobs might be expected to run. In this case it is only if the source of the pipeline’s trigger was either manually via the web or scheduled. In the case of GitLab web refers to triggering the pipeline using the Run Pipelines button, found in the CI/CD –> Pipelines page. Take note that with these rules, even though they are evaluated server side, you can leverage CI Variables. We encourage you to look into the upstream documentation for more information but suffice it to say there is a lot of potential control provided over jobs with these mechanisms.