[扩展推荐] Laravel Env Sync —— 让你本地的 .env 跟上项目的 .env.example 的变更

Laravel的 .env 文件令人着迷。它表面上看起来很纯真,但是在友好的表象之下,它是能够将您的整个应用程序跪倒的恶性野兽。在这篇文章中,我们将探讨管理不当的 .env 文件甚至使经验最丰富的开发人员都无法正常工作的一些方法,并介绍一种简单有效的技术来避免这些陷阱。

带上小板凳,让我从战壕中给你讲一个故事,这个故事是关于一个粗暴的开发人员(由你扮演,此时你正在 Web 开发职业生涯的高峰和低谷中翱翔)。

问题

示例1:在我的机器上正常运行

您的队友 Robin 在提交代码给 QA 之前让你进行一些新功能的代码审查。您可以通过运行 git pull the-feature-branchcomposer installnpm 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 pullgit 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 中引入了服务提供商的自动注册,我们就可以开始了!我们将使用的两个命令是:

  1. php artisan env:check — 提醒您 .env.example 中有,而.env 中没有的变量。

  2. php artisan env:check --reverse — 相反,.env 中有,而 .env.example 中没有的变量。

注意:此软件包还提供了其他命令:env:diffenv: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-commitpre-pushpre-rebasepost-updatepost-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 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://tighten.co/blog/dot-env-files-th...

译文地址:https://learnku.com/laravel/t/41257

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

文章发布一年后居然还是沙发,这么好的东西还是要赞一个!

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!