daq_flow 1.0.4

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 (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +62 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +165 -0
  8. data/Rakefile +10 -0
  9. data/bin/daq_flow +23 -0
  10. data/flash_flow.gemspec +28 -0
  11. data/flash_flow.yml.erb.example +42 -0
  12. data/lib/flash_flow.rb +7 -0
  13. data/lib/flash_flow/branch_merger.rb +55 -0
  14. data/lib/flash_flow/cmd_runner.rb +54 -0
  15. data/lib/flash_flow/config.rb +84 -0
  16. data/lib/flash_flow/data.rb +6 -0
  17. data/lib/flash_flow/data/base.rb +89 -0
  18. data/lib/flash_flow/data/bitbucket.rb +152 -0
  19. data/lib/flash_flow/data/branch.rb +124 -0
  20. data/lib/flash_flow/data/collection.rb +211 -0
  21. data/lib/flash_flow/data/github.rb +140 -0
  22. data/lib/flash_flow/data/store.rb +44 -0
  23. data/lib/flash_flow/git.rb +267 -0
  24. data/lib/flash_flow/install.rb +19 -0
  25. data/lib/flash_flow/lock.rb +23 -0
  26. data/lib/flash_flow/merge.rb +6 -0
  27. data/lib/flash_flow/merge/acceptance.rb +154 -0
  28. data/lib/flash_flow/merge/base.rb +116 -0
  29. data/lib/flash_flow/merge_order.rb +27 -0
  30. data/lib/flash_flow/notifier.rb +23 -0
  31. data/lib/flash_flow/options.rb +34 -0
  32. data/lib/flash_flow/resolve.rb +143 -0
  33. data/lib/flash_flow/shadow_repo.rb +44 -0
  34. data/lib/flash_flow/time_helper.rb +32 -0
  35. data/lib/flash_flow/version.rb +4 -0
  36. data/log/.keep +0 -0
  37. data/test/lib/data/test_base.rb +10 -0
  38. data/test/lib/data/test_branch.rb +206 -0
  39. data/test/lib/data/test_collection.rb +308 -0
  40. data/test/lib/data/test_store.rb +70 -0
  41. data/test/lib/lock/test_github.rb +74 -0
  42. data/test/lib/merge/test_acceptance.rb +230 -0
  43. data/test/lib/test_branch_merger.rb +78 -0
  44. data/test/lib/test_config.rb +63 -0
  45. data/test/lib/test_git.rb +73 -0
  46. data/test/lib/test_merge_order.rb +71 -0
  47. data/test/lib/test_notifier.rb +33 -0
  48. data/test/lib/test_resolve.rb +69 -0
  49. data/test/minitest_helper.rb +41 -0
  50. data/update_gem.sh +5 -0
  51. metadata +192 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 33db5905fd00b05127ee7fb761b6e7c0fe7b89f099f1afe916a5dfe0b6200530
4
+ data.tar.gz: b13fc8564da32777578df3574300292eae18f921a386041ecd78540272c5d5b0
5
+ SHA512:
6
+ metadata.gz: b0b1c21344c05c378027335209a898bbf584455184b35c77b037fad4db90ebd3fdd083aa0c6b2ae7cd1a1378de8c8128a5973463cca64aea76a07b7f9b8e3e33
7
+ data.tar.gz: 153b426a3577f8dc3648135fb1299229e824e86865ff4fc90638129036c7e024410a00857c4ed04a8907628d945c7c45296f0d1606913832bd61b53be84233d7
@@ -0,0 +1,11 @@
1
+ *.gem
2
+ coverage
3
+ /.bundle
4
+ .env
5
+ /log/*.log
6
+ /tmp
7
+ /doc
8
+ public/*
9
+ vendor/bundle
10
+ .DS_Store
11
+ .idea/
@@ -0,0 +1 @@
1
+ 2.5.1
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,62 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ daq_flow (1.0.0)
5
+ octokit (~> 4.1)
6
+ tb-bjb (>= 1.6.2)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activemodel (5.2.3)
12
+ activesupport (= 5.2.3)
13
+ activesupport (5.2.3)
14
+ concurrent-ruby (~> 1.0, >= 1.0.2)
15
+ i18n (>= 0.7, < 2)
16
+ minitest (~> 5.1)
17
+ tzinfo (~> 1.1)
18
+ addressable (2.5.2)
19
+ public_suffix (>= 2.0.2, < 4.0)
20
+ concurrent-ruby (1.1.5)
21
+ faraday (0.15.4)
22
+ multipart-post (>= 1.2, < 3)
23
+ faraday-http-cache (1.3.1)
24
+ faraday (~> 0.8)
25
+ faraday_middleware (0.13.1)
26
+ faraday (>= 0.7.4, < 1.0)
27
+ i18n (1.6.0)
28
+ concurrent-ruby (~> 1.0)
29
+ minitest (5.3.5)
30
+ minitest-stub_any_instance (1.0.1)
31
+ multipart-post (2.0.0)
32
+ octokit (4.14.0)
33
+ sawyer (~> 0.8.0, >= 0.5.3)
34
+ public_suffix (3.0.3)
35
+ rake (10.4.2)
36
+ sawyer (0.8.1)
37
+ addressable (>= 2.3.5, < 2.6)
38
+ faraday (~> 0.8, < 1.0)
39
+ simple_oauth (0.3.1)
40
+ tb-bjb (1.6.2)
41
+ activemodel (>= 4.1.6)
42
+ activesupport (>= 4.1.6)
43
+ faraday (~> 0.9)
44
+ faraday-http-cache (~> 1.2)
45
+ faraday_middleware (~> 0.10)
46
+ simple_oauth (~> 0.3)
47
+ thread_safe (0.3.6)
48
+ tzinfo (1.2.5)
49
+ thread_safe (~> 0.1)
50
+
51
+ PLATFORMS
52
+ ruby
53
+
54
+ DEPENDENCIES
55
+ bundler (~> 1.6)
56
+ daq_flow!
57
+ minitest (> 0)
58
+ minitest-stub_any_instance (> 0)
59
+ rake (> 0)
60
+
61
+ BUNDLED WITH
62
+ 1.17.1
@@ -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.
@@ -0,0 +1,165 @@
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 `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. Push the `merge_branch` to the `remote`
40
+ 7. The `merge_branch` is now a merge of your master branch plus all of your pull requests.
41
+
42
+ ### Notes
43
+
44
+ 1. Step 1 will not push your branch if you're on either the `merge_branch` or `master_branch`, but it will
45
+ still merge all the other branches and push the result.
46
+ 2. flash_flow creates a copy of your local git repo. The copy lives in /your/repo/dir/../.flash_flow/.
47
+ That's where it merges all the code and pushes to the remote from. This "shadow" directory is used so
48
+ that your local git repository is still available for your use while flash flow is running.
49
+
50
+
51
+ ### Configuring a lock
52
+ We use the "lock" configuration in flash_flow.yml. The lock ensures that no one else is running flash_flow
53
+ while you are so that you don't inadvertently have your newly pushed branch overwritten. The way we lock you
54
+ out is super janky, we open an issue on github when flash_flow starts and close it when flash_flow is done.
55
+ To configure the lock you need to specify the class name, your github token, your github repo, and the issue_id
56
+ that you want to open and close each time. The email alerts you get from github about this issue are annoying
57
+ and should be ignored.
58
+
59
+ ### Configuring branches
60
+ We use github to track our branches that we want to merge, and there are a few things about that worth noting.
61
+ In step 1 after your branch is pushed, a pull request into `master_branch` will be created on github. If you
62
+ add the "do not merge" label to a pull request, it will be excluded from the `merge_branch`. This is extremely
63
+ useful whenever one of your co-workers breaks the build, you can either run `flash_flow --no-merge` from their
64
+ branch, or go directly to github and add the "do not merge" label and then re-run flash_flow from your branch.
65
+
66
+ To use github as your source of merge branches you have to configure it with the class name, github token and
67
+ repo, your master branch name and both the unmergeable label and do not merge label, which must exist on github.
68
+ The unmergeable label is added to a pull request that has a conflict that can't be resolved and is therefore
69
+ excluded from the merge branch.
70
+
71
+ ### Configuring an issue tracker
72
+ We use Pivotal Tracker. When we have finished work for a story on a particular branch we run
73
+ `flash_flow --story <story_id>`, which will transition all of those stories to "finished" if they were previously
74
+ "started".
75
+
76
+ When code deploys to our review environment, our deploy script runs `flash_flow --review-deploy`, which transitions
77
+ stories associated with merged branches from "finished" to "delivered". At the same time, for a branch that has been
78
+ removed ("--no-merge"), if the story is "delivered" it will transition back to "finished". This means that the only
79
+ buttons that have to be manually clicked in tracker are "Start" and "Accept/Reject".
80
+
81
+ In addition, as part of our production deploy script, we run `flash_flow --prod-deploy`, which takes all the stories
82
+ that are newly in the `master_branch` and adds a comment "Deployed to production on 12/25/2015 at 11:11pm". Tracker
83
+ doesn't support a real state for "In production", so for us this comment serves as that state.
84
+
85
+ ### Runtime options
86
+
87
+ #### -v, --version
88
+ Print the current version of flash flow and exit.
89
+
90
+ #### -n, --no-merge
91
+ Runs flash_flow, but excludes the branch that you're on from the merge branch. If the branch you're on has breaking
92
+ tests, you may want to get it out of your `merge_branch`, and this will do that and ensure that the next times
93
+ flash_flow is run by anyone else it will not be included. It will add the "do not merge" label to your github pull
94
+ request if you're using that. Anytime you run flash_flow without this option, the branch you're running from will
95
+ be included in the `merge_branch` even if it has previously been set to "do not merge".
96
+
97
+ #### --rerere-forget
98
+ If you've resolved a merge conflict the wrong way, run with this option on the problem branch. The remembered
99
+ resolution will be deleted and you'll get to re-resolve your conflict.
100
+
101
+ #### --story <story_id>
102
+ Associates a story id with this branch. See "configuring an issue tracker" for why this can be useful.
103
+
104
+ #### --stories <story_id1,storyid2...>
105
+ Same as --story, but a comma-separated list so you can pass more than one story at a time.
106
+
107
+ #### -f, --force-push
108
+ Forces pushes your branch. All it does is add "-f" to the git push command, so you'd better make sure you know what
109
+ you're doing if you use this. The `merge_branch` always gets force pushed at the end, this option has nothing to do
110
+ with that.
111
+
112
+ #### --release-notes <hours>
113
+ Lists all the stories that have been deployed to production in the last <hours> hours. Only relevant if you run
114
+ --prod-deploy when you deploy.
115
+
116
+ #### --config-file FILE_PATH
117
+ This tells flash_flow how to find the configuration file. If you just put the file in config/flash_flow.yml you will
118
+ never need this option.
119
+
120
+ #### --prod-deploy
121
+ If you have Pivotal Tracker configured it will look at all stories associated with branches, and if that branch is
122
+ deployed to `master_branch` it will add a comment to those stories that says
123
+ "Deployed to production on MM/DD/YY at XX:XX". This is meant to be used right after every deploy to your production
124
+ environment. The acceptance branch will not be re-built in this case.
125
+
126
+ #### --review-deploy
127
+ If you have Pivotal Tracker configured it will look at all stories associated with branches, and if that branch is
128
+ deployed to `acceptance_branch` it will mark any finished stories as delivered. This is best used right after every
129
+ deploy to your acceptance environment. The acceptance branch will not be re-built in this case.
130
+
131
+ #### --resolve
132
+ Launch a bash shell to save your conflict resolutions. If your branch didn't merge the last time you ran flash flow
133
+ you'll run this command. This drops you into bash where you can save your resolved conflicts, then those resolutions
134
+ will be remembered the next time you run flash flow.
135
+
136
+ #### --resolve-manual
137
+ Print instructions that will show you how to resolve your merge conflicts without using flash flow's version of the
138
+ shell. If you don't use bash, or flash flow does odd things to your bash config, this is the way to go.
139
+
140
+ ### A note about merge conflicts
141
+ When we first started using flash_flow, if your branch had a merge conflict you were out of luck. You had to wait for
142
+ the branch that you were conflicting with to be merged to master, merge master into your branch, and then try again to
143
+ get your code into the merge branch.
144
+
145
+ Then we discovered `git rerere`, which is [the coolest feature of git that almost no one seems to have heard of](https://git-scm.com/blog/2010/03/08/rerere.html). Basically
146
+ what rerere does is remember how you resolved conflicts and auto-apply those patches when it notices the same conflicts.
147
+
148
+ If your branch has a conflict with the `merge_branch` flash_flow will look for a rerere patch and apply that if it
149
+ exists. If it doesn't, flash_flow will not merge your branch (but will continue merging all the others), and it will
150
+ spit out instructions for how to make your branch merge successfully. Once you follow those instructions (which involve
151
+ resolving the merge conflicts and saving the resolution), the next time you run flash_flow it will use that resolution
152
+ and everything will be sunshine and ponies.
153
+
154
+ In addition, flash_flow takes all your patches and copies them into the `merge_branch` where they are saved. Every time
155
+ flash_flow is run, those patches are first copied out of the `merge_branch` into your local rerere cache. The result of
156
+ this is that every time flash_flow is run all previous resolutions are available so once you've merged your branch and
157
+ flash_flow'ed it, it will merge successfully for everyone else too. rerere ftwftwftw.
158
+
159
+ ## Contributing
160
+
161
+ 1. Fork it ( https://github.com/flashfunders/flash_flow/fork )
162
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
163
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
164
+ 4. Push to the branch (`git push origin my-new-feature`)
165
+ 5. Create a new Pull Request
@@ -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]
@@ -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
+ elsif options[:version]
11
+ puts "Flash flow version #{FlashFlow::VERSION}\n"
12
+ exit(0)
13
+ end
14
+
15
+ FlashFlow::Config.configure!(options[:config_file])
16
+ case
17
+ when options[:resolve]
18
+ FlashFlow::Resolve.new(FlashFlow::Config.configuration.git, FlashFlow::Config.configuration.branch_info_file, logger: FlashFlow::Config.configuration.logger).start
19
+ when options[:resolve_manual]
20
+ FlashFlow::Resolve.new(FlashFlow::Config.configuration.git, FlashFlow::Config.configuration.branch_info_file, logger: FlashFlow::Config.configuration.logger).manual_instructions
21
+ else
22
+ FlashFlow::Merge::Acceptance.new(options).run
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 = "daq_flow"
7
+ spec.version = FlashFlow::VERSION
8
+ spec.authors = ["Brad Bennett"]
9
+ spec.email = ["bradleyjaybennett@gmail.com"]
10
+ spec.summary = %q{Merge your open prs together}
11
+ spec.description = %q{Flash flow is a command line tool for keeping your acceptance environment up to date}
12
+ spec.homepage = "https://github.com/bradleyjucsc/flash_flow"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency 'octokit', "~> 4.1"
21
+ spec.add_dependency 'tb-bjb', ">= 1.6.2"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.6"
24
+ spec.add_development_dependency "rake", "> 0"
25
+ spec.add_development_dependency "minitest", "> 0"
26
+ # spec.add_development_dependency "byebug", "> 0"
27
+ spec.add_development_dependency 'minitest-stub_any_instance', "> 0"
28
+ end
@@ -0,0 +1,42 @@
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 your branches use
9
+ remote: origin
10
+
11
+ # This branch is owned by flash_flow, and will be overwritten. Don't use a branch to which you make
12
+ # commits. Treat this as 100% ephemeral, this is the branch that you should deploy automatically to
13
+ # your review/staging env.
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: 'flash_flow.json'
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
+ ## We use Bitbucket as our source of truth for which branches to merge. All open pull requests that don't
29
+ ## have the "do not merge" label on them get merged. If you configure this flash_flow will automatically
30
+ ## create a PR for your branch when it runs. If your branch can't merge, it will still be PR'ed, but it
31
+ ## will have the "unmergeable" label on it (that label is strictly informational, no functionality is
32
+ ## affected at all).
33
+
34
+ #branches:
35
+ # class:
36
+ # name: 'FlashFlow::Data::Bitbucket'
37
+ # token: <%= ENV['GH_TOKEN'] %>
38
+ # repo: # Your github repo. For example, the flash_flow repo is 'flashfunders/flash_flow'
39
+ # master_branch: master
40
+ # unmergeable_label: unmergeable
41
+ # do_not_merge_label: 'do not merge'
42
+ # shippable_label: 'shippable'
@@ -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/resolve'
7
+ require 'flash_flow/merge'
@@ -0,0 +1,55 @@
1
+ module FlashFlow
2
+ class BranchMerger
3
+
4
+ attr_reader :conflict_sha, :resolutions, :result
5
+
6
+ def initialize(git, branch)
7
+ @git = git
8
+ @branch = branch
9
+ end
10
+
11
+ def do_merge(rerere_forget)
12
+ if sha.nil?
13
+ @result = :deleted
14
+ return
15
+ end
16
+
17
+ @git.run("merge --no-ff #{@git.remote}/#{@branch.ref}")
18
+
19
+ if @git.last_success? || try_rerere(rerere_forget)
20
+ @result = :success
21
+ else
22
+ @conflict_sha = merge_rollback
23
+ @result = :conflict
24
+ end
25
+ end
26
+
27
+ def sha
28
+ @sha if defined?(@sha)
29
+ @sha = get_sha
30
+ end
31
+
32
+ private
33
+
34
+ def try_rerere(rerere_forget)
35
+ if rerere_forget
36
+ @git.run('rerere forget')
37
+ false
38
+ else
39
+ @resolutions = @git.rerere_resolve!
40
+ end
41
+ end
42
+
43
+ def get_sha
44
+ @git.run("rev-parse #{@git.remote}/#{@branch.ref}")
45
+ @git.last_stdout.strip if @git.last_success?
46
+ end
47
+
48
+ def merge_rollback
49
+ @git.run("reset --hard HEAD")
50
+ @git.run("rev-parse HEAD")
51
+ @git.last_stdout.strip
52
+ end
53
+ end
54
+ end
55
+