[扩展推荐] Laravel Env Sync —— 让你本地的 .env 跟上项目的 .env.example 的变更
Laravel的 .env
文件令人着迷。它表面上看起来很纯真,但是在友好的表象之下,它是能够将您的整个应用程序跪倒的恶性野兽。在这篇文章中,我们将探讨管理不当的 .env
文件甚至使经验最丰富的开发人员都无法正常工作的一些方法,并介绍一种简单有效的技术来避免这些陷阱。
带上小板凳,让我从战壕中给你讲一个故事,这个故事是关于一个粗暴的开发人员(由你扮演,此时你正在 Web 开发职业生涯的高峰和低谷中翱翔)。
问题
示例1:在我的机器上正常运行
您的队友 Robin 在提交代码给 QA 之前让你进行一些新功能的代码审查。您可以通过运行 git pull the-feature-branch
,composer install
和 npm run dev
快速搭建本地环境。您的第一个操作是运行 phpunit
以确保基本面均已覆盖,但立即会遇到一个报错。您决定打开浏览器以模仿现实测试该功能,并遇到各种 500 和 404。担心您的队友没有运行单元测试而浪费了您的时间,您在团队的公共 Slack 频道中写了一个令人讨厌的正式而屈尊的消息:“嘿 Robin,在您的功能分支上测试失败了。以后,请确保在提交 PR 之前运行完整的测试套件,谢谢。”她礼貌地回答“嗯……他们正在我的机器上正常运行🤔”。
沮丧,但有点担心您过早发出了警报,您更深入地研究了错误日志,发现它们充满了丑陋的 [2018-02-28 16:21:36] local.ERROR: cURL error 3: <url> malformed
报错。二十分钟后,您将问题追溯到-您猜到了-新引入的 API 端缺少 .env
变量。希望挽回您仅剩的尊严并重新获得制高点,您搜索了分支的 .env.example
文件,以查找丢失的变量。但是,Robin 已经努力地添加了新的 .env
变量。有点尴尬,您假装若无其事地回应她,并抢了一个当之无愧的道歉“啊,知道了,谢谢!”
在办公室的另一天...
问题: pull 或 checkout 代码而忘记检查新添加的 .env.example
变量。
解决方案:一个在 git pull
或 git checkout
上自动运行的命令,并警告您的 .env
文件缺少 .env.example
文件中新添加的变量。
例子2: I Definitely Added That… Right?
现在轮到你叫 Robin 来 review 代码了,Robin 的脾气比你还要暴躁,她私信问你:“我好像没法让你的PR在我的本地环境正常运行,介意我们共享屏幕来看一下吗?“ 你们开始了讨论,并通过你们的智慧,快速定位到问题:她在 .env
文件中缺少了一个环境变量。因为检查 .env.example
文件是她代码 review 的一部分,她知道是你忘记了添加这个环境变量。她及时添加了这个新的环境变量,然后把代码推送到了仓库,以确保你和她的代码相同。你再一次感到了羞愧和尴尬,也感谢她的怜悯。你保证下次会记得
问题: 推送了新代码,但是忘记了添加新的环境变量到 .env.example
解决方案: 一个在 git push
前自动运行的命令,如果 .env
里的变量和 .env.example
文件里的不同就会阻止你推送。
示例3:回滚!
所有评审均已完成,代码已在 QA 环境中,产品人员已完成用户验收测试,并且部署列表已准备就绪!部署列表指示 DevOps 将 QA
分支与 master
合并。他们执行部署,这一次,您双手抱头,双脚跷在桌子上,惬意地看着 Jenkins 的构建顺利完成。构建完成,你继续你的一天,突然有人 ping 您:客户服务!客户抱怨他们无法访问该应用程序。Whoops, something went wrong
错误的屏幕快照正涌向技术支持。天塌下来;人们在办公室里尖叫和奔跑;到处都是报纸。您现在正在奔向 DevOps 的混乱之中,以慢动作大喊:“ 回回回滚滚滚 !!!”
在代码回滚和尘埃落定后,拉出日志,你立即掩面。[2018-02-28 16:21:36] local.ERROR: cURL error 3: <url> malformed
。你知道你又一次被可怕的 .env
文件打败了。
问题:部署分支,不应该在部署之前将 .env
变量添加到生产环境中。
解决方案:在构建过程中在 CI 中运行的命令,它捕获环境的 .env
文件中缺少的 .env.example
变量,并返回 1
的退出代码,在部署之前停止构建。
一个理想的解决方案
- 可以检查
.env
中缺少的.env.example
变量的命令 — 这将覆盖示例1和3中描述的场景 - 可以检查
.env
中有但是.env.example
中缺少的变量的命令 — 这可以覆盖示例2 - 将这些命令挂接到各种 Git 命令和 CI 构建中的方法
存在一个程序包
Julien Tant 推出名为 Laravel Env Sync 的程序包,它可以开箱即用地满足我们需求。谢谢,Julien!
让我们安装它并运行命令以开始使用。
composer require jtant/laravel-env-sync
由于 Laravel 5.5 中引入了服务提供商的自动注册,我们就可以开始了!我们将使用的两个命令是:
-
php artisan env:check
— 提醒您.env.example
中有,而.env
中没有的变量。 -
php artisan env:check --reverse
— 相反,.env
中有,而.env.example
中没有的变量。
注意:此软件包还提供了其他命令:
env:diff
和env:sync
。随意使用它们,但请确保您不依赖它们停止构建,因为它们不会返回退出代码。
将软件包挂接到 Composer 和 Git 中
幸运的是,Git 和 Composer 都使您很容易陷入各种行动。让我们看一下其中涉及的内容。
Composer hooks
在您的 composer.json
文件中,Laravel 随附了一个 scripts
条目:
"scripts": {
"post-root-package-install": [...],
"post-create-project-cmd": [...],
"post-autoload-dump": [...]
}
我们需要添加一个 post-install-cmd
钩子;此钩子下的任何命令都将在 composer install
之后运行。因为 composer install
通常在部署期间和切换分支之后运行,所以这将满足我们的大多数需求。
另外,由于 composer.json
受版本控制,因此添加此命令将覆盖整个团队。
这是添加到适当的 composer hook 的命令:
"scripts": {
"post-root-package-install": [...],
"post-create-project-cmd": [...],
"post-autoload-dump": [...],
"post-install-cmd": [
"php artisan env:check"
]
}
Boom!正式保护您避免使用缺少的 .env
变量进行部署。现在,让我们更进一步,并将此功能更深入地集成到我们的工作流程中。
Git 钩子
Git 钩子是在常见 Git 命令之前或之后运行的小段 bash 脚本。一些可用的钩子包括 pre-commit
,pre-push
,pre-rebase
,post-update
和 post-checkout
。
这些钩子文件可以基于每个项目进行配置,并存储在 your-project/.git/hooks
目录中。
在逐步创建钩子之前,我想简要介绍一下 Git 钩子。
版本控制 Git 钩子
Git 钩子是功能强大的工具,但是由于 .git
目录不受版本控制,因此其用途受到限制。在大多数情况下,我想使用它们,但是如果在整个团队中执行它们,它们的功能就会强大得多。
有几种有趣的版本控制 Git 钩子的方法,这是我的偏爱:
- 在项目的根目录下创建一个名为
githooks
的新目录 - 运行以下命令:
git config core.hooksPath githooks
注意:您将需要根据设置说明将此命令添加到 README 文件中,或者更好的是将其添加到
bin/setup
脚本中,该脚本可以快速,一致地加载到新开发人员。
创建我们的 Git 钩子
出于我们的目的,我们将需要设置以下钩子:post-checkout
和 pre-push
。
让我们从 pre-push
开始。当您运行 git push
命令时将执行此文件。如果脚本返回的退出代码为1
(通用失败退出代码),则将阻止推送。
pre-push
要创建此钩子,添加一个名为 pre-push
的文件到新建的 githooks
目录中,并使用以下内容进行填充:
#!/bin/sh
# 此 git 钩子可确保在 push 之前,所有 .env 变量都位于 .env.example 中。
php artisan env:check --reverse
exit $?
重要注意事项: Git 钩子文件必须具有可执行权限才能运行,如果不了解这些信息,调试起来将非常困难。要使钩子可执行,请运行以下命令:
chmod 777 .githooks/pre-push
太好了,您再也不会忘记添加漏掉的 .env.example
变量了。现在让我们解决 post-checkout
的问题。
post-checkout
我通常不记得在检出新分支后运行 composer install
。为了消除这一故障点(我的大脑),让我们设置我们的 post-checkout
钩子,以在每次分支切换后自动运行 composer install
。
创建一个 githooks/post-checkout
文件,并使用以下代码进行填充:
#!/bin/sh
# 此钩子调用以下参数:
#
# $3 - 指示文件检出还是分支检出的标志位
isFileCheckout=0
isBranchCheckout=1
if [ $3 -eq $isBranchCheckout ]
then
composer install
fi
您会在这里注意到一些古怪,因为否则,此钩子也将在文件检出期间运行,这是过头的。
我们不要忘记将文件设置为可执行文件:chmod 777 .githooks/post-checkout
现在我们已经设置了这些 Git 钩子,我们的工作流程将自动覆盖所有 .env
/ .env.example
derps。啊,感觉真好。
总结
如今你有了它,可以节省很多时间(至少对我而言)。
令我惊讶的是,作为一名程序员,我至今没有意识到 .env
文件有它们的巨大责任。当您考虑错误配置 .env
文件时可能发生的不良情况时,仅依靠你的记忆来维护 .env
文件是有风险的。一旦所有这些都自动完成,您应该会更加放心地进行部署,并且会对调试 .env
相关问题节省下来的大量时间相当满意。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
文章发布一年后居然还是沙发,这么好的东西还是要赞一个!