JUnit ืื™ืŸ GitLab CI ืžื™ื˜ Kubernetes

ื˜ืจืึธืฅ ื“ืขืจ ืคืึทืงื˜ ืึทื– ืึทืœืขืžืขืŸ ื•ื•ื™ื™ืกื˜ ื‘ื™ืฉืœื™ื™ืžืขืก ืึทื– ื˜ืขืกื˜ื™ื ื’ ื“ื™ื™ืŸ ื•ื•ื™ื™ื›ื•ื•ืืจื’ ืื™ื– ื•ื•ื™ื›ื˜ื™ืง ืื•ืŸ ื ื™ื™ื˜ื™ืง, ืื•ืŸ ืคื™ืœืข ื”ืึธื‘ืŸ ืฉื•ื™ืŸ ื˜ืืŸ ืขืก ืื•ื™ื˜ืึธืžืึทื˜ื™ืฉ ืคึฟืึทืจ ืึท ืœืึทื ื’ ืฆื™ื™ึทื˜, ืื™ืŸ ื“ื™ ื•ื•ืึทืกื˜ื ืึทืก ืคื•ืŸ Habr ืขืก ืื™ื– ื ื™ืฉื˜ ืึท ืื™ื™ืŸ ืจืขืฆืขืคึผื˜ ืคึฟืึทืจ ื‘ืึทืฉื˜ืขื˜ื™ืงืŸ ืึท ืงืึธืžื‘ื™ื ืึทืฆื™ืข ืคื•ืŸ โ€‹โ€‹โ€‹โ€‹ืึทื–ืึท ืคืึธืœืงืก ืคึผืจืึธื“ื•ืงื˜ืŸ ืื™ืŸ ื“ืขื ื ื™ืฉืข ื•ื•ื™ (ืื•ื ื“ื–ืขืจ ื‘ืึทืœื™ื‘ืกื˜ืข) GitLab ืื•ืŸ JUnit. ืœืึธืžื™ืจ ืึธื ืคื™ืœืŸ ื“ืขื ืจื™ืก!

JUnit ืื™ืŸ GitLab CI ืžื™ื˜ Kubernetes

ื™ื ื˜ืจืึทื“ืึทืงื˜ืขืจื™

ืขืจืฉื˜ืขืจ, ืœืึธื–ืŸ ืžื™ืจ ื’ืขื‘ืŸ ืขื˜ืœืขื›ืข ืงืึธื ื˜ืขืงืกื˜:

  • ื–ื™ื ื˜ ืึทืœืข ืื•ื ื“ื–ืขืจ ืึทืคึผืœืึทืงื™ื™ืฉืึทื ื– ืœื•ื™ืคืŸ ืื•ื™ืฃ Kubernetes, ืžื™ืจ ื•ื•ืขืœืŸ ื‘ืึทื˜ืจืึทื›ื˜ืŸ ืคืœื™ืกื ื“ื™ืง ื˜ืขืกืฅ ืื•ื™ืฃ ื“ื™ ืฆื•ื ืขืžืขืŸ ื™ื ืคืจืึทืกื˜ืจืึทืงื˜ืฉืขืจ.
  • ืคึฟืึทืจ ืคึฟืึทืจื–ืึทืžืœื•ื ื’ ืื•ืŸ ื“ื™ืคึผืœื•ื™ืžืึทื ื˜ ืžื™ืจ ื ื•ืฆืŸ werf (ืื™ืŸ ื˜ืขืจืžื™ื ืขืŸ ืคื•ืŸ ื™ื ืคืจืึทืกื˜ืจืึทืงื˜ืฉืขืจ ืงืึทืžืคึผืึธื•ื ืึทื ืฅ, ื“ืึธืก ืื•ื™ืš ืื•ื™ื˜ืึธืžืึทื˜ื™ืฉ ืžื™ื˜ืœ ืึทื– ื”ืขืœื ืื™ื– ื™ื ื•ื•ืึทืœื•ื•ื“).
  • ืื™ืš ื•ื•ืขืœ ื ื™ืฉื˜ ื’ื™ื™ืŸ ืื™ืŸ ื“ื™ ื“ืขื˜ืึทื™ืœืก ืคื•ืŸ ื“ื™ ืคืึทืงื˜ื™ืฉ ืฉืึทืคื•ื ื’ ืคื•ืŸ ื˜ืขืกืฅ: ืื™ืŸ ืื•ื ื“ื–ืขืจ ืคืึทืœ, ื“ืขืจ ืงืœื™ืขื ื˜ ืฉืจื™ื™ื‘ื˜ ื“ื™ ื˜ืขืกืฅ ื–ื™ืš, ืื•ืŸ ืžื™ืจ ื ืึธืจ ืขื ืฉื•ืจ ื–ื™ื™ืขืจ ืงืึทื˜ืขืจ (ืื•ืŸ ื“ื™ ื‘ื™ื™ึทื–ื™ื™ึทืŸ ืคื•ืŸ ืึท ืงืึธืจืึทืกืคึผืึทื ื“ื™ื ื’ ื‘ืึทืจื™ื›ื˜ ืื™ืŸ ื“ื™ ืฆื•ื ื•ื™ืคื’ื™ืกืŸ ื‘ืขื˜ืŸ).


ื•ื•ื™ ื•ื•ืขื˜ ื“ืขืจ ื’ืขื ืขืจืึทืœ ืกื™ืงื•ื•ืึทื ืก ืคื•ืŸ ืึทืงืฉืึทื ื– ืงื•ืงืŸ ื•ื•ื™?

  1. ื‘ื•ื™ืขืŸ ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ - ืžื™ืจ ื•ื•ืขืœืŸ ืคืึทืจืœืึธื–ืŸ ื“ื™ ื‘ืึทืฉืจื™ื™ึทื‘ื•ื ื’ ืคื•ืŸ ื“ืขื ื‘ื™ื ืข.
  2. ืฆืขื•ื•ื™ืงืœืขืŸ ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืฆื• ืึท ื‘ืึทื–ื•ื ื“ืขืจ ื ืึธืžืขืŸ ืคื•ืŸ ื“ื™ Kubernetes ืงื ื•ื™ืœ ืื•ืŸ ืึธื ื”ื™ื™ื‘ืŸ ื˜ืขืกื˜ื™ื ื’.
  3. ื–ื•ื›ืŸ ืคึฟืึทืจ ืึทืจื˜ืึทืคืึทืงืฅ ืื•ืŸ ืคึผืึทืจืกื™ื ื’ JUnit ืจื™ืคึผืึธืจืฅ ืžื™ื˜ GitLab.
  4. ื“ื™ืœื™ื˜ื™ื ื’ ืึท ืคืจื™ืขืจ ื‘ืืฉืืคืŸ ื ืึทืžืขืกืคึผืึทืกืข.

ืื™ืฆื˜ - ืฆื• ื™ืžืคึผืœืึทืžืขื ื˜ื™ื™ืฉืึทืŸ!

Customize

ื’ื™ื˜ืœืึทื‘ ืกื™

ืœืึธืžื™ืจ ืึธื ื”ื™ื™ื‘ืŸ ืžื™ื˜ ืึท ืคืจืึทื’ืžืขื ื˜ .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

Kubernetes

ืื™ืฆื˜ ืื™ืŸ ื“ืขืจ ื•ื•ืขื’ื•ื•ื™ื™ึทื–ืขืจ .helm/templates ืœืึธืžื™ืจ ืžืึทื›ืŸ YAML ืžื™ื˜ ื“ื–ืฉืึธื‘ - tests-job.yaml - ืฆื• ืœื•ื™ืคืŸ ื˜ืขืกืฅ ืื•ืŸ ื“ื™ Kubernetes ืจืขืกื•ืจืกืŸ ืขืก ื“ืึทืจืฃ. ื–ืขืŸ ื“ืขืจืงืœืขืจื•ื ื’ืขืŸ ื ืึธืš ืœื™ืกื˜ื™ื ื’:

{{- 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. ืงืึธื ืคื™ื’ืžืึทืคึผ ืžื™ื˜ ืคึผืจื•ื‘ื™ืจืŸ ืฉืจื™ืคื˜;
  2. ืึทืจื‘ืขื˜ ืžื™ื˜ ืึท ื‘ืึทืฉืจื™ื™ึทื‘ื•ื ื’ ืคื•ืŸ ื“ื™ ืคึผืึธื“ ืื•ืŸ ื“ื™ ืกืคึผืขืกื™ืคื™ืขื“ ื“ื™ืจืขืงื˜ื™ื•ื• command, ื•ื•ืึธืก ื ืึธืจ ืœื•ื™ืคื˜ ื“ื™ ื˜ืขืกืฅ;
  3. ืคึผื•ื•ืง ืื•ืŸ ืคึผื•ื•ืง, ื•ื•ืึธืก ืœืึธื–ืŸ ืื™ืจ ืฆื• ืงืจืึธื ืคึผืจื•ื‘ื™ืจืŸ ื“ืึทื˜ืŸ.

ื‘ืึทืฆืึธืœืŸ ื•ืคืžืขืจืงื–ืึทืžืงื™ื™ึทื˜ ืฆื• ื“ื™ ื™ื ื˜ืจืึทื“ืึทืงื˜ืขืจื™ ืฆื•ืฉื˜ืึทื ื“ ืžื™ื˜ if ืื™ืŸ ื“ื™ ืึธื ื”ื™ื™ื‘ ืคื•ืŸ ื“ื™ ื‘ืึทืฉื™ื™ึทืžืคึผืขืจืœืขืš - ืึทืงืึธืจื“ื™ื ื’ืœื™, ืื ื“ืขืจืข YAML ื˜ืขืงืขืก ืคื•ืŸ ื“ื™ ื”ืขืœื ื˜ืฉืึทืจื˜ ืžื™ื˜ ื“ื™ ืึทืคึผืœืึทืงื™ื™ืฉืึทืŸ ืžื•ื–ืŸ ื–ื™ื™ืŸ ืืœื ื’ืขื•ื•ื™ืงืœื˜ ืื™ืŸ ืคืึทืจืงืขืจื˜ ืคึผืœืึทืŸ ืึทื–ื•ื™ ืึทื– ื–ื™ื™ ื˜ืึธืŸ ื ื™ื˜ ื‘ืึทืงื•ืžืขืŸ ื“ื™ืคึผืœื•ื™ื“ ื‘ืขืฉืึทืก ื˜ืขืกื˜ื™ื ื’. ื“ืืก ืื™ื–:

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

ืึธื‘ืขืจ, ืื•ื™ื‘ ื“ื™ ื˜ืขืกืฅ ื“ืึทืจืคืŸ ืขื˜ืœืขื›ืข ื™ื ืคืจืึทืกื˜ืจืึทืงื˜ืฉืขืจ (ืœืžืฉืœ, Redis, RabbitMQ, Mongo, PostgreSQL ...) - ื–ื™ื™ืขืจ ื™ืึทืžืœืก ืงืขื ืขืŸ ื–ื™ื™ืŸ ืงื™ื™ืŸ ืœืขืฉ ืื•ื™ืก. ืฆืขื•ื•ื™ืงืœืขืŸ ื–ื™ื™ ืื•ื™ืš ืื™ืŸ ืึท ืคึผืจืึธื‘ืข ืกื•ื•ื™ื•ื•ืข ... ืึทื“ื–ืฉืึทืกื˜ื™ื ื’ ื–ื™ื™ ื•ื•ื™ ืื™ืจ ื–ืขืŸ ืคึผืึทืกื™ืง, ืคื•ืŸ ืœื•ื™ืฃ.

ืœืขืฆื˜ ืคืึทืจื‘ื™ื ื“ืŸ

ื•ื•ื™ื™ึทืœ ืคึฟืึทืจื–ืึทืžืœื•ื ื’ ืื•ืŸ ื“ื™ืคึผืœื•ื™ืžืึทื ื˜ ื ื™ืฆืŸ werf ืื™ื– ื ืึธืš ืืจื‘ืขื˜ืŸ ื‘ืœื•ื™ื– ืื•ื™ืฃ ื“ื™ ื‘ื•ื™ืขืŸ ืกืขืจื•ื•ืขืจ (ืžื™ื˜ ื’ื™ื˜ืœืึทื‘-ืจืึทื ืขืจ), ืื•ืŸ ื“ื™ ืคึผืึธื“ ืžื™ื˜ ื˜ืขืกืฅ ืื™ื– ืœืึธื ื˜ืฉื˜ ืื•ื™ืฃ ื“ื™ ื‘ืขืœ, ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืฉืึทืคึฟืŸ ืึท ื•ื•ืขื’ื•ื•ื™ื™ึทื–ืขืจ /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, ื ืึธืš ืžืึทื•ื ื˜ื™ื ื’ ืคื•ืŸ ื“ื™ืจืขืงื˜ืขืจื™ื–).

ื˜ืึทื›ืœืขืก

ื•ื•ืึธืก ื•ื•ืขื˜ ืžื™ืจ ื–ืขืŸ ื•ื•ืขืŸ ืžื™ืจ ืฆื•ืœื™ื™ื’ืŸ ื“ื™ ืฆื•ื’ืขื’ืจื™ื™ื˜ ืงืึทื ืคื™ื’ื™ืขืจื™ื™ืฉืึทืŸ?

ื“ื™ ืฆื•ื ื•ื™ืคื’ื™ืกืŸ ื‘ืขื˜ืŸ ื•ื•ืขื˜ ื•ื•ื™ื™ึทื–ืŸ ืงื™ืฆืขืจ ืกื˜ืึทื˜ื™ืกื˜ื™ืง ืคึฟืึทืจ ื˜ืขืกืฅ ืœื•ื™ืคืŸ ืื™ืŸ ื–ื™ื™ืŸ ืœืขืฆื˜ืข ืจืขืจื  - ืœื™ื ื™ืข:

JUnit ืื™ืŸ GitLab CI ืžื™ื˜ Kubernetes

ื™ืขื“ืขืจ ื˜ืขื•ืช ืงืขื ืขืŸ ื–ื™ื™ืŸ ืงืœื™ืงื˜ ื“ืึธ ืคึฟืึทืจ ืคืจื˜ื™ื:

JUnit ืื™ืŸ GitLab CI ืžื™ื˜ Kubernetes

NB: ะ’ะฝะธะผะฐั‚ะตะปัŒะฝั‹ะน ั‡ะธั‚ะฐั‚ะตะปัŒ ะทะฐะผะตั‚ะธั‚, ั‡ั‚ะพ ะผั‹ ั‚ะตัั‚ะธั€ัƒะตะผ NodeJS-ะฟั€ะธะปะพะถะตะฝะธะต, ะฐ ะฝะฐ ัะบั€ะธะฝัˆะพั‚ะฐั… โ€” .NETโ€ฆ ะะต ัƒะดะธะฒะปัะนั‚ะตััŒ: ะฟั€ะพัั‚ะพ ะฒ ั€ะฐะผะบะฐั… ะฟะพะดะณะพั‚ะพะฒะบะธ ัั‚ะฐั‚ัŒะธ ะฝะต ะฝะฐัˆะปะพััŒ ะพัˆะธะฑะพะบ ะฒ ั‚ะตัั‚ะธั€ะพะฒะฐะฝะธะธ ะฟะตั€ะฒะพะณะพ ะฟั€ะธะปะพะถะตะฝะธั, ะทะฐั‚ะพ ะฝะฐัˆะปะธ ะธั… ะฒ ะดั€ัƒะณะพะผ.

ืกืึธืฃ

ื•ื•ื™ ืื™ืจ ืงืขื ืขืŸ ื–ืขืŸ, ื’ืึธืจื ื™ืฉื˜ ืงืึธืžืคึผืœื™ืฆื™ืจื˜!

ืื™ืŸ ืคึผืจื™ื ืฆื™ืคึผ, ืื•ื™ื‘ ืื™ืจ ืฉื•ื™ืŸ ื”ืึธื‘ืŸ ืึท ืฉืึธืœ ืงืึทืœืขืงื˜ืขืจ ืื•ืŸ ืขืก ืึทืจื‘ืขื˜, ืึธื‘ืขืจ ืื™ืจ ื˜ืึธืŸ ื ื™ื˜ ื“ืึทืจืคึฟืŸ ืงื•ื‘ืขืจื ืขื˜ืขืก, ืึทื˜ืึทื˜ืฉื™ื ื’ ื˜ืขืกื˜ื™ื ื’ ืฆื• ืขืก ื•ื•ืขื˜ ื–ื™ื™ืŸ ืึทืŸ ืืคื™ืœื• ืกื™ืžืคึผืœืขืจ ืึทืจื‘ืขื˜ ื•ื•ื™ ื“ื™ืกืงืจื™ื™ื‘ื“ ื“ืึธ. ืื•ืŸ ืื™ืŸ GitLab CI ื“ืึทืงื™ื•ืžืขื ื˜ื™ื™ืฉืึทืŸ ืื™ืจ ื•ื•ืขื˜ ื’ืขืคึฟื™ื ืขืŸ ื‘ื™ื™ืฉืคื™ืœืŸ ืคึฟืึทืจ Ruby, Go, Gradle, Maven ืื•ืŸ ืขื˜ืœืขื›ืข ืื ื“ืขืจืข.

ืคึผืก

ืœื™ื™ืขื ืขืŸ ืื•ื™ืš ืื•ื™ืฃ ืื•ื ื“ื–ืขืจ ื‘ืœืึธื’:

ืžืงื•ืจ: www.habr.com

ืœื™ื™ื’ืŸ ืึท ื‘ืึทืžืขืจืงื•ื ื’