我有一个Web项目,只需通过推送新提交即可部署到ec2
实例。我远程使用post-recieve
git钩子来执行一个shell脚本,通过将项目检入生产目录来“部署”该项目。步骤是:快速应用上的npm install
,前端npm install
应用create-react-app
上的npm run build
,然后运行web-pack
(基本上使用srcs/components/
来从我的节点源代码构建一个优化的分发文件夹)。
这些步骤很昂贵,在许多情况下并不需要。例如。如果我所做的只是更新npm run build
中的节点组件,那么npm install
应该运行,但服务器上的#!/usr/bin/env bash
GIT_WORK_TREE=/home/ec2-user/absiteProd git checkout -f
### TODO: conditional NPM work
pm2 restart index
和前端不应该。如果我所做的只是在我的快递应用程序中添加了注释,则不应运行任何脚本。
我目前的服务器端部署脚本如下所示:
/home/ec2-user/absiteProd/frontend/package.json
我的问题是如何使用git(或grep,sed,awk等)来可靠地告诉我何时/home/ec2-user/absiteProd/server/package.json
,
{home> / home / ec2-user / absiteProd / frontend / sources`中的if `git log --stat -n 1` | grep --quite frontend/src/* ; then
cd home/ec2-user/frontend
npm run build
fi
或其他内容已更改?
目前我在以下方面取得了一些成功:
group by
但是,由于这似乎是应用程序部署中的一个常见要求,我觉得必须有一个更简单的方法?
答案 0 :(得分:1)
您可以在this thread中找到类似的需求:
如何在存储库中找到给定目录的最后一次提交?
如果自上次构建以来没有任何更改,我想避免重建项目的特定部分,所以我需要找到上次更改目录的sha。
您可以使用git rev-list
:
git rev-list -1 HEAD -- frontend/package.json
git rev-list -1 HEAD -- absiteProd/server/package.json
git rev-list -1 HEAD -- frontend/src
使用当前的HEAD SHA1(git rev-parse
,--verify
是可选的):
git rev-parse --verify HEAD
那是:
h=$(git rev-parse --verify HEAD)
b=false
if [[ "$(git rev-list -1 HEAD -- frontend/package.json)" == "${h}" ]]; then b=true; fi
if [[ "$(git rev-list -1 HEAD -- frontend/package.json)" == "${h}" ]]; then b=true; fi
if [[ "$(git rev-list -1 HEAD -- frontend/package.json)" == "${h}" ]]; then b=true; fi
if !b; then exit 0; fi
cd home/ec2-user/frontend
npm run build
答案 1 :(得分:1)
Git没有以任何有用的方式存储目录,因此您必须自己定义“任何内容”的含义(这有其优点,因为您可以定义您 >意味着而不是陷入别人对你无用的定义,但意味着你必须做更多的工作。)
也就是说,Git将每个文件存储为每次提交中的路径名。您的部署脚本需要一些工作树 - 在这种情况下,/home/ec2-user/absiteProd
- 从一个州到另一个州。由于它使用git checkout
来执行此操作,并且git checkout
对时间戳没有任何特殊处理,因此您现在有许多选项,其中包含许多不同的低级详细信息和后续后果。以下是两个显而易见且相当简单的起点:
/home/ec2-user/absiteProd
与先前的提交完全相同吗?如果是这样,哪个提交? (提交具有唯一的哈希ID,这些通常是在脚本中使用的东西。)然后,您可以使用Git将先前的提交与新提交进行比较,例如使用git diff --name-status
。这与你现在正在做的类似,但更好。
如果您的部署脚本是接收后脚本,则您已经拥有了从标准输入读取的引用的旧哈希ID和新哈希ID。因此,在这两个提交之间改变的文件集及其状态是:
git diff-tree -r --name-status $oldhash $newhash
如果git checkout
在任何文件上写入,那么这些文件将具有“now”作为其修改时间时间戳,因为git checkout
只是让系统的时间适用于更新文件。你能用这个吗?只要您从未在一秒钟内部署超过两次,您可以将其与make
构建系统相结合,后者根据时间戳构建文件。
如果此处make
合适,它可能是最佳选择,除了它最多每秒一次部署(或者您的底层操作系统对文件的时间戳解析有什么用)。您可以声明无论输出文件是什么,它们都依赖于相应的输入文件,并给出配方以从输入构建输出并运行{{1} }。