我一直在尝试使用Codeship和Heroku来持续部署我目前正在编写的AngularJS应用程序。该应用程序是使用Yeoman创建的,并使用bower和grunt。最初我认为这似乎是一个非常好的设置,因为Codeship可以免费使用,我很快就可以配置它来构建我的AngularJS项目,并且它提供了在构建之后添加部署步骤的能力。甚至有许多PaaS提供商可供选择(Heroku,S3,Google App Engine等)。然而,我似乎已经变得有点卡住让Heroku上的应用程序运行。
问题始于所有文档都建议我从/dist
删除.gitignore
路径,以便将此目录发布到Heroku post build。这主要来自于谈论从本地机器发布到Heroku的文档,但我认为无论如何这都是Codeship所做的。我不想这样做,因为我不相信我应该检查构建输出到源代码控制。有充分理由将/dist
文件夹添加到.gitignore
。此外,这种方式在某种程度上打败了CI服务器,因为我可能只是从我的机器上推送最新版本。
在进行了一些挖掘后,我发现我可以在我的packages.json文件中添加一个postinstall步骤,例如bower install && grunt build
,这将重新运行Heroku上的构建,从而重新填充所有的bower依赖项(其他的东西)他们希望我检查源代码控制!)和dist
目录。
尝试一下后,很明显我需要在bower
中添加grunt
和packages.json
作为依赖项,这意味着将它们从devDependencies
移到/dist
他们应该属于!
所以我现在好像被卡住了。我想要做的就是发布我的构建工件(/bower_components
)依赖项(server.js
)和将运行该站点的{{1}}文件。有谁知道如何使用Heroku和Codeship实现这一目标?或者,任何人都可以使用不同的工具取得成功。我正在寻找免费的东西,我愿意接受它不会生产稳定(不会扩展到多个服务器等),但现在这很好,因为我想做的就是不断部署应用程序内部测试,并能够与我的团队的非技术成员分享输出,以便我们可以讨论我们希望优先考虑的功能等。
任何建议都将不胜感激。
由于
答案 0 :(得分:3)
Ahoy,来自Codeship工作人员的Marko。您是否已向我们发送了有关此内容的应用消息?我确信我们可以在Codeship上构建您的应用程序并成功部署到Heroku。
作为一个非常简短的答案,最简单的方法是将bower
和grunt
添加到 package.json 中的依赖项中。另一种可能性是寻找已安装两种工具的自定义buildpack。
最后,您还可以在Codeship上运行这些工具,将新安装的文件添加到存储库,提交更改并将此新提交推送到Heroku。如果你想使用它,你很可能需要强制推动更改。
随时通过应用程序信使(网站的右下角)与我联系,我很乐意帮助您实现这一目标!
答案 1 :(得分:2)
我找到了两种让它发挥作用的方法。
使用mbuchetics Heroku构建包。一旦将应用程序推送到Heroku,这基本上可以重新构建应用程序。
我还有一些技巧可以用来完成这项工作。在Gruntfile.js
中,需要配置两个名为heroku:production
和heroku:development
的新任务。这就是buildpack为构建应用程序而执行的操作。我最初只是将主build
任务别名,但发现buildpack或Heroku在运行jshint
时遇到问题,所以最后我复制了build
任务并取出了部分我不需要。
同样在packages.json
我必须添加:
"scripts": {
"postinstall": "bower cache clean && bower install"
}
这确保了bower_components
在Heroku中可用。
这使我能够保持.gitignore
文件的正确性,以便dist
目录中的'二进制文件'和bower_components
目录中的依赖项不会被提交到源代码控制中。 / p>
这基本上是在Heroku上重新构建应用程序,我通常更喜欢在整个构建和部署管道中使用相同的“二进制文件”。这样我就知道构建的代码与测试的代码相同,并且是部署的代码相同。
它还会减慢部署速度,因为您必须等待应用程序构建两次。
我对两次构建应用程序的事实不满意,我尝试在CodeShip中使用自定义脚本管道而不是预先存在的Heroku管道。该脚本基本上修改了.gitignore
文件以允许提交dist
文件夹,然后将其推送到Heroku
远程(这使得origin
远程上的代码不受更改)。
我最终得到了以下bash脚本:
#!/bin/bash
gitRemoteName="heroku_$APP_NAME"
gitRemoteUrl="git@heroku.com:$APP_NAME.git"
# Configure git remote
git config --global user.email "you-email@example.com"
git config --global user.name "Build"
git remote add $gitRemoteName $gitRemoteUrl
# Allow dist to be pushed to heroku remote repo
echo '!dist' >> .gitignore
# Also make sure any other exclusions dont apply to that directory
echo '!dist/*' >> .gitignore
# Commit build output
git add -A .
herokuCommitMessage="Build $CI_BUILD_NUMBER for branch $CI_BRANCH. Commited by $CI_COMMITTER_NAME. Commit hash $CI_COMMIT_ID"
echo $herokuCommitMessage
git commit -m "$herokuCommitMessage"
# Must merge the last build in Heroku remote, but always chose new files in merge
git fetch $gitRemoteName
git merge "$gitRemoteName/master" -X ours -m "Merge last build and overwrite with new build"
# Branch is in detached mode so must reference the commit hash to push
git push $gitRemoteName $(git rev-parse HEAD):refs/heads/master
这只需要构建一个应用程序,并部署在测试阶段测试的相同二进制文件。
我现在已经使用过这个脚本很多次了,看起来相对稳定。但是我知道的一个问题是,当创建新管道时,master
分支上将没有代码,因此当尝试从heroku
远程执行合并时,此脚本将失败。目前我通过在开始构建之前初步推送master
分支到Heroku来解决这个问题,但我想可能有一个更好的Git命令,我可以沿着这条线运行; '只有在已经存在的情况下才合并这个分支'。