第四章:变量与缓存¶
变量类型¶
预定义变量¶
job_name:
script:
# 项目信息
- echo "Project: $CI_PROJECT_NAME"
- echo "Project URL: $CI_PROJECT_URL"
- echo "Project ID: $CI_PROJECT_ID"
# 仓库信息
- echo "Repo: $CI_REPOSITORY_URL"
- echo "Branch: $CI_COMMIT_REF_NAME"
- echo "Commit SHA: $CI_COMMIT_SHA"
- echo "Commit Message: $CI_COMMIT_MESSAGE"
- echo "Commit Author: $CI_COMMIT_AUTHOR"
# Pipeline 信息
- echo "Pipeline ID: $CI_PIPELINE_ID"
- echo "Pipeline URL: $CI_PIPELINE_URL"
- echo "Pipeline Source: $CI_PIPELINE_SOURCE"
# Job 信息
- echo "Job ID: $CI_JOB_ID"
- echo "Job Name: $CI_JOB_NAME"
- echo "Job Stage: $CI_JOB_STAGE"
- echo "Job URL: $CI_JOB_URL"
# Runner 信息
- echo "Runner ID: $CI_RUNNER_ID"
- echo "Runner Tags: $CI_RUNNER_TAGS"
# 用户信息
- echo "User: $GITLAB_USER_LOGIN"
- echo "User Email: $GITLAB_USER_EMAIL"
# 合并请求信息
- echo "MR IID: $CI_MERGE_REQUEST_IID"
- echo "MR Source Branch: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
- echo "MR Target Branch: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
自定义变量¶
# 在 .gitlab-ci.yml 中定义
variables:
APP_NAME: "myapp"
DEPLOY_ENV: "staging"
DATABASE_URL: "postgres://localhost:5432/mydb"
# 使用变量
deploy:
script:
- echo "Deploying $APP_NAME to $DEPLOY_ENV"
项目变量¶
GitLab → Settings → CI/CD → Variables
变量类型:
├── Variable # 普通变量
├── File # 文件变量
└── Masked # 掩码变量(日志中隐藏)
变量优先级¶
变量使用¶
环境变量¶
job_name:
variables:
LOCAL_VAR: "local value"
script:
- echo "Global: $GLOBAL_VAR"
- echo "Local: $LOCAL_VAR"
条件变量¶
job_name:
script:
- |
if [ "$CI_COMMIT_BRANCH" == "main" ]; then
export DEPLOY_ENV="production"
else
export DEPLOY_ENV="staging"
fi
- echo "Deploy to $DEPLOY_ENV"
动态变量¶
job_name:
script:
- export TIMESTAMP=$(date +%Y%m%d%H%M%S)
- export IMAGE_TAG="$CI_COMMIT_SHA-$TIMESTAMP"
- echo "Image tag: $IMAGE_TAG"
文件变量¶
# 定义文件变量(在 GitLab UI 中设置)
# KUBECONFIG: 文件内容
job_name:
script:
- kubectl config use-context my-context
- kubectl get pods
掩码变量¶
# 敏感信息设置为掩码变量
# 在日志中显示为 [MASKED]
job_name:
script:
- echo "API Key: $API_KEY"
# 输出: API Key: [MASKED]
缓存配置¶
缓存 Key¶
# 分支级别缓存
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- node_modules/
# 项目级别缓存
cache:
key: $CI_PROJECT_ID
paths:
- node_modules/
# 文件哈希缓存
cache:
key:
files:
- package-lock.json
- Gemfile.lock
prefix: $CI_COMMIT_REF_SLUG
paths:
- node_modules/
# 组合 Key
cache:
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
- node_modules/
缓存策略¶
缓存作用域¶
# 全局缓存
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- node_modules/
# Job 级别缓存
job_name:
cache:
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
paths:
- .npm/
- node_modules/
缓存失效¶
# 手动清除缓存
# GitLab → CI/CD → Pipelines → Clear Runner Caches
# 通过变量控制
cache:
key: "$CI_COMMIT_REF_SLUG-$CACHE_VERSION"
paths:
- node_modules/
variables:
CACHE_VERSION: "v1" # 修改此值清除缓存
制品管理¶
制品类型¶
# 普通制品
artifacts:
paths:
- dist/
expire_in: 1 week
# 报告制品
artifacts:
reports:
junit: report.xml
coverage_report:
coverage_format: cobertura
path: coverage.xml
# 代码质量报告
artifacts:
reports:
codequality: gl-code-quality-report.json
sast: gl-sast-report.json
dependency_scanning: gl-dependency-scanning-report.json
制品配置¶
job_name:
artifacts:
paths:
- dist/
- build/
exclude:
- dist/*.log
- build/.cache/
name: "artifacts-$CI_COMMIT_REF_NAME"
expire_in: 1 week
when: always # always, on_success, on_failure
制品传递¶
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
test:
stage: test
script:
- ls dist/
dependencies:
- build # 只下载 build 的制品
deploy:
stage: deploy
script:
- rsync -avz dist/ server:/app/
needs:
- job: build
artifacts: true
环境管理¶
环境定义¶
deploy:staging:
stage: deploy
script:
- echo "Deploy to staging"
environment:
name: staging
url: https://staging.app.example.com
on_stop: stop_staging
stop_staging:
stage: deploy
script:
- echo "Stop staging"
environment:
name: staging
action: stop
when: manual
动态环境¶
deploy:review:
stage: deploy
script:
- echo "Deploy review app for $CI_COMMIT_REF_NAME"
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_COMMIT_REF_NAME.app.example.com
on_stop: stop_review
only:
- branches
except:
- main
stop_review:
stage: deploy
script:
- echo "Stop review app"
environment:
name: review/$CI_COMMIT_REF_NAME
action: stop
when: manual
only:
- branches
except:
- main
环境变量¶
deploy:production:
stage: deploy
script:
- echo "Deploy to production"
environment:
name: production
variables:
DEPLOY_ENV: "production"
KUBE_NAMESPACE: "prod"
实战示例¶
多环境部署¶
stages:
- build
- deploy
variables:
REGISTRY: registry.example.com
IMAGE_NAME: $REGISTRY/myapp
build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $REGISTRY
- docker build -t $IMAGE_NAME:$CI_COMMIT_SHA .
- docker push $IMAGE_NAME:$CI_COMMIT_SHA
only:
- main
- develop
.deploy_template:
image: bitnami/kubectl:latest
script:
- kubectl config use-context $KUBE_CONTEXT
- kubectl set image deployment/$APP_NAME $APP_NAME=$IMAGE_NAME:$CI_COMMIT_SHA -n $KUBE_NAMESPACE
- kubectl rollout status deployment/$APP_NAME -n $KUBE_NAMESPACE
deploy:staging:
extends: .deploy_template
stage: deploy
environment:
name: staging
url: https://staging.app.example.com
variables:
KUBE_NAMESPACE: staging
APP_NAME: myapp
only:
- develop
when: manual
deploy:production:
extends: .deploy_template
stage: deploy
environment:
name: production
url: https://app.example.com
variables:
KUBE_NAMESPACE: production
APP_NAME: myapp
only:
- main
when: manual
密钥管理¶
# 使用 GitLab Secrets
# Settings → CI/CD → Variables
deploy:
script:
# SSH 部署
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan $DEPLOY_SERVER >> ~/.ssh/known_hosts
- ssh $DEPLOY_USER@$DEPLOY_SERVER "docker pull $IMAGE && docker restart app"
# Kubernetes 部署
- echo "$KUBE_CONFIG" | base64 -d > ~/.kube/config
- kubectl apply -f k8s/
小结¶
本章学习了:
- ✅ 变量类型和使用
- ✅ 缓存配置
- ✅ 制品管理
- ✅ 环境管理
- ✅ 实战示例
下一章¶
第五章:Docker 部署 - 学习 Docker 部署实践。