diff --git a/Gemfile b/Gemfile index 86d1237a..6c540155 100644 --- a/Gemfile +++ b/Gemfile @@ -3,4 +3,4 @@ source ENV['GEM_SOURCE'] || 'https://rubygems.org' gemspec gem 'cucumber', '< 3.0' if RUBY_VERSION < '2.1' -gem 'octokit', '~> 4.0' +gem 'octokit', '~> 4.12' diff --git a/lib/modulesync.rb b/lib/modulesync.rb index 188c29d0..2ce1344e 100644 --- a/lib/modulesync.rb +++ b/lib/modulesync.rb @@ -11,11 +11,19 @@ require 'monkey_patches' GITHUB_TOKEN = ENV.fetch('GITHUB_TOKEN', '') +GITHUB_ORGANIZATION = ENV.fetch('GITHUB_ORGANIZATION', '') Octokit.configure do |c| c.api_endpoint = ENV.fetch('GITHUB_BASE_URL', 'https://api.github.com') + c.auto_paginate = true + + # We use a different Accept header by default here so we can get access + # to the developer's preview that enables repository topics. + c.default_media_type = ::Octokit::Preview::PREVIEW_TYPES[:topics] end +GITHUB = Octokit::Client.new(:access_token => GITHUB_TOKEN) + module ModuleSync include Constants @@ -50,8 +58,16 @@ def self.module_files(local_files, path) local_files.map { |file| file.sub(/#{path}/, '') } end - def self.managed_modules(config_file, filter, negative_filter) - managed_modules = Util.parse_config(config_file) + def self.managed_modules(config_file, filter, negative_filter, topic) + if topic + managed_modules = [] + GITHUB.org_repos(GITHUB_ORGANIZATION).each do |repo| + managed_modules.push(repo.name) if repo.topics.include?(topic) + end + else + managed_modules = Util.parse_config(config_file) + end + if managed_modules.empty? puts "No modules found in #{config_file}. Check that you specified the right :configs directory and :managed_modules_conf file." exit @@ -133,8 +149,7 @@ def self.manage_module(puppet_module, module_files, module_options, defaults, op # We only do GitHub PR work if the GITHUB_TOKEN variable is set in the environment. repo_path = "#{namespace}/#{module_name}" puts "Submitting PR '#{options[:pr_title]}' on GitHub to #{repo_path} - merges #{options[:branch]} into master" - github = Octokit::Client.new(:access_token => GITHUB_TOKEN) - pr = github.create_pull_request(repo_path, 'master', options[:branch], options[:pr_title], options[:message]) + pr = GITHUB.create_pull_request(repo_path, 'master', options[:branch], options[:pr_title], options[:message]) puts "PR created at #{pr['html_url']}" # PR labels can either be a list in the YAML file or they can pass in a comma @@ -145,7 +160,7 @@ def self.manage_module(puppet_module, module_files, module_options, defaults, op # already exist. We DO NOT create missing labels. unless pr_labels.empty? puts "Attaching the following labels to PR #{pr['number']}: #{pr_labels.join(', ')}" - github.add_labels_to_an_issue(repo_path, pr['number'], pr_labels) + GITHUB.add_labels_to_an_issue(repo_path, pr['number'], pr_labels) end end end @@ -158,7 +173,7 @@ def self.update(options) local_files = self.local_files(path) module_files = self.module_files(local_files, path) - managed_modules = self.managed_modules("#{options[:configs]}/#{options[:managed_modules_conf]}", options[:filter], options[:negative_filter]) + managed_modules = self.managed_modules("#{options[:configs]}/#{options[:managed_modules_conf]}", options[:filter], options[:negative_filter], options[:topic]) errors = false # managed_modules is either an array or a hash diff --git a/lib/modulesync/cli.rb b/lib/modulesync/cli.rb index ec2ee64f..a9197d92 100644 --- a/lib/modulesync/cli.rb +++ b/lib/modulesync/cli.rb @@ -51,6 +51,9 @@ class Base < Thor class_option :negative_filter, :aliases => '-x', :desc => 'A regular expression to skip repositories.' + class_option :topic, + :aliases => '-t', + :desc => 'Use GitHub topic to populate list of managed modules.' class_option :branch, :aliases => '-b', :desc => 'Branch name to make the changes in. Defaults to the default branch of the upstream repository, but falls back to "master".', diff --git a/spec/unit/modulesync_spec.rb b/spec/unit/modulesync_spec.rb index 7b9e978b..8f67e9ab 100644 --- a/spec/unit/modulesync_spec.rb +++ b/spec/unit/modulesync_spec.rb @@ -5,7 +5,7 @@ it 'loads the managed modules from the specified :managed_modules_conf' do allow(ModuleSync).to receive(:local_files).and_return([]) allow(ModuleSync::Util).to receive(:parse_config).with('./config_defaults.yml').and_return({}) - expect(ModuleSync).to receive(:managed_modules).with('./test_file.yml', nil, nil).and_return([]) + expect(ModuleSync).to receive(:managed_modules).with('./test_file.yml', nil, nil, nil).and_return([]) options = { managed_modules_conf: 'test_file.yml' } ModuleSync.update(options)