I am trying to set up a system where, when I commit changes to my GitHub repository, my server also receives those commits.
To do that, I set my GitHub repo to send a post-receive hook to a URL on my rails app. I have a controller that will handle this.
The problem is this: how can I run git commands in a rails controller? I get how to do it in the command line.
Do I just type something like this:
# controller method where post-receive hook is sent
def commit
git pull origin development
end
Do this!
def commit
system "git pull origin development"
end
There is quite a big difference between what your stated goal is and what the command you're planning to use does. In order to get the commits, all you need to run is git fetch. You can use system or backticks in order to run shell commands from your ruby code, but you need to be careful about what you run. You should keep in mind that a pull is a merge, which means that at any time changes could conflict and it would leave your repository waiting for human intervention (not to mention files with conflict markers all over them) as it's part of the high-level user interface, and not meant at all to be scripted.
If you do want the version of the files in the tip, to do deployment or similar, you can check out http://gitolite.com/the-list-and-irc/deploy.html for some different ways to do that, depending on the situation.
You can use a combination of shelling out to git fetch and git checkout or rugged in your code to perform this update, and be aware that this is all IO-bound (part of it over the network) which means that it can take an arbitrary amount of time to run, which may not work too well with the rest of your app if it's blocking ruby's execution.
Try a Ruby abstraction on top of Git like Rugged or Ruby/Git. Both remain active while other similar libraries seem to have fallen by the wayside.
Related
I have a bunch of Integrationtests on Travis, that I need to run after my Ruby on Rails app has been deployed to Heroku. How can I do that?
I tried to use the HTTP-POST-Method but Travis required custom headers and JSON body and Heroku does not support both. Is there another way?
I can think of couple of solutions, but none is perfect.
One: You can create simple app that will translate normal Heroku deploy hook into format acceptable by Travis. Of course you need to host it somewhere, but it is a great use case for Amazon Lambda or similar solution. If you ever wanted to try doing serverless I think you have a perfect case. And the cost of hosting will be almost nothing.
Two: You can use release phase on Heroku. Create a script bin/notify-travis and this to your Procfile release: bin/notify-travis. The problem is how to get all the information about deployed code like commit sha. For that you can enable lab feature called dyno-metadata. It will inject additional config variables, one is HEROKU_SLUG_COMMIT which contains commit sha. If more data are required, then this solution may not work. Make sure that bin/notify-travis returns 0. It will run just before deployment. And if fails, your code won't be deployed.
Three: You can find or write custom buildpack that will send webhook to Travis. The problem is that it will run during build phase. In case of errors your code may not be deployed, but you will send a webhook. And also it can be problematic to get all required information about the build as in solution two.
So you have some options. I guess the first one is the best, but it may not fit your other requirements.
I am inspecting the gem Shoulda as an example. Shoulda no longer has the methods assert_good_value. So my question is, what is the best way to figure out when and why it was removed, and what it might have been replaced by?
So far, the only way I could think to do this is to clone the git related to Shoulda, and do :
git log -Sassert_good_value
Which brought back a few commits worth investigating. However, I'm not really sure how to investigate these commits other than git checkout into the SHA and see if I can see anything important. But doing so this way does not show me what was added/removed, and it also doesn't show me how or if any of these are connected to a git issue.
What am I possibly doing wrong, or what is the best way to accomplish this?
git log -p
That gives you a less interface containing each commit as a diff. Then enter /assert_good_value to search for a change to it.
To investigate the commits from doing the git log -Sassert_good_value, you could just git show into the SHA. That will return all the changes made by that certain commit.
Hope that helps!
I am newish to Rails and GitHub and struggling with managing two coders' development logs. Specifically:
How do I merge two developers development logs?
Can I automate their merger? Or can I differentiate them in some Railsy or GitHub Flowy way?
The Rails app I am developing on command line CentOS 6 is being worked on by another developer. We are using a private GitHub repo to help us manage our codebase and are trying to follow The GitHub Flow.
This strategy works well for almost every aspect of our project. The only major problem I've run into with this so far is that our development logs are (of course) out of sync. For instance, he branches from master, then I do. Then he merges to master, then I do, but my merge will fail, citing the automatic merge failure on log/develoment.log. Our logs will be structured like this:
log/development.log - mine
Shared: (Tens of thousands of lines of code from master branch point)
Not: (Thousands of lines of code unique to my branch)
log/development.log - his
Shared: (Tens of thousands of lines of code from master branch point)
Not: (Thousands of lines of code unique to his branch)
So, I find going through this manually, even with diff tools like git mergetool, impractical because of the volumes of code involved. (Am I simply too much of a vim novice to be able to put this to good use? Do others find this trivial?)
Is there a git or rails development strategy we can employ to keep these files without them clashing? (ex: some tinkering with Rails configuration to designate 'Development1' environment vs. 'Development2' environment)?
Is there some command line tool that merges two clashing logs based on time last updated? I'm imaging a tool that, given two clashing git-tracked documents can merge them by comparing the branch point/time, using that as the 'shared' base and adding in the remainder based on which was more recently updated (more recent > appended last). A more advanced version would walk back through commit history to append updates based on commit timestamps.
Logs are useful for your own purposes:
check requests sent
check params sent
check correct matching url/controller-action
check sql queries
check your own stuff (you can log things if you desire)
So because its for your only purpose, no need to pollute your repository with it: add log folder to your gitignore.
There is a recommended gitignore for Rails projects here.
BTW, if logs in console are enough for you, save your disk space and add:
config.logger = Logger.new(STDOUT)
in development.rb
I have a few Rails 3 apps deployed to Heroku that need to share some business logic. Apparently, although Heroku's Bundler support is pretty solid, it can't yet pull from a private Github repo. So instead I'm building a couple of gems, vendoring them into each app, checking them into git, and pushing them up with the rest of my code.
This has worked alright, but every time I want to change something in these shared gems I have to go to each app, gem unpack to the right directory, git add/git remove all the files that have changed, and so on, and it's becoming a bit of a pain. I may also want to set up different branches of my business logic, and having different applications follow different branches, but I don't know how I'd accomplish that by vendoring.
It looks like git submodules were invented for this kind of situation, but the last time I tried submodules I just found them horribly confusing. I suppose that's what I'd need to do, but the code snippet that Heroku gives as an example at that link is also pretty confusing.
So, my questions:
Are submodules what I want to use here?
What's the simplest possible git workflow I'd need in order to do what I'm describing?
I'm not a beginner with git, but I'm not quite intermediate either, and I want to start with a simple set of steps I can use to learn from. I'd need to track a local git repository from within my vendor/gems directory, pull in updates from that repository regularly, and do so in such a way that Heroku/Bundler doesn't throw a fit when I try to push the entire app to production.
Thank you!
You might find apenwarr’s git subtree command helpful. It provides a nice wrapper around Git’s subtree merge functionality.
Add a new subtree:
git subtree add --prefix=vendor/gems/shiny remote-or-url-to-shiny-gem branch
Pull new commits into the subtree:
git subtree pull --prefix=vendor/gems/shiny remote-or-url-to-shiny-gem branch
You might also like the --squash option if you do not want to incorporate the history.
You can also use git subtree to extract local commits that change the subtree so that they can be pushed to the subtree’s source repository (the split and push sub-commands).
You can use the git-subtree technique
http://progit.org/book/ch6-7.html
As for me, git-subtree was a non sufficient. It required too much tweaking and digging and the result had some annoying flaws and made it look like a bandage. BTW The mentioned apenwarr’s git subtree was last updated two years ago (as to Apr12...) and if git subtree is chosen then i recommend using helmo's fork (or alikes).
I would deifintly recommend using git submodules. Sure, its has some flaws too, but most of them are better handled in later version of git, and you could add some hooks and scripts to make it usable by git newbies. Plus, its far more widely used.
Regarding Heroku, it is now supported. If you need private repositories, Create a user and use its credentials for this purpose and use this format for the repository location:
https://username:password#github.com/user/repo.git
More, For Ruby apps, you can alternately do this with Bundler's :git option.
HTH
What is a good deployment strategy to use with Git + Heroku (Ruby on Rails)?
Currently, the way I work with my origin Git repository: All features (or 'stories') are first checked out as branches, then get merged with master and pushed to origin.
Anything pushed to origin/master triggers a script that pulls the new rails code to the staging area (simple rails webserver).
When the time comes for me to push a new production version to Heroku, should I create a new branch (called something like production_version_121), and push that somehow to Heroku?
Ideally, I'd like to pick and choose which features from previous development versions I should include into the production branch... test it, and push to Heroku.
For example, I may not want all the latest code to get pushed to production. I might want to feature "a" that I had worked on and feature "c" both merged into production somehow, without including experimental feature "b" which needs more debugging.
N.B. I'm going to try avoiding Capistrano at first and get something working manually for now.
Any thoughts? Best practices?
In the Gemcutter project we simply have a production branch. Any changes that we want to see on the production site get merged into that branch, and then deployed with:
git push heroku production:master
The staging branch serves a similar purpose for the staging site (also on Heroku)
Ever since I read Vincent Driessen's A successful Git branching model, I have been hooked. My entire company (8 of us) have now standardized on this model and a few other places I've consulted with have also started using it as well.
Most everyone I've shown it to says they were doing something similar already and found it very easy to adapt.
In a nutshell, you have 2 branches that are permanent (master and develop). Most of the time you'll just be making branches off of develop and merging them back into develop. Things get a little more complex when you get into doing production releases and hotfixes, but after reading the post a couple of times, it becomes engrained.
There's even a command line tool called git-flow to help you out.
There are a variety of ways to go about this, and it really depends on your preference.
I'll give you one possible strategy off the top of my head: Given you already have an automated staging setup that uses master, I would suggest creating a 'production' branch. When you want to promote a fix/feature to production, you would just merge the topic branch into your 'production' branch.
git checkout production
git pull . my-topic-branch
(resolve any conflicts)
When you are ready to actually push that code to your production server, you should tag the branch using a unique name (probably with a timestamp). Then you simply push the production branch to Heroku.
git checkout production
git tag release-200910201249
I'd suggest creating a script or git alias to automate the tagging for timestamps, since using a consistent naming scheme is important. I use something like this:
git config alias.dtag '!git tag release-`date "+%Y%m%d%H%M"`'
That allows me to do just type git dtag when I want to tag a release with a timestamp.
You can view you tags using git tag and view them using git show release-1234. For more information on tags, run git help tag. You may also find this Github guide on tagging helpful. I'd also recommend reading up other people's workflows (here's a nice writeup) and pick and choose what works for you.