如何在gitlab-ci.yml中通过SSH命令设置GitLab Runner环境变量
问题原因
GitLab CI 中 workflow、job 层级的 variables 字段仅支持静态字符串赋值,不会自动执行字段内的命令内容,所以你写的SSH命令只会被当做字面量处理,只有script段的内容才会被runner当做shell脚本执行。
解决方案
方案1:用before_script预赋值(单job/少量job场景)
before_script 会在当前job的script段之前执行,刚好满足你在script阶段开始前拿到变量的需求,配置示例如下:
workflow: rules: - if: $CI_PIPELINE_SOURCE == "schedule" when: always variables: BRANCH: prod DRIVE_PATH: /path/to/prod - when: always # 全局配置的话所有job都会执行,单个job使用就写在job内部 before_script: - | export TABLE_STATUS=$(ssh gitlab-runner@$TARGET_HOST "source $DRIVE_PATH/config/.config && mysql -u $USER -p$PASSWORD -e \"SELECT IF(MONTH(datetime) = MONTH(NOW()), IF(status = 1, 'TRUE', 'FALSE'), 'FALSE') FROM schema.table WHERE table_name = 'tbl_name';\" ") - echo "TABLE_STATUS 已赋值为:$TABLE_STATUS" your_job: script: # 此处直接使用变量即可 - if [ "$TABLE_STATUS" = "TRUE" ]; then echo "执行符合条件的逻辑"; fi
方案2:用dotenv artifacts预生成变量(多job共享场景)
如果需要多个job都用到这个变量,避免重复执行SSH命令,可以新增一个前置stage专门生成变量,后续所有stage的job都能自动加载这个变量:
stages: - pre_env # 前置变量生成stage,要放在所有业务stage之前 - build - deploy # 你的其他业务stage workflow: rules: - if: $CI_PIPELINE_SOURCE == "schedule" when: always variables: BRANCH: prod DRIVE_PATH: /path/to/prod - when: always generate_env_job: stage: pre_env script: - | TABLE_STATUS=$(ssh gitlab-runner@$TARGET_HOST "source $DRIVE_PATH/config/.config && mysql -u $USER -p$PASSWORD -e \"SELECT IF(MONTH(datetime) = MONTH(NOW()), IF(status = 1, 'TRUE', 'FALSE'), 'FALSE') FROM schema.table WHERE table_name = 'tbl_name';\" ") # 将变量写入dotenv文件 - echo "TABLE_STATUS=$TABLE_STATUS" >> build.env artifacts: reports: dotenv: build.env # 声明该文件为环境变量文件,后续job自动加载 build_job: stage: build script: - echo "直接读取变量 TABLE_STATUS=$TABLE_STATUS" deploy_job: stage: deploy script: - echo "所有后续job都可以直接使用该变量 TABLE_STATUS=$TABLE_STATUS"
内容的提问来源于stack exchange,提问作者gbruenjes
相关产品推荐
相关产品推荐

