CI/CD კონვეიერები: GitHub Actions, GitLab CI
CI/CD კონვეიერები: GitHub Actions, GitLab CI
1) CI/CD ამოცანა და ადგილი პლატფორმაში
CI/CD არის უწყვეტი ასამბლეა, ტესტირება და ცვლილებები საცავიდან სამუშაო გარემოში. მიზნები:- გამოშვების სიჩქარე და პროგნოზირება (მოკლე lead დრო).
- ხარისხი (ავტოსადგურები, სტატიკური/დინამიური ანალიზი).
- მიწოდების ჯაჭვის უსაფრთხოება (არტეფაქტების ხელმოწერა, წვდომის კონტროლი).
- საიმედოობა (კანარის დეპოზიტები, სწრაფი დაბრუნება).
- დაკვირვება (კვალი და მეტრიკა თითოეულ ეტაპზე).
ძირითადი პრინციპები: „pipeline as code“, იმუნური არტეფაქტები, „build once - run many“, „shift-left უსაფრთხოება“, „Least privilege“, დეტერმინისტული შეკრებები.
2) კონვეიერის არქიტექტურული ნიმუშები
Stage-gate: build → test → security → package → deploy → post-deploy checks.
Fan-out/Fan-in: პარალელური მატრიქსის შეკრებები (ენები/პლატფორმები) შედეგების შერწყმით.
Promotion: ერთი და იგივე არტეფაქტი მოძრაობს გარემოთი (dev - stage- ის საშუალებით), და არ გადაკეთდება.
Trunk-based + მოკლე ფილიალები: დრიფტის მინიმიზაცია, ავტომატიზირებული შემოწმება PR/MR- ზე.
Reusable: გამოყენებული workflow/შაბლონები (Actions: reusable workflows; GitLab: includes/child-pipelines).
GitOps (სურვილისამებრ): „შეკრების“ და „მიწოდების“ გამიჯვნა (Argo CD/Flux აკონტროლებს გარემოცვის დეკლარაციულ რეპო).
3) მიწოდების ჯაჭვის უსაფრთხოება
იდენტიფიკაცია: OIDC ფედერაცია runner- დან ღრუბელამდე (გრძელი გასაღებების გარეშე).
საიდუმლოებები: ცენტრალიზებული საცავი, კონტექსტის შეზღუდვა, ლოგოებში გაყვანის აკრძალვა.
არტეფაქტების/კონტეინერების ხელმოწერა (cosign/Sigstore), ხელმოწერის გადამოწმება admission კონტროლში.
SBOM (CycloneDX/SPDX) და SCA, SAST/DAST/Container Scan - „სავალდებულო კარიბჭე“.
პოლიტიკოსები: OPA/Conftest IaC/მანიფესტებისთვის, „no latest“, პრივილეგირებული კონტეინერების აკრძალვა.
Runner- ის იზოლაცია: კერძო ქსელში stranners, გამოეყო გამავალი წვდომა საჯარო ინტერნეტიდან.
4) GitHub Actions - სტრუქტურა და პრაქტიკა
4. 1 workflows სტრუქტურა
`.github/workflows/.yml` — триггеры (`on: push, pull_request, schedule, workflow_call`).
რეგულარული სამუშაო შეხვედრები სტანდარტიზაციისთვის (ლინტერი, SCA, კონტეინერის ასამბლეა, უკანა).
4. 2 მაგალითი: მრავალსართულიანი დალევა OIDC- ით და გამოსახულების ხელმოწერა
yaml name: ci-cd
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
id-token: write # для OIDC contents: read packages: write
jobs:
build_test_matrix:
runs-on: ubuntu-latest strategy:
matrix:
node: [18, 20]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4 with: { node-version: ${{ matrix. node }} }
- name: Cache npm uses: actions/cache@v4 with:
path: ~/.npm key: npm-${{ runner. os }}-${{ matrix. node }}-${{ hashFiles('/package-lock. json') }}
- run: npm ci
- run: npm run lint && npm test -- --ci
docker_build_sign:
runs-on: ubuntu-latest needs: build_test_matrix steps:
- uses: actions/checkout@v4
- name: Login to GHCR uses: docker/login-action@v3 with:
registry: ghcr. io username: ${{ github. actor }}
password: ${{ secrets. GITHUB_TOKEN }}
- name: Build image run:
docker build --pull --no-cache -t ghcr. io/org/app:${{ github. sha }}.
docker push ghcr. io/org/app:${{ github. sha }}
- name: Generate SBOM uses: anchore/syft-action@v0 with:
image: ghcr. io/org/app:${{ github. sha }}
format: cyclonedx-json output-file: sbom. json
- name: Cosign sign (OIDC)
uses: sigstore/cosign-installer@v3
- name: Sign image run:
cosign sign ghcr. io/org/app:${{ github. sha }} \
--yes \
--identity-token $ACTIONS_ID_TOKEN_REQUEST_TOKEN \
--rekor-url https://rekor. sigstore. dev
deploy_stage:
runs-on: ubuntu-latest needs: docker_build_sign environment:
name: stage url: https://stage. example. com steps:
- uses: actions/checkout@v4
- name: Assume cloud role via OIDC uses: aws-actions/configure-aws-credentials@v4 with:
role-to-assume: arn:aws:iam::123456789012:role/github-deployer aws-region: eu-central-1
- name: Helm deploy (canary 10%)
run:
helm upgrade --install app charts/app \
--set image. tag=${{ github. sha }} \
--set canary. enabled=true --set canary. traffic=10
- name: Smoke checks run:./scripts/smoke. sh
promote_prod:
runs-on: ubuntu-latest needs: deploy_stage environment:
name: production url: https://app. example. com concurrency: prod-release steps:
- name: Manual approval gate run: echo "Requires environment approvers in repo settings"
- name: Promote canary → 100% (blue-green)
run:
helm upgrade --install app charts/app \
--set image. tag=${{ github. sha }} \
--set canary. enabled=false
- name: Post-deploy checks & rollback on SLO breach run:./scripts/verify_or_rollback. sh
გასაღებები:
- 'permissions' მინიმუმამდეა შემცირებული, შედის 'id-token: write' OIDC- სთვის.
- Environments ერთად approvers და URL, 'concurrence' იცავს რბოლებს.
- კანარის ტრაფიკის ჩართვა და ავტომატური გამოტოვება SLO- ს საშუალებით.
4. 3 Reusable workflow (ზარის მაგალითი)
yaml jobs:
security_suite:
uses: org/.github/.github/workflows/security. yml@v1 with:
severity_threshold: high
5) GitLab CI - სტრუქტურა და პრაქტიკა
5. 1 ძირითადი სტრუქტურა
`.gitlab-ci. yml 'ფესვში; საკვანძო ობიექტები: 'stages', 'jobs', 'rules', 'needs', 'artifacts', 'environments', 'manual'.
Reuse: 'include:' (ადგილობრივი/remote შაბლონები), child/parent pipelines რთული მონორეპოსთვის.
5. 2 მაგალითი: მატრიცა, ქეში, ხელმოწერა, გარემო და approvals
yaml stages: [lint, test, build, security, deploy]
variables:
DOCKER_TLS_CERTDIR: "" # docker: dind acceleration
IMAGE_TAG: $CI_COMMIT_SHA
lint:
stage: lint image: node:20 script:
- npm ci
- npm run lint cache:
key: "npm-${CI_COMMIT_REF_SLUG}"
paths: [node_modules/]
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
test:
stage: test image: node:20 parallel:
matrix:
- NODE_VERSION: ["18", "20"]
script:
- nvm install $NODE_VERSION true
- npm ci
- npm test -- --ci artifacts:
when: always reports:
junit: report. xml
build_image:
stage: build image: docker:26. 1 services: [ "docker:26. 1-dind" ]
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG.
- docker push $CI_REGISTRY_IMAGE:$IMAGE_TAG artifacts:
expire_in: 1 week paths: [ "sbom. json" ]
after_script:
- syft $CI_REGISTRY_IMAGE:$IMAGE_TAG -o cyclonedx-json > sbom. json
security_scans:
stage: security image: alpine:3. 20 script:
- trivy image --exit-code 0 --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$IMAGE_TAG rules:
- if: '$CI_COMMIT_BRANCH == "main"'
deploy_stage:
stage: deploy image: bitnami/kubectl:1. 30 environment:
name: stage url: https://stage. example. com on_stop: stop_stage script:
- kubectl set image deploy/app app=$CI_REGISTRY_IMAGE:$IMAGE_TAG -n stage
-./scripts/smoke. sh needs: [build_image, security_scans]
when: manual allow_failure: false
stop_stage:
stage: deploy image: bitnami/kubectl:1. 30 environment:
name: stage action: stop script:
- kubectl rollout undo deploy/app -n stage
deploy_prod:
stage: deploy image: alpine/k8s:1. 30. 2 environment:
name: production url: https://app. example. com rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual allow_failure: false script:
-./scripts/canary_traffic. sh 10
-./scripts/verify_or_rollback. sh
გასაღებები:
- `parallel. matrix 'ახდენს მატრიქსის შეკრების სიმულაციას.
- 'artifacts' + ტესტის ანგარიშები.
- Environments 'on _ stop', სახელმძღვანელო 'when: manual' for approvals.
- DIND გამოსახულების შეკრებისთვის (უკეთესი - Kaniko/BuildKit k8s ranner).
5. 3 Child pipelines და include monorepo- სთვის
yaml include:
- local:.gitlab/ci/includes/security. yml
- project: org/platform/pipelines file: /k8s/deploy. yml ref: v1
stages: [prepare, component_a, component_b, deploy]
component_a:
stage: component_a trigger:
include:.gitlab/ci/component_a. yml strategy: depend
component_b:
stage: component_b trigger:
include:.gitlab/ci/component_b. yml strategy: depend
6) ერთფეროვნება და მრავალჯერადი მომსახურება
Directive based ownership: CODEOWNERS და scoped ტესტები ბილიკებზე.
Incremental builds: განსაზღვრეთ დაზარალებული პაკეტები/ჩარტები; ქეში ბილიკების გასაღებებზე და ლოკის ფაილებზე.
Dynamic pipelines: child-pipelines/' workflow _ call 'ამოქმედებულია მხოლოდ შეცვლილი კომპონენტებისთვის.
ვერსია: თითოეული მოდულის შემქმნელი, changelog release ეტაპზე.
7) კეშინგი და აჩქარება
შინაარსის მისამართის ქეში (hashFiles/lockfile).
ცალკეული ქეში დამოკიდებულებისა და არტეფაქტებისთვის.
Pre-warm runner images (toolchains, SDK).
ადგილობრივი პაკეტის სარკეები (npm/pip/maven) და კონტეინერის რეგისტრის ქეში.
8) გამოშვებული სტრატეგიები და გამოტოვება
Canary: ტრაფიკის პროცენტული თანდათანობითი ზრდა; მანქანების გაჩერება SLO- ს დეგრადაციის დროს.
Blue-Green: პარალელური მინები, მყისიერი გადართვა.
Shadow: მოთხოვნის დუბლირება კლიენტზე გავლენის გარეშე.
Feature flags: rollout დროშის დონეზე და არა გამოშვება.
Rollback: აშკარა სკრიპტები „ერთი ღილაკით“, არტეფაქტის ვერსია ინახება მეტამონაცემებში.
9) ინფრასტრუქტურა და GitOps
IaC: Terraform/Ansible/Helm კონტროლდება ცალკეულ რეპოში; policy-as-code, როგორც კარიბჭე.
GitOps წრე: Argo CD/Flux აკვირდება რეპო გარემოცვის მანიფესტებით; კონვეიერი მხოლოდ ქმნის არტეფაქტს და განაახლებს ვერსიებს Git- ში.
უპირატესობები: გარემოში ცვლილებების აშკარა ისტორია, იდემპოტენტობა, სტანდარტული გამოტოვება Git- ის საშუალებით.
10) დაკვირვება CI/CD
DORA მეტრიკა: გამონაყარის სიხშირე, კომიტიდან წარმოებამდე დრო, უარის თქმის პროცენტი, MTTR.
Telemetry: job რიგების დრო, სტადიების ხანგრძლივობა, hit-rate ქეში, ფლაკონის ტესტების სიხშირე.
უსაფრთხოების ლოგოები: ვინ წამოიწყო გამოშვება, რომელი კარიბჭე გაიარა, რა გამონაკლისები იქნა გაცემული.
11) წვდომის მენეჯმენტი და approvals
Branch დაცვა და სავალდებულო შემოწმება.
Environment-approvals: approvers- ის ცალკეული სიები stage/stage.
JIT წვდომა სახელმძღვანელო ნაბიჯებისთვის, სესიების ჟურნალები.
პასუხისმგებლობის გამიჯვნა: სხვადასხვა როლები „წერს კოდს“, „ამტკიცებს“, „გამოსცემს“.
12) ხშირი შეცდომები (ანტი-ნიმუშები)
გრძელი ღრუბლის გასაღებები რეპო საიდუმლოებებში OIDC როლების ნაცვლად.
სხვადასხვა არტეფაქტების შეკრება სტაგისა და მგრძნობელობისთვის (დარღვევა „საბინაო ერთეული“).
'latest' tags და mutable გამოსახულებები.
საიდუმლოებების გამოქვეყნება ნაბიჯების ლოგოებში (განუყოფელი ოსტატობა).
ერთი საერთო public-runner prod deploes- ისთვის.
უსაფრთხოების „კარიბჭის“ არარსებობა (SAST/SCA/Policy) და post-deploy შემოწმებები.
13) განხორციელების სიის სია (0-60 დღე)
0-15 დღე
კონფიგურაცია trunk-based, PR/MR წესები, სავალდებულო სტატიკური შემოწმებები.
ჩართეთ OIDC ფედერაცია ღრუბელში; მინიმალური 'permissions'.
განაწილება: საჯარო - CI- სთვის, პირადი - CD- სთვის.
16-30 დღე
დაამატეთ SBOM, სურათების ხელმოწერა; მტევანში - ხელმოწერის შემოწმება.
შემოიღეთ canary/blue-green; მანქანის rollback SLO- სთვის.
დამოკიდებულებისა და არტეფაქტების ქეში, სურათების პრე-warm.
31-60 დღე
გაყოფილი ასამბლეა და მიწოდება (GitOps), პოლიცია-as-code კარიბჭე.
დაამყარეთ DORA მეტრიკა და ალერტები payplines- ის დეგრადაციისთვის.
ყველა სერვისის შაბლონების შაბლონიზაცია.
14) საიმედოობის პრაქტიკული რჩევები
შეინარჩუნეთ მცირე, სწრაფი პაემნები (PR სიგნალამდე 10-12 წუთი).
მოკალი flaky ტესტები: quarantine ეტიკეტები + პარალელური ფიქსი.
ნუ შეურიეთ CI არტეფაქტები და არტეფაქტები; შეინახეთ მეტამონაცემები (commit, დრო, SBOM, ხელმოწერები).
მიეცით დეველოპერებს ადგილობრივი სკრიპტები, რომლებიც იდენტურია კონვეიერის ნაბიჯებთან (dev-seavity parity).
15) შაბლონები ხელახალი გამოყენებისთვის
15. 1 GitHub Actions - უსაფრთხოების reusable სამუშაო (გამარტივებული)
yaml name: security-suite on:
workflow_call:
inputs:
severity_threshold:
type: string required: false default: high jobs:
sast_sca:
runs-on: ubuntu-latest steps:
- uses: actions/checkout@v4
- run:./sec/sast. sh --threshold ${{ inputs. severity_threshold }}
- run:./sec/sca. sh --format cyclonedx-json --out sbom. json artifacts: # if using actions/upload-artifact
- sbom. json
15. 2 GitLab - ჩართულია deploy შაბლონი (გამარტივებული)
yaml
.deployment_template:
image: alpine/k8s:1. 30 script:
- helm upgrade --install $APP charts/$APP --set image. tag=$IMAGE_TAG rules:
- if: '$CI_COMMIT_BRANCH == "main"'
16) დასკვნა
GitHub Actions და GitLab CI უზრუნველყოფენ სექსუალურ მექანიზმებს სწრაფი და უსაფრთხო ციკლისთვის „კოდი - პროდ“. წარმატების გასაღები არის სტანდარტიზაცია და უსაფრთხოება: OIDC კლავიშების ნაცვლად, ხელმოწერა და SBOM, ხარისხის კარიბჭე, ერთი არტეფაქტი პოპულარიზაციით, GitOps მიწოდებით და DORA- ს საშუალებით დაკვირვებით. ააშენეთ plines, როგორც პროდუქტი: გაზომეთ, გაამარტივეთ, დააჩქარეთ - და გამოშვებები გახდება რუტინა და არა მოვლენა.