git - 如何在我的产品中处理硬编码 URL、数据库配置,该产品在 Git 级别具有多个模块?
问题描述
我正在开发多年来由多个开发人员开发的产品。
该产品建立在
- PHP
- jQuery
- 角
- 引导程序
该产品具有由服务器中的目录分隔的不同模块。这些模块也是我的 BitBucket 中的单独存储库。
幸运的是,所有模块都使用相同的数据库。在代码级别,数据库名称、URL(用于访问 API、指向服务器中其他文件夹的资产)等配置是硬编码的。
我们有 4 个实例(dev、production、abc、abcdev)。每个实例的硬编码配置都不同。我最近实现了 Git,并将所有代码推送到服务器中。
范围是维护单个存储库并为不同的实例提供不同的分支。由于值在很多地方都是硬编码的,分支之间的合并将非常困难
我觉得我应该处理它的方式是,创建另一个名为 的模块config
,添加大概包含json
URL、数据库相关信息的文件。
对于每个分支,该文件显然会有所不同,并且该文件不会在分支中更改。虽然这都是理论上的,但我该如何实施呢?或者还有其他更好的方法来处理这种情况吗?对于任何反馈,我们都表示感谢!谢谢!
解决方案
首先,将所有配置选项移动到一个(或多个)配置文件中。使用与语言无关的格式,例如 JSON 或 YAML。
将配置文件/目录放在源代码树的顶部,便于查找。
范围是维护单个存储库并为不同的实例提供不同的分支。
单一的回购是好的。不同的分支不是。管理许多长期存在的分支机构迅速变得复杂。
取而代之的是一个长寿的分支,可能是master
. 使用功能分支来隔离开发并在允许它们合并到master
. 这条路master
随时可以走。直接从 部署master
。
这就是它的样子。每个字母都是一个提交。每个[branch]
都是一个分支头。
I - J L - M - N [feature1]
/ \ /
A - B - C ----- F - G ----- K [master]
\ / \
D - E O - P [feature2]
这显示了两个已完成的功能,D - E
并且I - J
已经通过了 QA 并被合并到master
. 由于 QA 已经在功能分支上完成,因此master
已部署到生产环境中。有两个开放的功能分支,每个分支都会定期运行git rebase master
,因此它们是最新的、经过全面测试的代码。
请注意,没有直接提交master
,它仅通过功能分支合并进行更改。这意味着master
始终经过测试、可靠且随时可以部署。正在进行中的各个功能不会相互干扰,并且可以依赖于稳定的master
分支;如果出现问题,他们知道这是因为他们的工作,而不是因为有人破坏了开发分支。
但是不同的配置呢?
对于每个分支,该文件显然会有所不同,并且该文件不会在分支中更改。
相同的配置文件在不同的分支中不同是一种很好的方式来产生冲突,人们会不小心用测试和开发信息覆盖配置。
拥有一组配置文件更简单,其中包含所有不同上下文的配置,以及它们共享的默认值。
例如,您的数据库配置在YAML中可能如下所示。
default: &default
adapter: postgresql
encoding: unicode
username: postgres
development:
<<: *default
database: myapp_development
host: localhost
test:
<<: *default
database: myapp_test
host: localhost
production: &production
<<: *default
host: our.production.server
username: production_db_user
client1:
<<: *production
database: client1
client2:
<<: *production
database: client2
这使用YAML 锚点和别名来进行覆盖,<<: *default
表示包含标记为 的节点&default
。这消除了各种上下文之间的大量冗余。
让您的应用从环境变量中选择环境,或从上下文中猜测。
这就是 Rails 的做法,多个配置文件,每个文件都有每个上下文的配置部分。
下一步是从源代码中取出生产机密并将它们放入环境变量中。秘密是诸如密码和 API 密钥之类的东西。然后,当您的生产系统启动时,它们会以设置的环境变量启动。这就是 Heroku 等云托管网站的做法。
或者,您可以在配置文件中硬编码生产机密,但要加密。然后通过环境变量提供解密密钥。这意味着您只需要一个用于生产的环境变量,如果您要迁移旧系统,这可能会更简单。这就是 TravisCI 的做法。
这可能是一堆工作,具体取决于您现有的系统和工作流程当前的设置方式,但这是一个非常成功的模式。
推荐阅读
- reactjs - 我在 React.JS 组件上设置的状态有什么问题?
- python - 如何在 PySide2 中添加边框或设置透明 QLayout?
- javascript - 正确的 javascript 调用以通过 web api 上传文件
- r - 为什么是整数类型?
- java - 将 log4j.properties 放入 Eclipse 中的 Maven 项目中,在“src”文件夹中有一些“默认包”?
- c++ - C++ 和 WMI:在 IWbemClassObject::Put 方法中传递对 CIM 类的引用
- javascript - 多个代理可以同时使用唯一的 Twilio 编号吗?
- python - 为什么 Flask 忽略 Cache-Control?
- javascript - 在 React 中导航到跨源 URL 时出现问题
- java - 如何在 HTML(Thymeleaf、Spring、Java)中调用方法?