Git Post-receive hook with part of work tree

Git Post-receive hook with part of work tree

我想使用 git 将网站部署到测试服务器。我的网站是用 gulp 构建的 wordpress 主题,存储库看起来像

theme.git/
-- gulpfile.js
-- src/
-- build/

我已经按照 here and here 解释的步骤进行操作,即在服务器上设置裸存储库,配置 git 工作树的位置并编写 post-receive挂钩以将回购检出到该位置。

问题是我只想将 build/ 文件夹移动或复制到它在服务器上的位置。我唯一的想法是写一个 post-receive 挂钩,将回购拉到一个工作树位置(因为我想我读到裸回购通常根本没有工作树),然后 cp 将构建文件夹放入 wp-content/themes/

这似乎不必要地复杂,所以我想知道是否有更有效/更通用的方法来解决它。谢谢!

您如此广泛地使用 git 进行部署的做法似乎有点奇怪,主要是因为 git 主要是源代码管理系统,而不是部署工具。的确,你可以用 git 钩子做很多奇怪的事情,但出于某种原因,我觉得那些 return 的倾向会困扰你。

通常我会建议您使用某种 continuous integration 工具来完成这项工作。我自己可以使用的一种可能的工作流程是

  1. 将您的主题文件存储在位于 GitHub 的 public 存储库中。它是免费的,您的主题源代码中可能没有什么大秘密,作为额外的奖励,您甚至可以开源您的主题。
  2. 使用 Travis CI 为您的存储库设置一个 CI 作业。你基本上在云中获得了一个免费的构建机器实例,你可以在构建之前或之后做各种各样的事情。你可以例如。 运行 gulp build(或任何您的任务名称)在那里,因此您根本不必将 build 目录存储在 git 存储库中。
  3. 在 Travis after_success 挂钩中,您可以将构建目录复制到目标服务器,例如使用 scpHere is an example of doing the very same thing with FTP. Travis supports encryption of sensitive data,因此您不必担心(至少如此)在 git 存储库中存储用户名和密码。

当您想在每次向 git 存储库提交内容时部署构建时,该流程很有用。 顺便说一句,当您使用它时第一次感觉真的很神奇:"I just made this git push, and now the change is already live on my server."

但是您提到要将代码部署到测试服务器。的确,CI 工具(例如 Travis)可用于维护不同部署步骤之间的流程,其中许多是测试服务器。大型项目的示例流程可以是

development -> tests passing? -> release -> tests passing? -> integration -> tests passing? -> staging -> tests passing? -> production

...其中流程可以使用 CI 工具部分或完全自动化。

然而,在您的情况下,您听起来像是这样,部署构建是一种一次性的事情,您有时只想手动完成。(我很抱歉,如果我误解了你。)对于这类一次性任务,使用 shell 脚本或任务管理工具更合适。

您提到您已经在使用 gulp。这是一个非常方便的工具,尤其是因为您可以轻松组合不同的 "streams of tasks"。您可以有一个任务用于构建主题 (gulp build),另一个任务用于测试服务器部署 (gulp deploy-test),这只是扩展了 build 任务,增加了一个将文件复制到测试服务器。 gulp-scp looks like a fine plugin for the task (I haven't used it myself though, it was just the first search result from google). If that does not work out, you can always call scp manually with gulp-shell 或类似的。

您甚至可以 这样您就可以执行以下操作: gulp deploy --testgulp deploy --production

好了,这是你在 devops 的第一堂课。如果您对软件项目中的这种任务自动化感兴趣,那么您可以学到很多东西。

这是简单的 git read-tree 工作。为你的部署目录中的内容保留一个清单,也就是索引,并像这样使用预接收处理你的更新:

#!/bin/sh
while read old new ref; do [[ $ref = refs/heads/master ]] && {
    export GIT_INDEX_FILE=deployment-manifest
    export GIT_WORK_TREE=/path/to/deployment
    git read-tree -um `git write-tree` $new:build || exit 1
}; done

注意 如果以这种方式部署的某些文件已在部署树中更改,git read-tree 和推送将失败,因为 git 不会覆盖您未告知的内容。

我会将您的项目分成两个存储库。

  1. 来源。包括来源等等。排除 /build/ 目录。仅将其用于源代码管理。这永远不会进入网站(将您的代码存储在网站上可能不安全,即使是以 git 存储库的形式)。

  2. 部署。只有 /build/ 目录。您可以在目录中启动一个新的 git 存储库。这在服务器上有一个远程仓库;您可以像以前一样使用 post-receive 挂钩进行部署。

我一直使用 git 进行部署。一点也不奇怪,我不知道@cido 有什么反对意见。能够及时返回到 'deploy' 分支上的任何时间点并能够准确查看当时服务器上的内容具有很大的价值。

不要混淆用于存储的 git 存储库与用于部署的存储库。你应该有一个完全干净的 git 树检查到你的生产区域(不管是什么),正如我建议的那样,你可能想要一个单独的分支,称为 'deploy' 或 'production' 或 'staging' 或其他什么。

然后您的 post-receive 挂钩只需要 运行 进入您的生产区域的脚本,并拉取您的部署分支进行更新。

如果您需要此功能以防止文件被放置在 git 将执行的操作之外(例如,在 运行 时间生成的临时文件),那么您可能需要调用 [=10= 】 拉之前。如果您希望定期从头开始重建此服务器(例如在云部署中),您可能还想做其他事情,但听起来手动进行初始设置应该适合您的用例.

cp将构建目录放到适当的位置听起来不错,只是我会使用 rsync,因为如果只是增量更改,它通常会更快。