เจ•เฉเจฌเจฐเจจเฉ‡เจŸเจธ เจฆเฉ‡ เจจเจพเจฒ GitLab CI เจตเจฟเฉฑเจš JUnit

เจ‡เจธ เจคเฉฑเจฅ เจฆเฉ‡ เจฌเจพเจตเจœเฉ‚เจฆ เจ•เจฟ เจนเจฐ เจ•เฉ‹เจˆ เจšเฉฐเจ—เฉ€ เจคเจฐเฉเจนเจพเจ‚ เจœเจพเจฃเจฆเจพ เจนเฉˆ เจ•เจฟ เจคเฉเจนเจพเจกเฉ‡ เจธเฉŒเจซเจŸเจตเฉ‡เจ…เจฐ เจฆเฉ€ เจœเจพเจ‚เจš เจ•เจฐเจจเจพ เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจจ เจ…เจคเฉ‡ เจœเจผเจฐเฉ‚เจฐเฉ€ เจนเฉˆ, เจ…เจคเฉ‡ เจฌเจนเฉเจค เจธเจพเจฐเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ เจฒเฉฐเจฌเฉ‡ เจธเจฎเฉ‡เจ‚ เจคเฉ‹เจ‚ เจ†เจชเจฃเฉ‡ เจ†เจช เจนเฉ€ เจ•เจฐ เจฐเจนเฉ‡ เจนเจจ, เจนเฉˆเจฌเจฐ เจฆเฉ€ เจตเจฟเจธเจผเจพเจฒเจคเจพ เจตเจฟเฉฑเจš เจ…เจœเจฟเจนเฉ‡ เจชเฉเจฐเจธเจฟเฉฑเจง เจ‰เจคเจชเจพเจฆเจพเจ‚ เจฆเฉ‡ เจธเฉเจฎเฉ‡เจฒ เจจเฉ‚เฉฐ เจธเจฅเจพเจชเจค เจ•เจฐเจจ เจฒเจˆ เจ‡เฉฑเจ• เจตเฉ€ เจตเจฟเจ…เฉฐเจœเจจ เจจเจนเฉ€เจ‚ เจธเฉ€เฅค เจ‡เจน เจธเจฅเจพเจจ (เจธเจพเจกเจพ เจฎเจจเจชเจธเฉฐเจฆ) GitLab เจ…เจคเฉ‡ JUnitเฅค เจ†เจ“ เจ‡เจธ เจชเจพเฉœเฉ‡ เจจเฉ‚เฉฐ เจญเจฐเฉ€เจ!

เจ•เฉเจฌเจฐเจจเฉ‡เจŸเจธ เจฆเฉ‡ เจจเจพเจฒ GitLab CI เจตเจฟเฉฑเจš JUnit

เจœเจพเจฃ-เจชเจ›เจพเจฃ

เจชเจนเจฟเจฒเจพเจ‚, เจฎเฉˆเจจเฉ‚เฉฐ เจ•เฉเจ เจธเฉฐเจฆเจฐเจญ เจฆเฉ‡เจฃ เจฆเจฟเจ“:

  • เจ•เจฟเจ‰เจ‚เจ•เจฟ เจธเจพเจกเฉ€เจ†เจ‚ เจธเจพเจฐเฉ€เจ†เจ‚ เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจเจพเจ‚ เจ•เฉเจฌเจฐเจจเฉ‡เจŸเจธ 'เจคเฉ‡ เจšเฉฑเจฒเจฆเฉ€เจ†เจ‚ เจนเจจ, เจ…เจธเฉ€เจ‚ เจ‰เจšเจฟเจค เจฌเฉเจจเจฟเจ†เจฆเฉ€ เจขเจพเจ‚เจšเฉ‡ 'เจคเฉ‡ เจŸเฉˆเจธเจŸเจพเจ‚ เจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃ เจฌเจพเจฐเฉ‡ เจตเจฟเจšเจพเจฐ เจ•เจฐเจพเจ‚เจ—เฉ‡เฅค
  • เจ…เจธเฉˆเจ‚เจฌเจฒเฉ€ เจ…เจคเฉ‡ เจคเฉˆเจจเจพเจคเฉ€ เจฒเจˆ เจ…เจธเฉ€เจ‚ เจตเจฐเจคเจฆเฉ‡ เจนเจพเจ‚ werf (เจฌเฉเจจเจฟเจ†เจฆเฉ€ เจขเจพเจ‚เจšเฉ‡ เจฆเฉ‡ เจนเจฟเฉฑเจธเฉ‡ เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš, เจ‡เจธเจฆเจพ เจ†เจชเจฃเฉ‡ เจ†เจช เจนเฉ€ เจฎเจคเจฒเจฌ เจนเฉˆ เจ•เจฟ เจนเฉˆเจฒเจฎ เจธเจผเจพเจฎเจฒ เจนเฉˆ)เฅค
  • เจฎเฉˆเจ‚ เจŸเฉˆเจธเจŸเจพเจ‚ เจฆเฉ€ เจ…เจธเจฒ เจฐเจšเจจเจพ เจฆเฉ‡ เจตเฉ‡เจฐเจตเจฟเจ†เจ‚ เจตเจฟเฉฑเจš เจจเจนเฉ€เจ‚ เจœเจพเจตเจพเจ‚เจ—เจพ: เจธเจพเจกเฉ‡ เจ•เฉ‡เจธ เจตเจฟเฉฑเจš, เจ•เจฒเจพเจ‡เฉฐเจŸ เจ–เฉเจฆ เจŸเฉˆเจธเจŸ เจฒเจฟเจ–เจฆเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจ…เจธเฉ€เจ‚ เจธเจฟเจฐเจซ เจ‰เจนเจจเจพเจ‚ เจฆเฉ€ เจธเจผเฉเจฐเฉ‚เจ†เจค เจจเฉ‚เฉฐ เจฏเจ•เฉ€เจจเฉ€ เจฌเจฃเจพเจ‰เจ‚เจฆเฉ‡ เจนเจพเจ‚ (เจ…เจคเฉ‡ เจ…เจญเฉ‡เจฆ เจฆเฉ€ เจฌเฉ‡เจจเจคเฉ€ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจ…เจจเฉเจธเจพเจฐเฉ€ เจฐเจฟเจชเฉ‹เจฐเจŸ เจฆเฉ€ เจฎเฉŒเจœเฉ‚เจฆเจ—เฉ€)เฅค


เจ•เจพเจฐเจตเจพเจˆเจ†เจ‚ เจฆเจพ เจ†เจฎ เจ•เฉเจฐเจฎ เจ•เจฟเจนเฉ‹ เจœเจฟเจนเจพ เจฆเจฟเจ–เจพเจˆ เจฆเฉ‡เจตเฉ‡เจ—เจพ?

  1. เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจฌเจฃเจพเจ‰เจฃเจพ - เจ…เจธเฉ€เจ‚ เจ‡เจธ เจชเฉœเจพเจ… เจฆเฉ‡ เจตเจฐเจฃเจจ เจจเฉ‚เฉฐ เจ›เฉฑเจก เจฆเฉ‡เจตเจพเจ‚เจ—เฉ‡เฅค
  2. เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจจเฉ‚เฉฐ เจ•เฉเจฌเจฐเจจเฉ‡เจŸเจธ เจ•เจฒเฉฑเจธเจŸเจฐ เจฆเฉ‡ เจ‡เฉฑเจ• เจตเฉฑเจ–เจฐเฉ‡ เจจเฉ‡เจฎเจธเจชเฉ‡เจธ เจตเจฟเฉฑเจš เจคเฉˆเจจเจพเจค เจ•เจฐเฉ‹ เจ…เจคเฉ‡ เจœเจพเจ‚เจš เจธเจผเฉเจฐเฉ‚ เจ•เจฐเฉ‹เฅค
  3. เจ•เจฒเจพเจคเจฎเจ• เจšเฉ€เจœเจผเจพเจ‚ เจฆเฉ€ เจ–เฉ‹เจœ เจ•เจฐเจจเจพ เจ…เจคเฉ‡ GitLab เจจเจพเจฒ JUnit เจฐเจฟเจชเฉ‹เจฐเจŸเจพเจ‚ เจจเฉ‚เฉฐ เจชเจพเจฐเจธ เจ•เจฐเจจเจพเฅค
  4. เจชเจนเจฟเจฒเจพเจ‚ เจฌเจฃเจพเจ‡เจ† เจจเจพเจฎ-เจธเจฅเจพเจจ เจฎเจฟเจŸเจพเจ‰เจฃเจพเฅค

เจนเฉเจฃ - เจฒเจพเจ—เฉ‚ เจ•เจฐเจจ เจฒเจˆ!

เจตเจฟเจตเจธเจฅเจพ

เจ—เจฟเฉฑเจŸเจฒเจพเจฌ เจธเฉ€.เจ†เจˆ.

เจ†เจ‰ เจ‡เฉฑเจ• เจŸเฉเจ•เฉœเฉ‡ เจจเจพเจฒ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเฉ€เจ .gitlab-ci.yaml, เจœเฉ‹ เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจจเฉ‚เฉฐ เจคเฉˆเจจเจพเจค เจ•เจฐเจจ เจ…เจคเฉ‡ เจŸเฉˆเจธเจŸเจพเจ‚ เจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃ เจฆเจพ เจตเจฐเจฃเจจ เจ•เจฐเจฆเจพ เจนเฉˆเฅค เจธเฉ‚เจšเฉ€ เจ•เจพเจซเจผเฉ€ เจตเจฟเจธเจผเจพเจฒ เจธเจพเจฌเจค เจนเฉ‹เจˆ, เจ‡เจธ เจฒเจˆ เจ‡เจธ เจจเฉ‚เฉฐ เจŸเจฟเฉฑเจชเจฃเฉ€เจ†เจ‚ เจจเจพเจฒ เจชเฉ‚เจฐเฉ€ เจคเจฐเฉเจนเจพเจ‚ เจจเจพเจฒ เจชเฉ‚เจฐเจ• เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจธเฉ€:

variables:
# ะพะฑัŠัะฒะปัะตะผ ะฒะตั€ัะธัŽ werf, ะบะพั‚ะพั€ัƒัŽ ัะพะฑะธั€ะฐะตะผัั ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒ
  WERF_VERSION: "1.0 beta"

.base_deploy: &base_deploy
  script:
# ัะพะทะดะฐะตะผ namespace ะฒ K8s, ะตัะปะธ ะตะณะพ ะฝะตั‚
    - kubectl --context="${WERF_KUBE_CONTEXT}" get ns ${CI_ENVIRONMENT_SLUG} || kubectl create ns ${CI_ENVIRONMENT_SLUG}
# ะทะฐะณั€ัƒะถะฐะตะผ werf ะธ ะดะตะฟะปะพะธะผ โ€” ะฟะพะดั€ะพะฑะฝะตะต ะพะฑ ัั‚ะพะผ ัะผ. ะฒ ะดะพะบัƒะผะตะฝั‚ะฐั†ะธะธ
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#deploy-stage)
    - type multiwerf && source <(multiwerf use ${WERF_VERSION})
    - werf version
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - werf deploy --stages-storage :local
      --namespace ${CI_ENVIRONMENT_SLUG}
      --set "global.commit_ref_slug=${CI_COMMIT_REF_SLUG:-''}"
# ะฟะตั€ะตะดะฐะตะผ ะฟะตั€ะตะผะตะฝะฝัƒัŽ `run_tests`
# ะพะฝะฐ ะฑัƒะดะตั‚ ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒัั ะฒ ั€ะตะฝะดะตั€ะต Helm-ั€ะตะปะธะทะฐ
      --set "global.run_tests=${RUN_TESTS:-no}"
      --set "global.env=${CI_ENVIRONMENT_SLUG}"
# ะธะทะผะตะฝัะตะผ timeout (ะฑั‹ะฒะฐัŽั‚ ะดะพะปะณะธะต ั‚ะตัั‚ั‹) ะธ ะฟะตั€ะตะดะฐะตะผ ะตะณะพ ะฒ ั€ะตะปะธะท
      --set "global.ci_timeout=${CI_TIMEOUT:-900}"
     --timeout ${CI_TIMEOUT:-900}
  dependencies:
    - Build

.test-base: &test-base
  extends: .base_deploy
  before_script:
# ัะพะทะดะฐะตะผ ะดะธั€ะตะบั‚ะพั€ะธัŽ ะดะปั ะฑัƒะดัƒั‰ะตะณะพ ะพั‚ั‡ะตั‚ะฐ, ะธัั…ะพะดั ะธะท $CI_COMMIT_REF_SLUG
    - mkdir /mnt/tests/${CI_COMMIT_REF_SLUG} || true
# ะฒั‹ะฝัƒะถะดะตะฝะฝั‹ะน ะบะพัั‚ั‹ะปัŒ, ั‚.ะบ. GitLab ั…ะพั‡ะตั‚ ะฟะพะปัƒั‡ะธั‚ัŒ ะฐั€ั‚ะตั„ะฐะบั‚ั‹ ะฒ ัะฒะพะตะผ build-dirโ€™ะต
    - mkdir ./tests || true
    - ln -s /mnt/tests/${CI_COMMIT_REF_SLUG} ./tests/${CI_COMMIT_REF_SLUG}
  after_script:
# ะฟะพัะปะต ะพะบะพะฝั‡ะฐะฝะธั ั‚ะตัั‚ะพะฒ ัƒะดะฐะปัะตะผ ั€ะตะปะธะท ะฒะผะตัั‚ะต ั Jobโ€™ะพะผ
# (ะธ, ะฒะพะทะผะพะถะฝะพ, ะตะณะพ ะธะฝั„ั€ะฐัั‚ั€ัƒะบั‚ัƒั€ะพะน)
    - type multiwerf && source <(multiwerf use ${WERF_VERSION})
    - werf version
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - werf dismiss --namespace ${CI_ENVIRONMENT_SLUG} --with-namespace
# ะผั‹ ั€ะฐะทั€ะตัˆะฐะตะผ ะฟะฐะดะตะฝะธั, ะฝะพ ะฒั‹ ะผะพะถะตั‚ะต ัะดะตะปะฐั‚ัŒ ะธะฝะฐั‡ะต
  allow_failure: true
  variables:
    RUN_TESTS: 'yes'
# ะทะฐะดะฐะตะผ ะบะพะฝั‚ะตะบัั‚ ะฒ werf
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#infrastructure)
    WERF_KUBE_CONTEXT: 'admin@stage-cluster'
  tags:
# ะธัะฟะพะปัŒะทัƒะตะผ ั€ะฐะฝะฝะตั€ ั ั‚ะตะณะพะผ `werf-runner`
    - werf-runner
  artifacts:
# ั‚ั€ะตะฑัƒะตั‚ัั ัะพะฑั€ะฐั‚ัŒ ะฐั€ั‚ะตั„ะฐะบั‚ ะดะปั ั‚ะพะณะพ, ั‡ั‚ะพะฑั‹ ะตะณะพ ะผะพะถะฝะพ ะฑั‹ะปะพ ัƒะฒะธะดะตั‚ัŒ
# ะฒ ะฟะฐะนะฟะปะฐะนะฝะต ะธ ัะบะฐั‡ะฐั‚ัŒ โ€” ะฝะฐะฟั€ะธะผะตั€, ะดะปั ะฑะพะปะตะต ะฒะดัƒะผั‡ะธะฒะพะณะพ ะธะทัƒั‡ะตะฝะธั
    paths:
      - ./tests/${CI_COMMIT_REF_SLUG}/*
# ะฐั€ั‚ะตั„ะฐะบั‚ั‹ ัั‚ะฐั€ัˆะต ะฝะตะดะตะปะธ ะฑัƒะดัƒั‚ ัƒะดะฐะปะตะฝั‹
    expire_in: 7 day
# ะฒะฐะถะฝะพ: ัั‚ะธ ัั‚ั€ะพะบะธ ะพั‚ะฒะตั‡ะฐัŽั‚ ะทะฐ ะฟะฐั€ัะธะฝะณ ะพั‚ั‡ะตั‚ะฐ GitLabโ€™ะพะผ
    reports:
      junit: ./tests/${CI_COMMIT_REF_SLUG}/report.xml

# ะดะปั ัƒะฟั€ะพั‰ะตะฝะธั ะทะดะตััŒ ะฟะพะบะฐะทะฐะฝั‹ ะฒัะตะณะพ ะดะฒะต ัั‚ะฐะดะธะธ
# ะฒ ั€ะตะฐะปัŒะฝะพัั‚ะธ ะถะต ัƒ ะฒะฐั ะธั… ะฑัƒะดะตั‚ ะฑะพะปัŒัˆะต โ€” ะบะฐะบ ะผะธะฝะธะผัƒะผ ะธะท-ะทะฐ ะดะตะฟะปะพั
stages:
  - build
  - tests

build:
  stage: build
  script:
# ัะฑะพั€ะบะฐ โ€” ัะฝะพะฒะฐ ะฟะพ ะดะพะบัƒะผะตะฝั‚ะฐั†ะธะธ ะฟะพ werf
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#build-stage)
    - type multiwerf && source <(multiwerf use ${WERF_VERSION})
    - werf version
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - werf build-and-publish --stages-storage :local
  tags:
    - werf-runner
  except:
    - schedules

run tests:
  <<: *test-base
  environment:
# "ัะฐะผะฐ ัะพะปัŒ" ะธะผะตะฝะพะฒะฐะฝะธั namespaceโ€™ะฐ
# (https://docs.gitlab.com/ce/ci/variables/predefined_variables.html)
    name: tests-${CI_COMMIT_REF_SLUG}
  stage: tests
  except:
    - schedules

เจ•เจฌเจฐเจจเฉ‡เจŸเจฟเจธ

เจนเฉเจฃ เจกเจพเจ‡เจฐเฉˆเจ•เจŸเจฐเฉ€ เจตเจฟเฉฑเจš .helm/templates เจ†เจ“ เจœเฉŒเจฌ เจจเจพเจฒ YAML เจฌเจฃเจพเจˆเจ - tests-job.yaml โ€” เจŸเฉˆเจธเจŸเจพเจ‚ เจ…เจคเฉ‡ เจ•เฉเจฌเจฐเจจเฉ‡เจŸเจธ เจธเจฐเฉ‹เจคเจพเจ‚ เจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃ เจฒเจˆ เจ‡เจธเจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค เจธเฉ‚เจšเฉ€เจฌเฉฑเจง เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจธเจชเฉฑเจธเจผเจŸเฉ€เจ•เจฐเจจ เจตเฉ‡เจ–เฉ‹:

{{- if eq .Values.global.run_tests "yes" }}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: tests-script
data:
  tests.sh: |
    echo "======================"
    echo "${APP_NAME} TESTS"
    echo "======================"

    cd /app
    npm run test:ci
    cp report.xml /app/test_results/${CI_COMMIT_REF_SLUG}/

    echo ""
    echo ""
    echo ""

    chown -R 999:999 /app/test_results/${CI_COMMIT_REF_SLUG}
---
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Chart.Name }}-test
  annotations:
    "helm.sh/hook": post-install,post-upgrade
    "helm.sh/hook-weight": "2"
    "werf/watch-logs": "true"
spec:
  activeDeadlineSeconds: {{ .Values.global.ci_timeout }}
  backoffLimit: 1
  template:
    metadata:
      name: {{ .Chart.Name }}-test
    spec:
      containers:
      - name: test
        command: ['bash', '-c', '/app/tests.sh']
{{ tuple "application" . | include "werf_container_image" | indent 8 }}
        env:
        - name: env
          value: {{ .Values.global.env }}
        - name: CI_COMMIT_REF_SLUG
          value: {{ .Values.global.commit_ref_slug }}
       - name: APP_NAME
          value: {{ .Chart.Name }}
{{ tuple "application" . | include "werf_container_env" | indent 8 }}
        volumeMounts:
        - mountPath: /app/test_results/
          name: data
        - mountPath: /app/tests.sh
          name: tests-script
          subPath: tests.sh
      tolerations:
      - key: dedicated
        operator: Exists
      - key: node-role.kubernetes.io/master
        operator: Exists
      restartPolicy: OnFailure
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: {{ .Chart.Name }}-pvc
      - name: tests-script
        configMap:
          name: tests-script
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{ .Chart.Name }}-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Mi
  storageClassName: {{ .Chart.Name }}-{{ .Values.global.commit_ref_slug }}
  volumeName: {{ .Values.global.commit_ref_slug }}

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: {{ .Values.global.commit_ref_slug }}
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Mi
  local:
    path: /mnt/tests/
  nodeAffinity:
   required:
     nodeSelectorTerms:
     - matchExpressions:
       - key: kubernetes.io/hostname
         operator: In
         values:
         - kube-master
  persistentVolumeReclaimPolicy: Delete
  storageClassName: {{ .Chart.Name }}-{{ .Values.global.commit_ref_slug }}
{{- end }}

เจ•เจฟเจธ เจ•เจฟเจธเจฎ เจฆเฉ‡ เจธเจฐเฉ‹เจค เจ‡เจธ เจธเฉฐเจฐเจšเจจเจพ เจตเจฟเฉฑเจš เจฆเฉฑเจธเจฟเจ† เจ—เจฟเจ† เจนเฉˆ? เจคเฉˆเจจเจพเจค เจ•เจฐเจฆเฉ‡ เจธเจฎเฉ‡เจ‚, เจ…เจธเฉ€เจ‚ เจชเฉเจฐเฉ‹เจœเฉˆเจ•เจŸ เจฒเจˆ เจ‡เฉฑเจ• เจตเจฟเจฒเฉฑเจ–เจฃ เจจเฉ‡เจฎเจธเจชเฉ‡เจธ เจฌเจฃเจพเจ‰เจ‚เจฆเฉ‡ เจนเจพเจ‚ (เจ‡เจน เจ‡เจธ เจตเจฟเฉฑเจš เจฆเจฐเจธเจพเจ‡เจ† เจ—เจฟเจ† เจนเฉˆ .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) เจ…เจคเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ เจฐเฉ‹เจฒ เจ†เจŠเจŸ เจ•เจฐเฉ‹:

  1. ConfigMap เจŸเฉˆเจธเจŸ เจธเจ•เฉเจฐเจฟเจชเจŸ เจฆเฉ‡ เจจเจพเจฒ;
  2. เจ…เฉฑเจฏเฉ‚เจฌ เจชเฉŒเจก เจฆเฉ‡ เจตเจฐเจฃเจจ เจ…เจคเฉ‡ เจจเจฟเจฐเจงเจพเจฐเจค เจจเจฟเจฐเจฆเฉ‡เจธเจผเจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ command, เจœเฉ‹ เจธเจฟเจฐเจซ เจŸเฉˆเจธเจŸ เจšเจฒเจพเจ‰เจ‚เจฆเจพ เจนเฉˆ;
  3. เจชเฉ€เจตเฉ€ เจ…เจคเฉ‡ เจชเฉ€เจตเฉ€เจธเฉ€, เจœเฉ‹ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจŸเฉˆเจธเจŸ เจกเฉ‡เจŸเจพ เจธเจŸเฉ‹เจฐ เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆเฅค

เจฆเฉ‡ เจจเจพเจฒ เจธเจผเฉเจฐเฉ‚เจ†เจคเฉ€ เจธเจฅเจฟเจคเฉ€ เจตเฉฑเจฒ เจงเจฟเจ†เจจ เจฆเจฟเจ“ if เจฎเฉˆเจจเฉ€เจซเฉˆเจธเจŸ เจฆเฉ‡ เจธเจผเฉเจฐเฉ‚ เจตเจฟเฉฑเจš - เจ‡เจธเจฆเฉ‡ เจ…เจจเฉเจธเจพเจฐ, เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจฆเฉ‡ เจจเจพเจฒ เจนเฉˆเจฒเจฎ เจšเจพเจฐเจŸ เจฆเฉ€เจ†เจ‚ เจนเฉ‹เจฐ YAML เจซเจพเจˆเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจฒเจชเฉ‡เจŸเจฟเจ† เจœเจพเจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ เจ‰เจฒเจŸเจพ เจกเจฟเจœเจผเจพเจ‡เจจ เจคเจพเจ‚ เจœเฉ‹ เจ‰เจน เจŸเฉˆเจธเจŸเจฟเฉฐเจ— เจฆเฉŒเจฐเจพเจจ เจคเจพเจ‡เจจเจพเจค เจจเจพ เจนเฉ‹เจฃเฅค เจœเฉ‹ เจ•เจฟ เจนเฉˆ:

{{- if ne .Values.global.run_tests "yes" }}
---
ั ะดั€ัƒะณะพะน ัะผะปะธะบ
{{- end }}

เจชเจฐ, เจœเฉ‡เจ•เจฐ เจŸเฉˆเจธเจŸ เจ•เฉเจ เจฌเฉเจจเจฟเจ†เจฆเฉ€ เจขเจพเจ‚เจšเฉ‡ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ (เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, Redis, RabbitMQ, Mongo, PostgreSQL...) - เจ‰เจนเจจเจพเจ‚ เจฆเฉ‡ YAML เจนเฉ‹ เจธเจ•เจฆเฉ‡ เจนเจจ เจจเจพ เจฌเฉฐเจฆ เจ•เจฐ เจฆเจฟเจ“. เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจŸเฉˆเจธเจŸ เจตเจพเจคเจพเจตเจฐเจจ เจตเจฟเฉฑเจš เจตเฉ€ เจคเฉˆเจจเจพเจค เจ•เจฐเฉ‹... เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจฌเจฃเจพเจ“ เจœเจฟเจตเฉ‡เจ‚ เจคเฉเจธเฉ€เจ‚ เจ เฉ€เจ• เจธเจฎเจเจฆเฉ‡ เจนเฉ‹, เจฌเฉ‡เจธเจผเจ•เฅค

เจ…เฉฐเจคเจฎ เจ›เฉ‚เจน

เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ…เจธเฉˆเจ‚เจฌเจฒเฉ€ เจ…เจคเฉ‡ เจคเฉˆเจจเจพเจคเฉ€ เจนเฉเจฃ เจฒเจˆ เจตเจฐเจซ เจตเจฐเจ•เจธ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจธเจฟเจฐเจซ เจฌเจฟเจฒเจก เจธเจฐเจตเจฐ 'เจคเฉ‡ (เจ—เจฟเจŸเจฒเจฌ-เจฐเจจเจฐ เจฆเฉ‡ เจจเจพเจฒ), เจ…เจคเฉ‡ เจŸเฉˆเจธเจŸเจพเจ‚ เจตเจพเจฒเจพ เจชเฉŒเจก เจฎเจพเจธเจŸเจฐ 'เจคเฉ‡ เจฒเจพเจ‚เจš เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆ, เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจกเจพเจ‡เจฐเฉˆเจ•เจŸเจฐเฉ€ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉ‹เจตเฉ‡เจ—เฉ€เฅค /mnt/tests เจฎเจพเจธเจŸเจฐ 'เจคเฉ‡ เจ…เจคเฉ‡ เจ‡เจธ เจจเฉ‚เฉฐ เจฆเฉŒเฉœเจพเจ• เจจเฉ‚เฉฐ เจฆเฉ‡ เจฆเจฟเจ“, เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, NFS เจฐเจพเจนเฉ€เจ‚. เจตเจฟเจ†เจ–เจฟเจ† เจฆเฉ‡ เจจเจพเจฒ เจ‡เฉฑเจ• เจตเจฟเจธเจคเฉเจฐเจฟเจค เจ‰เจฆเจพเจนเจฐเจจ เจตเจฟเฉฑเจš เจชเจพเจ‡เจ† เจœเจพ เจธเจ•เจฆเจพ เจนเฉˆ K8s เจฆเจธเจคเจพเจตเฉ‡เจœเจผ.

เจจเจคเฉ€เจœเจพ เจ‡เจน เจนเฉ‹เจตเฉ‡เจ—เจพ:

user@kube-master:~$ cat /etc/exports | grep tests
/mnt/tests    IP_gitlab-builder/32(rw,nohide,insecure,no_subtree_check,sync,all_squash,anonuid=999,anongid=998)

user@gitlab-runner:~$ cat /etc/fstab | grep tests
IP_kube-master:/mnt/tests    /mnt/tests   nfs4    _netdev,auto  0       0

เจ•เฉ‹เจˆ เจตเฉ€ เจ—เจฟเจŸเจฒเฉˆเจฌ-เจฐเจจเจฐ 'เจคเฉ‡ เจธเจฟเฉฑเจงเฉ‡ NFS เจธเจผเฉ‡เจ…เจฐ เจฌเจฃเจพเจ‰เจฃ, เจ…เจคเฉ‡ เจซเจฟเจฐ เจ‡เจธเจจเฉ‚เฉฐ เจชเฉŒเจกเจพเจ‚ เจตเจฟเฉฑเจš เจฎเจพเจŠเจ‚เจŸ เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฎเจจเฉเจนเจพ เจ•เจฐเจฆเจพ เจนเฉˆเฅค

เจŸเจฟเฉฑเจชเจฃเฉ€

เจคเฉเจธเฉ€เจ‚ เจธเจผเจพเจ‡เจฆ เจชเฉเฉฑเจ› เจฐเจนเฉ‡ เจนเฉ‹เจตเฉ‹เจ—เฉ‡ เจ•เจฟ เจœเฉ‡ เจคเฉเจธเฉ€เจ‚ เจธเจผเฉˆเฉฑเจฒ เจฐเจจเจฐ 'เจคเฉ‡ เจธเจฟเฉฑเจงเฉ‡ เจŸเฉˆเจธเจŸเจพเจ‚ เจจเจพเจฒ เจธเจ•เฉเจฐเจฟเจชเจŸ เจšเจฒเจพ เจธเจ•เจฆเฉ‡ เจนเฉ‹ เจคเจพเจ‚ เจจเฉŒเจ•เจฐเฉ€ เจฌเจฃเจพ เจ•เฉ‡ เจนเจฐ เจšเฉ€เจœเจผ เจจเฉ‚เฉฐ เจ•เจฟเจ‰เจ‚ เจ—เฉเฉฐเจเจฒเจฆเจพเจฐ เจฌเจฃเจพเจ‰? เจœเจตเจพเจฌ เจฌเจนเฉเจค เจฎเจพเจฎเฉ‚เจฒเฉ€ เจนเฉˆ ...

เจ•เฉเจ เจŸเฉˆเจธเจŸเจพเจ‚ เจจเฉ‚เฉฐ เจ‡เจน เจชเฉเจธเจผเจŸเฉ€ เจ•เจฐเจจ เจฒเจˆ เจฌเฉเจจเจฟเจ†เจฆเฉ€ เจขเจพเจ‚เจšเฉ‡ (MongoDB, RabbitMQ, PostgreSQL, เจ†เจฆเจฟ) เจคเฉฑเจ• เจชเจนเฉเฉฐเจš เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆ เจ•เจฟ เจ‰เจน เจธเจนเฉ€ เจขเฉฐเจ— เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจฆเฉ‡ เจนเจจเฅค เจ…เจธเฉ€เจ‚ เจŸเฉˆเจธเจŸเจฟเฉฐเจ— เจจเฉ‚เฉฐ เจเจ•เฉ€เจ•เฉเจฐเจฟเจค เจฌเจฃเจพเจ‰เจ‚เจฆเฉ‡ เจนเจพเจ‚ - เจ‡เจธ เจชเจนเฉเฉฐเจš เจจเจพเจฒ, เจ…เจœเจฟเจนเฉ€เจ†เจ‚ เจตเจพเจงเฉ‚ เจ‡เจ•เจพเจˆเจ†เจ‚ เจจเฉ‚เฉฐ เจธเจผเจพเจฎเจฒ เจ•เจฐเจจเจพ เจ†เจธเจพเจจ เจนเฉ‹ เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค เจ‡เจธ เจคเฉ‹เจ‚ เจ‡เจฒเจพเจตเจพ, เจ…เจธเฉ€เจ‚ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚ เจฎเจฟเจ†เจฐเฉ€ เจคเฉˆเจจเจพเจคเฉ€ เจชเจนเฉเฉฐเจš (เจญเจพเจตเฉ‡เจ‚ NFS เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ, เจกเจพเจ‡เจฐเฉˆเจ•เจŸเจฐเฉ€เจ†เจ‚ เจฆเฉ€ เจตเจพเจงเฉ‚ เจฎเจพเจŠเจ‚เจŸเจฟเฉฐเจ—)เฅค

เจ‡เจธ เจฆเจพ เจจเจคเฉ€เจœเจพ

เจœเจฆเฉ‹เจ‚ เจ…เจธเฉ€เจ‚ เจคเจฟเจ†เจฐ เจ•เฉ€เจคเฉ€ เจธเฉฐเจฐเจšเจจเจพ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚ เจคเจพเจ‚ เจ…เจธเฉ€เจ‚ เจ•เฉ€ เจฆเฉ‡เจ–เจพเจ‚เจ—เฉ‡?

เจฐเจฒเฉ‡เจตเฉ‡เจ‚ เจฆเฉ€ เจฌเฉ‡เจจเจคเฉ€ เจ‡เจธเจฆเฉ€ เจจเจตเฉ€เจจเจคเจฎ เจชเจพเจˆเจชเจฒเจพเจˆเจจ เจตเจฟเฉฑเจš เจšเฉฑเจฒ เจฐเจนเฉ‡ เจŸเฉˆเจธเจŸเจพเจ‚ เจฒเจˆ เจธเฉฐเจ–เฉ‡เจช เจ…เฉฐเจ•เฉœเฉ‡ เจฆเจฟเจ–เจพเจเจ—เฉ€:

เจ•เฉเจฌเจฐเจจเฉ‡เจŸเจธ เจฆเฉ‡ เจจเจพเจฒ GitLab CI เจตเจฟเฉฑเจš JUnit

เจตเฉ‡เจฐเจตเจฟเจ†เจ‚ เจฒเจˆ เจนเจฐเฉ‡เจ• เจ—เจฒเจคเฉ€ เจจเฉ‚เฉฐ เจ‡เฉฑเจฅเฉ‡ เจ•เจฒเจฟเฉฑเจ• เจ•เฉ€เจคเจพ เจœเจพ เจธเจ•เจฆเจพ เจนเฉˆ:

เจ•เฉเจฌเจฐเจจเฉ‡เจŸเจธ เจฆเฉ‡ เจจเจพเจฒ GitLab CI เจตเจฟเฉฑเจš JUnit

NB: เจงเจฟเจ†เจจ เจฆเฉ‡เจฃ เจตเจพเจฒเฉ‡ เจชเจพเจ เจ• เจ‡เจน เจจเฉ‹เจŸเจฟเจธ เจ•เจฐเจจเจ—เฉ‡ เจ•เจฟ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• NodeJS เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจฆเฉ€ เจœเจพเจ‚เจš เจ•เจฐ เจฐเจนเฉ‡ เจนเจพเจ‚, เจ…เจคเฉ‡ เจธเจ•เฉเจฐเฉ€เจจเจธเจผเฉŒเจŸเจธ เจตเจฟเฉฑเจš - .NET... เจนเฉˆเจฐเจพเจจ เจจเจพ เจนเฉ‹เจตเฉ‹: เจฌเจธ เจ‡เจน เจนเฉˆ เจ•เจฟ เจฒเฉ‡เจ– เจจเฉ‚เฉฐ เจคเจฟเจ†เจฐ เจ•เจฐเจฆเฉ‡ เจธเจฎเฉ‡เจ‚, เจชเจนเจฟเจฒเฉ€ เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจ เจฆเฉ€ เจœเจพเจ‚เจš เจตเจฟเฉฑเจš เจ•เฉ‹เจˆ เจ—เจฒเจคเฉ€ เจจเจนเฉ€เจ‚ เจชเจพเจˆ เจ—เจˆ, เจชเจฐ เจ‰เจน เจฆเฉ‚เจœเฉ‡ เจตเจฟเฉฑเจš เจชเจพเจ เจ—เจ เจธเจจเฅค

เจธเจฟเฉฑเจŸเจพ

เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ เจคเฉเจธเฉ€เจ‚ เจฆเฉ‡เจ– เจธเจ•เจฆเฉ‡ เจนเฉ‹, เจ•เฉเจ เจตเฉ€ เจ—เฉเฉฐเจเจฒเจฆเจพเจฐ เจจเจนเฉ€เจ‚ เจนเฉˆ!

เจธเจฟเจงเจพเจ‚เจคเจ• เจคเฉŒเจฐ 'เจคเฉ‡, เจœเฉ‡เจ•เจฐ เจคเฉเจนเจพเจกเฉ‡ เจ•เฉ‹เจฒ เจชเจนเจฟเจฒเจพเจ‚ เจนเฉ€ เจธเจผเฉˆเฉฑเจฒ เจ•เฉเจฒเฉˆเจ•เจŸเจฐ เจนเฉˆ เจ…เจคเฉ‡ เจ‡เจน เจ•เฉฐเจฎ เจ•เจฐเจฆเจพ เจนเฉˆ, เจชเจฐ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ•เฉเจฌเจฐเจจเฉ‡เจŸเจธ เจฆเฉ€ เจฒเฉ‹เฉœ เจจเจนเฉ€เจ‚ เจนเฉˆ, เจคเจพเจ‚ เจ‡เจธ เจจเจพเจฒ เจŸเฉˆเจธเจŸเจฟเฉฐเจ— เจจเฉ‚เฉฐ เจœเฉ‹เฉœเจจเจพ เจ‡เฉฑเจฅเฉ‡ เจฆเฉฑเจธเฉ‡ เจ—เจ เจจเจพเจฒเฉ‹เจ‚ เจตเฉ€ เจธเฉŒเจ–เจพ เจ•เฉฐเจฎ เจนเฉ‹เจตเฉ‡เจ—เจพเฅค เจ…เจคเฉ‡ เจตเจฟเฉฑเจš GitLab CI เจฆเจธเจคเจพเจตเฉ‡เจœเจผ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจฐเฉ‚เจฌเฉ€, เจ—เฉ‹, เจ—เฉเจฐเฉ‡เจกเจฒ, เจฎเจพเจตเฉ‡เจจ เจ…เจคเฉ‡ เจ•เฉเจ เจนเฉ‹เจฐ เจฒเจˆ เจ‰เจฆเจพเจนเจฐเจฃเจพเจ‚ เจฎเจฟเจฒเจฃเจ—เฉ€เจ†เจ‚เฅค

PS

เจธเจพเจกเฉ‡ เจฌเจฒเฉŒเจ— 'เจคเฉ‡ เจตเฉ€ เจชเฉœเฉเจนเฉ‹:

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹