GitLab CI/CD實踐記錄


 

 

1. GitLab Runner

參考:《Configuring GitLab Runners

In GitLab CI/CD, Runners run the code defined in .gitlab-ci.yml. A GitLab Runner is a lightweight, highly-scalable agent that picks up a CI job through the coordinator API of GitLab CI/CD, runs the job, and sends the result back to the GitLab instance.

GitLab Runner的有多種形式:Repositories、Binaries、Docker service。參考:《Create a group Runner

1.1 安裝Git Lab Runner

1.1.1 Ubuntu中安裝gitlab-runner

參考:《Install GitLab Runner manually on GNU/Linux

curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash sudo apt-get install gitlab-runner

或者下載deb安裝包:https://gitlab-runner-downloads.s3.amazonaws.com/latest/deb/gitlab-runner_amd64.deb。

sudo dpkg -i gitlab-runner_amd64.deb

 

安裝好Runner之后,還需要將Runner注冊到Gitlab。

Ubuntu下注冊Runner為:GNU/Linux

sudo gitlab-runner register

一行命令注冊:

docker run --rm -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register \
  --non-interactive \
  --executor "docker" \
  --docker-image alpine:latest \
  --url "https://gitlab.com/" \
  --registration-token "PROJECT_REGISTRATION_TOKEN" \
  --description "docker-runner" \
  --tag-list "docker,aws" \
  --run-untagged="true" \
  --locked="false" \
  --access-level="not_protected"

1.1.3 docker中安裝gitlab-runner

參考:《Run GitLab Runner in a container

1.2 Git Lab Runner使用

docker中對Runner進行注冊有兩種方法:交互式注冊一行命令注冊

sudo gitlab-runner register \
  --non-interactive \
  --url "https://gitlab.com/" \
  --registration-token "PROJECT_REGISTRATION_TOKEN" \
  --executor "docker" \
  --docker-image alpine:latest \
  --description "docker-runner" \
  --tag-list "docker,aws" \
  --run-untagged="true" \
  --locked="false" \
  --access-level="not_protected"

這句話的意思是:注冊一個executor為docker,docker image為alpine:latest的gitlab-runner,到https://gitlab.com/,其token為PROJECT_REGISTRATION_TOKEN。

並且此gitlab-runner的tag為docker或aws,並設置interactive、locked、access等屬性。

上述參數url和registration-token從Settings->CI/CD->Runners中獲取:

另外--docker-image為指定的Runner的Docker image文件;--tag-list為Runner的tag列表。

查看所有注冊的GitLab Runner:

sudo gitlab-runner list

去注冊選定的GitLab Runner:

sudo gitlab-runner unregister --token g_L6R5T1RZDxbm1ttbx8 --url http://192.168.70.8/

 運行所有注冊的Runner:

sudo gitlab-runner run

1.3 Git Lab Runner的config.toml配置

config.toml默認位置在/etc/gitlab-runner/config.toml,詳細配置參考《Advanced configuration》。

Pipelines簡要介紹

Pipelines組成

參考:《CI/CD pipelines

Pipelines are the top-level component of continuous integration, delivery, and deployment.

Pipelines comprise:

Jobs, which define what to do. For example, jobs that compile or test code.

Stages, which define when to run the jobs. For example, stages that run tests after stages that compile the code.

Pipelines即流水線是持續集成、持續發布、持續部署的最頂層組件,由Stages和Jobs組成。

Jobs是真正執行單元,定義了做什么。Stags是對Jobs串接,定義了什么時候執行Jobs。

Pipelines調度

參考:《Pipeline schedules

Pipelines的調度按觸發模式可以分為:自動觸發和手動觸發,自動觸發又分為定時觸發和Merge請求觸發Pipelines for Merge Requests

默認通過commit觸發Pipeline,還可以被Merge Requests觸發。

比如下面build job 1可以被Merge Requests或者master上的分支觸發。

build job 1:
  stage: build
  tags:
  - mytag
  script:
  only:
    - merge_requests
    - master

還可以通過except關鍵字,排除觸發條件。

另外還可以打開Settings->CI/CD->Pipeline triggers,在其他pipeline中觸發。

輸入Decsription,然后Add trigger,即可增加Pipeline trigger。

可以命令行觸發,也可以在.gitlab-ci.yml中其他job中觸發。

trigger_build:
  stage: deploy
  script:
    - "curl -X POST -F token=<Pipeline trigger token> -F ref=<branch or tag> http://<gitlab server>/api/v4/projects/<project id>/trigger/pipeline"

在Pipeline之間傳遞artifacts:

build_submodule:
  image: debian
  stage: test
  script:
- curl --location --output artifacts.zip "https://gitlab.example.com/api/v4/projects/1/jobs/artifacts/master/download?job=test&job_token=$CI_JOB_TOKEN"
    - unzip artifacts.zip
  only:
    - tags

 

如果要在curl中傳遞參數可以通過:

curl --request POST \
  --form token=TOKEN \
  --form ref=master \
  --form "variables[UPLOAD_TO_S3]=true" \
  https://gitlab.example.com/api/v4/projects/9/trigger/pipeline

gitlab-ci.yml配置

stages配置 stage配置 .pre和.post

參考:《stages》《stage》《.pre and .post

stages is used to define stages that contain jobs and is defined globally for the pipeline.

Jobs of the same stage are run in parallel.Jobs of the next stage are run after the jobs from the previous stage complete successfully.

stage is defined per-job and relies on stages which is defined globally. It allows to group jobs into different stages, and jobs of the same stage are executed in parallel (subject to certain conditions).

 

The following stages are available to every pipeline:

.pre, which is guaranteed to always be the first stage in a pipeline.

.post, which is guaranteed to always be the last stage in a pipeline.

User-defined stages are executed after .pre and before .post.

The order of .pre and .post can’t be changed, even if defined out of order in .gitlab-ci.yml.

.pre和.post在所有stage的最前和最后執行,而不受pipelines中定義的順序。

一個示例如下:

stages:
  - build
  - test
  - deploy

job 0:
  stage: .pre
  script: make something useful before build stage

job 1:
  stage: build
  script: make build dependencies

job 2:
  stage: build
  script: make build artifacts

job 3:
  stage: test
  script: make test

job 4:
  stage: deploy
  script: make deploy

job 5:
  stage: .post
  script: make something useful at the end of pipeline

這個Pilelines中定義了5個stages,分別是.pre、build、test、deploy、.post;定義了6個jobs:分別是job 0、job 1、job 2、job 3、job 4、job 5。

所以此Pipellines的執行順序是.pre-[job 0]->build-[job 1/job 2]->test-[job 3]->deploy-[job 4]->.post[job 5],其中job1和job2並行執行

include配置

參考:《include

include requires the external YAML file to have the extensions .yml or .yaml, otherwise the external file won’t be included.

include包含如下類型:

Method Description
local Include a file from the local project repository.
file Include a file from a different project repository.
remote Include a file from a remote URL. Must be publicly accessible.
template Include templates which are provided by GitLab.

local示例如下:

include:
  - local: '/templates/.gitlab-ci-template.yml'

include: '.gitlab-ci-production.yml'

file示例如下:

include:
  - project: 'my-group/my-project'
    ref: master
    file: '/templates/.gitlab-ci-template.yml'

  - project: 'my-group/my-project'
    ref: v1.0.0
    file: '/templates/.gitlab-ci-template.yml'

  - project: 'my-group/my-project'
    ref: 787123b47f14b552955ca2786bc9542ae66fee5b # Git SHA
    file: '/templates/.gitlab-ci-template.yml'

remote示例如下:

include:
  - remote: 'https://gitlab.com/awesome-project/raw/master/.gitlab-ci-template.yml'

template示例如下:

include:
  - template: Android-Fastlane.gitlab-ci.yml
  - template: Auto-DevOps.gitlab-ci.yml

script before_script和after_script

參考:《script》《before_scrip and after_script

script is the only required keyword that a job needs. It’s a shell script which is executed by the Runner. 

before_script is used to define a command that should be run before each job, including deploy jobs, but after the restoration of any artifacts. This must be an array.

Scripts specified in before_script are concatenated with any scripts specified in the main script, and executed together in a single shell.

after_script is used to define the command that will be run after each job, including failed ones. This must be an array.

Scripts specified in after_script are executed in a new shell, separate from any before_script or script scripts.

before_script是在script運行之前,恢復artifacts之后運行,但是和script在一個shell中運行。

after_script單獨在一個shell中運行,並且在scirpt之后。

image services

參考:《image》《service

image用於指定Docker image,service用於指定連接到image指定Docker image的service Docker image。

The image keyword is the name of the Docker image the Docker executor will run to perform the CI tasks.
The services keyword defines just another Docker image that is run during your job and is linked to the Docker image that the image keyword defines. This allows you to access the service image during build time.

image可配置選項:

Setting Required GitLab version Description
name yes, when used with any other option 9.4 Full name of the image that should be used. It should contain the Registry part if needed.
entrypoint no 9.4 Command or script that should be executed as the container’s entrypoint. It will be translated to Docker’s --entrypoint option while creating the container. The syntax is similar to Dockerfile’s ENTRYPOINT directive, where each shell token is a separate string in the array.

service可配置選項:

Setting Required GitLab version Description
name yes, when used with any other option 9.4 Full name of the image that should be used. It should contain the Registry part if needed.
entrypoint no 9.4 Command or script that should be executed as the container’s entrypoint. It will be translated to Docker’s --entrypoint option while creating the container. The syntax is similar to Dockerfile’s ENTRYPOINT directive, where each shell token is a separate string in the array.
command no 9.4 Command or script that should be used as the container’s command. It will be translated to arguments passed to Docker after the image’s name. The syntax is similar to Dockerfile’s CMD directive, where each shell token is a separate string in the array.
alias no 9.4 Additional alias that can be used to access the service from the job’s container. Read Accessing the services for more information.

示例:

default:
  image:
    name: ruby:2.6
    entrypoint: ["/bin/bash"]

  services:
    - name: my-postgres:11.7
      alias: db-postgres
      entrypoint: ["/usr/local/bin/db-postgres"]
      command: ["start"]

  before_script:
    - bundle install

test:
  script:
    - bundle exec rake spec

only/except

參考:《only/except (basic)

only and except are two parameters that set a job policy to limit when jobs are created:

  1. only defines the names of branches and tags for which the job will run.
  2. except defines the names of branches and tags for which the job will not run.
Value Description
branches When the Git reference for a pipeline is a branch.
tags When the Git reference for a pipeline is a tag.
api For pipelines triggered by the pipelines API.
external When using CI services other than GitLab.
pipelines For multi-project pipelines created by using the API with CI_JOB_TOKEN.
pushes For pipelines triggered by a git push event, including for branches and tags.
schedules For scheduled pipelines.
triggers For pipelines created by using a trigger token.
web For pipelines created by using Run pipeline button in the GitLab UI, from the project’s CI/CD > Pipelines section.
merge_requests For pipelines created when a merge request is created or updated. Enables merge request pipelinesmerged results pipelines, and merge trains.
external_pull_requests When an external pull request on GitHub is created or updated (See Pipelines for external pull requests).
chat For pipelines created by using a GitLab ChatOps command.

示例1:

job:
  # use regexp
  only:
    - /^issue-.*$/---僅執行issues-開頭的分支、tags等。
  # use special keyword
  except:
    - branches----排除所有的branches

示例2:

job:
  only:
    - branches@gitlab-org/gitlab-----------在gitlab-org/gitlab的所有分支上運行。
  except:
    - master@gitlab-org/gitlab------------但是要排除master分支。
    - /^release/.*$/@gitlab-org/gitlab----以及release/xxx開頭。

參考:《only/except(advanced)

If you use multiple keys under only or except, the keys will be evaluated as a single conjoined expression. That is:

  • only: means “include this job if all of the conditions match”.
  • except: means “exclude this job if any of the conditions match”.

With only, individual keys are logically joined by an AND

示例1:

test:
  script: npm run test
  only:----下面refs、variables、kubernetes是與的關系,也即必須都滿足才會執行job;refs內部是或的而關系。
    refs:
      - master
      - schedules
    variables:
      - $CI_COMMIT_MESSAGE =~ /run-end-to-end-tests/
    kubernetes: active

示例2:

test:
  script: npm run test
  except:--------下面refs、changes是或的關系,也即只要滿足一個條件都不會執行job。
    refs:
      - master
    changes:
      - "README.md"

rules

參考:《rules

The rules keyword can be used to include or exclude jobs in pipelines.

Rules are evaluated in order until the first match.

When matched, the job is either included or excluded from the pipeline, depending on the configuration.

Clause Description
if Add or exclude jobs from a pipeline by evaluating an if statement.
changes Add or exclude jobs from a pipeline based on what files are changed.
exists Add or exclude jobs from a pipeline based on the presence of specific files.

Rules are evaluated in order until a match is found.

If a match is found, the attributes are checked to see if the job should be added to the pipeline.

If no attributes are defined, the defaults are:

  • when: on_success
  • allow_failure: false

The job is added to the pipeline:

  • If a rule matches and has when: on_successwhen: delayed or when: always.
  • If no rules match, but the last clause is when: on_successwhen: delayed or when: always (with no rule).

The job is not added to the pipeline:

  • If no rules match, and there is no standalone when: on_successwhen: delayed or when: always.
  • If a rule matches, and has when: never as the attribute.

參考:《when

when is used to implement jobs that are run in case of failure or despite the failure.

when can be set to one of the following values:

  1. on_success - execute job only when all jobs from prior stages succeed (or are considered succeeding because they are marked allow_failure). This is the default.
  2. on_failure - execute job only when at least one job from prior stages fails.
  3. always - execute job regardless of the status of jobs from prior stages.
  4. manual - execute job manually (added in GitLab 8.10).
  5. delayed - execute job after a certain period (added in GitLab 11.14).

參考:《allow_failure

allow_failure allows a job to fail without impacting the rest of the CI suite.

The default value is false, except for manual jobs using the when: manual syntax, unless using rules: syntax, where all jobs default to false, including when: manual jobs.

When enabled and the job fails, the job will show an orange warning in the UI.

However, the logical flow of the pipeline will consider the job a success/passed, and is not blocked.

job:
  script: "echo Hello, Rules!"
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: never-----------所有Merge Request觸發Pipeline,不運行此job。 - if: '$CI_PIPELINE_SOURCE == "schedule"'
      when: never-----------所有Schedule觸發Pipeline,不運行此job。 - when: on_success------所有其他情況,在前面所有job都成功情況下,運行此job。

參考:《rules:if

$CI_PIPELINE_SOURCE的取值可能情況包括:

Value Description
push For pipelines triggered by a git push event, including for branches and tags.
web For pipelines created by using Run pipeline button in the GitLab UI, from the project’s CI/CD > Pipelines section.
trigger For pipelines created by using a trigger token.
schedule For scheduled pipelines.
api For pipelines triggered by the pipelines API.
external When using CI services other than GitLab.
pipeline For multi-project pipelines created by using the API with CI_JOB_TOKEN.
chat For pipelines created by using a GitLab ChatOps command.
webide For pipelines created by using the WebIDE.
merge_request_event For pipelines created when a merge request is created or updated. Required to enable merge request pipelinesmerged results pipelines, and merge trains.
external_pull_request_event When an external pull request on GitHub is created or updated. See Pipelines for external pull requests.
parent_pipeline For pipelines triggered by parent/child pipeline with rules, use this in the child pipeline configuration so that it can be triggered by the parent pipeline.

Other commonly used variables for if clauses:

  • if: $CI_COMMIT_TAG: If changes are pushed for a tag.
  • if: $CI_COMMIT_BRANCH: If changes are pushed to any branch.
  • if: '$CI_COMMIT_BRANCH == "master"': If changes are pushed to master.
  • if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH': If changes are pushed to the default branch (usually master). Useful if reusing the same configuration in multiple projects with potentially different default branches.
  • if: '$CI_COMMIT_BRANCH =~ /regex-expression/': If the commit branch matches a regular expression.
  • if: '$CUSTOM_VARIABLE !~ /regex-expression/': If the custom variable CUSTOM_VARIABLE does not match a regular expression.
  • if: '$CUSTOM_VARIABLE == "value1"': If the custom variable CUSTOM_VARIABLE is exactly value1.

還有一些其他常用的變量:

參考:《Predefined environment variables reference

CI_MERGE_REQUEST_SOURCE_BRANCH_NAME: The URL of the source project of the merge request if the pipelines are for merge requests. Available only if only: [merge_requests] or rules syntax is used and the merge request is created.
CI_MERGE_REQUEST_TARGET_BRANCH_NAME: The target branch name of the merge request if the pipelines are for merge requests. Available only if only: [merge_requests] or rules syntax is used and the merge request is created.

variables

參考:《variables

GitLab CI/CD allows you to define variables inside .gitlab-ci.yml that are then passed in the job environment.

They can be set globally and per-job.

When the variables keyword is used on a job level, it will override the global YAML variables and predefined ones of the same name.

build b1:
  stage: .post
  only:
    - merge_requests
  variables:
    TRIGGER_SOURCE: "repo-a1"
  trigger:
    project: DevOps-testfarm/repo-b1
    branch: master

Git strategy

參考:《Git strategy

GIT_STRATEGY is used for getting recent application code, either globally or per-job in the variables section.

There are three possible values: clone, fetch, and none.

clone is the slowest option. It clones the repository from scratch for every job, ensuring that the local working copy is always pristine.
fetch is faster as it re-uses the local working copy (falling back to clone if it does not exist).
none also re-uses the local working copy, but skips all Git operations (including GitLab Runner’s pre-clone script, if present).

variables:
  GIT_STRATEGY: fetch

Git submodule strategy

 參考:《Git submodule strategy

The GIT_SUBMODULE_STRATEGY variable is used to control if / how Git submodules are included when fetching the code before a build. You can set them globally or per-job in the variables section.

There are three possible values: none, normal, and recursive:

none means that submodules won’t be included when fetching the project code. This is the default, which matches the pre-v1.10 behavior.

normal means that only the top-level submodules will be included.

git submodule sync
git submodule update --init

recursive means that all submodules (including submodules of submodules) will be included.

git submodule sync --recursive
git submodule update --init --recursive

Package Registry

參考《GitLab Package Registry

Conan

apt-get install python3-pip
pip install conan

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM