Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

2018 RubyHACK: put git to work - increase the quality of your rails project and let git do the boring work for you

73 views

Published on

This is the RubyHack 2018 presentation on automating your common tasks using git
The main idea is to use the tools you already have to improve your day to day work

Published in: Technology
  • Be the first to comment

  • Be the first to like this

2018 RubyHACK: put git to work - increase the quality of your rails project and let git do the boring work for you

  1. 1. Put Git to work increase the quality of your Rails project, and let git do the boring work for you
  2. 2. Happy Star Wars Day!
  3. 3. Rodrigo Urubatan  rodrigo@urubatan.com.br  http://twitter.com/urubatan  http://github.com/urubatan  http://linkedin.com/in/urubatan  http://sobrecodigo.com
  4. 4. 5 ways git can help deploy your rails application 1 – check every commit follow company standards 2 – identify where each commit come from 3 – make sure at least the changed files tests run before pushing code 4 – start CI build after pushing the code 5 – 2 different approaches to git push your deploy after the ci build succeded
  5. 5. There is a lot of boring manual work to do before each deploy! Check code against standards Pretty format commit messages Run tests for the files you changed to speed up development Start CI builds Start deployments Compile assets Run migrations when needed Install npm modules Reload application servers
  6. 6. This is my goal!
  7. 7. Git can help! Commit Check standards Format message Push code Run tests (locally) Start CI process Pull code Bundle install Yarn install Start deploy Npm install Bundle install Db migrate Restart service(s)
  8. 8. Putting it to work! Codding standards Git pre-commit hook Formatting commit message Git prepare-commit-msg hook Running tests Git pre-push hook Firing CI build Git post-receive hook Automatic deployment Git post-receive hook Or Git post-merge hook
  9. 9. I had one (more than one) evil coworker that didn’t follow any company standards This Photo by Unknown Author is licensed under CC BY
  10. 10. How to fight the Evil Coworker who does not follow good practices? This Photo by Unknown Author is licensed under CC BY-SA
  11. 11. rubocode + .git/hooks/pre-commit #!/bin/sh echo "Checking commit" if git rev-parse --verify HEAD >/dev/null 2>&1 then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # If you want to allow non-ASCII filenames set this variable to true. rubocop -R `git diff --cached --name-only $against` if [ "$?" != "0" ]; then cat <<EOF pretty Failed!! message!! EOF exit 1 fi
  12. 12. I found a commit and did not know where it came from This Photo by Unknown Author is licensed under CC BY
  13. 13. Formatting commit messages #!/bin/bash BRANCH_NAME=$(git symbolic-ref --short HEAD) BRANCH_NAME="${BRANCH_NAME##*/}" BRANCH_IN_COMMIT=$(grep -c "[$BRANCH_NAME]" $1) if [ -n "$BRANCH_NAME" ] && ! [[ $BRANCH_IN_COMMIT -ge 1 ]]; then sed -i.bak -e "1s/^/[$BRANCH_NAME] /" $1 fi
  14. 14. Life is too short to test before sharing my code!
  15. 15. Run your tests before pushing the code! #!/usr/bin/env ruby branch_name=`git symbolic-ref -q HEAD` branch_name = branch_name.gsub('refs/heads/', '').strip changed_files = `git diff --name-only #{ARGV[0]}/#{branch_name}`.split("n").map(&:strip).select{|n| n =~ /.rb$/} #run the file specific test test_files = changed_files.map do |name| if name =~ /^app/ name.gsub('app/', 'test/').gsub(/.rb$/, '_test.rb') elsif name =~ /^test/ name else nil end end.reject(&:nil?).uniq #abort if there is a test missing if !test_files.reject{|n| File.exists?(n)}.empty? puts %Q{ Aborting push because there are missing test files: #{test_files.reject{|n| File.exists?(n)}} } exit 1 end #if there are config files changes, run all tests if !changed_files.select{|n| n =~ /^config/}.empty? test_files = '' end system('git stash') result = system("rails test #{test_files.join(' ')}") system('git stash apply') unless result puts %Q{ Aborting push due to failed tests } exit 1 end
  16. 16. Trick’em into using your perfect hooks This Photo by Unknown Author is licensed under CC BY-NC-ND
  17. 17. And the evil trick!  npm i shared-git-hooks --save-dev or yarn add shared-git-hooks  Add your git hooks (with or without extension) to the hooks directory in your project
  18. 18. Too much automation? This Photo by Unknown Author is licensed under CC BY-NC-SA
  19. 19. Found out you need another gem or npm module when you decide to do some work in the airplane? This Photo by Unknown Author is licensed under CC BY-NC-SA
  20. 20. .git/hooks/post-merge #!/bin/bash bundle install yarn install
  21. 21. Continuous Integration This Photo by Unknown Author is licensed under CC BY-SA
  22. 22. Continuous integration pooling?
  23. 23. Firing CI Build .git/hooks/post-receive with a curl to your CI server Github integrated CI servers (github version of the above)
  24. 24. Jenkins curl -X POST http://username:user_api_token@your- jenkins.com/job/JobName/build?token=build_trigger_api_token
  25. 25. TravisCI body='{ "request": { "branch":"master" }}' curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token xxxxxx" -d "$body" https://api.travis-ci.com/repo/mycompany%2Fmyrepo/requests
  26. 26. TeamCity curl -X POST -u apiuser:apipassword -d '<build><buildType id="SpringPetclinic_Build"/></build>' http://localhost:8111/httpAuth/app/rest/buildQueue --header "Content-Type: application/xml" -H "Accept: application/json"
  27. 27. Bamboo export BAMBOO_USER=foo export BAMBOO_PASS=bar export PROJECT_NAME=TST export PLAN_NAME=DMY export STAGE_NAME=JOB1 curl --user $BAMBOO_USER:$BAMBOO_PASS -X POST -d "$STAGE_NAME&ExecuteAllStages" http://mybamboohost:8085/rest/api/latest/queue/$PROJECT_NAME- $PLAN_NAME
  28. 28. Automatic Deployment – Heroku Recipe 1 server 1 bare repository 1 simple script 1 deployment repository/path
  29. 29. My goal with this approach is to do this  git remote add production user@server:myapp.git  Git push production master This Just Deployed my code to production!
  30. 30. Git Bare Repository  mkdir myapp.git  cd myapp.git && git init --bare  vi hooks/post-receive
  31. 31. myapp.git/hooks/post-receive #!/bin/bash while read oldrev newrev ref do branch_received=`echo $ref | cut -d/ -f3` echo "Deploying branch $branch_received" /bin/bash --login -- <<__EOF__ cd /home/urubatan/projects/deployedapp git fetch git checkout -f $branch_received git pull yarn install bundle install rails db:migrate rails assets:precompile touch tmp/restart.txt __EOF__ done
  32. 32. Automatic Deployment – git pull style (post-merge hook) #!/bin/bash bundle install yarn install rails db:migrate rails assets:precompile touch tmp/restart.txt
  33. 33. Do you feel you need to track all that deploys? This Photo by Unknown Author is licensed under CC BY-SA
  34. 34. git-deploy  https://github.com/git-deploy/git-deploy  git deploy start (you can git deploy abort if needed)  Merge all feature branches that need deployment  git deploy sync  Push that to all your servers (maybe using our Heroku strategy?)  git deploy finish  Now you can use the git-deploy script to list all deployments, or go back to any one of them!
  35. 35. Questions?
  36. 36. Rodrigo Urubatan  I help ruby developers to use the best tools for each job so they can solve hard problems, with less bugs and have more free time.  rodrigo@urubatan.com.br  http://twitter.com/urubatan  http://bit.ly/weekly_rails_tips  http://github.com/urubatan  http://linkedin.com/in/urubatan  http://sobrecodigo.com
  37. 37. Whats next? A git ebook! http://bit.ly/weekly_rails_tips

×