Skip to content

Commit

Permalink
(maint) Add ticket reconciliation task as a Rake task
Browse files Browse the repository at this point in the history
I've had this script locally for a while now, but wanted to add it
to the repo (with docs :) ) in the hope that it might be of use more broadly
  • Loading branch information
austb authored and Zak-Kent committed Oct 4, 2019
1 parent fb8d8a0 commit 7209644
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ group :test do
gem 'mocha', '~> 1.0'
end

group :development do
gem 'httparty'
end

# This is a workaround for a bug in bundler, where it likes to look at ruby
# version deps regardless of what groups you want or not. This lets us
# conditionally shortcut evaluation entirely.
Expand Down
100 changes: 100 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,103 @@ namespace :package do
puts 'Implode is no longer needed, using packaging-as-a-gem'
end
end

namespace :release do
task :reconcile, [:release_version, :previous_version] do |t, versions|
require 'httparty'

project = 'PDB'.freeze
version = versions[:release_version]
prev_version = versions[:previous_version]
fix_version = "#{project} #{version}".freeze

puppetdb_repo = ENV['PDB_PATH'] || './'.freeze
pe_puppetdb_extensions_repo = ENV['PDB_PE_PATH'] || '../pe-puppetdb-extensions'.freeze
git_log = "git log --oneline --no-merges --no-decorate #{prev_version}..HEAD".freeze

api_url = 'https://tickets.puppetlabs.com/rest/api/2'.freeze
jql_search = "#{api_url}/search".freeze

url = "#{jql_search}?jql=fixVersion='#{fix_version}'"
response = HTTParty.get(url)
json = response.parsed_response

if json['maxResults'] <= json['total']
url = "#{jql_search}?maxResults=#{json['total']}&jql=fixVersion='#{fix_version}'"
response = HTTParty.get(url)
json = response.parsed_response
end

jira_issues = []
require 'pry'
json['issues'].each do |issue|
# puts issue['key']
jira_issues.push({
id: issue['id'],
ticket: issue['key'],
api_url: issue['self']
});
end

def construct_git_data(output, repo)
git_data = {}
output.each_line do |line|
commit, message = line.split(" ", 2)
_, pdb_ref = /^\((PDB-\d+)\)/.match(message).to_a

if pdb_ref
if git_data.include?(pdb_ref)
git_data[pdb_ref][:commits].push(commit)
else
git_data[pdb_ref] = {
commits: [commit],
}
end
else
# Allow (doc) (docs) (maint) case-insensitive
doc_regex = /^\(docs?\)/i
maint_regex = /^\(maint\)/i
i18n_regex = /^\(i18n\)/i
puts "INVESTIGATE! #{repo} #{line}" unless doc_regex =~ message || maint_regex =~ message || i18n_regex =~ message
end
end

git_data
end

out = `cd #{puppetdb_repo}; #{git_log}`
pdb_git_data = construct_git_data(out, 'puppetdb')

out = `cd #{pe_puppetdb_extensions_repo}; #{git_log}`
pe_git_data = construct_git_data(out, 'pe-puppetdb-extensions')

jira_issues.each do |issue|
ticket = issue[:ticket]
unless pdb_git_data.include?(ticket) || pe_git_data.include?(ticket)
puts "#{ticket} exists in JIRA with fixVersion '#{fix_version}', but there is no corresponding git commit"
end
end

def find_jira_match(jql_search, ticket, git_data, jira_issues, fix_version, repo)
jira_match = jira_issues.any? do |issue|
ticket == issue[:ticket]
end

url = "#{jql_search}?maxResults=1&jql=key=#{ticket} AND fixVersion='PDB n/a'"
response = HTTParty.get(url)
json = response.parsed_response

if !jira_match and json['issues'].empty?
puts "#{ticket} has a git commit(s) #{git_data[:commits]} in #{repo}, but its JIRA ticket does not have fixVersion '#{fix_version}'"
end
end

pdb_git_data.each do |ticket, data|
find_jira_match(jql_search, ticket, data, jira_issues, fix_version, 'puppetdb')
end

pe_git_data.each do |ticket, data|
find_jira_match(jql_search, ticket, data, jira_issues, fix_version, 'pe-puppetdb-exntesions')
end
end
end
6 changes: 6 additions & 0 deletions dev-docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Developer Documentation

## Table of Contents

1. Releases
* [Reconciling Git commits and Jira Tickets](./release/reconciliation.md)
73 changes: 73 additions & 0 deletions dev-docs/release/reconciliation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Reconciling Git commits and Jira tickets

The rake task `release:reconcile` will verify three things. First, that every commit either,
has an associated PDB ticket, or is prefixed by one of `(docs)`, `(maint)`, `(i18n)`.
Second, that every Jira ticket that has the fixVersion `PDB <release_version>` has an associate
git commit. And third it will verify that every commit whose message includes `(PDB-####)`
has a Jira ticket with the fixVersion `PDB <release_version>`.

It does not require authentication as it relies on our Jira API
being open to the public, and the git history residing on your computer.

## How to run

First, ensure you have checked out both `puppetdb` and `pe-puppetdb-extensions` and that both
branches are up to date with the `puppetlabs/[pupppetdb/pe-puppetdb-extension]` repo. This
task will look at the git history in your currently active branches, if it is inaccurate, your
results will be inaccurate as well.

```
bundle install
bundle exec rake release:reconcile[<release_version>,<previous_version>]
```

The rake task always requires 2 arguments to be provided, the version you will be releasing,
and the previously released version. Below are the two cases you'll run into.


For a z release, the previous release is always the proceeding release with the same `X.Y` version.

```
# Z release
bundle exec rake release:reconcile[5.2.10,5.2.9]
```

For an x or a y release, the previous version is the most recent release on the most recent y branch.
```
# X/Y release
# If the previous release was also a y release
bundle exec rake release:reconcile[6.7.0,6.6.0]
# or if y release has a maintained branch
bundle exec rake release:reconcile[6.4.0,6.3.1]
```

## Options

### Environment Variables

Environment variables all have a default value in the rake task,
but are also configurable on the command line.

* `PDB_PATH` - path to the PuppetDB repo (Default: `./`)
* `PDB_PE_PATH` - path to the pe-puppetdb-extensions repo (Default `../pe-puppetdb-extensions`)

## Output

The rake task will output nothing if all commits have a corresponding `PDB` ticket with the correct
`fixVersion`.

For commits that are not prefixed by a `(PDB-###)`, `(docs)`, `(maint)`, or `(i18n)`
it will output
```
INVESTIGATE! <repo> <commit message>
```

For mismatches between Jira and Git it will print one of
```
<ticket> exists in JIRA with fixVersion '<fix_version>', but there is no corresponding git commit
```
or
```
<ticket> has a git commit(s) <sha(s)> in <repo>, but its JIRA ticket does not have fixVersion '<fix_version>'
```

0 comments on commit 7209644

Please sign in to comment.