如何仅将 git repo 的子目录部署/推送到 Heroku?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7539382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I deploy/push only a subdirectory of my git repo to Heroku?
提问by Olivier Lacan
I have a project that uses Serveand is version controlled using Git. Serve creates an output
folder with static files that I want to deploy to Heroku.
我有一个使用Serve并且使用 Git 进行版本控制的项目。Serve 创建了一个output
文件夹,其中包含我想要部署到 Heroku 的静态文件。
I don't want to deploy the Serve project itself since the Heroku Cedar stack doesn't seem too fond of it, but most importantly I want to take advantage of Heroku's great support for static websites.
我不想部署 Serve 项目本身,因为 Heroku Cedar 堆栈似乎不太喜欢它,但最重要的是我想利用 Heroku 对静态网站的强大支持。
Is there a way to deploy a subfolder to a git remote?
Should I create a Git repo in the output
folder (that sounds wrong) and push that to Heroku?
有没有办法将子文件夹部署到 git 远程?我应该在output
文件夹中创建一个 Git 存储库(听起来不对)并将其推送到 Heroku?
回答by anshumans
There's an even easier way via git-subtree. Assuming you want to push your folder 'output' as the root to Heroku, you can do:
通过git-subtree有一种更简单的方法。假设您要将文件夹“输出”作为根目录推送到 Heroku,您可以执行以下操作:
git subtree push --prefix output heroku master
It appears currently that git-subtree is being included into git-core, but I don't know if that version of git-core has been released yet.
目前看来 git-subtree 已包含在 git-core 中,但我不知道该版本的 git-core 是否已发布。
回答by JnBrymn
I had a similar issue. In my case it was never a problem to blow away everything in the heroku repository and replace it with whatever is in my subdirectory. If this is your case you can use the following bash script. Just put it in your Rails app directory.
我有一个类似的问题。在我的情况下,吹走 heroku 存储库中的所有内容并将其替换为我的子目录中的任何内容从来都不是问题。如果是这种情况,您可以使用以下 bash 脚本。只需将它放在您的 Rails 应用程序目录中即可。
#!/bin/bash
#change to whichever directory this lives in
cd "$( dirname "cd bin
git init
git add .
git commit -m"deploy"
git push [email protected]:your-project-name.git -f
rm -fr .git
" )"
#create new git repository and add everything
git init
git add .
git commit -m"init"
git remote add heroku [email protected]:young-rain-5086.git
#pull heroku but then checkback out our current local master and mark everything as merged
git pull heroku master
git checkout --ours .
git add -u
git commit -m"merged"
#push back to heroku, open web browser, and remove git repository
git push heroku master
heroku open
rm -fr .git
#go back to wherever we started.
cd -
I'm sure there are plenty of ways to improve upon this - so feel free to tell me how!
我相信有很多方法可以改进这一点 - 所以请随时告诉我如何改进!
回答by LessQuesar
I started with what John Berryman put, but actually it can be simpler if you don't care at all about the heroku git history.
我从 John Berryman 提出的开始,但实际上如果你根本不关心 heroku git 历史,它会更简单。
##代码##I guess official git subtree
is the best answer, but i had issue getting subtree to work on my mac.
我想官方git subtree
是最好的答案,但我在让子树在我的 mac 上工作时遇到了问题。
回答by bbozo
After a long and hard month of trying different things and getting bitten every time I realized,
经过漫长而艰难的一个月尝试不同的事情并且每次我意识到都被咬后,
just because Heroku uses a git repository as a deployment mechanism, you should not treat it as a git repository
仅仅因为 Heroku 使用 git 存储库作为部署机制,您不应该将其视为 git 存储库
it could have been rsync just as well, they went for git, don't get distracted because of this
它也可以是 rsync,他们选择了 git,不要因为这个而分心
if you do so, you open up yourself to all kinds of hurt. All of the aforementioned solutions fail miserably somewhere:
如果你这样做,你就会对各种伤害敞开心扉。所有上述解决方案都在某处惨遭失败:
- it requires something to be done every time, or periodically, or unexpected things happen (pushing submodules, syncing subtrees, ...)
- if you use an engine for example to modularize your code, Bundler will eat you alive, it's impossible to describe the amount of frustration I've had with that project during the quest to find a good solution for this
- you try to add the engine as git repo link +
bundle deploy
- fail, you need to bundle update every time - you try to add the engine as a
:path
+bundle deploy
- fail, the dev team considers:path
option as "you're not using Bundler with this gem option" so it'll not bundle for production - also, every refresh of the engine wants to update your rails stack -_-
- you try to add the engine as git repo link +
- only solution I've found is to use the engine as a
/vendor
symlink in development, and actually copy the files for production
- 它需要每次或周期性地做一些事情,或者发生意想不到的事情(推送子模块,同步子树,......)
- 例如,如果你使用一个引擎来模块化你的代码,Bundler 会活活吃掉你,我无法描述我在寻找一个好的解决方案的过程中对该项目的挫败感
- 您尝试将引擎添加为 git repo link +
bundle deploy
- 失败,您每次都需要捆绑更新 - 您尝试将引擎添加为
:path
+bundle deploy
- 失败,开发团队将:path
选项视为“您没有将 Bundler 与此 gem 选项一起使用”,因此它不会捆绑用于生产 - 此外,引擎的每次刷新都想更新您的 Rails 堆栈-_-
- 您尝试将引擎添加为 git repo link +
- 我发现的唯一解决方案是
/vendor
在开发中使用引擎作为符号链接,并实际复制文件以进行生产
The solution
解决方案
The app in question has 4 projects in git root:
有问题的应用程序在 git root 中有 4 个项目:
- api - depending on the profile will run on 2 different heroku hosts - upload and api
- web - the website
- web-old - the old website, still in migration
- common - the common components extracted in an engine
- api - 根据配置文件将在 2 个不同的 Heroku 主机上运行 - 上传和 api
- 网络 - 网站
- web-old - 旧网站,仍在迁移中
- common - 在引擎中提取的通用组件
All of the projects have a vendor/common
symlink looking at the root of the common
engine. When compiling source code for deployment to heroku we need to remove the symlink and rsync it's code to physically be in the vendor folder of each separate host.
所有项目都有一个vendor/common
查看common
引擎根目录的符号链接。在编译部署到 heroku 的源代码时,我们需要删除符号链接和 rsync,它的代码物理上位于每个单独主机的供应商文件夹中。
- accepts a list of hostnames as arguments
- runs a git push in your development repo and then runs a clean git pull in a separate folder, making sure no dirty (uncommited) changes are pushed to the hosts automatically
- deploys the hosts in parallel - every heroku git repo is pulled, new code is rsynced into the right places, commited with basic push information in the git commit comment,
- in the end, we send a ping with curl to tell the hobby hosts to wake up and tail the logs to see if all went wine
- plays nice with jenkins too :D (automatic code push to test servers after successful tests)
- 接受主机名列表作为参数
- 在你的开发仓库中运行一个 git push 然后在一个单独的文件夹中运行一个干净的 git pull,确保没有脏的(未提交的)更改被自动推送到主机
- 并行部署主机 - 每个 heroku git repo 都被拉取,新代码被同步到正确的位置,在 git commit 注释中提交基本推送信息,
- 最后,我们发送一个带有 curl 的 ping 来告诉业余主机唤醒并跟踪日志,看看是否都喝了酒
- jenkins 也很好用 :D(测试成功后自动将代码推送到测试服务器)
Works very very nice in the wild with minimal (no?) problems 6 months now
现在 6 个月了,在野外工作非常好,问题很少(没有?)
Here's the script https://gist.github.com/bbozo/fafa2bbbf8c7b12d923f
这是脚本https://gist.github.com/bbozo/fafa2bbbf8c7b12d923f
Update 1
更新 1
@AdamBuczynski, it's never so straightforward.
@AdamBuczynski,从来没有这么简单。
1st you will always have a production and test environment at the least - and a bunch of function specific clusters at the worse - suddenly 1 folder needs to map to n heroku projects as a pretty basic requirement and it all needs to be organized somehow so that the script "knows" what source you want to deploy where,
第一,您将始终至少拥有一个生产和测试环境 - 更糟糕的是一堆特定于功能的集群 - 突然 1 个文件夹需要映射到 n 个 heroku 项目作为一个非常基本的要求,并且这一切都需要以某种方式进行组织,以便脚本“知道”你想要部署的源,
2nd you will want to share code between projects - now comes the sync_common
part, the shennanigans with symlinks in development being replaced by actual rsynced code on Heroku because Heroku requires a certain folder structure and bundler and rubygems really really really make things ugly very badly if you want to extract the common threads into a gem
第二,您将希望在项目之间共享代码 - 现在是sync_common
部分,开发中带有符号链接的恶作剧被 Heroku 上的实际 rsynced 代码所取代,因为 Heroku 需要特定的文件夹结构,而 bundler 和 rubygems 真的真的让事情变得非常糟糕,如果你想要将公共线程提取到 gem 中
3rd you will want to plug in CI and it will change a bit how subfolders and git repo need to be organized, in the end in the simplest possible use case you end up with the aforementioned gist.
第三,你会想要插入 CI,它会改变子文件夹和 git repo 需要组织的方式,最后在最简单的可能用例中,你最终会得到上述要点。
In other projects I need to plug in Java builds, when selling software to multiple clients you will need to filter modules that get installed depending on the installation requirements and whatnot,
在其他项目中,我需要插入 Java 版本,当向多个客户销售软件时,您需要根据安装要求和诸如此类的内容过滤安装的模块,
I should really consider exploring bundling things into a Rakefile or something and do everything that way...
我真的应该考虑探索将东西捆绑到 Rakefile 或其他东西中,然后以这种方式做所有事情......