【问题标题】:Git Post-receive hook with part of work tree带有部分工作树的 Git Post-receive 钩子
【发布时间】:2015-07-16 18:02:56
【问题描述】:

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

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

我已经按照herehere 解释的步骤在服务器上设置了一个裸存储库,配置 git 工作树的位置并编写一个 post-receive 挂钩以将 repo 签出到该位置.

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

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

【问题讨论】:

    标签: wordpress git deployment githooks


    【解决方案1】:

    您在部署中如此广泛地使用git 的方法似乎有点奇怪,主要是因为 git 主要是一个源代码管理系统,而不是一个部署工具。的确,你可以用 git hooks 做很多奇怪的事情,但出于某种原因,我觉得这些事情会再次困扰你。

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

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

    当您想要在每次向 git 存储库提交内容时部署构建时,该流程很有用。 顺便说一句,当您第一次使用它时,感觉真的很神奇:"我刚刚创建了这个git push,现在更改已经在我的服务器上生效了。”

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

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

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

    但是,在您的情况下,您听起来好像部署构建是一次性的事情,有时您只想手动执行。(如果我误解了您,我深表歉意。)对于这类一次性任务,使用 shell 脚本或任务管理工具更合适。

    您提到您已经在使用gulp。对于这项工作来说,这是一个非常方便的工具,尤其是因为您可以轻松组合不同的“任务流”。您可以有一项任务用于构建主题 (gulp build),另一项用于测试服务器部署 (gulp deploy-test),它只是扩展了 build 任务,并增加了一个将文件复制到测试服务器的步骤。 gulp-scp 看起来是一个很好的任务插件(虽然我自己没有使用它,它只是谷歌的第一个搜索结果)。如果这不起作用,您可以随时使用gulp-shell 或类似名称手动调用scp

    您甚至可以parametrize the deployment tasks,这样您就可以执行以下操作: gulp deploy --testgulp deploy --production

    你去吧,这是你在devops 的第一课。如果您觉得软件项目中的这种任务自动化听起来很有趣,那么还有很多东西需要学习。

    【讨论】:

    • 虽然这里有一些很好的信息,但它并没有回答有关使用 Git 钩子的问题。
    • 我赞成这个答案,因为我认为这是对 OP 关于“更有效/更常见的方式”的查询的有用响应,而 jthill 的答案对 git hooks 很有用方面。
    【解决方案2】:

    这是简单的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 不会覆盖你没有告诉它的内容。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

        不要将用于存储的 git 存储库与用于部署的 git 存储库混淆。您应该将一个完全干净的 git 树检出到您的生产区域(无论是什么),并且正如我建议的那样,您可能希望有一个单独的分支,称为“部署”或“生产”或“暂存”或其他任何东西。

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

        如果您需要它对放置在 git 将执行的操作之外的文件(例如在运行时生成的临时文件)具有鲁棒性,那么您可能需要在拉取之前调用 git clean -dfx。如果您希望定期从头开始重建此服务器(例如在云部署中),您可能还需要做其他事情,但听起来手动进行初始设置应该适合您的用例.

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

        【讨论】:

        • 对不起,Ewan,如果我听起来反对使用 git 进行部署;这根本不是我的本意。我在一家软件公司工作,所以我见过很多项目在我们手中流动。只是我从未见过使用 git 进行部署的项目。当然有发布的标签(例如,使用 git flow 时)等等,但实际部署总是使用其他工具处理。如果你说你一直在使用它,我相信你。只是从 my POV 和 my 的经验来看,使用 git 进行部署的想法感觉很奇怪。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-13
        • 2014-10-28
        • 1970-01-01
        • 2012-01-02
        • 2012-02-17
        • 2011-04-15
        • 2012-05-18
        相关资源
        最近更新 更多