flash_flow 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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'