gitlab高级功能之 CICD Steps

CICD Steps

    • [1. 介绍](#1. 介绍)
    • [2. 定义 Steps](#2. 定义 Steps)
      • [2.1 Inputs](#2.1 Inputs)
      • [2.2 Outputs](#2.2 Outputs)
    • [3. Using steps](#3. Using steps)
      • [3.1 Set environment variables](#3.1 Set environment variables)
      • [3.2 Running steps locally](#3.2 Running steps locally)
    • [4. Scripts](#4. Scripts)
    • [5. Actions](#5. Actions)
      • [5.1 已知的问题](#5.1 已知的问题)
    • [6. 表达式](#6. 表达式)
    • [7. 实操](#7. 实操)
      • [7.1 单个step](#7.1 单个step)
      • [7.2 多个step](#7.2 多个step)
      • [7.3 复用steps](#7.3 复用steps)
      • [7.4 添加output到step](#7.4 添加output到step)
      • [7.5 使用远程step](#7.5 使用远程step)

1. 介绍

  • Steps是作业中可重用且可组合的部分。
  • 每个Step都定义可由其他Steps使用的结构化输入和输出。
  • Step可以来自本地文件、GitLab.com 存储库或任何其他 Git 源。

Steps 是用于运行作业的 shell 脚本的替代方案。它们提供了更多的结构,可以组合,并且可以测试和重用。 exec:命令是通过使用 Exec 系统调用来运行的,而不是通过运行 shell 来运行。

2. 定义 Steps

Steps在 step.yml 文件中定义。每个文件都有两个文档:规范和定义。

  • 规范提供了输入、输出、类型、描述和默认值
  • 定义提供了该步骤的实现。步骤定义有两种:
    • exec 类型,执行命令

      # (spec goes here)
      ---
      # Example exec definition
      exec:
      command: [ docker, run, -it, ubuntu, uname, -a ]
      
    • steps类型,运行一系列其他步骤

      # (spec goes here)
      ---
      # Example steps definition
      steps:
        - name: greet_user
          step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
          inputs:
            echo: hello ${{ inputs.name }}
        - name: print_system_information
          step: ./my-local-steps/uname
      

2.1 Inputs

Inputs可以是以下类型:

  • string
  • number
  • boolean
  • array
  • struct

默认输入类型是string。,如果输入没有定义默认值,那么它是必需的。

默认值不能使用仅在步骤定义中允许的表达式 (${{ }})。

2.2 Outputs

Outputs可以是以下类型:

  • string
  • number
  • boolean
  • array
  • struct
  • raw_string
  • step_result

outputs会写入 ${{ output_file }},格式为 key=value,其中 key 是输出的名称。除非类型为 raw_string,否则值应以 JSON 格式写入。

Steps写入的值类型必须与声明的类型匹配,默认的输出类型为 raw_string。

特殊的输出类型 step_result 用于将步骤的执行委托给其他步骤。例如,script 和 action-runner 步骤。

Steps类型定义中的输出使用表达式来从子步骤的输出进行聚合。由于规范中不允许使用表达式,因此 outputs 关键字出现在定义中。为了保持封装性并允许重构,调用者无法直接访问子步骤的输出。

3. Using steps

关键字 step 指向远程或本地steps;

  • 远程steps引用由 Git 仓库的 URL、符号 @ 和标签或分支(版本)组成。steps运行器会在仓库根目录下查找名为 step.yml 的文件。

  • 本地steps以 . 开头,指向一个目录,步骤运行器会在该目录中查找 step.yml 文件。本地引用始终使用路径分隔符 /,无论操作系统是什么。在加载文件时,会使用适合操作系统的分隔符。

    Example job using steps

    my-job:
    run:
    - name: greet_user
    step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
    inputs:
    echo: hello $[[ GITLAB_USER_LOGIN ]]
    - name: print_system_information
    step: ./my-local-steps/uname

要在作业中使用steps,请在变量中提供steps并调用作业脚本关键字的steps运行程序。史诗 11525 中建议支持使用作业中的步骤作为 GitLab CI 管道配置中的运行关键字。

# Example work-around until run keyword is implemented
my-job:
  image: registry.gitlab.com/gitlab-org/step-runner:v0
  variables:
    STEPS: |
      - name: greet_user
        step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
        inputs:
          echo: hello $GITLAB_USER_LOGIN
      - name: print_system_information
        step: ./my-local-steps/uname
  script:
    # Run the step-runner's ci command which ready from the STEPS environment variable
    - /step-runner ci

3.1 Set environment variables

你不需要为steps声明环境变量。任何以 key=value 形式写入 ${{ export_file }} 的导出都会添加到全局执行环境中。导出的值是纯字符串(无 JSON)。

你可以在steps执行期间使用 env 关键字来临时设置环境变量:

# Example job using env
my-job:
  run:
    - name: greet_user
      step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
      env:
        USER: $[[ GITLAB_USER_LOGIN ]]
      inputs:
        echo: hello ${{ env.USER }}

Steps定义还可以临时设置环境变量

# (spec goes here)
---
# Example step definition using env
env:
  USER: ${{ inputs.user }}
steps:
  - name: greet_user
    step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
    inputs:
      echo: hello ${{ env.USER }}

环境变量的优先顺序是: steps定义 -> steps参考(调用步骤) -> 全局环境

Steps定义中设置的环境变量会覆盖调用步骤时设置的变量,依此类推。

3.2 Running steps locally

要在本地运行steps,请下载 step-runner 并运行 ci 命令。这与用于在生产中运行步骤的二进制文件相同。

STEPS=$(yq '."my-job"'.run .gitlab-ci.yml) step-runner ci

您可以使用 delve 进行调试。在 pkg/runner.go) 中的 Run 处设置断点。

STEPS=$(yq '."my-job"'.run .gitlab-ci.yml) dlv debug . ci

4. Scripts

虽然通常使用steps代替 shell 脚本,但有时仍然需要 shell 脚本。 script 关键字将自动选择正确的 shell 并运行脚本。

# Example job using script
my-job:
  run:
    - name: greet_user
      script: echo hello $[[ GITLAB_USER_LOGIN ]]

仅支持 bash shell

5. Actions

您可以使用 action 关键字运行 GitHub 操作。输入和输出的工作方式与步骤相同。步骤和操作可以互换使用。

# Example job using action
my-job:
  run:
    - name: greet_user
      step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@v1
      inputs:
        echo: hello $[[ GITLAB_USER_LOGIN ]]
    - name: greet_user_again
      action: mikefarah/yq@master
      inputs:
        cmd: echo ["${{ steps.greet_user.outputs.echo }} again!"] | yq .[0]

5.1 已知的问题

GitLab 中运行的操作不支持直接上传artifacts。artifacts必须写入文件系统和缓存,并使用现有的artifacts关键字进行选择。

6. 表达式

表达式是一种用双大括号 (${{ }}) 括起来的mini语言,它们可以引用inputsenv(步骤共享的环境)和先前步骤的输出(steps.<step_name>.outputs)。

表达式还可以引用work_dir,它是构建目录。 step_dir 缓存步骤定义和关联文件。以及output_file 和export_file,这是输出和导出的写入位置。

表达式与模板插值不同,模板插值使用双方括号 ($[[ ]]) 并在作业生成期间进行评估。表达式在作业环境中执行步骤之前进行计算。

7. 实操

cat stap.yml

# 规范有一个名为 who 的输入, who 是可选的,默认值为 world
spec:
  inputs:
    who:
      default: world
# 使用 三重破折号 (---) 将文件分隔为两个 YAML 文档:在 spec 之后添加第二个 YAML 文档,第二个文件是实现,就像函数体一样,使用 exec 键
---
exec:
  command: # bash 和 -c 参数启动 Bash shell 并从命令行参数获取脚本输入。除了 shell 脚本之外,您还可以使用命令来执行 docker 或 terraform 等程序。
    - bash
    - -c
    - "echo hello ${{ inputs.who }}" # echo hello ${{ input.name }} 参数包含 ${{ }} 内的表达式。表达式在最后可能的时刻进行计算,并且可以访问当前的执行上下文。此表达式访问输入并读取 who 的值。如果定义了who,则用定义的值替换;如果缺省没有定义who,则使用默认值。

7.1 单个step

cat .gitlab-ci.yml

stages:   # List of stages for jobs, and their order of execution
  - build
  - test
  - deploy

hello-world:
  variables:
    STEPS:
      expand: false
      value: |
        - name: hello_world # 每个调用都会被赋予一个名称,以便您可以在后续步骤中引用输出
          step: . # 每次调用都指定要运行的步骤。本地引用 (.) 指向存储库的根目录
  image: registry.gitlab.com/gitlab-org/step-runner:v0
  script:
    - /step-runner ci # 作业脚本调用位于step-runner:v0 映像中的step-runner ci



7.2 多个step

stages:   # List of stages for jobs, and their order of execution
  - build
  - test
  - deploy

hello-world:
  variables:
    STEPS:
      expand: false
      value: |
        - name: hello_world
          step: .
        - name: hello_steps
          step: .
          inputs:
            who: gitlab steps
  image: registry.gitlab.com/gitlab-org/step-runner:v0
  script:
    - /step-runner ci

7.3 复用steps




7.4 添加output到step

将output添加到你的 hello step中

# 规范有一个名为 who 的输入, who 是可选的,默认值为 world
spec:
  inputs:
    who:
      default: world
  outputs: # 在本规范中,定义了一个没有默认值的输出问候语。因为没有默认值,所以需要输出问候语;输出以 key=value 的形式写入文件 ${{ output_file }} (在运行时提供)。
    greeting: {}
# 使用 三重破折号 (---) 将文件分隔为两个 YAML 文档:在 spec 之后添加第二个 YAML 文档,第二个文件是实现,就像函数体一样,使用 exec 键
---
exec:
  command: # bash 和 -c 参数启动 Bash shell 并从命令行参数获取脚本输入。除了 shell 脚本之外,您还可以使用命令来执行 docker 或 terraform 等程序。
    - bash
    - -c
    - "echo greeting=hello ${{ inputs.who }} | tee ${{ output_file }}" # 此步骤运行 echo greeting=hello ${{inputs.who}} 并将输出发送到日志和输出文件 (tee ${{output_file}})。
spec:
  outputs:
    all_greetings: {}
---
steps:
  - name: hello_world
    step: ./hello
  - name: hello_steps
    step: ./hello
    inputs:
      who: gitlab steps
outputs:
  all_greetings: "${{ steps.hello_world.outputs.greeting }} and ${{ steps.hello_steps.outputs.greeting }}"


7.5 使用远程step

cat .gitlab-ci.yml

hello-world:
  variables:
    STEPS:
      expand: false
      value: |
        - name: hello_everybody
          step: .
        - name: all_my_greetings
          step: gitlab.com/gitlab-org/ci-cd/runner-tools/echo-step@master
          inputs:
            echo: "all my greetings say ${{ steps.hello_everybody.outputs.all_greetings }}"
  image: registry.gitlab.com/gitlab-org/step-runner:v0
  script:
    - /step-runner ci
相关推荐
Vince丶4 小时前
window 安装GitLab服务器笔记
笔记·gitlab·gitlab服务器
雨声不在9 小时前
gitlab多项目流水线
gitlab
你脸上有BUG9 小时前
【Git】ssh如何配置gitlab+github
git·ssh·gitlab·github
凤山老林2 天前
Docker 部署 GitLab
运维·docker·容器·gitlab
boss-dog3 天前
Gitlab中如何进行仓库迁移
运维·服务器·gitlab
一叶轻舟随风行3 天前
GitPuk快速安装配置教程(入门级)
gitlab·gitpuk安装教程
Swift社区3 天前
【GitLab CI/CD 实践】从 0 到 1 搭建高效自动化部署流程
运维·ci/cd·自动化·gitlab
执着11114 天前
【Gitlab】虚拟机硬盘文件丢失,通过xx-flat.vmdk恢复方法
gitlab
梁萌4 天前
03-DevOps-安装并初始化Gitlab
运维·gitlab·devops
明月心9524 天前
采用gitlab的package registry 方式 通过api 上传发布包,解决git命令拉取大文件异常退出问题
git·gitlab