Skip to content
On this page

总结

  1. 在 GitHub Actions 中可以通过 Contexts 去获取上下文信息。 每个上下文都是一个包含属性的对象,这些属性可以是字符串或其他对象。利用 github、runner、jobs、steps 上下文可以获取关于当前工作流的相关信息,例如触发事件、分支名、仓库名,Commit Id等等
  2. 环境变量也作为上下文信息中的一种,可以读取、修改。获取相关信息可以在 CI 中用于:项目打包配置、连接服务器配置、测试环境域名前缀等

提问

  • [ ] 你们项目中是如何管理环境变量的

  • [x] 在 CI 中获取当前分支名 - run: echo $GITHUB_REF_NAME

1. 前提提要、场景

环境变量的使用场景很多

  • 比如在 OSS 篇使用宿主机的环境变量,存储云服务的权限
  • CRA 使用环境变量 PUBLIC_URL 配置静态资源的基础路径
  • 前端的异常监控服务中还会用到 Git 的 Commit/Tag 作为 Release 方便定位代码,其中 Commit/Tag 的名称从环境变量中获取。

2. 环境变量

Linux 系统中,使用 env 列出所有环境变量,可以环境变量进行修改与获取操作,export 设置环境变量,$<name> 获取环境变量。

sh
$ env
KEY=demo

$ echo $KEY
demo

$ printenv KEY # 或者通过 printenv 获取环境变量
demo


$ export KEY=demo2 # 设置环境变量

$ echo $KEY
demo2

$ echo ${NAME:-demo} # 获取环境变量 Name, 默认值为 demo

我们在前后端,都会用到大量的环境变量。环境变量可将非应用层内数据安全地注入到应用当中
Node.js 中可通过 process.env.<name> 进行获取。

2. CI 中的环境变量

CI 作为与 Git 集成的工具,其中注入了诸多与 Git 相关的环境变量。

例如 GitHub 中的 Github Actions virables

环境变量描述
CI当前环境是否在 CI 中,true
GITHUB_REPOSITORY仓库名称。
GITHUB_EVENT_NAME触发当前 CI 的 Webhook 事件名称
GITHUB_SHA当前的 Commit Id。
GITHUB_REF_NAME当前的分支名称
GITHUB_HEAD_REF触发工作流的合并分支,仅在 pull_request or pull_request_target 有效

GitLab 中的 Gitlab CI virables

环境变量描述
CI当前环境是否在 CI 中,true
CI_PROJECT_PATH仓库名称。
CI_COMMIT_SHORT_SHA当前的 Commit Id。
CI_COMMIT_REF_NAME当前的分支名称
  1. Commit Id / Tag 可作为版本号,注入到日志系统与 Sentry 中追踪异常。
    如,当在异常系统中收到一条报警,查看其 Commit Id / Tag 便可定位到从哪次部署开始出现问题,或者哪次代码提交开始出现问题。
  2. Branch Name 可作为 Preview 前缀。

3. CI 中设置环境变量

在 Github Actions 中,可通过 env 设置环境变量,并可通过 $GITHUB_ENV 在不同的 Step 共享环境变量。

设置环境变量:echo "{environment_variable_name}={value}" >> $GITHUB_ENV

yml
# 如何在 Github Actions 中设置环境变量
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable
- run: echo $KEY
  env:
    KEY: demo

- name: Check GITHUB_ENV
  run: |
    echo $GITHUB_ENV
- run: echo "KEY1=$(echo demo)" >> $GITHUB_ENV
- run: echo $KEY1

4. 环境变量 - CI

不同的 CI 产品会在构建服务器中自动注入环境变量。例如自动执行 export CI=true

测试、构建等工具均会根据环境变量判断当前是否在 CI 中,如果在,则执行更为严格的校验。 如 create-react-app

指令/场景本地CI
npm test交互式直接执行
ESLint 报错警告(Warn)异常退出

因此,可在本地中通过该环境变量进行更为严格的校验。比如在 git hooks 中。

sh
# 可使用该命令,演示在 CI 中的表现
$ CI=true npm run test

$ CI=true npm run build

5. CI 中验证环境变量

在 GitHub Actions 中可以通过 Contexts 去获取上下文信息。
有 github、env、jobs、steps 等等上下文,详细看上方连接,使用方法 ${{ <context> }},可以结合表达式一起使用 Expressions,例如 ${{ toJSON(github) }}

yml
name: CI Env Check
on: [push]
jobs:
  env:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: echo $CI
      - run: echo $GITHUB_REPOSITORY
      - run: echo $GITHUB_EVENT_NAME
      - run: echo $GITHUB_SHA
      - run: echo $GITHUB_REF_NAME
      - run: echo $GITHUB_HEAD_REF
      - name: Dump GitHub context
        run: echo '${{ toJSON(github) }}'

6. 项目的环境变量管理

6.1 项目的环境变量,可通过以下方式进行设置

  1. 读取本地/宿主机拥有环境变量
  2. CI 拥有环境环境变量,当然 CI Runner 可认为是宿主机,CI 也可传递环境变量 (命令式或者通过 Github/Gitlab 手动操作)
  3. Dockerfile 可传递环境变量
  4. docker-compose 可传递环境变量
  5. kubernetes 可传递环境变量 (env、ConfigMap、secret)
  6. 一些配置服务,如 consulvault

6.2 一般前端项目可进行以下配置

  1. 敏感数据:在 vault 或者 k8s 的 secket 中注入环境变量,也可通过 Github/Gitlab 设置中进行注入环境变量
  2. 非敏感数据:在项目目录 .env 中维护
  3. Git/OS相关的:相关通过 CI 注入环境变量