multi_repo 0.1.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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +16 -0
- data/.github/workflows/ci.yaml +32 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rubocop.yml +4 -0
- data/.rubocop_cc.yml +4 -0
- data/.rubocop_local.yml +0 -0
- data/.whitesource +3 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +90 -0
- data/Rakefile +6 -0
- data/bin/console +8 -0
- data/exe/multi_repo +29 -0
- data/lib/multi_repo/cli.rb +92 -0
- data/lib/multi_repo/helpers/git_mirror.rb +198 -0
- data/lib/multi_repo/helpers/license.rb +106 -0
- data/lib/multi_repo/helpers/pull_request_blaster_outer.rb +129 -0
- data/lib/multi_repo/helpers/readme_badges.rb +84 -0
- data/lib/multi_repo/helpers/rename_labels.rb +26 -0
- data/lib/multi_repo/helpers/update_branch_protection.rb +24 -0
- data/lib/multi_repo/helpers/update_labels.rb +34 -0
- data/lib/multi_repo/helpers/update_milestone.rb +33 -0
- data/lib/multi_repo/helpers/update_repo_settings.rb +23 -0
- data/lib/multi_repo/labels.rb +31 -0
- data/lib/multi_repo/repo.rb +56 -0
- data/lib/multi_repo/repo_set.rb +27 -0
- data/lib/multi_repo/service/artifactory.rb +122 -0
- data/lib/multi_repo/service/code_climate.rb +119 -0
- data/lib/multi_repo/service/docker.rb +178 -0
- data/lib/multi_repo/service/git/minigit_capturing_patch.rb +12 -0
- data/lib/multi_repo/service/git.rb +90 -0
- data/lib/multi_repo/service/github.rb +238 -0
- data/lib/multi_repo/service/rubygems_stub.rb +103 -0
- data/lib/multi_repo/service/travis.rb +68 -0
- data/lib/multi_repo/version.rb +3 -0
- data/lib/multi_repo.rb +44 -0
- data/multi_repo.gemspec +44 -0
- data/repos/.gitkeep +0 -0
- data/scripts/delete_labels +23 -0
- data/scripts/destroy_branch +23 -0
- data/scripts/destroy_remote +26 -0
- data/scripts/destroy_tag +31 -0
- data/scripts/each_repo +23 -0
- data/scripts/fetch_repos +18 -0
- data/scripts/git_mirror +9 -0
- data/scripts/github_rate_limit +10 -0
- data/scripts/hacktoberfest +138 -0
- data/scripts/make_alumni +50 -0
- data/scripts/new_rubygems_stub +17 -0
- data/scripts/pull_request_blaster_outer +24 -0
- data/scripts/pull_request_labeler +59 -0
- data/scripts/pull_request_merger +63 -0
- data/scripts/reenable_repo_workflows +33 -0
- data/scripts/rename_labels +22 -0
- data/scripts/restart_travis_builds +31 -0
- data/scripts/show_commit_history +86 -0
- data/scripts/show_org_members +19 -0
- data/scripts/show_org_repos +13 -0
- data/scripts/show_org_stats +82 -0
- data/scripts/show_project_cards +35 -0
- data/scripts/show_repo_set +13 -0
- data/scripts/show_tag +33 -0
- data/scripts/show_travis_status +63 -0
- data/scripts/update_branch_protection +22 -0
- data/scripts/update_labels +16 -0
- data/scripts/update_milestone +21 -0
- data/scripts/update_repo_settings +15 -0
- metadata +366 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
opt :prs, "The list of PRs to merge", :type => :strings, :required => true
|
11
|
+
opt :add, "Labels to add", :type => :strings, :required => true
|
12
|
+
opt :remove, "Labels to remove", :type => :strings, :required => true
|
13
|
+
|
14
|
+
MultiRepo::CLI.common_options(self, :only => :dry_run)
|
15
|
+
end
|
16
|
+
|
17
|
+
# TODO: Normalize any PR format to `org/repo#pr`
|
18
|
+
PR_REGEX = %r{^([^/#]+/[^/#]+)#([^/#]+)$}
|
19
|
+
Optimist.die :prs, "must be in the form `org/repo#pr`" unless opts[:prs].all? { |pr| pr.match?(PR_REGEX) }
|
20
|
+
|
21
|
+
def github
|
22
|
+
MultiRepo::Service::Github.client
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_labels(repo_name, pr_number, labels:, dry_run:, **_)
|
26
|
+
labels = Array(labels)
|
27
|
+
if dry_run
|
28
|
+
puts "** dry-run: github.add_labels_to_an_issue(#{repo_name.inspect}, #{pr_number.inspect}, #{labels.inspect})".light_black
|
29
|
+
else
|
30
|
+
github.add_labels_to_an_issue(repo_name, pr_number, labels)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def remove_labels(repo_name, pr_number, labels:, dry_run:, **_)
|
35
|
+
Array(labels).each do |label|
|
36
|
+
remove_label(repo_name, pr_number, label: label, dry_run: dry_run)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def remove_label(repo_name, pr_number, label:, dry_run:, **_)
|
41
|
+
if dry_run
|
42
|
+
puts "** dry-run: github.remove_label(#{repo_name.inspect}, #{pr_number.inspect}, #{label.inspect})".light_black
|
43
|
+
else
|
44
|
+
github.remove_label(repo_name, pr_number, label)
|
45
|
+
end
|
46
|
+
rescue Octokit::NotFound
|
47
|
+
# Ignore labels that are not found, because we want them removed anyway
|
48
|
+
end
|
49
|
+
|
50
|
+
opts[:prs].each do |pr|
|
51
|
+
puts MultiRepo::CLI.header(pr)
|
52
|
+
|
53
|
+
repo_name, pr_number = PR_REGEX.match(pr).captures
|
54
|
+
|
55
|
+
add_labels(repo_name, pr_number, labels: opts[:add], **opts)
|
56
|
+
remove_labels(repo_name, pr_number, labels: opts[:remove], **opts)
|
57
|
+
|
58
|
+
puts
|
59
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
opt :prs, "The list of PRs to merge", :type => :strings, :required => true
|
11
|
+
opt :assignee, "GitHub user to assign when merging", :type => :string, :required => true
|
12
|
+
opt :labels, "Labels to apply when merging", :type => :strings
|
13
|
+
|
14
|
+
MultiRepo::CLI.common_options(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
# TODO: Normalize any PR format to `org/repo#pr`
|
18
|
+
PR_REGEX = %r{^([^/#]+/[^/#]+)#([^/#]+)$}
|
19
|
+
Optimist.die :prs, "must be in the form `org/repo#pr`" unless opts[:prs].all? { |pr| pr.match?(PR_REGEX) }
|
20
|
+
|
21
|
+
def merge_pull_request(repo_name, pr_number, dry_run:, **_)
|
22
|
+
if dry_run
|
23
|
+
puts "** dry-run: github.merge_pull_request(#{repo_name.inspect}, #{pr_number.inspect})".light_black
|
24
|
+
else
|
25
|
+
begin
|
26
|
+
MultiRepo::Service::Github.client.merge_pull_request(repo_name, pr_number)
|
27
|
+
rescue Octokit::MethodNotAllowed => err
|
28
|
+
raise unless err.to_s.include?("Pull Request is not mergeable")
|
29
|
+
|
30
|
+
puts "** WARN: Pull Request is not mergeable"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_labels(repo_name, pr_number, labels:, dry_run:, **_)
|
36
|
+
labels = Array(labels)
|
37
|
+
if dry_run
|
38
|
+
puts "** dry-run: github.add_labels_to_an_issue(#{repo_name.inspect}, #{pr_number.inspect}, #{labels.inspect})".light_black
|
39
|
+
else
|
40
|
+
MultiRepo::Service::Github.client.add_labels_to_an_issue(repo_name, pr_number, labels)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def assign_user(repo_name, pr_number, assignee:, dry_run:, **_)
|
45
|
+
assignee = assignee[1..] if assignee.start_with?("@")
|
46
|
+
if dry_run
|
47
|
+
puts "** dry-run: github.update_issue(#{repo_name.inspect}, #{pr_number.inspect}, \"assignee\" => #{assignee.inspect})".light_black
|
48
|
+
else
|
49
|
+
MultiRepo::Service::Github.client.update_issue(repo_name, pr_number, "assignee" => assignee)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
opts[:prs].each do |pr|
|
54
|
+
puts MultiRepo::CLI.header(pr)
|
55
|
+
|
56
|
+
repo_name, pr_number = PR_REGEX.match(pr).captures
|
57
|
+
|
58
|
+
merge_pull_request(repo_name, pr_number, opts)
|
59
|
+
add_labels(repo_name, pr_number, opts) if opts[:labels].present?
|
60
|
+
assign_user(repo_name, pr_number, opts)
|
61
|
+
|
62
|
+
puts
|
63
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
opt :org, "The organization to reenable workflows in", :type => :string, :required => true
|
11
|
+
opt :extra_repos, "Extra repos to reenable workflows in", :type => :strings, :default => []
|
12
|
+
|
13
|
+
MultiRepo::CLI.common_options(self, :only => :dry_run)
|
14
|
+
ende
|
15
|
+
|
16
|
+
github = MultiRepo::Service::Github.new(**opts.slice(:dry_run))
|
17
|
+
|
18
|
+
repos = (github.org_repo_names(opts[:org]) + opts[:extra_repos]).sort
|
19
|
+
repos.each do |repo_name|
|
20
|
+
puts MultiRepo::CLI.header(repo_name)
|
21
|
+
|
22
|
+
disabled_workflows = github.disabled_workflows
|
23
|
+
if disabled_workflows.any?
|
24
|
+
disabled_workflows.each do |w|
|
25
|
+
puts "** Enabling #{w.html_url} (#{w.id})"
|
26
|
+
github.enable_workflow(github, repo_name, w.html_url, w.id)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
puts "** No disabled workflows found"
|
30
|
+
end
|
31
|
+
|
32
|
+
puts
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
opt :old, "The old label names.", :type => :strings, :required => true
|
11
|
+
opt :new, "The new label names.", :type => :strings, :required => true
|
12
|
+
|
13
|
+
MultiRepo::CLI.common_options(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
rename_hash = opts[:old].zip(opts[:new]).to_h
|
17
|
+
puts "Renaming: #{rename_hash.pretty_inspect}"
|
18
|
+
puts
|
19
|
+
|
20
|
+
MultiRepo::CLI.each_repo(**opts) do |repo|
|
21
|
+
MultiRepo::Helpers::RenameLabels.new(repo.name, rename_hash, **opts).run
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
require 'travis'
|
9
|
+
require 'travis/pro/auto_login'
|
10
|
+
|
11
|
+
opts = Optimist.options do
|
12
|
+
opt :ref, "The branch or release tag to rebuild.", :type => :string, :required => true
|
13
|
+
|
14
|
+
MultiRepo::CLI.common_options(self, :except => :dry_run, :repo_set_default => nil)
|
15
|
+
end
|
16
|
+
opts[:repo_set] = opts[:ref].split("-").first unless opts[:repo] || opts[:repo_set]
|
17
|
+
|
18
|
+
puts "Restarting Travis builds for #{opts[:ref]}:"
|
19
|
+
|
20
|
+
MultiRepo::CLI.repos_for(**opts).collect do |repo|
|
21
|
+
repo = Travis::Pro::Repository.find(repo.name)
|
22
|
+
begin
|
23
|
+
last_build = repo.last_on_branch(opts[:ref])
|
24
|
+
rescue Travis::Client::NotFound
|
25
|
+
# Ignore repo which doesn't have Travis enabled for that branch
|
26
|
+
next
|
27
|
+
end
|
28
|
+
|
29
|
+
puts "- #{repo.name}..."
|
30
|
+
last_build.restart
|
31
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
require "active_support/core_ext/object/blank"
|
9
|
+
require "active_support/core_ext/string/inflections"
|
10
|
+
|
11
|
+
DISPLAY_FORMATS = %w[commit pr-title pr-label]
|
12
|
+
|
13
|
+
opts = Optimist.options do
|
14
|
+
opt :from, "The commit log 'from' ref", :type => :string, :required => true
|
15
|
+
opt :to, "The commit log 'to' ref" , :type => :string, :required => true
|
16
|
+
opt :display, "How to display the history. Valid values are: #{DISPLAY_FORMATS.join(", ")}", :default => "commit"
|
17
|
+
opt :summary, "Display a summary of the repos.", :default => false
|
18
|
+
|
19
|
+
opt :skip, "The repos to skip", :type => :strings, :default => []
|
20
|
+
|
21
|
+
MultiRepo::CLI.common_options(self, :except => :dry_run)
|
22
|
+
end
|
23
|
+
Optimist.die :display, "must be one of: #{DISPLAY_FORMATS.join(", ")}" unless DISPLAY_FORMATS.include?(opts[:display])
|
24
|
+
|
25
|
+
range = "#{opts[:from]}..#{opts[:to]}"
|
26
|
+
|
27
|
+
puts "Git commit log between #{opts[:from]} and #{opts[:to]}\n\n"
|
28
|
+
|
29
|
+
repos_with_changes = []
|
30
|
+
|
31
|
+
MultiRepo::CLI.repos_for(**opts).each do |repo|
|
32
|
+
next if opts[:skip].include?(repo.name)
|
33
|
+
|
34
|
+
puts MultiRepo::CLI.header(repo.name)
|
35
|
+
repo.git.fetch(output: false)
|
36
|
+
|
37
|
+
case opts[:display]
|
38
|
+
when "pr-label", "pr-title"
|
39
|
+
github ||= MultiRepo::Service::Github.client
|
40
|
+
pr_label_display = opts[:display] == "pr-label"
|
41
|
+
|
42
|
+
results = {}
|
43
|
+
if pr_label_display
|
44
|
+
results["bug"] = []
|
45
|
+
results["enhancement"] = []
|
46
|
+
end
|
47
|
+
results["other"] = []
|
48
|
+
|
49
|
+
log = repo.git.client.capturing.log({:oneline => true}, range)
|
50
|
+
log.lines.each do |line|
|
51
|
+
next unless (match = line.match(/Merge pull request #(\d+)\b/))
|
52
|
+
|
53
|
+
pr = github.pull_request(repo.name, match[1])
|
54
|
+
label = pr.labels.detect { |l| results.key?(l.name) }&.name || "other"
|
55
|
+
results[label] << pr
|
56
|
+
end
|
57
|
+
|
58
|
+
changes_found = false
|
59
|
+
|
60
|
+
results.each do |label, prs|
|
61
|
+
next if prs.blank?
|
62
|
+
changes_found = true
|
63
|
+
|
64
|
+
puts "\n## #{label.titleize}\n\n" if pr_label_display
|
65
|
+
prs.each do |pr|
|
66
|
+
puts "* #{pr.title} [[##{pr.number}]](#{pr.html_url})"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
repos_with_changes << repo if changes_found
|
71
|
+
when "commit"
|
72
|
+
output = repo.git.client.capturing.log({:oneline => true, :decorate => true, :graph => true}, range)
|
73
|
+
puts output
|
74
|
+
repos_with_changes << repo if output.present?
|
75
|
+
end
|
76
|
+
puts
|
77
|
+
end
|
78
|
+
|
79
|
+
if opts[:summary] && repos_with_changes.any?
|
80
|
+
puts
|
81
|
+
puts "Here are the changes per affected repository in GitHub:"
|
82
|
+
repos_with_changes.each do |repo|
|
83
|
+
puts "* [#{repo.name}](https://github.com/#{repo.name}/compare/#{opts[:from]}...#{opts[:to]})"
|
84
|
+
end
|
85
|
+
puts
|
86
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
opt :org, "The org to list the users for", :type => :string, :required => true
|
11
|
+
opt :team, "Show members of a specific team", :type => :string
|
12
|
+
opt :alumni, "Whether or not to include alumni", :default => false
|
13
|
+
end
|
14
|
+
|
15
|
+
github = MultiRepo::Service::Github.new
|
16
|
+
members = opts[:team] ? github.team_member_names(opts[:org], opts[:team]) : github.org_member_names(opts[:org])
|
17
|
+
members -= github.team_member_names(opts[:org], "alumni") unless opts[:alumni]
|
18
|
+
|
19
|
+
puts members
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
opt :org, "The org to list the repos for", :type => :string, :required => true
|
11
|
+
end
|
12
|
+
|
13
|
+
puts MultiRepo::Service::Github.org_repo_names(opts[:org])
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
opt :since, "Since what date.", :type => :string, :required => true
|
11
|
+
|
12
|
+
MultiRepo::CLI.common_options(self, :except => :dry_run)
|
13
|
+
end
|
14
|
+
|
15
|
+
class OrgStats
|
16
|
+
def initialize(since:, **opts)
|
17
|
+
@since = since
|
18
|
+
@opts = opts
|
19
|
+
|
20
|
+
@total_commits = Hash.new(0)
|
21
|
+
@total_merges = Hash.new(0)
|
22
|
+
@names = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
MultiRepo::CLI.each_repo(**@opts) { |repo| run_one(repo) }
|
27
|
+
|
28
|
+
puts
|
29
|
+
puts "Total Commits:"
|
30
|
+
print_totals(@total_commits)
|
31
|
+
|
32
|
+
puts
|
33
|
+
puts "Grand Total Commits: #{@total_commits.values.sum}"
|
34
|
+
|
35
|
+
puts
|
36
|
+
puts "Total Merges:"
|
37
|
+
print_totals(@total_merges)
|
38
|
+
|
39
|
+
puts
|
40
|
+
puts "Grand Total Merges: #{@total_merges.values.sum}"
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def run_one(repo)
|
46
|
+
repo.git.fetch
|
47
|
+
repo.git.hard_checkout("master")
|
48
|
+
|
49
|
+
puts "Commits:"
|
50
|
+
commits = repo.git.client.capturing.shortlog("--summary", "--numbered", "--email", "--no-merges", "--since", @since)
|
51
|
+
puts commits
|
52
|
+
|
53
|
+
parse_data(commits).each do |number, name, email|
|
54
|
+
@total_commits[email] += number.to_i
|
55
|
+
@names[email] ||= name
|
56
|
+
end
|
57
|
+
|
58
|
+
puts "Merges:"
|
59
|
+
merges = repo.git.client.capturing.shortlog("--summary", "--numbered", "--email", "--merges", "--since", @since, "--grep", "Merge pull request #")
|
60
|
+
puts merges
|
61
|
+
|
62
|
+
parse_data(merges).each do |number, name, email|
|
63
|
+
@total_merges[email] += number.to_i
|
64
|
+
@names[email] ||= name
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_data(data)
|
69
|
+
data
|
70
|
+
.chomp
|
71
|
+
.lines(:chomp => true)
|
72
|
+
.map { |l| l.match(/^\s*(\d+)\s+([^<]+)<([^>]+)>/).captures }
|
73
|
+
end
|
74
|
+
|
75
|
+
def print_totals(totals)
|
76
|
+
totals.sort_by { |_email, number| -number }.each do |email, number|
|
77
|
+
puts "#{number.to_s.rjust(8)} #{@names[email]} <#{email}>"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
OrgStats.new(**opts).run
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
opt :project_id, "The project ID", :type => :integer, :required => true
|
11
|
+
opt :column, "The column within the project", :type => :string, :required => true
|
12
|
+
|
13
|
+
MultiRepo::CLI.common_options(self, :only => :repo)
|
14
|
+
end
|
15
|
+
|
16
|
+
github = MultiRepo::Service::Github.client
|
17
|
+
repo = opts[:repo].first
|
18
|
+
projects_headers = {:accept => "application/vnd.github.inertia-preview+json"}
|
19
|
+
|
20
|
+
projects = github.send(repo.include?("/") ? :projects : :org_projects, repo, projects_headers)
|
21
|
+
project = projects.detect { |p| p.number == opts[:project_id] }
|
22
|
+
Optimist.die :project_id, "not found" if project.nil?
|
23
|
+
|
24
|
+
column = github.project_columns(project.id, projects_headers).detect { |c| c.name == opts[:column] }
|
25
|
+
Optimist.die :column, "not found" if column.nil?
|
26
|
+
|
27
|
+
cards = github.column_cards(column.id, projects_headers)
|
28
|
+
issues = cards.map do |card|
|
29
|
+
org, repo, _issues, id = URI.parse(card.content_url).path.split("/").last(4)
|
30
|
+
github.issue("#{org}/#{repo}", id)
|
31
|
+
end
|
32
|
+
|
33
|
+
issues.each do |issue|
|
34
|
+
puts "* #{issue.title} [[##{issue.number}]](#{issue.html_url})"
|
35
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
MultiRepo::CLI.common_options(self, :only => :repo_set)
|
11
|
+
end
|
12
|
+
|
13
|
+
puts MultiRepo::CLI.repos_for(**opts).collect(&:name)
|
data/scripts/show_tag
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
require 'more_core_extensions/core_ext/array/tableize'
|
9
|
+
|
10
|
+
opts = Optimist.options do
|
11
|
+
opt :tag, "The tag name.", :type => :string, :required => true
|
12
|
+
|
13
|
+
MultiRepo::CLI.common_options(self, :except => :dry_run, :repo_set_default => nil)
|
14
|
+
end
|
15
|
+
opts[:repo_set] = opts[:tag].split("-").first unless opts[:repo] || opts[:repo_set]
|
16
|
+
|
17
|
+
HEADER = %w(Repo SHA Message).freeze
|
18
|
+
|
19
|
+
def show_tag(repo, tag)
|
20
|
+
line =
|
21
|
+
begin
|
22
|
+
repo.git.client.capturing.show({:summary => true, :oneline => true}, tag)
|
23
|
+
rescue MiniGit::GitError => err
|
24
|
+
""
|
25
|
+
end
|
26
|
+
|
27
|
+
sha, message = line.split(" ", 2)
|
28
|
+
[repo.name, sha, message]
|
29
|
+
end
|
30
|
+
|
31
|
+
repos = MultiRepo::CLI.repos_for(**opts)
|
32
|
+
table = [HEADER] + repos.collect { |repo| show_tag(repo, opts[:tag]) }
|
33
|
+
puts table.tableize(:max_width => 75)
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
gem "action_view"
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'more_core_extensions/core_ext/array/tableize'
|
11
|
+
require 'action_view' # For ActionView::Helpers::DateHelper
|
12
|
+
require 'travis'
|
13
|
+
require 'travis/pro/auto_login'
|
14
|
+
|
15
|
+
opts = Optimist.options do
|
16
|
+
opt :ref, "The branch or release tag to check status for.", :type => :string, :required => true
|
17
|
+
|
18
|
+
MultiRepo::CLI.common_options(self, :except => :dry_run, :repo_set_default => nil)
|
19
|
+
end
|
20
|
+
opts[:repo_set] = opts[:ref].split("-").first unless opts[:repo] || opts[:repo_set]
|
21
|
+
|
22
|
+
date_helper = Class.new { include ActionView::Helpers::DateHelper }.new
|
23
|
+
|
24
|
+
travis_repos = MultiRepo::CLI.repos_for(**opts).collect do |repo|
|
25
|
+
repo = Travis::Pro::Repository.find(repo.name)
|
26
|
+
begin
|
27
|
+
last_build = repo.last_on_branch(opts[:ref])
|
28
|
+
rescue Travis::Client::NotFound
|
29
|
+
# Ignore repo which doesn't have Travis enabled for that branch
|
30
|
+
next
|
31
|
+
end
|
32
|
+
|
33
|
+
status, status_sort =
|
34
|
+
case last_build.state
|
35
|
+
when "errored", "failed"
|
36
|
+
[last_build.state.red, 0]
|
37
|
+
when "created", "started"
|
38
|
+
[last_build.state.yellow, 1]
|
39
|
+
when "passed"
|
40
|
+
[last_build.state.green, 2]
|
41
|
+
else
|
42
|
+
[last_build.state, 3]
|
43
|
+
end
|
44
|
+
|
45
|
+
date_sort = last_build.finished_at
|
46
|
+
date = "#{date_helper.time_ago_in_words(date_sort)} ago" if date_sort
|
47
|
+
|
48
|
+
last_build_url = "https://travis-ci.com/github/#{last_build.repository.slug}/builds/#{last_build.id}"
|
49
|
+
|
50
|
+
{
|
51
|
+
"Repo" => repo.name,
|
52
|
+
"Status" => status,
|
53
|
+
"Status Sort" => status_sort,
|
54
|
+
"Date" => date,
|
55
|
+
"Date Sort" => date_sort,
|
56
|
+
"URL" => last_build_url
|
57
|
+
}
|
58
|
+
end.compact
|
59
|
+
|
60
|
+
# Reverse sort by date then stable sort by status
|
61
|
+
travis_repos = travis_repos.sort_by { |v| v["Date Sort"].to_s }.reverse.sort_by.with_index { |v, n| [v["Status Sort"], n] }
|
62
|
+
|
63
|
+
puts travis_repos.tableize(:columns => ["Repo", "Status", "Date", "URL"])
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
opt :branch, "The branch to protect.", :type => :string, :required => true
|
11
|
+
|
12
|
+
MultiRepo::CLI.common_options(self, :repo_set_default => nil)
|
13
|
+
end
|
14
|
+
opts[:repo_set] = opts[:branch] unless opts[:repo] || opts[:repo_set]
|
15
|
+
|
16
|
+
MultiRepo::CLI.repos_for(**opts).each do |repo|
|
17
|
+
next if opts[:branch] != "master" && repo.config.has_real_releases
|
18
|
+
|
19
|
+
puts MultiRepo::CLI.header(repo.name)
|
20
|
+
MultiRepo::Helpers::UpdateBranchProtection.new(repo.name, **opts).run
|
21
|
+
puts
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
MultiRepo::CLI.common_options(self, :repo_set_default => nil)
|
11
|
+
end
|
12
|
+
opts[:repo] = MultiRepo::Labels.all.keys.sort unless opts[:repo] || opts[:repo_set]
|
13
|
+
|
14
|
+
MultiRepo::CLI.each_repo(**opts) do |repo|
|
15
|
+
MultiRepo::Helpers::UpdateLabels.new(repo.name, **opts).run
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
opt :title, "The milestone title.", :type => :string, :required => true
|
11
|
+
opt :due_on, "The due date.", :type => :string
|
12
|
+
opt :close, "Whether to close the milestone.", :default => false
|
13
|
+
|
14
|
+
MultiRepo::CLI.common_options(self)
|
15
|
+
end
|
16
|
+
Optimist.die(:due_on, "is required") if !opts[:close] && !opts[:due_on]
|
17
|
+
Optimist.die(:due_on, "must be a date format") if opts[:due_on] && !MultiRepo::Service::GitHub.valid_milestone_date?(opts[:due_on])
|
18
|
+
|
19
|
+
MultiRepo::CLI.each_repo(**opts) do |repo|
|
20
|
+
MultiRepo::Helpers::UpdateMilestone.new(repo.name, **opts).run
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/inline"
|
4
|
+
gemfile do
|
5
|
+
source "https://rubygems.org"
|
6
|
+
gem "multi_repo", require: "multi_repo/cli", path: File.expand_path("..", __dir__)
|
7
|
+
end
|
8
|
+
|
9
|
+
opts = Optimist.options do
|
10
|
+
MultiRepo::CLI.common_options(self)
|
11
|
+
end
|
12
|
+
|
13
|
+
MultiRepo::CLI.each_repo(**opts) do |repo|
|
14
|
+
MultiRepo::Helpers::UpdateRepoSettings.new(repo.name, **opts).run
|
15
|
+
end
|