使用 GitLab CI 的多个命名环境的相同步骤

Same steps for multiple named environments with GitLab CI

有没有办法配置多个专门命名的环境(具体来说,teststageprod)?

在他们的文档 (https://docs.gitlab.com/ce/ci/environments.html) 中,他们讨论了动态创建的环境,但它们都是基于提交的。

除了更换 slug 外,我的所有构建步骤都相同:

deploy_to_test:
    environment:
         name: test
         url: ${CI_ENVIRONMENT_SLUG}.mydomain.com
    scripts:
         - deploy ${CI_ENVIRONMENT_SLUG}

deploy_to_stage:
    environment:
         name: stage
         url: ${CI_ENVIRONMENT_SLUG}.mydomain.com
    scripts:
         - deploy ${CI_ENVIRONMENT_SLUG}

 deploy_to_prod:
    environment:
         name: prod
         url: ${CI_ENVIRONMENT_SLUG}.mydomain.com
    scripts:
         - deploy ${CI_ENVIRONMENT_SLUG}

有什么方法可以将其压缩成一组指令吗?类似于:

deploy:
    environment:
         url: ${CI_ENVIRONMENT_SLUG}.mydomain.com
    scripts:
         - deploy ${CI_ENVIRONMENT_SLUG}

是的,您可以使用 anchors。如果我正确地遵循文档,您将使用隐藏键 .XX 重写它,然后使用 <<: *X.

应用它

例如定义键:

.job_template: &deploy_definition
    environment:
         url: ${CI_ENVIRONMENT_SLUG}.mydomain.com
    scripts:
         - deploy ${CI_ENVIRONMENT_SLUG}

然后可以使用<<: *job_template写入所有块。我假设 environment 会将名称与预定义的 URL.

合并
deploy_to_test:
   <<: *deploy_definition
    environment:
         name: test

deploy_to_stage:
   <<: *deploy_definition
    environment:
         name: stage

 deploy_to_prod:
   <<: *deploy_definition
    environment:
         name: prod

上面 link 的完整文档部分:

YAML has a handy feature called 'anchors', which lets you easily duplicate content across your document. Anchors can be used to duplicate/inherit properties, and is a perfect example to be used with hidden keys to provide templates for your jobs.

The following example uses anchors and map merging. It will create two jobs, test1 and test2, that will inherit the parameters of .job_template, each having their own custom script defined:

.job_template: &job_definition  # Hidden key that defines an anchor named 'job_definition'
  image: ruby:2.1
  services:
    - postgres
    - redis

test1:
  <<: *job_definition           # Merge the contents of the 'job_definition' alias
  script:
    - test1 project

test2:
  <<: *job_definition           # Merge the contents of the 'job_definition' alias
  script:
    - test2 project

& sets up the name of the anchor (job_definition), << means "merge the given hash into the current one", and * includes the named anchor (job_definition again). The expanded version looks like this:

.job_template:
  image: ruby:2.1
  services:
    - postgres
    - redis

test1:
  image: ruby:2.1
  services:
    - postgres
    - redis
  script:
    - test1 project

test2:
  image: ruby:2.1
  services:
    - postgres
    - redis
  script:
    - test2 project

除了提供的答案之外,我想添加另一种类似的方法来实现同样的事情,但它比使用模板然后将其合并到一个阶段更灵活。

您也可以创建一个隐藏密钥,但采用这种格式,例如,

.login: &login |
  cmd1
  cmd2
  cmd3
  ...

然后您可以使用星号“*”将其应用于不同的阶段,例如:

deploy:
  stage: deploy
  script:
    - ...
    - *login
    - ...

bake:
  stage: bake
  script:
    - ...
    - *login
    - ...

结果相当于:

deploy:
  stage: deploy
  script:
    - ...
    - cmd1
    - cmd2
    - cmd3
    - ...

bake:
  stage: bake
  script:
    - ...
    - cmd1
    - cmd2
    - cmd3
    - ...

Based on the resource of: https://gitlab.com/gitlab-org/gitlab-ce/issues/19677#note_13008199

至于模板实现,是"merged"。以我自己的经验,如果在合并模板后追加更多的脚本,模板脚本将被覆盖。而且您不能一次应用多个模板。只会执行最后的模板脚本。例如:

.tmp1: &tmp1
  script:
    - a
    - b

.tmp2: &tmp2
  script:
    - c
    - d

job1:
  <<: *tmp1
  <<: *tmp2
  stage: xxx

job2:
  <<: *tmp2
  stage: yyy
  script:
    - e
    - f

等效结果为:

job1:
  stage: xxx
  script:
    - c
    - d

job2:
  stage: yyy
  script:
    - e
    - f

如果不确定语法是否正确,只需将 .gitlab.yml 文件内容复制并粘贴到 "CI Lint" 进行验证。该按钮位于“管道”选项卡中。

以防万一:Gitlab 提供(自 11.3 起)一个 extends 关键字,可用于 "templates" yaml 条目(据我了解):

official doc

您是否尝试过为各种环境实现变量并为各种环境使用不同的作业?我已经为你想出了一个解决方案。

image: node:latest
variables:
  GIT_DEPTH: '0' 

stages:
  - build
  - deploy

workflow:
    rules:
      - if: $CI_COMMIT_REF_NAME ==  "develop"
        variables:
          DEVELOP: "true"
          ENVIRONMENT_NAME: Develop
          WEBSITE_URL: DEVELOP_WEBSITE_URL
          S3_BUCKET: (develop-s3-bucket-name)
          AWS_REGION: ************** develop
          AWS_ACCOUNT: ********develop

      - if: $CI_COMMIT_REF_NAME == "main" 
        variables:                                 
          PRODUCTION:  "true"
          ENVIRONMENT_NAME: PRODUCTION
          WEBSITE_URL: $PROD_WEBSITE_URL
          S3_BUCKET: $PROD-S3-BUCKET-NAME
          AWS_REGION: ************** (prod-region)
          AWS_ACCOUNT: ***********(prod-acct)
      - when: always 

build-app:
  stage: build
  script:
     #build-script
  environment: 
    name: $ENVIRONMENT_NAME

deploy-app:
  stage: deploy
  script:
     #deploy-script
  environment: 
    name: $ENVIRONMENT_NAME