7

I have been trying out Codeship and Heroku for continuous deployment of an AngularJS application I writing at the moment. The app was created using Yeoman and uses bower and grunt. Initially I thought this seemed like a really good setup as Codeship was free to use and I was quickly able to configure this to build my AngularJS project and it offered the ability to add a deployment step after the build. There were even many PaaS providers to choose from (Heroku, S3, Google App Engine etc). However I seem to have become a bit stuck with getting the app to run on Heroku.

The problem started from the fact that all the documentation suggested that I remove the /dist path from my .gitignore so that this directory is published to Heroku post build. This was mainly from documentation that talked about publishing to Heroku from a local machine, but I figure this is all Codeship is doing under the hood anyway. I didn't want to do this as I don't believe I should be checking build output into source control. The /dist folder was added to .gitignore for a good reason. Furthermore, this kind of defeats the point of having a CI server somewhat, as I might as well just push the latest build from my machine.

After some more digging around I found out that I could add a postinstall step to my packages.json file such as bower install && grunt build which would re-run the build on Heroku and hence repopulate all the bower dependencies (something else they wanted me to check in to source control!) and the dist directory.

After giving this a try it became apparent that I would need to add bower and grunt as dependencies in packages.json, which meant moving them from devDependencies which is where they should belong!

So I now seem to be stuck. All I want to do is publish my build artefacts (/dist) the dependencies (/bower_components) and the server.js file that will run the site. Does anyone know how to achieve this with Heroku and Codeship? Alternatively has anyone had any success with this using different tools. I am looking for something that is free and I am willing to accept that it will not be production stable (won't scale to multiple servers etc), but this is fine for now as all I want to do is continuously deploy the app for internal testing and to be able to share the output with non-technical members of my team so we can discuss features we'd like to prioritise etc.

Any advice would be greatly appreciated.

Thanks

4

2 回答 2

3

Ahoy,来自 Codeship 工作人员的 Marko。您是否已经向我们发送了有关此问题的应用内消息?我确信我们可以让您的应用程序在 Codeship 上构建并成功部署到 Heroku。

作为一个非常简短的答案,最简单的方法是在package.jsonbower中添加和添加grunt到您的依赖项。另一种可能性是寻找已经安装了这两种工具的自定义构建包。

最后,您还可以在 Codeship 上运行工具,将新安装的文件添加到存储库,提交更改并将这个新提交推送到 Heroku。如果你想使用它,你很可能需要强制推送更改。

请随时通过应用内信使(网站右下角)与我联系,我很乐意帮助您完成这项工作!

于 2015-05-04T12:26:04.023 回答
2

我找到了两种方法来让它工作。

Heroku 节点自定义构建包

使用mbuchetics Heroku 构建包。这可以通过在将应用程序推送到 Heroku 后基本上重新构建应用程序来实现。

为了完成这项工作,我仍然不得不使用一些技巧。在Gruntfile.js需要配置的两个新任务中,称为heroku:productionheroku:development。这是 buildpack 为构建应用程序而执行的操作。我最初只是为主要build任务起别名,但发现 buildpack 或 Heroku 在运行时出现问题,jshint所以最后我复制了build任务并取出了我不需要的部分。

同样在packages.json我不得不添加这个:

"scripts": {
    "postinstall": "bower cache clean && bower install"
}

这确保了bower_components在 Heroku 中可用。

优点

这使我能够保持.gitignore文件完好无损,以便目录中的“二进制文件”和dist目录中的依赖bower_components项不会提交到源代码管理中。

缺点

这基本上是在 Heroku 上重新构建应用程序,我通常更喜欢在整个构建和部署管道中使用相同的“二进制文件”。这样我就知道构建的代码和测试的代码相同,部署的代码也相同。

它还会减慢部署速度,因为您必须等待应用程序构建两次。

CodeShip 自定义脚本部署

对我两次构建我的应用程序这一事实不满意,我尝试在 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 命令可以运行:'如果它已经存在,只合并这个分支'。

于 2015-05-04T16:32:29.337 回答