flash_flow 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +81 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +152 -0
  8. data/Rakefile +10 -0
  9. data/bin/flash_flow +23 -0
  10. data/flash_flow.gemspec +28 -0
  11. data/flash_flow.yml.erb.example +83 -0
  12. data/lib/flash_flow.rb +7 -0
  13. data/lib/flash_flow/branch_merger.rb +52 -0
  14. data/lib/flash_flow/cmd_runner.rb +37 -0
  15. data/lib/flash_flow/config.rb +71 -0
  16. data/lib/flash_flow/data.rb +6 -0
  17. data/lib/flash_flow/data/base.rb +58 -0
  18. data/lib/flash_flow/data/branch.rb +131 -0
  19. data/lib/flash_flow/data/collection.rb +181 -0
  20. data/lib/flash_flow/data/github.rb +129 -0
  21. data/lib/flash_flow/data/store.rb +33 -0
  22. data/lib/flash_flow/deploy.rb +184 -0
  23. data/lib/flash_flow/git.rb +248 -0
  24. data/lib/flash_flow/install.rb +19 -0
  25. data/lib/flash_flow/issue_tracker.rb +52 -0
  26. data/lib/flash_flow/issue_tracker/pivotal.rb +160 -0
  27. data/lib/flash_flow/lock.rb +25 -0
  28. data/lib/flash_flow/lock/github.rb +91 -0
  29. data/lib/flash_flow/notifier.rb +24 -0
  30. data/lib/flash_flow/notifier/hipchat.rb +36 -0
  31. data/lib/flash_flow/options.rb +36 -0
  32. data/lib/flash_flow/time_helper.rb +11 -0
  33. data/lib/flash_flow/version.rb +3 -0
  34. data/test/lib/data/test_base.rb +10 -0
  35. data/test/lib/data/test_branch.rb +203 -0
  36. data/test/lib/data/test_collection.rb +238 -0
  37. data/test/lib/data/test_github.rb +23 -0
  38. data/test/lib/data/test_store.rb +53 -0
  39. data/test/lib/issue_tracker/test_pivotal.rb +221 -0
  40. data/test/lib/lock/test_github.rb +70 -0
  41. data/test/lib/test_branch_merger.rb +76 -0
  42. data/test/lib/test_config.rb +84 -0
  43. data/test/lib/test_deploy.rb +175 -0
  44. data/test/lib/test_git.rb +73 -0
  45. data/test/lib/test_issue_tracker.rb +43 -0
  46. data/test/lib/test_notifier.rb +33 -0
  47. data/test/minitest_helper.rb +38 -0
  48. metadata +217 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a836475713f58f0a511b59b28b404af5d43b20bd
4
+ data.tar.gz: f301d93bfcab8720f1a9f76b6e60d69fb8da0530
5
+ SHA512:
6
+ metadata.gz: 57776f50518921b2f3c16407b11bb54cc294d141d11e1936509ecd72d1ee0343ca2931e319561395c68c3eaa644393bd29611d52dd87e7eb3d787f3b3533af04
7
+ data.tar.gz: e60cd7cb7dcd124dfdb62ee1900f5fae8785e04d02c4179f91f814971ef7e5be32200b6dee1ab88ef539415f3f760027a4e426cd68f3637227e9a9951bfbca0f
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ coverage
2
+ /.bundle
3
+ .env
4
+ /log/*.log
5
+ /tmp
6
+ /doc
7
+ public/*
8
+ vendor/bundle
9
+ .DS_Store
10
+ .idea/
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fund_america.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,81 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ flash_flow (1.0.0)
5
+ hipchat
6
+ octokit
7
+ pivotal-tracker
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.3.8)
13
+ builder (3.2.2)
14
+ byebug (3.5.1)
15
+ columnize (~> 0.8)
16
+ debugger-linecache (~> 1.2)
17
+ slop (~> 3.6)
18
+ columnize (0.9.0)
19
+ crack (0.4.2)
20
+ safe_yaml (~> 1.0.0)
21
+ debugger-linecache (1.2.0)
22
+ domain_name (0.5.25)
23
+ unf (>= 0.0.5, < 1.0.0)
24
+ faraday (0.9.2)
25
+ multipart-post (>= 1.2, < 3)
26
+ hipchat (1.5.2)
27
+ httparty
28
+ mimemagic
29
+ http-cookie (1.0.2)
30
+ domain_name (~> 0.5)
31
+ httparty (0.13.7)
32
+ json (~> 1.8)
33
+ multi_xml (>= 0.5.2)
34
+ json (1.8.3)
35
+ mime-types (2.6.2)
36
+ mimemagic (0.3.0)
37
+ mini_portile (0.6.2)
38
+ minitest (5.3.5)
39
+ minitest-stub_any_instance (1.0.1)
40
+ multi_xml (0.5.5)
41
+ multipart-post (2.0.0)
42
+ netrc (0.10.3)
43
+ nokogiri (1.6.6.2)
44
+ mini_portile (~> 0.6.0)
45
+ nokogiri-happymapper (0.5.9)
46
+ nokogiri (~> 1.5)
47
+ octokit (4.1.1)
48
+ sawyer (~> 0.6.0, >= 0.5.3)
49
+ pivotal-tracker (0.5.13)
50
+ builder
51
+ crack
52
+ nokogiri (>= 1.5.5)
53
+ nokogiri-happymapper (>= 0.5.4)
54
+ rest-client (>= 1.8.0)
55
+ rake (10.4.2)
56
+ rest-client (1.8.0)
57
+ http-cookie (>= 1.0.2, < 2.0)
58
+ mime-types (>= 1.16, < 3.0)
59
+ netrc (~> 0.7)
60
+ safe_yaml (1.0.4)
61
+ sawyer (0.6.0)
62
+ addressable (~> 2.3.5)
63
+ faraday (~> 0.8, < 0.10)
64
+ slop (3.6.0)
65
+ unf (0.1.4)
66
+ unf_ext
67
+ unf_ext (0.0.7.1)
68
+
69
+ PLATFORMS
70
+ ruby
71
+
72
+ DEPENDENCIES
73
+ bundler (~> 1.6)
74
+ byebug
75
+ flash_flow!
76
+ minitest
77
+ minitest-stub_any_instance
78
+ rake
79
+
80
+ BUNDLED WITH
81
+ 1.10.6
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 FlashFunders
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,152 @@
1
+ # Flash Flow
2
+
3
+ Flash Flow is a ruby gem that helps your team keep your acceptance environment up to date. Check out
4
+ [this gist](https://gist.github.com/bradleyjucsc/bfbb8742889edf1b423a) for a detailed explanation of
5
+ how it works.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'flash_flow'
12
+
13
+ And then run:
14
+
15
+ $ bundle install
16
+ $ bundle exec flash_flow --install
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install flash_flow
21
+
22
+ And then run:
23
+
24
+ $ flash_flow --install
25
+
26
+ After "installing" flash_flow, you'll have a file "config/flash_flow.yml.erb". If your remote is origin,
27
+ your master branch is master, and you're fine using "acceptance" as the branch that flash_flow owns, you
28
+ are ready to go for flash_flow basic. If not, edit that file and change branch and remote names accordingly.
29
+
30
+ ## Usage
31
+ flash_flow is a ruby script which, in the simplest case, can just be run by calling `flash_flow`.
32
+ What that will do (once your application is properly configured) is:
33
+
34
+ 1. Push your branch to the `merge_remote`
35
+ 2. Reset your `merge_branch` to be the same as your `master_branch`
36
+ 3. Get your list of pull requests from github (or use the saved list, more on that later)
37
+ 4. Filter out any "removed" branches
38
+ 5. Merge the rest into the newly created `merge_branch`
39
+ 6. Force push the `merge_branch` to the `merge_remote`
40
+
41
+ ### Notes
42
+
43
+ 1. Step 1 will not push your branch if you're on either the `merge_branch` or `master_branch`, but it will
44
+ still merge all the other branches and push the result.
45
+ 2. flash_flow uses your local git repo. It resets everything back to the branch you started in, but you should not do
46
+ anything else in your repo while it's running because lots of mayhem will ensue.
47
+
48
+
49
+ ### Configuring a lock
50
+ We use the "lock" configuration in flash_flow.yml. The lock ensures that no one else is running flash_flow
51
+ while you are so that you don't inadvertently have your newly pushed branch overwritten. The way we lock you
52
+ out is super janky, we open an issue on github when flash_flow starts and close it when flash_flow is done.
53
+ To configure the lock you need to specify the class name, your github token, your github repo, and the issue_id
54
+ that you want to open and close each time. The email alerts you get from github about this issue are annoying
55
+ and should be ignored.
56
+
57
+ ### Configuring branches
58
+ We use github to track our branches that we want to merge, and there are a few things about that worth noting.
59
+ In step 1 after your branch is pushed, a pull request into `master_branch` will be created on github. If you
60
+ add the "do not merge" label to a pull request, it will be excluded from the `merge_branch`. This is extremely
61
+ useful whenever one of your co-workers breaks the build, you can either run `flash_flow --no-merge` from their
62
+ branch, or go directly to github and add the "do not merge" label and then re-run flash_flow from your branch.
63
+ To use github as your source of merge branches you have to configure it with the class name, github token and
64
+ repo, your master branch name and both the unmergeable label and do not merge label, which must exist on github.
65
+ The unmergeable label is added to a pull request that has a conflict that can't be resolved and is therefore
66
+ excluded from the merge branch.
67
+
68
+ ### Configuring an issue tracker
69
+ We use Pivotal Tracker. Anytime flash_flow is run, all the branches that get merged, if they have any stories
70
+ associated with them (added via the `--stories` option), those stories will transition to "finished" if they
71
+ were previously "started". When code deploys to our review environment, our deploy script runs
72
+ `flash_flow --review-deploy`, which transitions stories associated with merged branches from "finished" to
73
+ "delivered". At the same time, for a branch that has been removed ("--no-merge"), if the story is "delivered"
74
+ it will transition back to "finished". In addition, as part of our production deploy
75
+ script, we run `flash_flow --prod-deploy`, which takes all the stories that are newly in the `master_branch`
76
+ and adds a comment "Deployed to production on 12/25/2015 at 11:11pm". So using the story option can be handy.
77
+
78
+ ### Configuring hipchat
79
+ When a branch other than the one you're on doesn't merge cleanly and can't be fixed by rerere (more on that later
80
+ too), a notification can go out to Hipchat. The Hipchat notifier needs your token (api v2 token) and the room
81
+ to which the message will be sent.
82
+
83
+ ### Runtime options
84
+
85
+ #### -n, --no-merge
86
+ Runs flash_flow, but excludes the branch that you're on from the merge branch. If the branch you're on has breaking
87
+ tests, you may want to get it out of your `merge_branch`, and this will do that and ensure that the next times
88
+ flash_flow is run by anyone else it will not be included. It will add the "do not merge" label to your github pull
89
+ request if you're using that. Anytime you run flash_flow without this option, the branch you're running from will
90
+ be included in the `merge_branch` even if it has previously been set to "do not merge".
91
+
92
+ #### --rerere-forget
93
+ If you've resolved a merge conflict the wrong way, run with this option on the problem branch. The remembered
94
+ resolution will be deleted and you'll get to re-resolve your conflict.
95
+
96
+ #### --story <story_id>
97
+ Associates a story id with this branch. See "configuring an issue tracker" for why this can be useful.
98
+
99
+ #### --stories <story_id1,storyid2...>
100
+ Same as --story, but a comma-separated list so you can pass more than one story at a time.
101
+
102
+ #### -f, --force-push
103
+ Forces pushes your branch. All it does is add "-f" to the git push command, so you'd better make sure you know what
104
+ you're doing if you use this. The `merge_branch` always gets force pushed at the end, this option has nothing to do
105
+ with that.
106
+
107
+ #### --release-notes <hours>
108
+ Lists all the stories that have been deployed to production in the last <hours> hours. Only relevant if you run
109
+ --prod-deploy when you deploy.
110
+
111
+ #### --config-file FILE_PATH
112
+ This tells flash_flow how to find the configuration file. If you just put the file in config/flash_flow.yml you will
113
+ never need this option.
114
+
115
+ #### --prod-deploy
116
+ If you have Pivotal Tracker configured it will look at all stories associated with branches, and if that branch is
117
+ deployed to `master_branch` it will add a comment to those stories that says
118
+ "Deployed to production on MM/DD/YY at XX:XX". This is meant to be used right after every deploy to your production
119
+ environment. The acceptance branch will not be re-built in this case.
120
+
121
+ #### --review-deploy
122
+ If you have Pivotal Tracker configured it will look at all stories associated with branches, and if that branch is
123
+ deployed to `acceptance_branch` it will mark any finished stories as delivered. This is best used right after every
124
+ deploy to your acceptance environment. The acceptance branch will not be re-built in this case.
125
+
126
+ ### Merge conflicts
127
+ When we first started using flash_flow, if your branch had a merge conflict you were out of luck. You had to wait for
128
+ the branch that you were conflicting with to be merged to master, merge master into your branch, and then try again to
129
+ get your code into the merge branch.
130
+
131
+ Then we discovered git rerere, which is the coolest feature of git that almost no one seems to have heard of. Googling
132
+ it turns up a few really good resources on how it works, but in one sentence or less what it does is remember how you
133
+ resolved conflicts and apply those patches.
134
+
135
+ If your branch has a conflict with the `merge_branch` flash_flow will look for a rerere patch and apply that if it
136
+ exists. If it doesn't, flash_flow will not merge your branch (but will continue merging all the others), and it will
137
+ spit out instructions for how to make your branch merge successfully. Once you follow those instructions (which involve
138
+ resolving the merge conflicts and saving the resolution), the next time you run flash_flow it will use that resolution
139
+ and everything will be sunshine and ponies.
140
+
141
+ In addition, flash_flow takes all your patches and copies them into the `merge_branch` where they are saved. Every time
142
+ flash_flow is run, those patches are first copied out of the `merge_branch` into your local rerere cache. The result of
143
+ this is that every time flash_flow is run all previous resolutions are available so once you've merged your branch and
144
+ flash_flow'ed it, it will merge successfully for everyone else too. rerere ftwftwftw.
145
+
146
+ ## Contributing
147
+
148
+ 1. Fork it ( https://github.com/flashfunders/flash_flow/fork )
149
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
150
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
151
+ 4. Push to the branch (`git push origin my-new-feature`)
152
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/test*.rb', 'test/**/test*.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task :default => [:test]
data/bin/flash_flow ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'flash_flow'
4
+
5
+ options = FlashFlow::Options.parse
6
+
7
+ if options[:install]
8
+ FlashFlow::Install.install
9
+ exit(0)
10
+ end
11
+
12
+ FlashFlow::Config.configure!(options[:config_file])
13
+ case
14
+ when options[:prod_deploy]
15
+ FlashFlow::IssueTracker::Base.new(FlashFlow::Config.configuration.issue_tracker).production_deploy
16
+ when options[:review_deploy]
17
+ FlashFlow::IssueTracker::Base.new(FlashFlow::Config.configuration.issue_tracker).stories_delivered
18
+ when options[:release_notes]
19
+ FlashFlow::IssueTracker::Base.new(FlashFlow::Config.configuration.issue_tracker).release_notes(options[:release_notes])
20
+ else
21
+ FlashFlow::Deploy.new(options).run
22
+ FlashFlow::IssueTracker::Base.new(FlashFlow::Config.configuration.issue_tracker).stories_pushed
23
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'flash_flow/version'
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "flash_flow"
7
+ spec.version = FlashFlow::VERSION
8
+ spec.authors = ["Flashfunders"]
9
+ spec.email = ["engineering@flashfunders.com"]
10
+ spec.summary = %q{Implementation of the flashfunders workflow}
11
+ spec.homepage = ""
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_dependency 'octokit'
20
+ spec.add_dependency 'hipchat'
21
+ spec.add_dependency 'pivotal-tracker'
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.6"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "minitest"
26
+ spec.add_development_dependency "byebug"
27
+ spec.add_development_dependency 'minitest-stub_any_instance'
28
+ end
@@ -0,0 +1,83 @@
1
+ ## The basic settings for your app
2
+
3
+ git:
4
+ # This is what allows you to resolve merge conflicts using flash_flow, rerere is amazing. There's
5
+ # more description elsewhere about how this works.
6
+ use_rerere: true
7
+
8
+ # Which remote to push the merge branch to
9
+ merge_remote: origin
10
+
11
+ # This branch is owned by flash_flow, it force pushes every time. So don't use a branch to which you make
12
+ # commits. Treat this as 100% ephemeral, but if you can you should deploy it automatically to your
13
+ # review/staging env when it gets pushed.
14
+ merge_branch: acceptance
15
+
16
+ # This is your mainline production branch that is the basis for the merge branch
17
+ master_branch: master
18
+
19
+ # An arbitrary file that flash_flow will write to in the merge branch and use to store branch information.
20
+ # Make sure it doesn't collide with a file you actually need in your application. You don't need to look at
21
+ # this file in general.
22
+ branch_info_file: 'your/random/file'
23
+
24
+
25
+
26
+ ### Everything below here is optional and should be deleted or remain commented out if you don't need it
27
+
28
+
29
+ ## This will send merge conflict notifications to the hipchat room configured below, only for branches
30
+ ## other than your own.
31
+
32
+ #notifier:
33
+ # class:
34
+ # name: 'FlashFlow::Notifier::Hipchat'
35
+ # token: <%= ENV['HIPCHAT_TOKEN'] %>
36
+ # room: 'Flash Flow Notifications'
37
+
38
+
39
+ ## If you use Pivotal Tracker, this integration can finish, deliver, un-deliver, and comment when
40
+ ## deployed to production if you set it up.
41
+ ## Must be used in conjuction with the "--story or --stories" options.
42
+ ## You need to run "flash_flow --review-deploy" when you deploy to your review enviroment to get the
43
+ ## deliver/un-deliver functionality.
44
+ ## You need to run "flash_flow --prod-deploy" when you deploy to production to get the "Deployed to production"
45
+ ## The timezone attribute will be set to system time zone (TZ environment variable).
46
+ ## comment when your story is deployed to prod.
47
+
48
+ #issue_tracker:
49
+ # class:
50
+ # name: 'FlashFlow::IssueTracker::Pivotal'
51
+ # token: <%= ENV['TRACKER_TOKEN'] %>
52
+ # project_id: # Your Pivotal project id goes here
53
+ # timezone: 'US/Pacific'
54
+
55
+
56
+ ## We use this to ensure only one person at a time runs flash_flow. It checks the github issue when
57
+ ## flash_flow starts, and if it's open flash_flow exits. Otherwise it opens the issue (thus locking
58
+ ## other users out) and then closes it when flash_flow is done with its work. Using github in this way
59
+ ## is weird, and not a 100% reliable lock, but it at least prevents most possible cases of odd
60
+ ## concurrency issues.
61
+
62
+ #lock:
63
+ # class:
64
+ # name: 'FlashFlow::Lock::Github'
65
+ # token: <%= ENV['GH_TOKEN'] %>
66
+ # repo: # Your github repo. For example, the flash_flow repo is 'flashfunders/flash_flow'
67
+ # issue_id: # Your github issue id goes here
68
+
69
+
70
+ ## We use Github as our source of truth for which branches to merge. All open pull requests that don't
71
+ ## have the "do not merge" label on them get merged. If you configure this flash_flow will automatically
72
+ ## create a PR for your branch when it runs. If your branch can't merge, it will still be PR'ed, but it
73
+ ## will have the "unmergeable" label on it (that label is strictly informational, no functionality is
74
+ ## affected at all).
75
+
76
+ #branches:
77
+ # class:
78
+ # name: 'FlashFlow::Data::Github'
79
+ # token: <%= ENV['GH_TOKEN'] %>
80
+ # repo: # Your github repo. For example, the flash_flow repo is 'flashfunders/flash_flow'
81
+ # master_branch: master
82
+ # unmergeable_label: unmergeable
83
+ # do_not_merge_label: 'do not merge'
data/lib/flash_flow.rb ADDED
@@ -0,0 +1,7 @@
1
+ module FlashFlow; end
2
+
3
+ require 'flash_flow/options'
4
+ require 'flash_flow/install'
5
+ require 'flash_flow/config'
6
+ require 'flash_flow/deploy'
7
+ require 'flash_flow/issue_tracker'