CI/CD Advance
gitlab duo chat
์ง๋ฌธ์ด ์์ผ๋ฉด duo chat์ ์ด์ฉํ์. ๋ฉ๋ด๊ฐ ์ฐพ๊ธฐ ์ด๋ ต๋ค. ์๋น์ค์ ๋ฐ๋ผ์ ์์์๋ ์๋ค.

start pipeline
.gitlab-ci.yml ์์ฑ (gitlab-ci.yaml์ ๋์ํ์ง์์)
stage
job
stage๊ฐ ์์ฑ์ด ๋๋ค. ๊ทธ๋ฆฌ๊ณ job์ด ์์ฑ์ด ๋๋ค.
stage๋ tagging system๊ณผ ๋น์ทํ๋ค. ๋ชจ๋ ๊ฒ์ Job์ผ๋ก ์์ง์ด์ง๋ง stage๋ job์ ๊ทธ๋ฃนํ ์ํค๋ ์ญํ ์ ํ๋ค.
image: docker:latest
services:
- docker:dind
variables:
CS_DEFAULT_BRANCH_IMAGE: $CI_REGISTRY_IMAGE/$CI_DEFAULT_BRANCH:$CI_COMMIT_SHA
DOCKER_DRIVER: overlay2
RUNNER_GENERATE_ARTIFACTS_METADATA: 'true'
stages:
- mybuild
- mytest
build:
stage: mybuild
variables:
IMAGE: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
before_script:
- docker info
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- cd app
- docker build -t $IMAGE .
after_script:
- docker push $IMAGE
test:
stage: mytest
image: alpine:latest
script:
- echo helloscript, before_script, and after_script
before_script: script์ ์ ์คํ๋๋ค. ๊ทธ๋ฆฌ๊ณ script์ ๊ฐ์ shell์์ ์คํ๋๋ค.
script : runner์ ์ํด์ ์คํ๋๋ค. exitcode๋ ์ฌ๊ธฐ์์ ๋ฆฌํด๋๋ค.
after_script : Runs in a separate shell after the before_script / script statements. (๋ค๋ฅธ ์์์ ์คํ๋๋ค. ) , exitcode ์ ๋ํด์๋ ์๊ดํ์ง ์๋๋ค.
test์ ์ฝ๋ ์ถ๊ฐ
test:
stage: mytest
image: alpine:latest
script:
- echo hello
after_script:
- echo "Our race track has been tested!"์คํ ์์
stage ์์๋๋ก ์คํ๋๋ค.
Jobs in the next stage will start after all jobs in the previous stage have completed successfully
๋ค์ ๋จ๊ณ์ ์์ ์ ์ด์ ๋จ๊ณ์ ๋ชจ๋ ์์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋ ํ ์์๋ฉ๋๋ค.

GitLab Runners
type
SSH
Shell
Virtual Box
Parallels
Docker
Docker Autoscaler (Beta)
Docker Machine
Kubernetes
Custom
tag
tag๋ฅผ ์ด์ฉํด์ runner๋ฅผ ์ ํํ ์ ์๋ค.
job:
tags:
- myrunner์คํ ์์ ์์
need๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ์์ ๋ค์์ ์คํ์ ํ ์ ์๋ค.
๊ฒฝ์ฐ์ ๋ฐ๋ผ์ stage๋ฅผ ๋์์ ์คํํ๊ณ ์ถ์์ ์๋ค.
test:
stage: mytest
image: alpine:latest
script:
- echo hello
after_script:
- echo "Our race track has been tested!"
needs: []
super_fast_test:
stage: test
script:
- echo "If youre not first youre last"
- return 0
needs: []๋๊ฐ์ ์ก์ด ๋ค๋ฅธ์ก์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋์์ ์คํ๋๋ค.

build๊ฐ ์๋๋๋ test๊ฐ ์คํ๋๋ค.
job dependencies๊ฐ ์๊ฒผ๊ณ dependency๊ฐ ์๋๊ฒ์ ๋ณผ์ ์๋ค.
Directed Acyclic Graph
stage์ถ๊ฐํ๊ณ ๋ค์ ์ฝ๋๋ฅผ ์ถ๊ฐํด๋ณด์.
stages:
- race
build_car_a:
stage: mybuild
script:
- echo "build_car_a"
build_car_b:
stage: mybuild
script:
- echo "build_car_b"
build_car_c:
stage: mybuild
script:
- echo "build_car_c"
build_car_d:
stage: mybuild
script:
- echo "build_car_d"
build_car_e:
stage: mybuild
script:
- echo "build_car_e"
build_car_f:
stage: mybuild
script:
- echo "build_car_f"
test_car_a:
stage: mytest
needs: [build_car_a]
script:
- echo "test_car_a"
test_car_b:
stage: mytest
needs: [build_car_b]
script:
- echo "test_car_b"
test_car_c:
stage: mytest
needs: [build_car_c]
script:
- echo "test_car_c"
test_car_d:
stage: mytest
needs: [build_car_d]
script:
- echo "test_car_d"
test_car_e:
stage: mytest
needs: [build_car_e]
script:
- echo "test_car_e"
test_car_f:
stage: mytest
needs: [build_car_f]
script:
- echo "test_car_f"
race_car_a:
stage: race
needs: [test_car_a]
script:
- echo "race_car_a"
race_car_b:
stage: race
needs: [test_car_b]
script:
- echo "race_car_b"
race_car_c:
stage: race
needs: [test_car_c]
script:
- echo "race_car_c"
race_car_d:
stage: race
needs: [test_car_d]
script:
- echo "race_car_d"
race_car_e:
stage: race
needs: [test_car_e]
script:
- echo "race_car_e"
race_car_f:
stage: race
needs: [test_car_f]
script:
- echo "race_car_f"

์ฌ๊ธฐ์์ ๋ณด๋ฉด ๋ณผ์ ์๋ค.
์๋ณตํ์.
Stageless Pipelines
๋ฒ์ ์ ๋ฐ๋ผ์ ๋ค๋ฅด์ง๋ง ๊ธฐ์กด์๋ need๋ ๋ค๋ฅธ stage์ job์ ์ ์ฉํ ์ ์์์ต๋๋ค.
์ด์ ๋ ๊ฐ์ stage์์๋ need๊ฐ ์ ์ฉ๋จ. Allows โneedsโ keyword to be used in the same stage
ํ์ดํ๋ผ์ธ์ ์ข๋ ํจ๊ณผ์ ์ผ๋ก ๋ง๋ค์ ์์ต๋๋ค.
์คํ์์๋ฅผ ์ข๋ ๋ช ํํ๊ฒ ์ ํ ์ ์์ต๋๋ค.
Available in (All tiers; 14.2+)
Caching Basics
To cache, a GitLab Runner will take the content you cached and store it in GCP Cloud Storage
Cache Execution Order
Pipeline starts.
job A runs.
before_script is executed.
script is executed.
after_script is executed.
cache runs and the vendor/ directory is zipped into cache.zip. This file is then saved in the directory based on the runnerโs setting and the cache: key.
job B runs.
The cache is extracted (if found).
before_script is executed.
script is executed.
Pipeline finishes.
why cache?
์์ ๊ฐ์ ๋ค์ด๋ก๋ํ ์ฝํ ์ธ ๊ณต์ : ์ฝ๋์ ์ฌ๋ฌ ๋ธ๋์น์์ ์ํํ ์๋ ์์ต๋๋ค. ์ฝ๋ ์ข ์์ฑ ์ ์ฅ(๋ค์์ ๋ค์ด๋ก๋ํ ๋๊น์ง ๊ธฐ๋ค๋ฆด ํ์ ์์) ํ์ดํ๋ผ์ธ ์๋ ํฅ์
job A:
stage: mybuild
script:
- mkdir vendor/
- echo "Hello World" > vendor/hello.txt
cache:
key: build-cache
paths:
- vendor/
after_script:
- echo "world"
job B:
stage: mytest
script:
- cat vendor/hello.txt
cache:
key: build-cache
paths:
- vendor/
hello.txt๋ฅผ ๋ค์์์ ์ด ๋ฐ์์ ์ฒ๋ฆฌํ ์ ์๋ค.
hello world ๊ฐ ์ฐํ๋๊ฑธ ๋ณผ์ ์๋ค. ํ์ผ์ ๊ฐ์ ธ์๋ค๋ ๋ป์ด๋ค.
์ข๋ ์๋ฏธ์๋ ์ํ์ ํด๋ณด์. ruby๋ฅผ ๋น๋๋ฅผ ๋จผ์ ํด์ ๊ทธ๊ฑธ ์บ์ํด๋๊ณ ๋ค์์์ ์์ ๊ฐ์ ธ์์ ์ฌ์ฉํ ์ ์๋ค.
์ข๋ ์๋ฏธ์๋ ์ํ์ ํด๋ณด์. ruby๋ฅผ ๋น๋๋ฅผ ๋จผ์ ํด์ ๊ทธ๊ฑธ ์บ์ํด๋๊ณ ๋ค์์์ ์์ ๊ฐ์ ธ์์ ์ฌ์ฉํ ์ ์๋ค.
# Cache modules in between jobs
cache:
- key: cache-$CI_COMMIT_REF_SLUG
fallback_keys:
- cache-$CI_DEFAULT_BRANCH
- cache-default
paths:
- vendor/ruby
- Gemfile.locknpm๋ ๋ง์ฐฌ๊ฐ์ง์ด๋ค. ์ฒ์๋ถํฐ ๋ค ์ค์นํ์ง ์๊ณ ์ค์น๋ ํ์ผ๋ค์ ๋ค์ด๋ฐ์ํ ์ฌ์ฉํ๋ฉด ๋น๋ ์๊ฐ์ ์ค์ผ์ ์๋ค.
Allowing Job Failure (job ์คํจ๋ฅผ ํ์ฉ)
We need to find a way to configure the pipeline so that even when the unit test job fails, subsequent jobs still execute.
๋จ์ ํ ์คํธ ์์ ์ด ์คํจํ๋๋ผ๋ ํ์ ์์ ์ด ๊ณ์ ์คํ๋๋๋ก ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ
allow_failure: true - failing job is logged in the pipeline as failed, but does not prevent subsequent jobs from executing
allow_failure ๋ฅผ ์ฌ์ฉํ๋ฉด๋๋ค.
์คํฌ๋ฆฝํธ exit 1 ์ ์คํจ๋ฅผ ๋ฆฌํดํ๋ค.
stage์ deploy๋ฅผ ์ถ๊ฐํ๋ค.allow_failure: true ๊ฐ ์์ผ๋ฉด deploy๋ ์คํ๋์ง ์๋๋ค.
stages:
- deploy
super_fast_test:
stage: mytest
script:
- exit 1
needs: []
allow_failure: true
deploy:
stage: deploy
script:
- echo "Deploying"
needs: [super_fast_test]allow_failure: true ์๋ ๊ฒฝ์ฐ 
allow_failure: true ์๋ ๊ฒฝ์ฐ 
rules
rules์ ์ถ๊ฐ
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH๋ง๋ ์กฐ๊ฑด์๋ง ์คํ์ด ๋๋ค.
When is a Job NOT created in a Pipeline?
When is a Job NOT created in a Pipeline?
A job is not included in a pipeline if:
None of the rules defined for the job evaluate to true
A rule evaluates to true, but has clause of when: never
No rules are defined but a when: never clause is specified
๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ์์ ์ ํ์ดํ๋ผ์ธ์ ํฌํจ๋์ง ์์ต๋๋ค:
์์ ์ ๋ํด ์ ์๋ ๊ท์น ์ค ์ด๋ ๊ฒ๋ ์ฐธ์ผ๋ก ํ๊ฐ๋์ง ์์ต๋๋ค.
๊ท์น์ด ์ฐธ์ผ๋ก ํ๊ฐ๋์ง๋ง
when: never์ ์ด ์์ต๋๋ค.๊ท์น์ด ์ ์๋์ด ์์ง ์์ง๋ง
when: never์ ์ด ์ง์ ๋์ด ์์ต๋๋ค.
job:
script: echo "Hello, World!"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: never
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: on_success๋๊ฐ์ ๊ฒฝ์ฐ์๋ job์ด ์คํ๋์ง ์๋๋ค.
when: on_success : ์ด์ ์์ ์ด ์ฑ๊ณตํ๋ค๊ณ ๊ฐ์ ํ์ฌ ์์ ์ ์คํํ๋๋ก ์ง์ํฉ๋๋ค. ์ด์ค์ ์ค๋ฉด ๊ธฐ์กด if๋ ์ด๋๊ฒ๋ ๋ง์กฑํ์ง ์์๋ ์ฌ๊ธฐ๊น์ง ์ค๊ฒ ๋๋ค.
when: manual
์๋์ผ๋ก ์คํํ๊ณ ์ถ์ผ๋ฉด when: manual ์ ์ถ๊ฐํ๋ฉด ๋๋ค.
ํ๋ฉด์์ ์คํ๋ฒํผ์ด ๋์ค๋ฏ๋ก ๊ทธ๊ฑธ ๋๋ฅด๋ฉด๋๋ค.
super_fast_test:
stage: mytest
script:
- exit 1
needs: []
allow_failure: true
deploy:
stage: deploy
script:
- echo "Deploying"
needs: [super_fast_test]
when: manual
If $CI_PIPELINE_SOURCE is set to merge_request_event or schedule, the job is executed
CI_PIPELINE_SOURCE๊ฐ merge_request_event ๋๋ ์ค์ผ์ค๋ก ์ค์ ๋ ๊ฒฝ์ฐ ์์ ์ด ์คํ๋ฉ๋๋ค.
job:
script: echo "Hello, World!"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "schedule"when for delaying a job run
If used as when: delayed, start_in is also required.
job:
script: echo "Hello, World!"
rules:
- if: $CI_COMMIT_BRANCH == "master"
when: delayed
start_in: 3 hoursusing changes and if
job:
script: docker build -t
rules:
- if: $VAR == "string value"
changes:
- Dockerfile
- docker/scripts/*
when: manual๊ฒฝ๋ก์ค์ ํ์ผ์ด ๋ฐ๊ท๋ฉด ์คํ๋๋๋ก ํ ์ ์๋ค.
์ ๋ด์ฉ์ ๋๊ฐ์ ๊ฒฝ๋ก์ ํ์ผ์ด ํ๋๋ผ๋ ๋ฐ๊ท๋ฉด ์คํ๋๋ค. AND๋ฅผ ์คํํ๋ ค๋ฉด ์๋์ ๊ฐ์ด ํ๋ฉด๋๋ค.
changes:
- Dockerfile AND docker/scripts/*variables Processing Order
The order of precedence for variables is (from highest to lowest): ๋ณ์์ ์ฐ์ ์์๋ (๋์ ๊ฒ๋ถํฐ ๋ฎ์ ๊ฒ) ์ ๋๋ค
CICD pipeline Trigger variables, scheduled pipeline variables, and manual pipeline run variables.
Project-level variables or protected variables.
Group-level variables or protected variables.
Instance-level variables or protected variables.
Inherited environment variables.
YAML-defined job-level variables.
YAML-defined global variables.
Deployment variables.
Predefined environment variables.

Stroing with artifacts
build:
stage: build
script:
- echo hi > test.txt
artifacts:
paths:
- test.txt
expire_in: 1 hour
artifacts์ ๋ค์ด๋ก๋ํ ์ ์์ต๋๋ค.
template
How to get SAST from GitLab
SAST๋ Static Application Security Testing์ ์ฝ์์ด๋ค.
include:
- template: Security/SAST.gitlab-ci.ymlsast job: chosen stage does not exist; available stages are .pre, mytest, deploy, .postadd test stage
stages:
- testNow that we have SAST lets add a few more security templates to our project to confirm that our code is secure
include:
- template: Code-Quality.gitlab-ci.yml
child process
SAST๋ฅผ ํ์ฑํํ์ฌ ํ์ดํ๋ผ์ธ์ ๋ฐ๋ชจํ ํ ๋ณด์ ํ์์ ๋ ๋ง์ ์ค์บ๋๋ก ์์ฒด ํ์ดํ๋ผ์ธ์ ์คํํ๊ณ ์์ผ๋ฉฐ ์ด๋ฅผ ํ์ดํ๋ผ์ธ๊ณผ ํตํฉํ๊ธฐ๋ฅผ ์ํ๋ค๋ ์ฌ์ค์ ์๋ ค์ค๋๋ค. ์ด๋ฅผ ์ํ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ํ์ ํ์ดํ๋ผ์ธ์ ์ค์ ํ๋ ๊ฒ์ด๋ผ๊ณ ๊ฒฐ์ ํฉ๋๋ค.
์ ์ฒด ์ฝ๋๋ฅผ ์ ๋ฐ์ดํธํ์.
image: docker:latest
services:
- docker:dind
stages:
- build
- test
build:
stage: build
script:
- echo hellonew stage ์ถ๊ฐ
stages:
- build
- test
- extra-securityextra-security ์ถ๊ฐ. trigger๋ฅผ ์ฌ์ฉํ๊ณ include๋ฅผ ์ฌ์ฉํ๋ค.
downstream_security:
stage: extra-security
trigger:
include:
- local: security-pipeline/security.gitlab-ci.ymlcreate folder and file
security-pipeline/security.gitlab-ci.yml
image: docker:latest
include:
- template: Code-Quality.gitlab-ci.yml
- template: Jobs/Dependency-Scanning.gitlab-ci.yml
- template: Jobs/SAST.gitlab-ci.yml
- template: Jobs/Secret-Detection.gitlab-ci.yml์ด๋ค ํ์ดํ๋ผ์ธ์ด๋ผ๋ ์ถ๊ฐํด์ ์ฌ์ฉํ ์ ์๋ค.

Downstream Pipelines
Two types:
Parent-child
ํ์ดํ๋ผ์ธ์ด ๊ฐ์ ํ๋ก์ ํธ์ ์กด์ฌ
๋ถ๋ชจ ํ์ดํ๋ผ์ธ๊ณผ ๋์ผํ ํ๋ก์ ํธ, ์ฐธ์กฐ ๋ฐ ์ปค๋ฐ SHA์์ ์คํ๋ฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ํ์ดํ๋ผ์ธ์ด ์คํ๋๋ ์ฐธ์กฐ์ ์ ์ฒด ์ํ์ ์ง์ ์ ์ธ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค(์์ ํ์ดํ๋ผ์ธ์ ํธ๋ฆฌ๊ฑฐํ ๋
strategy:depend๋ฅผ ์ฌ์ฉํ์ง ์๋ ํ).์ค์ฒฉ๋ ๋ ๋ฒจ 2๊ฐ๋ก ์ ํ
Multi-project
ํ์ดํ๋ผ์ธ์ ์ฌ๋ฌ ํ๋ก์ ํธ์ ์กด์ฌํฉ๋๋ค.
์ ์คํธ๋ฆผ(ํธ๋ฆฌ๊ฑฐ๋ง) ํ์ดํ๋ผ์ธ์ ๋ค์ด์คํธ๋ฆผ(ํธ๋ฆฌ๊ฑฐ๋ง) ํ์ดํ๋ผ์ธ์ ๋ํ ์ ์ด ๊ถํ์ด ๋ง์ง ์์ต๋๋ค.
์คํ ์ค์ธ ํ๋ก์ ํธ์ ์ ์ฒด ์ฐธ์กฐ ์ํ์๋ ์ํฅ์ ์ฃผ์ง๋ง ํธ๋ฆฌ๊ฑฐ ํ์ดํ๋ผ์ธ์ ์ฐธ์กฐ ์ํ์๋ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.
๋ ๋ฆฝ์ ์ด๋ฏ๋ก ์ค์ฒฉ ์ ํ์ด ์์ต๋๋ค.
Rules & Child Pipelines
Allows you to get creative and make dynamic changes to the current results of your pipelines ์ฐฝ์๋ ฅ์ ๋ฐํํ์ฌ ํ์ดํ๋ผ์ธ์ ํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ๋์ ์ผ๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
Last updated
Was this helpful?