如何根据工作流变量部署到不同的环境?

Posted

技术标签:

【中文标题】如何根据工作流变量部署到不同的环境?【英文标题】:How to deploy to different enviroments based on workflow variables? 【发布时间】:2022-01-11 22:40:41 【问题描述】:

我找到了following proposal 并对其进行了测试(参见代码示例),但无法使其工作。

我们在 Gitlab 14.3.4 上运行,如何确定此版本是否可用?如果此功能不起作用,如果我有不同的运行器用于我的 prod 一个用于开发环境,我该如何部署到不同的环境?到目前为止,我为每个环境使用其专用标签的管道 - 因为动态标签是 not available so far。

任何帮助将不胜感激 - 谢谢!

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
    - if: '$CI_PIPELINE_SOURCE == "parent_pipeline"'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: "$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS"
      when: never
    - if: '$CI_COMMIT_BRANCH =~ /^feature.*$/'
      variables:
        TARGET: dev
    - if: "$CI_COMMIT_BRANCH"

【问题讨论】:

【参考方案1】:

我认为您可能会混淆什么是可用的和不可用的(我认为您链接的答案也是如此)。您绝对可以使用变量来填充您的工作应该运行的运行程序,我今天在 SaaS 产品的工作流程中使用它。

使用变量来确定运行器标签仍然可能令人困惑,因为变量是否正常工作在很大程度上取决于您在哪里定义它。如果您的变量在 CI/CD 管道的 根范围 内(即,在*** variable 块内或 workflow 块内)它将正常工作。如果您尝试在作业范围内(即在job:rules:if:variables 块内)定义规则,它将无法正常工作。由于您上面的示例在工作流块中,因此它将正确选择您的标签并将其应用于下游作业。

您可以在此处查看更多信息:https://gitlab.com/gitlab-org/gitlab/-/issues/35742#note_704836498

这是一个证明动态标签的例子:

workflow:
  rules:
    - variables:
        RUNNER: shared-macos-amd64

test:
  image: alpine:latest
  tags:
    - $RUNNER
  script:
    - echo $CI_RUNNER_DESCRIPTION

这在 macos runner 上正确启动(并打印一个错误,因为我不在他们的测试版中):

【讨论】:

这个变量设置非常有效,你是对的 - 但你的跑步者选择示例不适合我。在工作流部分,我有一条规则,if: '$TARGET == null && $CI_COMMIT_BRANCH =~ /^feature.*$/ || $TARGET == "dev"' 设置了variables: RUNNER_ACCOUNT_SHELL: test-shell,但在工作中我得到一个“这个工作被卡住了,因为你没有任何在线的活跃跑步者或分配给他们的任何这些标签可用: $RUNNER_ACCOUNT_SHELL" 错误 该错误通常意味着您的变量设置不正确,因为该变量被解释为它没有值的字符串。如果您设置了一个基值(没有 if 检查),它是否正确解决了这个问题?如果是这样,您需要检查您的 if 检查以确保其正常工作。 我在第一个作业中“打印”了环境变量,并且以正确的方式分配了参数......可能是版本问题吗?【参考方案2】:

更新@Patrick 的答案,我让它工作并想描述我的解决方案。我的问题是由使用的变量引起的——当我使用 PR 进行测试时,我从未设置过 CI_COMMIT_BRANCH,但使用 CI_MERGE_REQUEST_SOURCE_BRANCH_NAME 它可以工作。

workflow:
  rules:
    # No build duplicates when committing to a branch with open pull request (PR)
    - if: "$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS"
      when: never
    # Deploy to development when PR from feature-branch
    - if: "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature.*$/"
      variables:
        TARGET: dev
    # Deploy to test when committing (after merging) to develop-branch
    - if: '$CI_COMMIT_BRANCH == "dev"'
      variables:
        TARGET: test
    # Deploy to staging when committing (after merging) to release-branch
    - if: '$CI_COMMIT_BRANCH =~ /^release\/.*$/'
      variables:
        TARGET: stage
    # Deploy to production when committing (after merging) to master-branch
    - if: '$CI_COMMIT_BRANCH == "main"'
      variables:
        TARGET: prod
    - if: '$CI_PIPELINE_SOURCE == "web"'
    - if: '$CI_PIPELINE_SOURCE == "parent_pipeline"'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: "$CI_COMMIT_BRANCH"

解决方法在于使用predefined variables。

CI_COMMIT_REF_NAME - 为其构建项目的分支或标签名称。 CI_COMMIT_BRANCH - 提交分支名称。在分支管道中可用,包括默认分支的管道。在合并请求管道或标签管道中不可用。 CI_BUILD_REF_NAME - 不清楚 CI_MERGE_REQUEST_SOURCE_BRANCH_NAME - 合并请求的源分支名称。 CI_MERGE_REQUEST_TARGET_BRANCH_NAME - 合并请求的目标分支名称。 CI_OPEN_MERGE_REQUESTS - 使用当前分支和项目作为合并请求源的最多四个合并请求的逗号分隔列表。如果分支具有关联的合并请求,则仅在分支和合并请求管道中可用。例如,gitlab-org/gitlab!333、gitlab-org/gitlab-foss!11。

【讨论】:

以上是关于如何根据工作流变量部署到不同的环境?的主要内容,如果未能解决你的问题,请参考以下文章

如何跨不同版本K8S,为有状态工作负载做蓝绿部署

工作的环境部署

如何从本地 VirtualBox / Vagrant 开发环境部署到生产环境?

如何将内部 MobileFirst 混合应用程序部署到专用的 Bluemix 环境?

从同一个 git 存储库部署到具有不同环境变量的弹性 beanstalk 上的不同环境

环境变量和工匠不在生产服务器上工作