Skip to content

Instantly share code, notes, and snippets.

@vochicong
Last active March 28, 2019 11:14
Show Gist options
  • Save vochicong/72a1e40c256e8b336293f671c6a31fa6 to your computer and use it in GitHub Desktop.
Save vochicong/72a1e40c256e8b336293f671c6a31fa6 to your computer and use it in GitHub Desktop.
Pronto, Octokit を使って、CircleCI からGitHubでホストしているRailsプロジェクトのPRに対してコードレビューを実施
#!/usr/bin/env bash
# CircleCIから環境変数を受け取り、コードレビューのrakeタスクに渡す
set -eu
export GITHUB_OWNER=$CIRCLE_PROJECT_USERNAME
export GITHUB_REPO=$CIRCLE_PROJECT_REPONAME
export PRONTO_GITHUB_ACCESS_TOKEN=$GITHUB_ACCESS_TOKEN
set -x
bin/rake pr:code_review
echo DONE
# ProntoのチェッカーをGemfileに指定してインストール
group :development, :test do
# Pronto: auto code review
gem 'pronto-rubocop', require: false
gem 'pronto-reek', require: false
gem 'pronto-flay', require: false
end
# GitHubのPRに対して差分をコードチェックし、コメントをPRに記入する。
# 必要な環境変数(例):
# CI_PULL_REQUESTS: CircleCIが自動的に定義している
# PRONTO_GITHUB_ACCESS_TOKEN: GitHubアクセストークン、CircleCIで定義しておくこと
# GITHUB_OWNER
# GITHUB_REPO
require 'octokit'
require 'pronto'
Pronto::GemNames.new.to_a.each { |gem_name| require "pronto/#{gem_name}" }
namespace :pr do
desc 'Check a PR'
task :code_review, ['id'] => :environment do |task, args|
formatters = pronto_formatters
pr_ids(args.id).each do |pr_id|
base = base_branch(pr_id)
Pronto.run("origin/#{base}", '.', formatters)
end
end
private
def pronto_formatters
status_formatter = Pronto::Formatter::GithubStatusFormatter.new
comment_formatter = Pronto::Formatter::GithubPullRequestFormatter.new
formatters = [status_formatter, comment_formatter]
end
# CI_PULL_REQUESTSから関連PRのIDを(複数)取り出す
def pr_ids(pr_id = nil)
ids = ENV.fetch('CI_PULL_REQUESTS', '').split(',').map { |url| pr_id url }
ids.push pr_id if pr_id
ids
end
# PRのURLから、最後の数値列を取り出しPRのIDとする
def pr_id(pr_url)
pr_url[/\d+$/].to_i
end
# GraphQLのQueryでPRのIDを指定して title, url, branchを取得
def query(pr_id)
owner, name = ENV['GITHUB_OWNER'], ENV['GITHUB_REPO']
<<~"GRAPHQL"
query {
repository(owner: "#{owner}", name: "#{name}") {
pullRequest(number: #{pr_id}) {
title
url
baseRefName
headRefName
}
}
}
GRAPHQL
end
# PRのマージ先を特定
def base_branch(pr_id)
q = query(pr_id)
pr = graphql(query: q)[:data][:repository][:pullRequest]
base = pr[:baseRefName]
puts "*** #{pr[:url]}"\
" #{pr[:baseRefName]} ← #{pr[:headRefName]}"\
": #{pr[:title]}"
base
end
def client
Octokit::Client.new(access_token: ENV['PRONTO_GITHUB_ACCESS_TOKEN'])
end
def graphql(query:, variables: {})
client.post '/graphql', { query: query, variables: variables }.to_json
end
end
# コマンドラインで現在のブランチとマージ先のブランチの差分に対してコードチェック
# Check the diff between current branch and the branch specified
# PR `TO_BRANCH` ← `FROM_BRANCH`における変更箇所のチェックを行うには
git checkout FROM_BRANCH
bin/pronto run -c origin/TO_BRANCH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment