GitLab CI/CD Keywords and Usage | Complete Reference Guide
GitLab CI/CD provides a rich set of keywords and conditions to control pipeline execution. This guide covers essential keywords, stage conditions, and usage patterns for effective pipeline management.
🏗️ Build Keywords
Section titled “🏗️ Build Keywords”script
Section titled “script”The core keyword that defines what commands to execute in a job.
build_job: script: - echo "Building application" - npm install - npm run buildbefore_script and after_script
Section titled “before_script and after_script”Execute commands before and after the main script.
build_job: before_script: - echo "Preparing environment" - export NODE_ENV=production script: - npm run build after_script: - echo "Cleaning up" - rm -rf temp/Specify the Docker image to use for the job.
build_job: image: node:18-alpine script: - npm run build
build_with_specific_image: image: name: node:18 entrypoint: [""] script: - npm run buildservices
Section titled “services”Additional Docker containers to run alongside the job.
test_with_database: image: node:18 services: - postgres:13 - redis:6-alpine variables: POSTGRES_DB: testdb POSTGRES_USER: testuser POSTGRES_PASSWORD: testpass script: - npm run test:integration🎭 Stage Keywords
Section titled “🎭 Stage Keywords”stages
Section titled “stages”Define the order of stages in the pipeline.
stages: - prepare - build - test - security - deploy - cleanupAssign a job to a specific stage.
prepare_env: stage: prepare script: - echo "Preparing environment"
build_app: stage: build script: - echo "Building application"
test_app: stage: test script: - echo "Testing application"Hidden Jobs and Templates
Section titled “Hidden Jobs and Templates”Create reusable job templates using .job_name syntax.
.deploy_template: &deploy image: alpine:latest before_script: - apk add --no-cache curl script: - echo "Deploying to $ENVIRONMENT"
deploy_staging: <<: *deploy stage: deploy variables: ENVIRONMENT: staging only: - develop
deploy_production: <<: *deploy stage: deploy variables: ENVIRONMENT: production only: - main⚙️ Run Conditions - when Keyword
Section titled “⚙️ Run Conditions - when Keyword”on_success (Default)
Section titled “on_success (Default)”Job runs only when all previous jobs succeed.
deploy_job: stage: deploy when: on_success # This is the default script: - echo "Deploying after successful build and test"always
Section titled “always”Job runs regardless of previous job status.
cleanup_job: stage: cleanup when: always script: - echo "Cleaning up resources" - rm -rf temp/ - docker system prune -fJob never runs automatically (must be triggered manually).
emergency_rollback: stage: deploy when: never script: - echo "Rolling back to previous version" - kubectl rollout undo deployment/myappon_failure
Section titled “on_failure”Job runs only when at least one previous job fails.
notify_failure: stage: notify when: on_failure script: - echo "Build failed, sending notification" - curl -X POST -H 'Content-type: application/json' --data '{"text":"Build failed!"}' $SLACK_WEBHOOKmanual
Section titled “manual”Job requires manual intervention to start.
deploy_production: stage: deploy when: manual script: - echo "Deploying to production" environment: name: productiondelayed
Section titled “delayed”Job starts after a specified delay.
deploy_with_delay: stage: deploy when: delayed start_in: 30 minutes script: - echo "Deploying after delay"🎯 Job Control Keywords
Section titled “🎯 Job Control Keywords”only and except
Section titled “only and except”Control when jobs run based on branches, tags, or other conditions.
# Using onlydeploy_production: script: - echo "Deploying to production" only: - main - /^release\/.*$/
# Using excepttest_job: script: - npm test except: - schedules - triggers
# Complex conditionscomplex_job: script: - echo "Complex conditions" only: refs: - main - develop variables: - $DEPLOY_ENABLED == "true" changes: - src/**/* - package.jsonMore powerful alternative to only and except.
# Basic rulesdeploy_job: script: - echo "Deploying" rules: - if: '$CI_COMMIT_BRANCH == "main"' - if: '$CI_COMMIT_TAG'
# Complex rules with when conditionstest_job: script: - npm test rules: - if: '$CI_COMMIT_BRANCH == "main"' when: always - if: '$CI_COMMIT_BRANCH == "develop"' when: manual - changes: - "src/**/*" when: on_success - when: never
# Rules with variablesconditional_deploy: script: - echo "Conditional deployment" rules: - if: '$DEPLOY_TO_STAGING == "true"' variables: ENVIRONMENT: staging - if: '$DEPLOY_TO_PRODUCTION == "true"' variables: ENVIRONMENT: production when: manualallow_failure
Section titled “allow_failure”Allow job to fail without affecting pipeline status.
experimental_test: script: - npm run experimental-tests allow_failure: true
optional_security_scan: script: - security-scan allow_failure: exit_codes: - 2 - 3📦 Artifacts and Dependencies
Section titled “📦 Artifacts and Dependencies”artifacts
Section titled “artifacts”Save files and directories after job completion.
build_job: script: - npm run build artifacts: name: "build-$CI_COMMIT_SHORT_SHA" paths: - dist/ - build/ exclude: - "**/*.tmp" - "dist/debug/" expire_in: 1 week when: on_success reports: junit: test-results.xml coverage: coverage.xmldependencies
Section titled “dependencies”Control which artifacts are downloaded.
test_job: dependencies: - build_job script: - npm test
deploy_job: dependencies: - build_job script: - deploy.shAdvanced job dependencies for parallel execution.
build_backend: stage: build script: - build-backend.sh
build_frontend: stage: build script: - build-frontend.sh
test_integration: stage: test needs: - build_backend - build_frontend script: - integration-tests.sh🌐 Environment and Variables
Section titled “🌐 Environment and Variables”environment
Section titled “environment”Deploy to specific environments with tracking.
deploy_staging: script: - deploy.sh staging environment: name: staging url: https://staging.myapp.com on_stop: stop_staging
deploy_production: script: - deploy.sh production environment: name: production url: https://myapp.com auto_stop_in: 1 week
stop_staging: script: - stop-environment.sh staging environment: name: staging action: stop when: manualvariables
Section titled “variables”Define job-specific variables.
# Global variablesvariables: GLOBAL_VAR: "global_value" NODE_VERSION: "18"
# Job-specific variablesbuild_job: variables: BUILD_ENV: production OPTIMIZE: "true" script: - echo "Building with $BUILD_ENV environment" - echo "Optimization: $OPTIMIZE"
# Conditional variables with rulesdeploy_job: script: - deploy.sh rules: - if: '$CI_COMMIT_BRANCH == "main"' variables: ENVIRONMENT: production - if: '$CI_COMMIT_BRANCH == "develop"' variables: ENVIRONMENT: staging🔄 Parallel and Matrix Jobs
Section titled “🔄 Parallel and Matrix Jobs”parallel
Section titled “parallel”Run multiple instances of the same job.
test_parallel: script: - echo "Running test chunk $CI_NODE_INDEX of $CI_NODE_TOTAL" - npm run test:chunk:$CI_NODE_INDEX parallel: 5
# Matrix jobstest_matrix: script: - npm run test parallel: matrix: - NODE_VERSION: ["16", "18", "20"] OS: ["ubuntu", "alpine"]🕒 Scheduling and Triggers
Section titled “🕒 Scheduling and Triggers”workflow
Section titled “workflow”Control when pipelines run.
workflow: rules: - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS' when: never - if: '$CI_COMMIT_BRANCH'
# Scheduled pipelinesscheduled_cleanup: script: - cleanup-old-artifacts.sh only: - schedulestrigger
Section titled “trigger”Trigger downstream pipelines.
trigger_downstream: trigger: project: mygroup/downstream-project branch: main strategy: depend
# Multi-project pipelinedeploy_microservices: trigger: include: - project: mygroup/user-service file: .gitlab-ci.yml - project: mygroup/order-service file: .gitlab-ci.yml🏷️ Tags and Resources
Section titled “🏷️ Tags and Resources”Specify which runners to use.
build_gpu: tags: - gpu - linux script: - train-model.py
deploy_kubernetes: tags: - kubernetes - production script: - kubectl apply -f deployment.yamlresource_group
Section titled “resource_group”Ensure only one job runs at a time for a resource.
deploy_production: resource_group: production script: - deploy-to-production.sh
migrate_database: resource_group: production script: - migrate-database.sh🔒 Security and Cache
Section titled “🔒 Security and Cache”Cache dependencies between jobs.
build_job: cache: key: files: - package-lock.json - yarn.lock paths: - node_modules/ - .yarn-cache/ policy: pull-push script: - npm ci - npm run build
test_job: cache: key: files: - package-lock.json paths: - node_modules/ policy: pull script: - npm testid_tokens
Section titled “id_tokens”Generate OIDC tokens for secure authentication.
deploy_aws: id_tokens: AWS_TOKEN: aud: https://aws.amazon.com script: - aws sts assume-role-with-web-identity --role-arn $AWS_ROLE_ARN --role-session-name gitlab-ci --web-identity-token $AWS_TOKEN📊 Advanced Usage Patterns
Section titled “📊 Advanced Usage Patterns”Conditional Job Execution with Complex Logic
Section titled “Conditional Job Execution with Complex Logic”smart_deploy: script: - | if [ "$CI_COMMIT_BRANCH" = "main" ]; then echo "Deploying to production" deploy-production.sh elif [ "$CI_COMMIT_BRANCH" = "develop" ]; then echo "Deploying to staging" deploy-staging.sh else echo "Feature branch deployment" deploy-preview.sh fi rules: - if: '$CI_COMMIT_BRANCH =~ /^(main|develop|feature\/.*)$/' when: on_success - when: neverDynamic Pipeline Generation
Section titled “Dynamic Pipeline Generation”generate_tests: stage: prepare script: - | for service in $(ls services/); do cat >> dynamic_jobs.yml << EOF test_${service}: stage: test script: - cd services/${service} - npm test EOF done artifacts: paths: - dynamic_jobs.yml
include: - local: dynamic_jobs.ymlPipeline Templates with Includes
Section titled “Pipeline Templates with Includes”# In .gitlab-ci-template.yml.deploy_template: image: alpine:latest before_script: - apk add --no-cache curl kubectl script: - kubectl apply -f k8s/ environment: name: $ENVIRONMENT url: $DEPLOYMENT_URL
# In main .gitlab-ci.ymlinclude: - local: '.gitlab-ci-template.yml'
deploy_staging: extends: .deploy_template variables: ENVIRONMENT: staging DEPLOYMENT_URL: https://staging.myapp.com only: - develop
deploy_production: extends: .deploy_template variables: ENVIRONMENT: production DEPLOYMENT_URL: https://myapp.com when: manual only: - mainThis comprehensive guide covers the essential GitLab CI/CD keywords and usage patterns for building robust and flexible pipelines.