如何在 GitHub Actions 中使用 env 文件?
Posted
技术标签:
【中文标题】如何在 GitHub Actions 中使用 env 文件?【英文标题】:How do I use an env file with GitHub Actions? 【发布时间】:2020-05-27 06:50:32 【问题描述】:我有多个环境(dev、qa、prod)并且我正在使用 .env 文件来存储机密等...现在我正在切换到 GitHub Actions,我想使用我的 .env 文件并声明它们进入 github 操作 yml 的 env
部分。
但是从我目前看到的情况来看,我似乎无法设置文件路径,我必须手动重新声明所有变量。
我应该如何进行最佳实践?
【问题讨论】:
嗨,OP!这有什么好运气吗?我也面临着与 Github Actions 相同的问题——试图找出一种方法来以某种方式存储不同环境的秘密变量。 基本上,您必须手动将各个 .env 文件的内容(例如.env.stage
、.env.production
)复制到相应的 GitHub Actions 秘密变量(例如 WEBSITE_ENV_STAGE
、WEBSITE_ENV_PRODUCTION
)中。然后在您的 GitHub Actions 工作流脚本中,从所需变量(如 echo "$ secrets.WEBSITE_ENV_STAGE " > .env
)创建 .env
文件,并在工作流中使用它。
我还有 2 种方法可以让您在项目中使用 .env
文件。见my answer below。
【参考方案1】:
这里的一个快速解决方案可能是在您需要之前手动创建.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
【讨论】:
您的解决方案更简单。非常感谢 这是最简单也是最好的解决方案。 我们有相同的解决方案,但这很麻烦,我有 36 个环境变量要编辑。 必须删除多余的 > 才能正常工作 尝试使用此解决方案时,我不断收到以下错误:`line 3: unexpected EOF while looking for matching `'。我能够通过单独传递秘密来解决它。我在下面发布了代码。【参考方案2】:执行此操作的最简单方法是将 .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
有多种方法可以确定$YOUR_ENVIRONMENT
,但通常可以从GITHUB_REF
对象中提取。您的应用程序应该能够根据需要从 .env 文件中读取数据。
【讨论】:
Github Secret 不是已经加密了吗?看起来您正在加密一个加密文件,而 Github 已经在进行解密以读取机密文件。 @Brettins 这里的.env
文件可能包含许多键。将它们编码为字符串的目的是,您无需在 github secrets 上逐一声明。
@brian ,这实际上似乎是我的情况的完美解决方案,但是我对 openssl 命令感到困惑,我们需要在哪里运行此命令?
@uneebmeer 您可以在终端中运行它以生成 base64 版本字符串。【参考方案3】:
编辑: 您使用的是 Circleci 上下文,因此您拥有每个环境的一组秘密。我知道他们正在努力将秘密带到组织层面,也许是团队层面......没有信息他们是否会创建像我们在 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
你这样做:
id: dotenv
uses: ./.github/actions/dotenv-action
然后你可以像这样引用alpine版本 $ steps.dotenv.outputs.version
【讨论】:
那个 .env 文件在哪里?因为它没有保存在 repo 中 - 这就是拥有 .env 文件的意义 好吧,它看起来像一个常见的模式(有一个 CI 任务正在读取的 .env 文件——例如参见circleci.com/orbs/registry/orb/anilanar/dotenv)。如果您可以提供一个变量作为任务的path
,这个答案看起来很适合您的问题。
@HRK44 “我想使用我的 .env 文件”我知道你已经有了它们,我想在 S3 或其他东西中。如果您拥有它们并且正在寻找安全存储,您可以存储在 S3 中并使用 aws secret+key 下载并添加到操作中。如果没有,您必须生成它们,将 github 机密打印到文件中,并使用 sed 替换占位符或对文件进行简单的回显,无论您喜欢什么。如果不是这种情况,请澄清您的情况。 nilleb 他正在从 Circleci 迁移到 Github,所以在这种情况下 orb 没有用
@Ayo 在 CircleCi 中很好,我们将环境存储在 CircleCi 中,我们有多个版本的环境(dev、qa、prod 等),但在 GitHub 操作中,我们只能存储一个版本的秘密。现在我们正在使用 Jenkins(其中存储了机密),并且根据构建类型,它将使用 dev/qa/prod 机密。我们如何使用 Github Actions 做到这一点?
好吧,我想我明白了。您使用的是 Circleci 上下文,因此您拥有每个环境的一组秘密。我知道他们正在努力将秘密带到组织级别,也许还有团队级别……没有信息他们是否会创建像我们在 CCI 中那样的上下文。我考虑过在 yml 上使用 $env_GITHUB_KEY 将 env 添加为秘密名称的前缀,例如 STAGE_GITHUB_KEY 或 INTEGRATION_GITHUB_KEY 作为一种解决方法......你怎么看?【参考方案4】:
我看到 3 种非常简单的方法可以让您的 .env
文件变量参与 GitHub 操作工作流程。它们的不同取决于您是将文件存储在存储库中(最差的做法)还是将其保留在存储库中(最佳做法)。
您将文件保存在存储库中:
有一些ready-made actions 允许读取.env
变量(例如Dotenv Action、Simple Dotenv)。
(简单,手动,更新时烦人.env
变量)您将文件保留在存储库之外:
您手动将各个.env
文件(例如.env.stage
、.env.production
)的内容复制到各个GitHub Actions secret variables(例如WEBSITE_ENV_STAGE
、WEBSITE_ENV_PRODUCTION
)中。
然后在您的 GitHub Actions 工作流脚本中,从所需的变量(如 echo "$secrets.WEBSITE_ENV_STAGE " > .env
)创建 .env
文件,并在工作流中使用它。
(虽然准备一次,但涉及更多,然后在本地计算机上更改您的 .env
变量,然后在 GitHub 上一键同步这些变量)如上面的第 2 项,文件是离开存储库。
dev
环境中的本地计算机上,您编写调用API 端点的NodeJS 脚本,并将.env
文件写入所需的GitHub Actions 秘密变量(如上至WEBSITE_ENV_STAGE
或同时写入阶段和生产变量一次);
这是在工作流中使用.env
文件变量的多种方式选择。使用任何符合您的偏好和情况。
【讨论】:
为什么这个投票被否决了?我觉得这是一个很好的答案。 这是最好的答案【参考方案5】:另一种选择是使用来自 github 的 Environments 功能。尽管免费计划中的私人回购不提供此功能。 您可以在存储库、配置文件/组织级别和环境中设置范围变量。靠近存储库的配置变量优先于其他变量。
【讨论】:
【参考方案6】:您还可以使用来自 github-marketplace 的专用 github action
创建 .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
根据您在 github 存储库中为机密定义的值,这将创建一个 .env
文件,如下所示:
DEBUG: false
SOME_API_KEY: "123456abcdef"
SECRET_KEY: password123
更多信息:https://github.com/marketplace/actions/create-env-file
【讨论】:
【参考方案7】:我遇到了同样的问题。我想要的是将 .env 文件上传到我的服务器,而不是在我的 Github 存储库中定义 env 变量。由于我没有跟踪我的 .env 文件,所以每次我的工作流程运行时 .env 文件都会被删除。所以我所做的是:
-
在我的服务器项目根目录中添加了
.env
文件。
在我的工作流程中的actions/checkout@v2
中的with
键下添加了clean: false
例如:
jobs:
build:
runs-on: self-hosted
strategy:
matrix:
node-version: [14.x]
- uses: actions/checkout@v2
with:
clean: 'false'
这可以防止 git 删除未跟踪的文件,例如 .env。欲了解更多信息,请参阅:actions/checkout
【讨论】:
【参考方案8】:我尝试使用公认的解决方案,但 GitHub 操作抱怨 shell 命令。我不断收到此错误:line 3: unexpected EOF while looking for matching ``'
我没有直接在 shell 脚本中引用秘密,而是将它们单独传递。
- name: Create env file
run: |
touch .env
echo POSTGRES_USER=$POSTGRES_USER > .env
echo POSTGRES_PASSWORD=$POSTGRES_PASSWORD > .env
cat .env
env:
POSTGRES_USER: $ secrets.POSTGRES_USER
POSTGRES_PASSWORD: $ secrets.POSTGRES_PASSWORD
【讨论】:
【参考方案9】:另一种方法是按照https://docs.github.com/en/actions/security-guides/encrypted-secrets#limits-for-secrets 中的描述进行操作
所以基本上将您的.env
文件视为“大秘密”。在这种情况下,加密的.env
文件会保留在您的存储库中,这应该没问题。然后在您的操作中有一个步骤来解密.env
文件。
这消除了必须在 .env
中创建每个单独的秘密作为 Github 秘密的开销。在这种情况下,唯一需要维护的 Github 密码是加密密码。如果您有多个.env
文件,例如qa.env
、prod.env
等...我强烈建议为每个文件使用不同的加密密码,然后将每个加密密码作为“环境机密”存储在 Github 中,而不是“repo secret”(如果您喜欢使用 Github 环境。请参阅https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment)。
如果您不想在您的存储库中提交(加密的).env
文件,那么我将使用https://***.com/a/64452700/1806782 中描述的 base64 方法(类似于https://docs.github.com/en/actions/security-guides/encrypted-secrets#storing-base64-binary-blobs-as-secrets 中的内容),然后创建用于托管编码内容的新 Github 密码。
对于像我这样讨厌手动重复性任务的人来说,如今可以使用 Github CLI 工具轻松编写 Github 秘密创建脚本。看
https://cli.github.com/manual/gh_secret_set 。它还支持从 env 文件“批量”创建秘密(参见 -f
、--env-file
标志)
【讨论】:
【参考方案10】:您需要在存储库的“秘密”部分定义环境变量。然后,您可以在工作流程中简单地使用您的秘密。
示例用法:
- uses: some-action@v1
env:
API_KEY: $ secrets.API_KEY
SECRET_ID: $ secrets.SECRET_ID
with:
password: $ secrets.MY_PASSWORD
这是文档:
https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets
【讨论】:
这没有回答我的问题,我说的是如何用这个系统以最好的方式处理多个环境(dev、qa、stage、prod 等)?跨度>以上是关于如何在 GitHub Actions 中使用 env 文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 GitHub Actions 中使用 env 文件?
如何在 GitHub Actions 中构建的 Dockerfile 中使用 github 令牌并尝试克隆私有存储库?