├── .gitignore
├── files_to_copy
├── .hound.yml
├── .rspec
├── Gemfile
├── .travis.yml
├── circle.yml
├── .gitignore
├── README.md
└── .rubocop.yml
├── Gemfile
├── tools.rb
├── README.md
├── Gemfile.lock
├── migrate_links.rb
├── LICENSE
├── migrate_code.rb
└── migrate_issues.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | .keys
2 | .krausefx
3 | all_cloned
4 | workspace
5 |
--------------------------------------------------------------------------------
/files_to_copy/.hound.yml:
--------------------------------------------------------------------------------
1 | ruby:
2 | config_file: .rubocop.yml
3 |
--------------------------------------------------------------------------------
/files_to_copy/.rspec:
--------------------------------------------------------------------------------
1 | --color --require spec_helper --format d
2 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | gem "octokit", "~> 4.0"
2 | gem "pry"
3 | gem "excon"
4 | gem "colored"
5 |
--------------------------------------------------------------------------------
/files_to_copy/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gemspec path: "fastlane"
4 |
5 | gem "rake"
6 |
--------------------------------------------------------------------------------
/tools.rb:
--------------------------------------------------------------------------------
1 | @tools = %w(fastlane fastlane_core deliver snapshot frameit pem sigh produce cert gym pilot credentials_manager scan supply watchbuild match spaceship screengrab)
2 |
--------------------------------------------------------------------------------
/files_to_copy/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 | osx_image: xcode7.1
3 | os: osx
4 | before_install:
5 | - gem update --system
6 | - gem install bundler
7 | rvm:
8 | - 2.1.6
9 | script: rake test_all
10 |
--------------------------------------------------------------------------------
/files_to_copy/circle.yml:
--------------------------------------------------------------------------------
1 | machine:
2 | xcode:
3 | version: "7.2"
4 | dependencies:
5 | override:
6 | - gem install bundler
7 | - bundle check --path=/tmp/vendor/bundle || bundle install --path=/tmp/vendor/bundle --jobs=4 --retry=3
8 | cache_directories:
9 | - /tmp/vendor/bundle
10 | test:
11 | override:
12 | - bundle exec rake test_all
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # fastlane - monorepo
2 | Scripts to migrate to a monorepo, more information on [krausefx.com](https://krausefx.com)
3 |
4 | ## Source Code
5 |
6 | ### migrate_code.rb
7 |
8 | Migrate the actual repos (source code)
9 |
10 | ### migrate_links.rb
11 |
12 | Updates all the links from
13 |
14 | ```
15 | https://github.com/fastlane/sigh
16 | ```
17 |
18 | to
19 |
20 | ```
21 | https://github.com/fastlane/fastlane/tree/master/sigh
22 | ```
23 |
24 | ### migrate_issues.rb
25 |
26 | Migrate all the GitHub issues
27 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | specs:
3 | addressable (2.5.0)
4 | public_suffix (~> 2.0, >= 2.0.2)
5 | coderay (1.1.1)
6 | colored (1.2)
7 | excon (0.54.0)
8 | faraday (0.11.0)
9 | multipart-post (>= 1.2, < 3)
10 | method_source (0.8.2)
11 | multipart-post (2.0.0)
12 | octokit (4.6.2)
13 | sawyer (~> 0.8.0, >= 0.5.3)
14 | pry (0.10.4)
15 | coderay (~> 1.1.0)
16 | method_source (~> 0.8.1)
17 | slop (~> 3.4)
18 | public_suffix (2.0.5)
19 | sawyer (0.8.1)
20 | addressable (>= 2.3.5, < 2.6)
21 | faraday (~> 0.8, < 1.0)
22 | slop (3.6.0)
23 |
24 | PLATFORMS
25 | ruby
26 |
27 | DEPENDENCIES
28 | colored
29 | excon
30 | octokit (~> 4.0)
31 | pry
32 |
33 | BUNDLED WITH
34 | 1.13.7
35 |
--------------------------------------------------------------------------------
/files_to_copy/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | *.rbc
3 | /.config
4 | coverage/
5 | /InstalledFiles
6 | /pkg/
7 | /spec/reports/
8 | /test/tmp/
9 | /test/version_tmp/
10 | /tmp/
11 |
12 | ## Specific to RubyMotion:
13 | .dat*
14 | .repl_history
15 | build/
16 |
17 | ## Documentation cache and generated files:
18 | /.yardoc/
19 | /_yardoc/
20 | /doc/
21 | /rdoc/
22 |
23 | ## Environment normalisation:
24 | /.bundle/
25 | /lib/bundler/man/
26 |
27 | # for a library or gem, you might want to ignore these files since the code is
28 | # intended to run in multiple environments; otherwise, check them in:
29 | Gemfile.lock
30 | .ruby-version
31 | .ruby-gemset
32 |
33 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34 | .rvmrc
35 |
36 | # Added by Felix
37 | /*.itmsp
38 | .idea
39 | spec/fixtures/*.itmsp/*.png
40 | /integration
41 | **/report.xml
42 | **/.bundle
43 |
--------------------------------------------------------------------------------
/migrate_links.rb:
--------------------------------------------------------------------------------
1 | require 'pry'
2 |
3 | new_repo = "fastlane"
4 | exceptions = ["countdown", "boarding", "fastlane.tools", "refresher", "examples", "setups", "shenzhen", "itc-api-docs", "enhancer", "brewed-jenkins", "codes", "code-of-conduct", "spaceship.airforce"]
5 | not_in_line = ["/graphs", "/releases", "/tree/", "/blob", "/issues"]
6 |
7 | Dir["./workspace/**/*"].each do |path|
8 | next unless File.exist?(path)
9 | next if File.directory?(path)
10 | next unless ["rb", "txt", "md"].include?(path.split(".").last)
11 |
12 | puts "Converting #{path}"
13 |
14 | content = File.read(path)
15 | content.gsub!(/https\:\/\/github.com\/fastlane\/([\w\-\d]+)[\w\d\-\/]*/) do |line|
16 | tool_name = Regexp.last_match[1]
17 | if exceptions.include?(tool_name) or not_in_line.any? { |a| line.include?(a) }
18 | line
19 | else
20 | "https://github.com/fastlane/#{new_repo}/tree/master/#{tool_name}"
21 | end
22 | end
23 |
24 | File.write(path, content)
25 | end
26 |
27 | puts "Changed files locally, open the workspace to commit and push those changes"
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 fastlane
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/migrate_code.rb:
--------------------------------------------------------------------------------
1 | # From http://scottwb.com/blog/2012/07/14/merge-git-repositories-and-preseve-commit-history/
2 |
3 | require 'tmpdir'
4 | require 'colored'
5 | require 'pry'
6 |
7 | def cmd(command)
8 | puts "$ #{command}".yellow
9 | puts `#{command}`
10 | end
11 |
12 | require './tools'
13 | names = @tools
14 | names << "countdown"
15 |
16 | url = "https://github.com/fastlane/fastlane" # the repo everything goes to
17 |
18 | new_branch_name = "monorepo"
19 | path = Dir.mktmpdir
20 | path = "all_cloned"
21 | destination = "workspace"
22 | FileUtils.rm_rf(path)
23 | FileUtils.rm_rf(destination)
24 | FileUtils.mkdir_p(path)
25 | FileUtils.mkdir_p(destination)
26 |
27 | cmd "cd '#{destination}' && git clone '#{url}'"
28 | parent_name = url.split("/").last
29 | destination = File.join(destination, parent_name)
30 | raise "Destination repo must be the fastlane repo".red unless File.exist?(File.join(destination, "fastlane.gemspec"))
31 |
32 | Dir.chdir(destination) do
33 | cmd "git checkout -b '#{new_branch_name}'"
34 | end
35 |
36 | # Move the main tool into its subfolder
37 | subfolder_name = ENV["SUBFOLDER_NAME"] || "fastlane"
38 |
39 |
40 | def copy_with_hidden(from, to)
41 | FileUtils.mv(Dir[File.join(from, "*")], to) # move everything away to create a new fastlane folder
42 |
43 | # to also copy hidden files...
44 | Dir.foreach(from).each do |current|
45 | next if current == '.' or current == '..'
46 | next if current.include?("git")
47 | FileUtils.mv(File.join(from, current), File.join(to, File.basename(current)))
48 | end
49 | end
50 |
51 | tmp = Dir.mktmpdir
52 | copy_with_hidden(destination, tmp)
53 | # FileUtils.mv(Dir[File.join(destination, "*")], tmp) # move everything away to create a new fastlane folder
54 | FileUtils.mkdir_p(File.join(destination, subfolder_name))
55 | # FileUtils.mv(Dir[File.join(tmp, "*")], File.join(destination, subfolder_name))
56 | copy_with_hidden(tmp, File.join(destination, subfolder_name))
57 |
58 | names.each do |name|
59 | cmd "cd '#{path}' && git clone 'https://github.com/fastlane/#{name}' && cd #{name} && git remote rm origin"
60 | end
61 |
62 | names.each do |name|
63 | puts "Rewriting history of '#{name}'"
64 | commit_message = "Migrate #{name} to the fastlane mono repo"
65 | commit_body = "You can read more about the change in our blog post: https://krausefx.com/blog/our-goal-to-unify-fastlane-tools"
66 |
67 | ref = File.expand_path("#{path}/#{name}")
68 | puts "Going to '#{ref}'".green
69 | Dir.chdir(ref) do
70 | cmd "mkdir #{name}"
71 | Dir.foreach(".") do |current| # foreach instead of glob to have hidden items too
72 | next if current == '.' or current == '..'
73 | next if current.include?(".git")
74 | cmd "git mv '#{current}' '#{name}/'"
75 | end
76 | cmd "git add -A"
77 | cmd "git commit -m '#{commit_message}' -m '#{commit_body}'"
78 | end
79 |
80 | puts "Going to '#{destination}' (to merge stuff)".green
81 | Dir.chdir(destination) do
82 | cmd "git remote add local_ref '#{ref}'"
83 | cmd "git pull local_ref master"
84 | cmd "git remote rm local_ref"
85 | cmd "git add -A"
86 | cmd "git commit -m '#{commit_message}' -m '#{commit_body}'"
87 | end
88 | end
89 |
90 | # foreach => hidden files as well
91 |
92 | def remove_dot_files(path)
93 | Dir.chdir(path) do
94 | Dir.foreach(".") do |current|
95 | next if current == '.' or current == '..'
96 | next if current == ".git"
97 | next if current == ".rspec"
98 |
99 | if current.start_with?(".")
100 | puts "Deleting '#{current}' dot file"
101 | FileUtils.rm_rf(current)
102 | end
103 | end
104 | end
105 | end
106 |
107 | remove_dot_files(destination)
108 | names.each do |current|
109 | remove_dot_files(File.join(destination, current))
110 | end
111 | cmd "cd #{destination} && git add -A && git commit -m 'Removed dot files'"
112 |
113 | # Migrate the countdown repo too
114 | FileUtils.mv(File.join(destination, "countdown", "Rakefile"), File.join(destination, "Rakefile"))
115 |
116 | # Copy files from files_to_copy
117 | Dir.foreach("files_to_copy").each do |current|
118 | next if current == '.' or current == '..'
119 | FileUtils.cp(File.join("files_to_copy", current), File.join(destination, File.basename(current)))
120 | end
121 |
122 | Dir[File.join(destination, "*/Gemfile")].each do |current| # one * only, that's important, otherwise it matches ./Gemfile
123 | next if current.include?("fastlane/Gemfile")
124 | File.write(current, "source \"https://rubygems.org\"\n\ngemspec\n")
125 | end
126 |
127 | # We leave the countdown folder for now, as it also contains documentation about things
128 | Dir.chdir(destination) do
129 | cmd "git add -A"
130 | cmd "git commit -m 'Switched to fastlane mono repo'"
131 | end
132 |
133 | puts `open '#{path}'`
134 | puts `open '#{destination}'`
135 |
136 | puts "To push the changes run this:"
137 | puts "cd '#{destination}' && git push origin #{new_branch_name}".green
138 |
--------------------------------------------------------------------------------
/files_to_copy/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | fastlane
6 | ============
7 |
8 | [](https://twitter.com/FastlaneTools)
9 | [](https://github.com/fastlane/fastlane/blob/master/LICENSE)
10 | [](http://rubygems.org/gems/fastlane)
11 | [](https://travis-ci.org/fastlane/fastlane)
12 |
13 | `fastlane` is a tool for iOS and Android developers to automate tedious tasks like generating screenshots, dealing with provisioning profiles and releasing your application.
14 |
15 | You define how your process looks like
16 |
17 | ```ruby
18 | lane :beta do
19 | increment_build_number
20 | cocoapods
21 | match
22 | deliver
23 | sh "./customScript.sh"
24 |
25 | slack
26 | end
27 | ```
28 |
29 | To deploy your app to the App Store you can run
30 | ```
31 | fastlane beta
32 | ```
33 |
34 |
35 | | fastlane
36 | --------------------------|------------------------------------------------------------
37 | :sparkles: | Connect all iOS and Android build tools into one workflow (both `fastlane` tools and third party tools)
38 | :monorail: | Define different `deployment lanes` for App Store deployment, beta builds or testing
39 | :ship: | Deploy from any computer, including a CI-server
40 | :wrench: | Extend and customise the functionality
41 | :thought_balloon: | Never remember any difficult commands, just `fastlane`
42 | :tophat: | Easy setup assistant to get started in a few minutes
43 | :email: | Automatically pass on information from one build step to another (e.g. path to the `ipa` file)
44 | :page_with_curl: | Store **everything** in git. Never again lookup the build commands in the `Jenkins` configs
45 | :rocket: | Saves you **hours** for every app update you release
46 | :pencil2: | Very flexible configuration using a fully customisable `Fastfile`
47 | :mountain_cableway: | Implement a fully working Continuous Delivery process
48 | :ghost: | [Jenkins Integration](https://github.com/fastlane/fastlane/blob/master/docs/Jenkins.md): Show the output directly in the Jenkins test results
49 | :book: | Automatically generate a markdown documentation of your lane config
50 | :hatching_chick: | Over 150 built-in integrations available
51 | :computer: | Support for both iOS, Mac OS and Android apps
52 | :octocat: | Full git and mercurial support
53 |
54 | ##### Like this tool? [Be the first to know about updates and new fastlane tools](https://tinyletter.com/krausefx).
55 |
56 | ## Installation
57 |
58 | sudo gem install fastlane --verbose
59 |
60 | Make sure, you have the latest version of the Xcode command line tools installed:
61 |
62 | xcode-select --install
63 |
64 | If you experience slow launch times of fastlane, try running
65 |
66 | gem cleanup
67 |
68 | System Requirements: `fastlane` requires Mac OS X or Linux with Ruby 2.0.0 or above.
69 |
70 | If you want to take a look at a project, already using `fastlane`, check out the [fastlane-examples](https://github.com/fastlane/examples) with `fastlane` setups by Wikipedia, Product Hunt, MindNode and more.
71 |
72 | ## Quick Start
73 |
74 | The setup assistant will create all the necessary files for you, using the existing app metadata from iTunes Connect.
75 |
76 | - ```cd [your_project_folder]```
77 | - ```fastlane init```
78 | - Follow the setup assistant, which will set up ```fastlane``` for you
79 | - Further customise the ```Fastfile``` with [actions](https://github.com/fastlane/fastlane/blob/master/docs/Actions.md).
80 |
81 | ## Available commands
82 |
83 | Usually you'll use fastlane by triggering individual lanes:
84 |
85 | fastlane [lane_name]
86 |
87 | #### Other commands
88 |
89 | - `fastlane actions`: List all available `fastlane` actions
90 | - `fastlane action [action_name]`: Shows a more detailed description of an action
91 | - `fastlane lanes`: Lists all available lanes with description
92 | - `fastlane list`: Lists all available lanes without description
93 | - `fastlane new_action`: Create a new action (integration) for fastlane
94 |
95 | ## [`fastlane`](https://fastlane.tools) Toolchain
96 |
97 | Additionally to the `fastlane` commands, you now have access to those `fastlane` tools:
98 |
99 | - [`deliver`](https://github.com/fastlane/deliver): Upload screenshots, metadata and your app to the App Store
100 | - [`snapshot`](https://github.com/fastlane/snapshot): Automate taking localized screenshots of your iOS app on every device
101 | - [`frameit`](https://github.com/fastlane/frameit): Quickly put your screenshots into the right device frames
102 | - [`pem`](https://github.com/fastlane/pem): Automatically generate and renew your push notification profiles
103 | - [`sigh`](https://github.com/fastlane/sigh): Because you would rather spend your time building stuff than fighting provisioning
104 | - [`produce`](https://github.com/fastlane/produce): Create new iOS apps on iTunes Connect and Dev Portal using the command line
105 | - [`cert`](https://github.com/fastlane/cert): Automatically create and maintain iOS code signing certificates
106 | - [`codes`](https://github.com/fastlane/codes): Create promo codes for iOS Apps using the command line
107 | - [`spaceship`](https://github.com/fastlane/spaceship): Ruby library to access the Apple Dev Center and iTunes Connect
108 | - [`pilot`](https://github.com/fastlane/pilot): The best way to manage your TestFlight testers and builds from your terminal
109 | - [`boarding`](https://github.com/fastlane/boarding): The easiest way to invite your TestFlight beta testers
110 | - [`gym`](https://github.com/fastlane/gym): Building your iOS apps has never been easier
111 | - [`match`](https://github.com/fastlane/match): Easily sync your certificates and profiles across your team using git
112 |
113 | ## Need help?
114 | Please submit an issue on GitHub and provide information about your setup
115 |
116 | ## Special Thanks
117 |
118 | Thanks to all [contributors](https://github.com/fastlane/fastlane/graphs/contributors) for extending and improving `fastlane`.
119 |
120 | ## Code of Conduct
121 |
122 | Help us keep `fastlane` open and inclusive. Please read and follow our [Code of Conduct](https://github.com/fastlane/code-of-conduct).
123 |
124 | ## License
125 | This project is licensed under the terms of the MIT license. See the LICENSE file.
126 |
127 | > This project and all fastlane tools are in no way affiliated with Apple Inc or Google. This project is open source under the MIT license, which means you have full access to the source code and can modify it to fit your own needs. All fastlane tools run on your own computer or server, so your credentials or other sensitive information will never leave your own computer. You are responsible for how you use fastlane tools.
128 |
--------------------------------------------------------------------------------
/files_to_copy/.rubocop.yml:
--------------------------------------------------------------------------------
1 |
2 | Style/ClassCheck:
3 | EnforcedStyle: kind_of?
4 |
5 | # Cop supports --auto-correct.
6 | # Configuration parameters: EnforcedStyle, SupportedStyles.
7 | Style/BracesAroundHashParameters:
8 | Enabled: false
9 |
10 | Lint/UselessAssignment:
11 | Exclude:
12 | - '**/spec/**/*'
13 |
14 | # Cop supports --auto-correct.
15 | # Configuration parameters: EnforcedStyle, SupportedStyles.
16 | Style/IndentHash:
17 | Enabled: false
18 |
19 | Style/RaiseArgs:
20 | EnforcedStyle: exploded
21 |
22 | Style/DoubleNegation:
23 | Enabled: false
24 |
25 | Lint/HandleExceptions:
26 | Enabled: false
27 |
28 | # Cop supports --auto-correct.
29 | Lint/UnusedBlockArgument:
30 | Enabled: false
31 |
32 | # Needed for $verbose
33 | Style/GlobalVars:
34 | Enabled: false
35 |
36 | Style/FileName:
37 | Enabled: false
38 |
39 | # $? Exit
40 | Style/SpecialGlobalVars:
41 | Enabled: false
42 |
43 | Metrics/AbcSize:
44 | Max: 63
45 | Exclude:
46 | - '**/lib/*/options.rb'
47 |
48 | # Both string notations are okay
49 | Style/StringLiterals:
50 | Enabled: false
51 |
52 | # The %w might be confusing for new users
53 | Style/WordArray:
54 | MinSize: 19
55 |
56 | # Not a good thing
57 | Style/RedundantSelf:
58 | Enabled: false
59 |
60 | # raise and fail are both okay
61 | Style/SignalException:
62 | Enabled: false
63 |
64 | # Better too much 'return' than one missing
65 | Style/RedundantReturn:
66 | Enabled: false
67 |
68 | # Having if in the same line might not always be good
69 | Style/IfUnlessModifier:
70 | Enabled: false
71 |
72 | # That looks wrong
73 | Style/AlignHash:
74 | Enabled: false
75 |
76 | # and and or is okay
77 | Style/AndOr:
78 | Enabled: false
79 |
80 | # Configuration parameters: CountComments.
81 | Metrics/ClassLength:
82 | Max: 320
83 |
84 | Metrics/CyclomaticComplexity:
85 | Max: 17
86 |
87 | # Configuration parameters: AllowURI, URISchemes.
88 | Metrics/LineLength:
89 | Max: 370
90 |
91 | # Configuration parameters: CountKeywordArgs.
92 | Metrics/ParameterLists:
93 | Max: 17
94 |
95 | Metrics/PerceivedComplexity:
96 | Max: 18
97 |
98 | Style/DotPosition:
99 | Enabled: false
100 |
101 | Style/GuardClause:
102 | Enabled: false
103 |
104 |
105 |
106 | # Split
107 |
108 |
109 | # e.g.
110 | # def self.is_supported?(platform)
111 | # we may never use `platform`
112 | Lint/UnusedMethodArgument:
113 | Enabled: false
114 |
115 | # the let(:key) { ... }
116 | Lint/ParenthesesAsGroupedExpression:
117 | Exclude:
118 | - '**/spec/**/*'
119 |
120 | # We use `is_supported?` everywhere already
121 | Style/PredicateName:
122 | Enabled: false
123 |
124 | # Disable '+ should be surrounded with a single space' for xcodebuild_spec.rb
125 | Style/SpaceAroundOperators:
126 | Exclude:
127 | - '**/spec/actions_specs/xcodebuild_spec.rb'
128 |
129 | Metrics/MethodLength:
130 | Exclude:
131 | - '**/lib/fastlane/actions/*.rb'
132 | - '**/bin/fastlane'
133 | - '**/lib/*/options.rb'
134 | Max: 60
135 |
136 | AllCops:
137 | Include:
138 | - '**/fastlane/Fastfile'
139 | Exclude:
140 | - '**/lib/assets/custom_action_template.rb'
141 |
142 | ##################
143 | # TODO
144 | ##################
145 |
146 | # Offense count: 7
147 | # Configuration parameters: CountComments.
148 | Metrics/ClassLength:
149 | Max: 320
150 |
151 | # Offense count: 4
152 | Metrics/CyclomaticComplexity:
153 | Max: 17
154 |
155 | # Offense count: 489
156 | # Configuration parameters: AllowURI, URISchemes.
157 | Metrics/LineLength:
158 | Max: 372
159 |
160 | # Offense count: 5
161 | # Configuration parameters: CountKeywordArgs.
162 | Metrics/ParameterLists:
163 | Max: 17
164 |
165 | # Offense count: 3
166 | Metrics/PerceivedComplexity:
167 | Max: 18
168 |
169 | # Offense count: 1
170 | # Cop supports --auto-correct.
171 | Style/Alias:
172 | Enabled: false
173 |
174 | # Offense count: 14
175 | # Cop supports --auto-correct.
176 | # Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles.
177 | Style/AlignHash:
178 | Enabled: false
179 |
180 | # Offense count: 22
181 | # Cop supports --auto-correct.
182 | # Configuration parameters: EnforcedStyle, SupportedStyles.
183 | Style/AndOr:
184 | Enabled: false
185 |
186 | # Offense count: 1
187 | # Configuration parameters: EnforcedStyle, SupportedStyles.
188 | Style/ClassAndModuleChildren:
189 | Enabled: false
190 |
191 | # Offense count: 19
192 | Style/Documentation:
193 | Enabled: false
194 |
195 | # Offense count: 112
196 | # Cop supports --auto-correct.
197 | # Configuration parameters: EnforcedStyle, SupportedStyles.
198 | Style/DotPosition:
199 | Enabled: false
200 |
201 | # Offense count: 12
202 | # Cop supports --auto-correct.
203 | # Configuration parameters: EnforcedStyle, SupportedStyles.
204 | Style/EmptyLinesAroundClassBody:
205 | Enabled: false
206 |
207 | # Configuration parameters: MinBodyLength.
208 | Style/GuardClause:
209 | Enabled: false
210 |
211 | # Offense count: 4
212 | # Cop supports --auto-correct.
213 | # Configuration parameters: MaxLineLength.
214 | Style/IfUnlessModifier:
215 | Enabled: false
216 |
217 | # Offense count: 74
218 | # Cop supports --auto-correct.
219 | # Configuration parameters: EnforcedStyle, SupportedStyles.
220 | Style/MultilineOperationIndentation:
221 | Enabled: false
222 |
223 | # Offense count: 10
224 | # Cop supports --auto-correct.
225 | Style/NumericLiterals:
226 | MinDigits: 14
227 |
228 | # Offense count: 2
229 | # Cop supports --auto-correct.
230 | Style/PerlBackrefs:
231 | Enabled: false
232 |
233 | # Offense count: 19
234 | # Cop supports --auto-correct.
235 | # Configuration parameters: AllowMultipleReturnValues.
236 | Style/RedundantReturn:
237 | Enabled: false
238 |
239 | # Offense count: 77
240 | # Cop supports --auto-correct.
241 | Style/RedundantSelf:
242 | Enabled: false
243 |
244 | # Offense count: 38
245 | # Cop supports --auto-correct.
246 | # Configuration parameters: EnforcedStyle, SupportedStyles.
247 | Style/SignalException:
248 | Enabled: false
249 |
250 | # Offense count: 5
251 | # Cop supports --auto-correct.
252 | # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
253 | Style/SpaceInsideBlockBraces:
254 | Enabled: false
255 |
256 | # Offense count: 291
257 | # Cop supports --auto-correct.
258 | # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles.
259 | Style/SpaceInsideHashLiteralBraces:
260 | Enabled: false
261 |
262 | # Offense count: 8
263 | # Cop supports --auto-correct.
264 | Style/SpaceInsideParens:
265 | Enabled: false
266 |
267 | # Offense count: 881
268 | # Cop supports --auto-correct.
269 | # Configuration parameters: EnforcedStyle, SupportedStyles.
270 | Style/StringLiterals:
271 | Enabled: false
272 |
273 | # Offense count: 9
274 | # Cop supports --auto-correct.
275 | # Configuration parameters: WordRegex.
276 | Style/WordArray:
277 | MinSize: 19
278 |
--------------------------------------------------------------------------------
/migrate_issues.rb:
--------------------------------------------------------------------------------
1 | require 'octokit'
2 | require 'pry'
3 | require 'excon'
4 | require 'colored'
5 | require 'json'
6 |
7 |
8 | class Hendl
9 | # e.g. KrauseFx/fastlane
10 | attr_accessor :source
11 | attr_accessor :destination
12 |
13 | attr_accessor :open_only
14 |
15 | # Reason on why this was necessary
16 | attr_accessor :reason
17 |
18 | def initialize(source: nil, destination: nil, reason: nil, open_only: false)
19 | self.source = source
20 | self.destination = destination
21 | self.reason = reason
22 | self.open_only = open_only
23 | self.start
24 | end
25 |
26 | def client
27 | @client ||= Octokit::Client.new(access_token: ENV["GITHUB_API_TOKEN"])
28 | end
29 |
30 | def start
31 | client.auto_paginate = true
32 | puts "Fetching issues from '#{source}'..."
33 | counter = 0
34 | client.issues(source, per_page: 1000, state: "all").each do |original|
35 | if self.open_only and original.state != "open"
36 | puts "Skipping #{original.number} as it's not an open one"
37 | next
38 | end
39 |
40 | next unless original.pull_request.nil? # no PRs for now
41 |
42 | labels = original.labels.collect { |a| a[:name] }
43 | if labels.include?("migrated") or labels.include?("migration_failed")
44 | puts "Skipping #{original.number} because it's already migrated or failed"
45 | next
46 | end
47 |
48 | hendl(original)
49 | smart_sleep
50 | counter += 1
51 | end
52 | puts "[SUCCESS] Migrated #{counter} issues / PRs"
53 | end
54 |
55 | def hendl(original)
56 | puts "Hendling #{original.number}"
57 | if original.pull_request.nil?
58 | hendl_issue(original)
59 | else
60 | # hendl_pr(original)
61 | end
62 | end
63 |
64 | def smart_sleep
65 | # via https://developer.github.com/guides/best-practices-for-integrators/#dealing-with-abuse-rate-limits
66 | # at least one second between requests
67 | # also https://developer.github.com/v3/#rate-limiting
68 | # maximum of 5000 requests an hour => 83 requests per minute
69 | sleep 2.5
70 | end
71 |
72 | def table(user_id, body)
73 | "
74 |
75 |
76 |
77 | |
78 |
79 | #{body}
80 | |
81 |
82 |
"
83 | end
84 |
85 | # We copy over all the issues, and also mention everyone
86 | # so that people are automatically subscribed to notifications
87 | def hendl_issue(original)
88 | original_comments = client.issue_comments(source, original.number)
89 | comments = []
90 | original_comments.each do |original_comment|
91 | table_code = table(original_comment.user.id, "@#{original_comment.user.login} commented")
92 | body = [table_code, original_comment.body]
93 | comments << {
94 | created_at: original_comment.created_at.iso8601,
95 | body: body.join("\n\n")
96 | }
97 | end
98 |
99 | actual_label = original.labels.collect { |a| a[:name] }
100 |
101 | tool_name_label = source.split("/").last
102 | table_link = "Imported from #{source}##{original.number}"
103 | table_code = table(original.user.id, "Original issue by @#{original.user.login} - #{table_link}")
104 | body = [table_code, original.body]
105 | data = {
106 | issue: {
107 | title: original.title,
108 | body: body.join("\n\n"),
109 | created_at: original.created_at.iso8601,
110 | labels: actual_label + [tool_name_label],
111 | closed: original.state != "open"
112 | },
113 | comments: comments
114 | }
115 | data[:issue][:closed_at] = original.closed_at.iso8601 if original.state != "open"
116 |
117 | response = Excon.post("https://api.github.com/repos/#{destination}/import/issues", body: data.to_json, headers: request_headers)
118 | response = JSON.parse(response.body)
119 | status_url = response['url']
120 | puts response
121 |
122 | new_issue_url = nil
123 |
124 | begin
125 | (5..35).each do |request_num|
126 | sleep(request_num)
127 |
128 | puts "Sending #{status_url}"
129 | async_response = Excon.get(status_url, headers: request_headers) # if this crashes, make sure to have a valid token with admin permission to the actual repo
130 | async_response = JSON.parse(async_response.body)
131 | puts async_response.to_s.yellow
132 |
133 | new_issue_url = async_response['issue_url']
134 | break if new_issue_url.to_s.length > 0
135 | puts "unable to get new issue url for #{original.number} after #{request_num - 4} requests".yellow
136 | end
137 | rescue => ex
138 | puts "Something went wrong, wups"
139 | puts ex.to_s
140 | # If the error message is
141 | # {"message"=>"Not Found", "documentation_url"=>"https://developer.github.com/v3"}
142 | # that just means that fastlane-bot doesn't have admin access
143 | end
144 |
145 | if new_issue_url.to_s.length > 0
146 | new_issue_url.gsub!("api.github.com/repos", "github.com")
147 |
148 | client.update_issue(source, original.number, labels: (actual_label + ["migrated"]))
149 |
150 | # reason, link to the new issue
151 | puts "closing old issue #{original.number}"
152 | body = []
153 | body << "This issue was migrated to #{new_issue_url}. Please post all further comments there."
154 | body << reason
155 | puts new_issue_url
156 | client.add_comment(source, original.number, body.join("\n\n"))
157 | smart_sleep
158 | client.close_issue(source, original.number) unless original.state == "closed"
159 | else
160 | puts "unable to find new issue url, not closing or commenting".red
161 | client.update_issue(source, original.number, labels: (actual_label + ["migration_failed"]))
162 | puts "Status URL: #{status_url}"
163 | # This means we have to manually migrate the issue
164 | # if you want to try it again, just remove the migration_failed tag
165 | end
166 | end
167 |
168 | def request_headers
169 | {
170 | "Accept" => "application/vnd.github.golden-comet-preview+json",
171 | "Authorization" => ("token " + ENV["GITHUB_API_TOKEN"]),
172 | "Content-Type" => "application/x-www-form-urlencoded",
173 | "User-Agent" => "fastlane bot"
174 | }
175 | end
176 |
177 | # We want to comment on PRs and tell the user to re-submit it
178 | # on the new repo, as we can't migrate them automatically
179 | def hendl_pr(original)
180 | puts "#{original.number} is a pull request"
181 | if original.state != "open"
182 | puts "#{original.number} is already closed - nothing to do here"
183 | return
184 | end
185 |
186 | body = ["Hello @#{original.user.login},"]
187 | body << reason
188 | body << "Sorry for the troubles, we'd appreciate if you could re-submit your Pull Request with these changes to the new repository"
189 |
190 | client.add_comment(source, original.number, body.join("\n\n"))
191 | smart_sleep
192 | client.close_pull_request(source, original.number)
193 | end
194 | end
195 |
196 | require './tools'
197 | destination = "fastlane/fastlane" # TODO: Should be fastlane
198 | names = Array(ENV["TOOL"] || @tools.delete_if { |a| a == "fastlane" }) # we don't want to import issues from our own repo
199 | open_only = !ENV["ALL"]
200 |
201 | puts "Migrating #{names.join(', ')}"
202 |
203 | names.each do |current|
204 | Hendl.new(source: "fastlane/#{current}",
205 | destination: destination,
206 | reason: "`fastlane` is now a mono repo, you can read more about the change in our [blog post](https://krausefx.com/blog/our-goal-to-unify-fastlane-tools). All tools are now available in the [fastlane main repo](https://github.com/fastlane/fastlane) :rocket:",
207 | open_only: open_only)
208 | end
209 |
--------------------------------------------------------------------------------