ืืืช ืืคืื ืงืฆืืืช ืื ืืืฆืืช ืืืืชืจ, ืฉืืื ื ืืืจืกื ืืืื ืืืช ืฉื GitLab, ืืื ืืืืืืช ืืืฆืืืข ื ืื ืืืืื ืืืืจ ืืฉืืืื ืืืงืฉืช ืืืืื (MR), ืืืืฆืขืืช ืกืงืืจืช ืืงืื ืืืืืืืช.
ืืืื ื ืขืฉื ืืช ืืคืื ืงืฆืืื ืืืืช ืืืื ืืืืืช ืืขืฆืื ื - ื ืืกืืจ ืขื ืืืืื ืขื ืฉืืื ืืคืชืืื ืืชื ื ืืืืื ื-MR.
ืืื ืื ืืืื ื ืืืฅ?
ืืืจืืื ืฉืื ื ืืืื ืืืจืฉืืช ืืขืฆืื ืืงืืืช ืืงื ืืช ืจืืฉืืื GitLab. ืืื, ืืืืืื ืฉืืคืืชืื ืืชืืฆืข ืืืืืื ืกืืืจื ืืื ืืืฉื ืืืื ืืจื ื, ืืืฉ ืชืื ืื ืชืงืฆืืื ืงืคืื ื, ืจืืืฉืช ืจืืฉืืื ืืช ืื ืืืื ืขืฆืื ืขื ืืคืื ืงืฆืืื ืืืืช ืืืจืืฉื ืืืืื ืืืืืฉื ืืืืฉืื ืจืืื, ืืื ืฆืจืื ืืขืฉืืช ืขืืืื ืขืืฉืื.
ืืชืืฆืื ืืื ืขืืื:
- ืื ืืืกืืจ ืืืืืืื ืืืืื ืืกื ืืคืื ืืืื ืื ืขืืืจ ืืคืชืืื ืืกืืืืื, ืืื ืื ืืคืชืืื ืฉืืฉ ืืื ืืช ืืืืืช ืืืืืื ืืงืืืื ืืชื ืืฉืืืืช ืืขืช ืืืืื MRs ืฉื ืื ืฉืื ืืืจืื ืืืื ืืก;
- ืื ืชื ืืช ืืืืืื ืืช ืืืฆืข ืืืืืืื ืืืชื ืืืืงืจืื ืขื ืกื ืืฃ ืืืืกืืจ ืฉืื ืืื ืกืงืืจืช ืงืื, ืื ืื ืื ื'ืื ืืืจ, ืฉืืชืงืื ืืขืืืื ืจืง ืืชืืื.
ืืืืจ ืืจืืฉืื ืฉืขืฉืืชื ืืื ืืืื, ืืชืื ืืืื ื ืฉืืืฉืื ืืืืื ืืืจ ืขืฉื ืืฉืื ืืืื (ืืื ืืฉื ืืช ืืช ืืงืื), ืืื ืืชืืจืจ ืฉืขืืืื ืื ืืื ืืืฉืื ืืื ืืืจืกืช ืืงืืืื.
ืชืื ืืช ืขืืืื ืืืืืช
ืืืืืื, ืืืื ื ืืืืจ ืืืฉืืจื ืืงืฉืืช ืืืืื ืืืืืจ ืืืืงื
- ืืืื ื ืืฆืืจ ืืกืืืื ืืืืฉื ื-GitLab API (ืืจืื ื ืงืื ืืืืข ืขื ืืกืคืจ ืืืฆืืขืืช "ืืขื" ื"ื ืื")
- ืืืื ื ืืกืืฃ ืืช ืืืกืืืื ืืืฉืชื ื GitLab
- ืืืื ื ืฉืืืช ืืช ืืืืืื ืืืงืจื ืฉื ืฉืืืืืช ืืฆื ืจืช (ืื ืืื ืืกืคืืง ืืฆืืขืืช ืืขื)
- ืืืื ื ืืืืจ ืืช ืืืืืช ืืืฆืืขื ืืืืง ืืฆืื ืืจ ื-CI/CD
- ืื ื ืืืกืจืื ืขื ืืชืืืืืืืืช ืืกื ืืคืื ืืืื ืื; ืื ืืฉืื ืืืื ืืชืืฆืขืื ืจืง ืืืืฆืขืืช MR
- ืืื ื ืืืืง ืื ืงืจื ืืกืืฃ
1. ืฆืืจ ืืกืืืื ืืืืฉื ื-API
ืขืืืจ ืื ืืืืจืืช ืืฉืชืืฉ โ Access Tokens ืืจืฉืื ืืช ืืืกืืืื:
ืืฉืืื ืืงืืืช ืืกืืืื
ืืืฉืช API ืืืคืฉืจืช ืื ืืขืฉืืช ืืืขื ืื ืืืจ ืขื ืืืืืจืื ืฉืื, ืื ืื ื ืืืืืฅ ืืืฆืืจ ืืฉืืื Gitlab ื ืคืจื, ืืชืช ืื ืืืืืืช ืืื ืืืืืืช ืืืืืจืื ืฉืื (ืืืฉื Reporter) ืืืงืื ืืกืืืื ืืืฉืืื ืื.
2. ืืืกืฃ ืืช ืืืกืืืื ืืืฉืชื ื Gitlab
ืืืฉื, ืืฉืื ืืงืืื ืงืืืื ื ืืกืืืื QmN2Y0NOUFlfeXhvd21ZS01aQzgK
ืคืชื ืืช ืืืืจืืช โ CI/CD โ ืืฉืชื ืื โ ืืืกืฃ ืืฉืชื ื โ GITLAB_TOKEN_FOR_CI
ืืชืืฆืื ืืื ืื ื ืืงืืืื:
ื ืืชื ืืขืฉืืช ืืืช ืืืืืจ ืืื ืื ืขื ืงืืืฆืช ืืืืจืื.
3. ืื ื ืฉืืื ืืืกืืจ ืขื ืืืืื ืื ืื ืืชืงืื ืืืฉืืจ ืฉื ืขืืืชืื ืืืืจ ืกืงืืจืช ืืงืื.
ืืืงืจื ืฉืื ื, ืืืืกืืจ ืขื ืืืืื ืืืื ืฉืฆืื ืืจ ืืืจืืื ืืืืืจ ืฉืืืื ืื โโืื ืืืื ืืกืคืืง ืืฆืืขืืช.
ืขืืืจ ืื ืืืืจืืช โ ืืืื โ ืืงืฉืืช ืืืืื โ ืืืืื ืฆ'ืงืื ืืืคืขื ืืช ืืืคืฉืจืืช ืืืฉืืจื ืืจืืื ืืืืืื ืืืกืชืืื ืืืฆืืื.
4. ืืงืืช ืืฆืื ืืจ
ืื ืขืืืื ืื ืืฆืจืช ืฆืื ืืจ CI/CD ืขืืืจ ืืืืฉืื ืฉืื
ืฆืืจ ืงืืืฅ ืืฉืืจืฉ ืืืืืจ .gitlab-ci.yml ืขื ืืชืืื ืืคืฉืื ืืืืชืจ:
stages:
- build
- test
variables:
NEED_VOTES: 1
include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
run-myapp:
stage: build
script: echo "Hello world"
ืืืืจ ื ืคืจื ืขืืืจ ืชืฆืืจืช CI/CD
ืื ื ืืืืืฅ ืืืฆืืจ ืืืืจ ื ืคืจื ืฉืื ืืชื ืฆืจืื ืืืฆืืจ ืงืืืฅ myapp.gitlab-ci.yml ืืื ืืืืืืจ ืืช ืืฆืื ืืจ. ืื ืชืืื ืืฉืืื ืืื ืืืชืจ ืืืืฉื ืฉื ืืฉืชืชืคืื ืฉืืืืืื ืืฉื ืืช ืืช ืฆืื ืืจ ืืื ืืื ืืืงืื ืืกืืืื ืืืฉื.
ืืืื ืฆืืจื ืืฆืืื ืืช ืืืืงืื ืฉื ืงืืืฅ ืืฆืื ืืจ ืืืืฉ ืขื ืืื ืืขืืจ ืืืืืจ myapp - ืืืืจืืช - CI/CD - ืงืืื ืืจืืื - ื ืชืื ืชืฆืืจืช CI ืืืชืื ืืืฉืืช - ืฆืืื ืืช ืืงืืืฅ ืืืืฉ, ืืืฉื. myapp.gitlab-ci.yml@gitlab-ce-mr-approvals/Ci
ืืืค: ืืฉืชืืฉ ื-linter ืืื ืืืฆืข ืฉืื ืืืื ืืงืืฆื GitLab CI
ืื ืื ืืชื ืขืืื ืืื, ืขืืืื ืืจื MR ืชืืื ืขืืจื ืืืื, ืืืจืืฅ ืืช ืื ืืฉืื ืืืื ืฉืื ืืงืืฆื ืฆืื ืืจ ืืจื linter. ืื ืชืขืฉื ืืขืืช ืืชืืืืจ ืฉื ืงืืืฅ ื-YAML, ืืื ืื ืืฉืืืจ ืืช ืฆืื ืืจ ืืืืฆืืจ ืฉืื, ืืื ืคืฉืื ืืืกืื ืืช ืืืืืื.
ืืืืื ืืืืืืื ืขื ืจืฆืืขืืช ืฉืชืืืื ืืื ืืช ืืฆืื ืืจ ืฉืืื:
ืืืืืื ืืฉืื ืืืืืืช:
stages:
- lint
lint:
stage: lint
image: sebiwi/gitlab-ci-validate:1.3.0
variables:
GITLAB_HOST: https://gitlab.com
script:
- CI_FILES=(./*.yml)
- for f in "${CI_FILES[@]}"; do
gitlab-ci-validate $f;
done;
ื ืืชืจ ืืืืกืืฃ ืืื ืคืจืืืจืื ืืฆืื ืืจ ืฉืื ืืื ืฉืื ืืขืืื:
stages:
- test
variables:
NEED_VOTES: 1
include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
ืืืฉืชื ื NEED_VOTES ืงืืืข ืืื "ืืืืื ืืืขืื" ืฆืจืื ืืืืืช ื-MR ืืื ืฉืืืืืื ืืืื ืืืื. ืขืจื ืฉืืื ืืืื ืืืืจ ืฉืืชื ืืขืฆืื ืืืื ืืืฉืจ ืืช ื-MR ืฉืื ืขื ืืื "ืืืืชื" ืืืชื.
include ืืืื ืืช ืฉืื ืืืืืงื, ืฉืืืืง ืืช ืืกืคืจ ื"ืืืืงืื".
ืืฆืื ืืจ ืืคืฉืื ืืืืชืจ ืืืืฆืขืืช ืืืืืื ืฉื myapp.gitlab-ci.yml
stages:
- build
- test
variables:
NEED_VOTES: 0
include:
- remote: "https://gitlab.com/gitlab-ce-mr-approvals/ci/-/raw/master/check-approve.gitlab-ci.yml"
run-myapp:
stage: build
image: openjdk
script:
- echo CI_MERGE_REQUEST_TARGET_BRANCH_NAME $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
- java HelloWorld.java
ืชืืื check-approve.gitlab-ci.yml
ci-mr:
stage: test
script:
- echo ${CI_API_V4_URL}
- echo "CI_PROJECT_ID ${CI_PROJECT_ID}"
- echo "CI_COMMIT_SHA ${CI_COMMIT_SHA}"
- "export MR_ID=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .id else {} end" | grep --invert-match {})"
- "export MR_TITLE=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .title else {} end" | grep --invert-match {})"
- "export MR_WIP=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .work_in_progress else {} end" | grep --invert-match {})"
- "export MR_UPVOTES=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .upvotes else {} end" | grep --invert-match {})"
- "export MR_DOWNVOTES=$(curl --silent --request GET --header "PRIVATE-TOKEN: $GITLAB_TOKEN_FOR_CI" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests | jq ".[] | if .sha == \"${CI_COMMIT_SHA}\" then .downvotes else {} end" | grep --invert-match {})"
- MR_VOTES=$(expr ${MR_UPVOTES} - ${MR_DOWNVOTES})
- NEED_VOTES_REAL=${NEED_VOTES:-1}
- echo "MR_ID ${MR_ID} MR_TITLE ${MR_TITLE} MR_WIP ${MR_WIP} MR_UPVOTES ${MR_UPVOTES} MR_DOWNVOTES ${MR_DOWNVOTES}"
- echo "MR_VOTES ${MR_VOTES} Up vote = 1, down vote = -1, MR OK if votes >=${NEED_VOTES_REAL}"
- if [ "${MR_VOTES}" -ge "$(expr ${NEED_VOTES_REAL})" ];
then
echo "MR OK";
else
echo "MR ERROR Need more votes";
exit 1;
fi
image: laptevss/gitlab-api-util
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^release/.*$/'
ืืืืข ื ืืกืฃ ืขื ืื ืฉืงืืจื ืืืืื ืืืืืืช:
- ืืฉื ื ืืืืื ืฉืืืืืงื ืชืชืืฆืข ืจืง ืืขืช ืืฆืืจืช MR ืืกื ืืคืื ืืืกืืจ ืื ืฉืืจืืจ/*
- ืืืืฆืขืืช ื-API ืฉื GitLab, ืื ื ืืงืืืื ืืช ืืกืคืจ "ืืืืชื" ื-"ืืืกืืืืงืื"
- ืืืฉื ืืช ืืืืื ืืื ืชืืืืืช ืืืืืืืช ืืฉืืืืืืช
- ืื ืืืคืจืฉ ืงืื ืืืขืจื ืฉืืืืจื ื ื-NEED_VOTES, ืื ื ืืืกืืื ืืช ืืืืืช ืืืืืื
5. ืืืกืืจ ืืชืืืื ืืขื ืคืื ืืืื ืื
ืื ื ืืืืืจืื ืืช ืืกื ืืคืื ืฉืืืืืื ืขืืื ื ืืขืจืื ืืืงืืจืืช ืงืื ืืืฆืืื ืื ืฉื ืืชื ืืขืืื ืืืชื ืจืง ืืจื MR.
ืืื ืืขืฉืืช ืืืช, ืขืืืจ ืื ืืืืจืืช โ ืืืืจ โ ืกื ืืคืื ืืืื ืื:
6. ืืืืง
ืืืืจ NEED_VOTES: 0
ืื ืื ื ืขืืฉืื MR ืืฉืืื "ืืืกืืืืง".
ืืืืื ื ืืื ืืื:
ืืขืช ืฉืื "ืืืืชื" ืืืชืื ืืืืืง ืฉืื:
ืืงืืจ: www.habr.com