GitLab CI如何基于文件变更条件执行作业步骤?
解决GitLab CI作业按需执行环节的方案
针对你的需求,提供两种可落地的实现方式,按需选择:
方案一:拆分模板,通过规则动态选择执行逻辑
将原模板拆分为基础通用模板、完整流程模板、轻量测试模板,再通过rules根据文件变更情况选择继承的模板,逻辑更清晰易维护。
1. 重构模板配置
首先定义三个分层模板:
# 基础通用模板:包含所有不变的核心配置 .template_MWAA:DAGS:Test:Base stage: Test extends: - .template_MWAA needs: [] variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" PYTHONPATH: "$CI_PROJECT_DIR/airflow-mwaa/dags" cache: key: $CI_JOB_NAME_SLUG-python paths: - .cache/pip script: - echo "Starting .template_MWAA:DAGS:Test template" - cd "$CI_PROJECT_DIR/airflow-mwaa" - airflow db init - ./tests-ci.sh coverage: '/^TOTAL\s+\d+\s+\d+\s+(\d+%)$/' artifacts: reports: junit: $CI_PROJECT_DIR/airflow-mwaa/test_results/report.xml # 完整流程模板:包含依赖安装和缓存清理环节 .template_MWAA:DAGS:Test:Full extends: .template_MWAA:DAGS:Test:Base before_script: - echo "Starting .install_dependencies template" - pip3 install -r "$CI_PROJECT_DIR/airflow-mwaa/requirements/$AIRFLOW_VERSION/requirements.txt" after_script: # remove older files from terraform providers cache - find "$PIP_CACHE_DIR" -mindepth 1 -mtime +14 -type f -delete - find "$PIP_CACHE_DIR" -mindepth 1 -mtime +14 -type d -empty -delete # 轻量测试模板:仅执行核心测试环节,无before/after脚本 .template_MWAA:DAGS:Test:Lite extends: .template_MWAA:DAGS:Test:Base
2. 修改具体作业配置
通过rules根据文件变更动态切换继承的模板:
mwaa:dags:test:2.8.1: variables: AIRFLOW_VERSION: 2.8.1 PYTHON_VERSION: 3.11 rules: # 受保护分支:requirements目录变更时用完整流程 - if: $CI_COMMIT_REF_PROTECTED == "true" changes: - airflow-mwaa/requirements/**/* extends: .template_MWAA:DAGS:Test:Full when: on_success allow_failure: false # 受保护分支:无requirements变更时用轻量流程 - if: $CI_COMMIT_REF_PROTECTED == "true" extends: .template_MWAA:DAGS:Test:Lite when: on_success allow_failure: false # MR场景:dags/tests/requirements任一变更时用完整流程 - if: $CI_PIPELINE_SOURCE == "merge_request_event" changes: - airflow-mwaa/dags/**/* - airflow-mwaa/tests/**/* - airflow-mwaa/requirements/**/* extends: .template_MWAA:DAGS:Test:Full allow_failure: false when: on_success # MR场景:仅dags/tests变更且无requirements变更时用轻量流程 - if: $CI_PIPELINE_SOURCE == "merge_request_event" changes: - airflow-mwaa/dags/**/* - airflow-mwaa/tests/**/* except: changes: - airflow-mwaa/requirements/**/* extends: .template_MWAA:DAGS:Test:Lite allow_failure: false when: on_success # MR手动触发:默认用完整流程 - if: $CI_PIPELINE_SOURCE == "merge_request_event" extends: .template_MWAA:DAGS:Test:Full when: manual allow_failure: true - when: never
方案二:在脚本内加条件判断(无需拆分模板)
如果不想修改模板结构,可以直接在before_script和after_script中加入文件变更判断,仅当airflow-mwaa/requirements/**有变更时才执行对应逻辑。
修改原模板的before/after脚本
.template_MWAA:DAGS:Test # 保留原有其他配置(stage、variables、cache、script等)不变 before_script: - | # 区分MR和普通分支场景,确定diff对比的基准SHA if [ "$CI_PIPELINE_SOURCE" = "merge_request_event" ]; then DIFF_BASE=$CI_MERGE_REQUEST_TARGET_BRANCH_SHA else DIFF_BASE=$CI_COMMIT_BEFORE_SHA fi # 判断requirements目录是否有变更,有则执行依赖安装 if git diff --name-only $DIFF_BASE $CI_COMMIT_SHA | grep -q "^airflow-mwaa/requirements/"; then echo "Starting .install_dependencies template" pip3 install -r "$CI_PROJECT_DIR/airflow-mwaa/requirements/$AIRFLOW_VERSION/requirements.txt" else echo "No changes in requirements directory, skipping dependency installation" fi after_script: - | # 同before_script的基准SHA判断逻辑 if [ "$CI_PIPELINE_SOURCE" = "merge_request_event" ]; then DIFF_BASE=$CI_MERGE_REQUEST_TARGET_BRANCH_SHA else DIFF_BASE=$CI_COMMIT_BEFORE_SHA fi # 判断requirements目录是否有变更,有则执行缓存清理 if git diff --name-only $DIFF_BASE $CI_COMMIT_SHA | grep -q "^airflow-mwaa/requirements/"; then echo "Cleaning old pip cache files" find "$PIP_CACHE_DIR" -mindepth 1 -mtime +14 -type f -delete find "$PIP_CACHE_DIR" -mindepth 1 -mtime +14 -type d -empty -delete else echo "No changes in requirements directory, skipping cache cleanup" fi
具体作业配置无需修改
保持原作业配置即可:
mwaa:dags:test:2.8.1: variables: AIRFLOW_VERSION: 2.8.1 PYTHON_VERSION: 3.11 extends: - .template_MWAA:DAGS:Test
内容的提问来源于stack exchange,提问作者python_dev
相关产品推荐
相关产品推荐

