Skip to content

Commit

Permalink
Merge pull request #323 from platanus/github-octokit
Browse files Browse the repository at this point in the history
GitHub octokit
  • Loading branch information
agomezcampero authored Oct 13, 2020
2 parents 4f7af85 + 6e75364 commit 0a1adc2
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Features:
- Disable observers in test environment [#319](https://github.com/platanus/potassium/pull/319)
- Allow user to select custom Github repository [#318](https://github.com/platanus/potassium/pull/318)
- Add pull request template to github enabled projects [#320](https://github.com/platanus/potassium/pull/320)
- Use a Ruby gem instead of hub to create Github repositories [#323](https://github.com/platanus/potassium/pull/323)

Fix:
- Fix shrine issues related to configuration and uploader validation [#302](https://github.com/platanus/potassium/pull/302)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ The following optional integrations are also added:
and [Sendgrid](https://github.com/platanus/send_grid_mailer) with recipient interceptor support
- [Sentry](https://sentry.io) to monitor exceptions and errors
- [Vue.js](https://vuejs.org) or [Angular 2](https://angular.io/) for frontend development
- Creates the Github repository of your choice for the project (it uses `hub` under the hood). A local git repository will always be created.
- Creates the Github repository of your choice for the project. A local git repository will always be created.

A few more things are added to the project:

Expand Down
25 changes: 24 additions & 1 deletion lib/potassium/cli_options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,15 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
name: "github_private",
desc: "Whether the github repository is private or not",
negatable: true,
default_value: false,
default_value: "none",
default_test_value: false
},
{
type: :switch,
name: "github_has_org",
desc: "Whether the github repository should belong to an organization",
negatable: true,
default_value: "none",
default_test_value: false
},
{
Expand All @@ -141,6 +149,13 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
default_value: "none",
default_test_value: "none"
},
{
type: :flag,
name: "github_access_token",
desc: "Github personal access token used to auth to Github API",
default_value: "none",
default_test_value: "none"
},
{
type: :switch,
name: "schedule",
Expand All @@ -162,6 +177,14 @@ module Potassium::CliOptions # rubocop:disable Metrics/ModuleLength
name: :front_end,
desc: "Decides which front-end framework to use. Available: Vue, Angular 2, None",
default_test_value: "None"
},
{
type: :switch,
name: "test",
desc: "Whether or not it is a test project creation",
negatable: true,
default_value: false,
default_test_value: true
}
]

Expand Down
98 changes: 84 additions & 14 deletions lib/potassium/recipes/github.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'octokit'

class Recipes::Github < Rails::AppBuilder
def ask
github_repo_create = answer(:github) do
Expand All @@ -8,30 +10,98 @@ def ask
end

def setup_repo
github_repo_private = answer(:github_private) do
setup_repo_private
setup_repo_org
setup_repo_name
set(:github_access_token, get_access_token)
end

def create
return unless selected?(:github_repo)

create_github_repo
copy_file '../assets/.github/pull_request_template.md', '.github/pull_request_template.md'
end

private

def setup_repo_private
repo_private = answer(:github_private) do
Ask.confirm('Should the repository be private?')
end
github_repo_organization = answer(:github_org) do
Ask.input('What is the organization or user for this repository?', default: 'platanus')
set(:github_repo_private, repo_private)
end

def setup_repo_org
has_organization = answer(:github_has_org) do
Ask.confirm('Is this repo for a Github organization?')
end
set(:github_has_org, has_organization)
if has_organization
repo_organization = answer(:github_org) do
Ask.input('What is the organization for this repository?', default: 'platanus')
end
set(:github_org, repo_organization)
end
github_repo_name = answer(:github_name) do
end

def setup_repo_name
repo_name = answer(:github_name) do
Ask.input('What is the name for this repository?', default: get(:dasherized_app_name))
end
set(:github_repo_name, "#{github_repo_organization}/#{github_repo_name}")
set(:github_repo_private, github_repo_private)
set(:github_repo_name, repo_name)
end

def create
return unless selected?(:github_repo)
def create_github_repo
options = { private: get(:github_repo_private) }
options[:organization] = get(:github_org) if get(:github_has_org)
repo_name = get(:github_repo_name)

github_repo_create(get(:github_repo_name), get(:github_repo_private))
copy_file '../assets/.github/pull_request_template.md', '.github/pull_request_template.md'
is_retry = false
begin
github_client(is_retry).create_repository(repo_name, options)
rescue Octokit::Unauthorized
is_retry = true
retry if retry_create_repo
end
end

private
def retry_create_repo
puts "Bad credentials, information on Personal Access Tokens here:"
puts "https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token"
puts "Make sure to give repo access to the personal access token"
Ask.confirm("Do you want to retry?")
end

def github_client(is_retry = false)
access_token = is_retry ? set_access_token : get(:github_access_token)
octokit_client.new(access_token: access_token)
end

def octokit_client
if answer(:test)
require_relative '../../../spec/support/fake_octokit'
FakeOctokit
else
Octokit::Client
end
end

def get_access_token
return File.open(config_filename, 'r').read if File.exists?(config_filename)

set_access_token
end

def set_access_token
access_token = answer(:github_access_token) do
Ask.input('Enter a GitHub personal access token', password: true)
end
File.open(config_filename, 'w') { |f| f.write(access_token) }
access_token
end

def github_repo_create(repo_name, private_repo = false)
flag = private_repo ? "-p" : ""
run "hub create #{flag} #{repo_name}"
def config_filename
@config_filename ||= File.expand_path('~/.potassium')
end
end
1 change: 1 addition & 0 deletions potassium.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency "gli", "~> 2.12.2"
spec.add_runtime_dependency "inquirer", "~> 0.2"
spec.add_runtime_dependency "levenshtein", "~> 0.2"
spec.add_runtime_dependency "octokit", "~> 4.18"
spec.add_runtime_dependency "rails", Potassium::RAILS_VERSION
spec.add_runtime_dependency "semantic", "~> 1.4"
end
45 changes: 38 additions & 7 deletions spec/features/github_spec.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
require "spec_helper"

RSpec.describe "GitHub" do
let(:github_org) { "platanus" }
let(:org_name) { "platanus" }
let(:repo_name) { PotassiumTestHelpers::APP_NAME.dasherize }
let(:access_token) { "1234" }
let(:pr_template_file) { IO.read("#{project_path}/.github/pull_request_template.md") }

before do
Expand All @@ -14,23 +15,53 @@
create_dummy_project(
"github" => true,
"github_private" => false,
"github_org" => github_org,
"github_name" => repo_name
"github_has_org" => false,
"github_name" => repo_name,
"github_access_token" => access_token
)

expect(FakeGithub).to have_created_repo("#{github_org}/#{repo_name}")
expect(FakeOctokit).to have_created_repo(repo_name)
expect(pr_template_file).to include('Contexto')
end

it "creates the private github repository" do
create_dummy_project(
"github" => true,
"github_private" => true,
"github_org" => github_org,
"github_name" => repo_name
"github_has_org" => false,
"github_name" => repo_name,
"github_access_token" => access_token
)

expect(FakeGithub).to have_created_private_repo("#{github_org}/#{repo_name}")
expect(FakeOctokit).to have_created_private_repo(repo_name)
expect(pr_template_file).to include('Contexto')
end

it "creates the github repository for the organization" do
create_dummy_project(
"github" => true,
"github_private" => false,
"github_has_org" => true,
"github_org" => org_name,
"github_name" => repo_name,
"github_access_token" => access_token
)

expect(FakeOctokit).to have_created_repo_for_org(repo_name, org_name)
expect(pr_template_file).to include('Contexto')
end

it "creates the private github repository for the organization" do
create_dummy_project(
"github" => true,
"github_private" => true,
"github_has_org" => true,
"github_org" => org_name,
"github_name" => repo_name,
"github_access_token" => access_token
)

expect(FakeOctokit).to have_created_private_repo_for_org(repo_name, org_name)
expect(pr_template_file).to include('Contexto')
end
end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@
config.before(:each) do
FakeGithub.clear!
FakeHeroku.clear!
FakeOctokit.clear!
end
end
31 changes: 31 additions & 0 deletions spec/support/fake_octokit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class FakeOctokit
RECORDER = File.expand_path(File.join('..', '..', 'tmp', 'octokit'), File.dirname(__FILE__))

def initialize(options); end

def create_repository(repo_name, options)
File.open(RECORDER, 'a') do |file|
file.write "#{repo_name}, #{options.map { |key, value| "#{key}: #{value}" }}"
end
end

def self.clear!
FileUtils.rm_rf RECORDER
end

def self.has_created_repo?(repo_name)
File.read(RECORDER).include? repo_name
end

def self.has_created_private_repo?(repo_name)
has_created_repo?(repo_name) && File.read(RECORDER).include?("private: true")
end

def self.has_created_repo_for_org?(repo_name, org_name)
has_created_repo?(repo_name) && File.read(RECORDER).include?("organization: #{org_name}")
end

def self.has_created_private_repo_for_org?(repo_name, org_name)
has_created_private_repo?(repo_name) && has_created_repo_for_org?(repo_name, org_name)
end
end

0 comments on commit 0a1adc2

Please sign in to comment.