简体   繁体   English

gitlab-ci.yml 中的条件变量

[英]Conditional variables in gitlab-ci.yml

Depending on branch the build comes from I need to use slightly different command line arguments.根据构建来自的分支,我需要使用稍微不同的命令行参数。 Particularly I would like to upload snapshot nexus artifacts when building from a branch, and release artifact when building off master.特别是我想在从分支构建时上传快照关系工件,并在构建主时释放工件。

Is there a way to conditionally alter variables?有没有办法有条件地改变变量?

I tried to use except/only keywords like this我尝试使用像这样的 except/only 关键字

stages:
    - stage


variables:
    TYPE: Release


.upload_common:
    stage: stage
    tags: ["Win"]
    script: 
        - echo Uploading %TYPE%


.upload_snapshot:
    variables:
        TYPE: "Snapshot"
    except:
        - master


upload:
    extends: 
        - .upload_common
        - .upload_snapshot

Unfortunately it skips whole upload step when building off master.不幸的是,它在构建 master 时跳过了整个上传步骤。

The reason I am using 'extends' pattern here is that I have win and mac platforms which use slightly different variables substitution syntax ($ vs %).我在这里使用“扩展”模式的原因是我有 win 和 mac 平台,它们使用稍微不同的变量替换语法($ vs %)。 I also have a few different build configuration - Debug/Release, 32bit/64bit.我还有一些不同的构建配置 - 调试/发布,32 位/64 位。

The code below actually works, but I had to duplicate steps for release and snapshot, one is enabled at a time.下面的代码确实有效,但我不得不重复发布和快照的步骤,一次启用一个。

stages:
    - stage


.upload_common:
    stage: stage
    tags: ["Win"]
    script: 
        - echo Uploading %TYPE%


.upload_snapshot:
    variables:
        TYPE: "Snapshot"
    except:
        - master

.upload_release:
    variables:
        TYPE: "Release"
    only:
        - master


upload_release:
    extends: 
        - .upload_common
        - .upload_release


upload_snapshot:
    extends: 
        - .upload_common
        - .upload_snapshot

The code gets much larger when snapshot/release configuration is multiplied by Debug/Release, Mac/Win, and 32/64bits.当快照/发布配置乘以调试/发布、Mac/Win 和 32/64 位时,代码会变得更大。 I would like to keep number of configurations at minimum.我想保持最少的配置数量。

Having ability to conditionally altering just a few variables would help me reducing this code a lot.有条件地改变几个变量的能力将帮助我减少很多代码。

Another addition in GitLab 13.7 are the rules:variables . GitLab 13.7 中的另一个新增功能是rules:variables This allows some logic in setting vars:这允许设置变量的一些逻辑:

job:
  variables:
    DEPLOY_VARIABLE: "default-deploy"
  rules:
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
      variables:                              # Override DEPLOY_VARIABLE defined
        DEPLOY_VARIABLE: "deploy-production"  # at the job level.
    - if: $CI_COMMIT_REF_NAME =~ /feature/
      variables:
        IS_A_FEATURE: "true"                  # Define a new variable.
  script:
    - echo "Run script with $DEPLOY_VARIABLE as an argument"
    - echo "Run another script if $IS_A_FEATURE exists"

Unfortunatelly YAML-anchors or GitLab-CI's extends don't seem to allow to combine things in script array of commands as of today. 不幸的是,到目前为止,YAML锚或GitLab-CI的extends似乎不允许在命令的script数组中进行组合。

I use built-in variable CI_COMMIT_REF_NAME in combination with global or job-only before_script to solve similar tasks without repeating myself. 我将内置变量CI_COMMIT_REF_NAME与全局或仅作业的before_script结合使用来解决类似的任务,而无需重复自己的工作。

Here is an example of my workaround on how to set environment variable to different values dynamically for PROD and DEV during delivery or deployment: 这是我的解决方法示例,该方法解决了如何在交付或部署过程中为PROD和DEV动态地将环境变量设置为不同的值:

.provide ssh private deploy key: &provide_ssh_private_deploy_key
  before_script:
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
    - |
      if [ "$CI_COMMIT_REF_NAME" == "master" ]; then
        echo "$SSH_PRIVATE_DEPLOY_KEY_PROD" > ~/.ssh/id_rsa
        MY_DYNAMIC_VAR="we are in master (PROD)"
      else
        echo "$SSH_PRIVATE_DEPLOY_KEY_DEV" > ~/.ssh/id_rsa
        MY_DYNAMIC_VAR="we are NOT in master (DEV)"
      fi
    - chmod 600 ~/.ssh/id_rsa


deliver-via-ssh:
  stage: deliver
  <<: *provide_ssh_private_deploy_key
  script:
    - echo Stage is deliver
    - echo $MY_DYNAMIC_VAR
    - ssh ...

Also consider this workaround for concatenation of "script" commands: https://stackoverflow.com/a/57209078/470108 另外,请考虑以下解决方法以串联“脚本”命令: https : //stackoverflow.com/a/57209078/470108

hopefully it helps. 希望它会有所帮助。

A nice way to prepare variables for other jobs is the dotenv report artifact .为其他作业准备变量的一个好方法是dotenv report artifact Unfortunately, these variables cannot be used in many places, but if you only need to access them from other jobs scripts, this is the way:不幸的是,这些变量在很多地方都不能使用,但是如果您只需要从其他作业脚本访问它们,则是这样:

# prepare environment variables for other jobs
env:
  stage: .pre
  script:
    # Set application version from GIT tag or fake it
    - echo "APPVERSION=${CI_COMMIT_TAG:-0.1-dev-$CI_COMMIT_REF_SLUG}+$CI_COMMIT_SHORT_SHA" | tee -a .env
  artifacts:
    reports:
      dotenv: .env

In the script of this job you can conditionally prepare and write your environment values into a file, then make a dotenv artifact out of it.在此作业的脚本中,您可以有条件地准备环境值并将其写入文件,然后从中制作 dotenv 工件。 Subsequent - or better yet dependent - jobs will pick up the variables for their scripts from there.后续 - 或者更好的依赖- 作业将从那里获取脚本的变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM