如何在 GitHub Actions 中使用 env 文件?

HRK*_*K44 18 github environment-variables github-actions

我有多个环境(dev、qa、prod),我使用 .env 文件来存储机密等......现在我要切换到 GitHub Actions,我想使用我的 .env 文件并将它们声明到env部分github 操作 yml。

但从我目前所见,似乎我无法设置文件路径,我必须手动重新声明所有变量。

作为最佳实践,我应该如何进行?

Val*_*Shi 41

我建议使用 3 种非常简单的方法将.env文件变量纳入 GitHub Actions 工作流程。它们的不同取决于您是将文件存储在存储库中(最差做法)还是将其保留在存储库之外(最佳做法)。

  1. 您将.env文件保存在存储库中:

  2. 简单,手动,更新.env变量时很烦人)您将文件保留在存储库之外(保留在那里并保持更新.env.example):

    • 您手动将各个文件的内容.env (例如.env.stage.env.production)复制到各自的 GitHub Actions秘密变量(例如WEBSITE_ENV_STAGEWEBSITE_ENV_PRODUCTION)中。

    • 然后在 GitHub Actions 工作流程脚本中.env从所需的变量创建文件,如下所示echo "${{secrets.WEBSITE_ENV_STAGE }}" > .env,并在工作流程中使用它。

  3. 虽然准备一次,然后.env在本地计算机上更改变量,然后一键在 GitHub 上同步这些变量,但涉及更多一点)如上面的第 2 项所示,该文件不在存储库中。

    • 现在,您可以使用 GitHub Actions API创建或更新密钥。在环境中的本地计算机上,dev编写调用 API 端点的 NodeJS 脚本,并将.env文件写入所需的 GitHub Actions 秘密变量(如上所述,同时写入WEBSITE_ENV_STAGE或同时写入阶段和生产变量);

.env这是在工作流程中使用文件变量的多种方法。使用任何符合您的喜好和情况的内容。

仅供参考,还有第四种方式,可以使用一些第三方服务,例如Dotenv VaultHasiCorp Vault(还有更多此类服务),您可以在其中保存秘密变量以读取这些变量,以便.env在构建时使用 CI/CD 管道创建文件。阅读此处了解详细信息。

  • 将 .env 保留在存储库中是不好的做法,并且存在潜在的安全问题,尤其是在拥有 AWS 凭证或任何类型的云提供商凭证时。 (9认同)
  • @JeffGruenbaum 我在回答中明确提到了这一点。尽管将“.env”文件放入 VCS 中是最糟糕的做法,但它在现实中被许多人使用。以及许多其他最糟糕的做法。 (5认同)

小智 39

这里的一个快速解决方案可能是.env在需要之前手动创建文件。

- name: Create env file
        run: |
          touch .env
          echo API_ENDPOINT="https://xxx.execute-api.us-west-2.amazonaws.com" >> .env
          echo API_KEY=${{ secrets.API_KEY }} >> .env
          cat .env

Run Code Online (Sandbox Code Playgroud)

  • 我们有相同的解决方案,但这很麻烦,我有 36 个环境变量需要编辑。 (10认同)
  • @aRtoo 您可以将整个 env 文件粘贴到一个名为“ENV_FILE”的密钥中,然后执行“echo "${{secrets.ENV_FILE }}" > .env`。我用稍微更好的方法更新了答案 (3认同)
  • 注意:**切勿将结构化数据用作秘密**。结构化数据可能会导致日志中的秘密编辑失败,因为编辑很大程度上依赖于找到特定秘密值的精确匹配。例如,请勿使用 JSON、XML 或 YAML(或类似内容)的 blob 来封装机密值,因为这会显着降低正确编辑机密的可能性。相反,为每个敏感值创建单独的秘密。参考:https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-secrets (3认同)
  • @DollarAkshay,您在编辑时不应该添加自己的内容,而应该为了清晰起见而更新语言。您的添加完全属于另一个答案。 (2认同)

ank*_*512 9

github action您还可以使用github-marketplace 中的专用工具来创建.env文件。

用法示例:

name: Create envfile

on: [push]

jobs:

  create-envfile:
 
    runs-on: ubuntu-18.04
 
    steps:
    - name: Make envfile
      uses: SpicyPizza/create-envfile@v1
      with:
        envkey_DEBUG: false
        envkey_SOME_API_KEY: "123456abcdef"
        envkey_SECRET_KEY: ${{ secrets.SECRET_KEY }}
        file_name: .env
Run Code Online (Sandbox Code Playgroud)

根据您在 github 存储库中为机密定义的值,这将创建一个.env如下所示的文件:

DEBUG: false
SOME_API_KEY: "123456abcdef"
SECRET_KEY: password123
Run Code Online (Sandbox Code Playgroud)

更多信息: https: //github.com/marketplace/actions/create-env-file


Ayo*_*Ayo 8

编辑:您使用的是 Circleci Contexts,因此您拥有每个 env 的一组秘密。我知道他们正在努力将秘密带到组织级别,也许是团队级别……如果他们会像我们在 CCI 中那样创建某种上下文,则没有任何信息。

我已经考虑在 yml 上使用 ${env}_GITHUB_KEY 添加 env 作为秘密名称的前缀,例如 STAGE_GITHUB_KEY 或 INTEGRATION_GITHUB_KEY 作为现在的解决方法......你怎么看?

--- 原始答案:如果我理解你的话,你已经将 dotenv 文件存储在某个地方,并且你想将所有这些秘密注入到步骤中,而不必手动将它们添加到 github 秘密并在你迁移的每个工作流中进行映射... 对?

有人执行了一项操作,该操作读取 dotenv 文件并将其值放入输出中,因此您可以在进一步的步骤中使用它们链接。这是链接:https : //github.com/marketplace/actions/dotenv-action

.env 文件中存在的任何内容都将转换为输出变量。例如带有内容的 .env 文件:

VERSION=1.0
AUTHOR=Mickey Mouse
Run Code Online (Sandbox Code Playgroud)

你做:

id: dotenv
uses: ./.github/actions/dotenv-action
Run Code Online (Sandbox Code Playgroud)

然后稍后你可以像这样引用 alpine 版本 ${{ steps.dotenv.outputs.version }}


小智 8

最简单的方法是创建 .env 文件作为 github 机密,然后在您的操作中创建 .env 文件。
所以第 1 步是在 github 中创建 .env 文件作为一个秘密作为 base64 编码的字符串:
openssl base64 -A -in qa.env -out qa.txt
或者
cat qa.env | base64 -w 0 > qa.txt
然后在你的行动中,你可以做类似的事情

- name: Do Something with env files
  env:
    QA_ENV_FILE: ${{ secrets.QA_ENV_FILE }}
    PROD_ENV_FILE: ${{ secrets.PROD_ENV_FILE }}
  run: |
    [ "$YOUR_ENVIRONMENT" = qa ] && echo $QA_ENV_FILE | base64 --decode > .env
    [ "$YOUR_ENVIRONMENT" = prod ] && echo $PROD_ENV_FILE | base64 --decode > .env
Run Code Online (Sandbox Code Playgroud)

有多种确定方法,$YOUR_ENVIRONMENT但通常可以从GITHUB_REF对象中提取。您的应用程序应该能够根据需要读取 .env 文件。

  • @Brettins 这里的 .env 文件可能包含许多键。将它们编码成字符串的目的是这样你就不需要在 github 上声明每一个秘密。 (7认同)
  • @brian,这实际上似乎是我的情况的完美解决方案,但是我对 openssl 命令感到困惑,我们需要在哪里运行这个命令? (2认同)