318 lines
17 KiB
Markdown
318 lines
17 KiB
Markdown
<!---
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
or more contributor license agreements. See the NOTICE file
|
|
distributed with this work for additional information
|
|
regarding copyright ownership. The ASF licenses this file
|
|
to you under the Apache License, Version 2.0 (the
|
|
"License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
software distributed under the License is distributed on an
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
KIND, either express or implied. See the License for the
|
|
specific language governing permissions and limitations
|
|
under the License.
|
|
-->
|
|
|
|
# Git / JIRA Release Audit
|
|
|
|
This is an application for performing an audit between the histories on our git
|
|
branches and the `fixVersion` field set on issues in JIRA. It does this by
|
|
building a Sqlite database from the commits found on each git branch,
|
|
identifying Jira IDs and release tags, and then requesting information about
|
|
those issues from Jira. Once both sources have been collected, queries can be
|
|
performed against the database to look for discrepancies between the sources of
|
|
truth (and, possibly, bugs in this script).
|
|
|
|
## Setup
|
|
|
|
The system prerequisites are Python3 with VirtualEnv available and Sqlite. Also,
|
|
you'll need the content of this directory and a local checkout of git repository.
|
|
|
|
Build a VirtualEnv with the script's dependencies with:
|
|
|
|
```shell script
|
|
$ python3 --version
|
|
Python 3.7.6
|
|
$ python3 -m venv ./venv
|
|
$ ./venv/bin/pip install -r ./requirements.txt
|
|
...
|
|
Successfully installed...
|
|
```
|
|
|
|
## Basic Usage
|
|
|
|
The tool provides basic help docs.
|
|
|
|
```shell script
|
|
$ ./venv/bin/python ./git_jira_release_audit.py --help
|
|
usage: git_jira_release_audit.py [-h] [--populate-from-git POPULATE_FROM_GIT]
|
|
[--populate-from-jira POPULATE_FROM_JIRA]
|
|
[--db-path DB_PATH]
|
|
[--initialize-db INITIALIZE_DB]
|
|
[--report-new-for-release-line REPORT_NEW_FOR_RELEASE_LINE]
|
|
[--report-new-for-release-branch REPORT_NEW_FOR_RELEASE_BRANCH]
|
|
[--git-repo-path GIT_REPO_PATH]
|
|
[--remote-name REMOTE_NAME]
|
|
[--development-branch DEVELOPMENT_BRANCH]
|
|
[--development-branch-fix-version DEVELOPMENT_BRANCH_FIX_VERSION]
|
|
[--release-line-regexp RELEASE_LINE_REGEXP]
|
|
[--parse-release-tags PARSE_RELEASE_TAGS]
|
|
[--fallback-actions-path FALLBACK_ACTIONS_PATH]
|
|
[--branch-filter-regexp BRANCH_FILTER_REGEXP]
|
|
[--jira-url JIRA_URL] --branch-1-fix-version
|
|
BRANCH_1_FIX_VERSION --branch-2-fix-version
|
|
BRANCH_2_FIX_VERSION
|
|
|
|
optional arguments:
|
|
-h, --help show this help message and exit
|
|
|
|
Building the audit database:
|
|
--populate-from-git POPULATE_FROM_GIT
|
|
When true, populate the audit database from the Git
|
|
repository. (default: True)
|
|
--populate-from-jira POPULATE_FROM_JIRA
|
|
When true, populate the audit database from Jira.
|
|
(default: True)
|
|
--db-path DB_PATH Path to the database file, or leave unspecified for a
|
|
transient db. (default: audit.db)
|
|
--initialize-db INITIALIZE_DB
|
|
When true, initialize the database tables. This is
|
|
destructive to the contents of an existing database.
|
|
(default: False)
|
|
|
|
Generating reports:
|
|
--report-new-for-release-line REPORT_NEW_FOR_RELEASE_LINE
|
|
Builds a report of the Jira issues that are new on the
|
|
target release line, not present on any of the
|
|
associated release branches. (i.e., on branch-2 but
|
|
not branch-{2.0,2.1,...}) (default: None)
|
|
--report-new-for-release-branch REPORT_NEW_FOR_RELEASE_BRANCH
|
|
Builds a report of the Jira issues that are new on the
|
|
target release branch, not present on any of the
|
|
previous release branches. (i.e., on branch-2.3 but
|
|
not branch-{2.0,2.1,...}) (default: None)
|
|
|
|
Interactions with the Git repo:
|
|
--git-repo-path GIT_REPO_PATH
|
|
Path to the git repo, or leave unspecified to infer
|
|
from the current file's path. (default:
|
|
./git_jira_release_audit.py)
|
|
--remote-name REMOTE_NAME
|
|
The name of the git remote to use when identifying
|
|
branches. Default: 'origin' (default: origin)
|
|
--development-branch DEVELOPMENT_BRANCH
|
|
The name of the branch from which all release lines
|
|
originate. Default: 'master' (default: master)
|
|
--development-branch-fix-version DEVELOPMENT_BRANCH_FIX_VERSION
|
|
The Jira fixVersion used to indicate an issue is
|
|
committed to the development branch. (default: 3.0.0)
|
|
--release-line-regexp RELEASE_LINE_REGEXP
|
|
A regexp used to identify release lines. (default:
|
|
branch-\d+$)
|
|
--parse-release-tags PARSE_RELEASE_TAGS
|
|
When true, look for release tags and annotate commits
|
|
according to their release version. An Expensive
|
|
calculation, disabled by default. (default: False)
|
|
--fallback-actions-path FALLBACK_ACTIONS_PATH
|
|
Path to a file containing _DB.Actions applicable to
|
|
specific git shas. (default: fallback_actions.csv)
|
|
--branch-filter-regexp BRANCH_FILTER_REGEXP
|
|
Limit repo parsing to branch names that match this
|
|
filter expression. (default: .*)
|
|
--branch-1-fix-version BRANCH_1_FIX_VERSION
|
|
The Jira fixVersion used to indicate an issue is
|
|
committed to the specified release line branch
|
|
(default: None)
|
|
--branch-2-fix-version BRANCH_2_FIX_VERSION
|
|
The Jira fixVersion used to indicate an issue is
|
|
committed to the specified release line branch
|
|
(default: None)
|
|
|
|
Interactions with Jira:
|
|
--jira-url JIRA_URL A URL locating the target JIRA instance. (default:
|
|
https://issues.apache.org/jira)
|
|
```
|
|
|
|
### Build a Database
|
|
|
|
This invocation will build a "simple" database, correlating commits to
|
|
branches. It omits gathering the detailed release tag data, so it runs pretty
|
|
quickly.
|
|
|
|
Example Run:
|
|
|
|
```shell script
|
|
$ ./venv/bin/python3 ./git_jira_release_audit.py \
|
|
--db-path=audit.db \
|
|
--development-branch-fix-version=3.0.0 \
|
|
--branch-1-fix-version=1.7.0 \
|
|
--branch-2-fix-version=2.4.0
|
|
INFO:git_jira_release_audit.py:origin/branch-1.0 has 1433 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
|
INFO:git_jira_release_audit.py:origin/branch-1.1 has 2111 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
|
INFO:git_jira_release_audit.py:origin/branch-1.2 has 2738 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
|
INFO:git_jira_release_audit.py:origin/branch-1.3 has 3296 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
|
INFO:git_jira_release_audit.py:origin/branch-1.4 has 3926 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
|
INFO:git_jira_release_audit.py:origin/branch-2 has 3325 commits since its origin at 0d0c330401ade938bf934aafd79ec23705edcc60.
|
|
INFO:git_jira_release_audit.py:origin/branch-2.0 has 2198 commits since its origin at 0d0c330401ade938bf934aafd79ec23705edcc60.
|
|
INFO:git_jira_release_audit.py:origin/branch-2.1 has 2749 commits since its origin at 0d0c330401ade938bf934aafd79ec23705edcc60.
|
|
INFO:git_jira_release_audit.py:origin/branch-2.2 has 2991 commits since its origin at 0d0c330401ade938bf934aafd79ec23705edcc60.
|
|
INFO:git_jira_release_audit.py:origin/branch-2.3 has 3312 commits since its origin at 0d0c330401ade938bf934aafd79ec23705edcc60.
|
|
INFO:git_jira_release_audit.py:retrieving 5850 jira_ids from the issue tracker
|
|
|
|
origin/branch-1 100%|████████████████████████████████████| 4084/4084 [00:00<00:00, 9805.33 commit/s]
|
|
origin/branch-1.0 100%|█████████████████████████████████| 1433/1433 [00:00<00:00, 10479.89 commit/s]
|
|
origin/branch-1.1 100%|█████████████████████████████████| 2111/2111 [00:00<00:00, 10280.60 commit/s]
|
|
origin/branch-1.2 100%|██████████████████████████████████| 2738/2738 [00:00<00:00, 8833.51 commit/s]
|
|
origin/branch-1.3 100%|██████████████████████████████████| 3296/3296 [00:00<00:00, 9746.93 commit/s]
|
|
origin/branch-1.4 100%|██████████████████████████████████| 3926/3926 [00:00<00:00, 9750.96 commit/s]
|
|
origin/branch-2 100%|████████████████████████████████████| 3325/3325 [00:00<00:00, 9688.14 commit/s]
|
|
origin/branch-2.0 100%|██████████████████████████████████| 2198/2198 [00:00<00:00, 8804.18 commit/s]
|
|
origin/branch-2.1 100%|██████████████████████████████████| 2749/2749 [00:00<00:00, 9328.67 commit/s]
|
|
origin/branch-2.2 100%|██████████████████████████████████| 2991/2991 [00:00<00:00, 9215.56 commit/s]
|
|
origin/branch-2.3 100%|██████████████████████████████████| 3312/3312 [00:00<00:00, 9063.19 commit/s]
|
|
fetch from Jira 100%|████████████████████████████████████████| 5850/5850 [10:40<00:00, 9.14 issue/s]
|
|
```
|
|
|
|
Optionally, the database can be build to include release tags, by specifying
|
|
`--parse-release-tags=true`. This is more time-consuming, but is necessary for
|
|
auditing discrepancies between git and Jira. Optionally, limit the branches
|
|
under consideration by specifying a regex filter with `--branch-filter-regexp`.
|
|
Running the same command but including this flag looks like this:
|
|
|
|
```shell script
|
|
origin/branch-1 100%|███████████████████████████████████████| 4084/4084 [08:58<00:00, 7.59 commit/s]
|
|
origin/branch-1.0 100%|█████████████████████████████████████| 1433/1433 [03:54<00:00, 6.13 commit/s]
|
|
origin/branch-1.1 100%|█████████████████████████████████████| 2111/2111 [41:26<00:00, 0.85 commit/s]
|
|
origin/branch-1.2 100%|█████████████████████████████████████| 2738/2738 [07:10<00:00, 6.37 commit/s]
|
|
origin/branch-1.3 100%|██████████████████████████████████| 3296/3296 [2h 33:13<00:00, 0.36 commit/s]
|
|
origin/branch-1.4 100%|██████████████████████████████████| 3926/3926 [7h 22:41<00:00, 0.15 commit/s]
|
|
origin/branch-2 100%|████████████████████████████████████| 3325/3325 [2h 05:43<00:00, 0.44 commit/s]
|
|
origin/branch-2.0 100%|█████████████████████████████████████| 2198/2198 [52:18<00:00, 0.70 commit/s]
|
|
origin/branch-2.1 100%|█████████████████████████████████████| 2749/2749 [17:09<00:00, 2.67 commit/s]
|
|
origin/branch-2.2 100%|█████████████████████████████████████| 2991/2991 [52:15<00:00, 0.95 commit/s]
|
|
origin/branch-2.3 100%|████████████████████████████████████| 3312/3312 [05:08<00:00, 10.74 commit/s]
|
|
fetch from Jira 100%|████████████████████████████████████████| 5850/5850 [10:46<00:00, 9.06 issue/s]
|
|
```
|
|
|
|
### Run a Report
|
|
|
|
With a database populated with branch information, the build-in reports can be
|
|
run.
|
|
|
|
`--report-new-for-release-line`
|
|
> Builds a report of the Jira issues that are new on the target release line,
|
|
not present on any of the associated release branches. (i.e., on branch-2 but
|
|
not branch-{2.0,2.1,...})
|
|
|
|
`--report-new-for-release-branch`
|
|
> Builds a report of the Jira issues that are new on the target release branch,
|
|
not present on any of the previous release branches. (i.e., on branch-2.3 but
|
|
not branch-{2.0,2.1,...})
|
|
|
|
Either way, the output is a csv file containing a summary of each JIRA id found
|
|
matching the report criteria.
|
|
|
|
Example Run:
|
|
|
|
```shell script
|
|
$ ./venv/bin/python3.7 ./git_jira_release_audit.py \
|
|
--populate-from-git=false \
|
|
--populate-from-jira=false \
|
|
--branch-1-fix-version=1.7.0 \
|
|
--branch-2-fix-version=2.4.0 \
|
|
--report-new-for-release-branch=origin/branch-2.3
|
|
INFO:git_jira_release_audit.py:retrieving 292 jira_ids from the issue tracker
|
|
INFO:git_jira_release_audit.py:generated report at new_for_origin-branch-2.3.csv
|
|
|
|
fetch from Jira 100%|████████████████████████████████████████| 292/292 [00:03<00:00, 114.01 issue/s]
|
|
$ head -n5 new_for_origin-branch-2.3.csv
|
|
key,issue_type,priority,summary,resolution,components
|
|
HBASE-21070,Bug,Critical,SnapshotFileCache won't update for snapshots stored in S3,Fixed,['snapshots']
|
|
HBASE-21773,Bug,Critical,rowcounter utility should respond to pleas for help,Fixed,['tooling']
|
|
HBASE-21505,Bug,Major,Several inconsistencies on information reported for Replication Sources by hbase shell status 'replication' command.,Fixed,['Replication']
|
|
HBASE-22057,Bug,Major,Impose upper-bound on size of ZK ops sent in a single multi(),Fixed,[]
|
|
```
|
|
|
|
### Explore the Database
|
|
|
|
With a populated database, query it with sqlite:
|
|
|
|
```shell script
|
|
$ sqlite3 audit.db
|
|
SQLite version 3.24.0 2018-06-04 14:10:15
|
|
Enter ".help" for usage hints.
|
|
sqlite> -- count the number of distinct commits on a release branch
|
|
sqlite> select count(distinct jira_id), branch from git_commits group by branch;
|
|
3437|origin/branch-1
|
|
1189|origin/branch-1.0
|
|
1728|origin/branch-1.1
|
|
2289|origin/branch-1.2
|
|
2788|origin/branch-1.3
|
|
3289|origin/branch-1.4
|
|
2846|origin/branch-2
|
|
1813|origin/branch-2.0
|
|
2327|origin/branch-2.1
|
|
2566|origin/branch-2.2
|
|
2839|origin/branch-2.3
|
|
|
|
sqlite> -- find the issues for which the git commit record and JIRA fixVersion disagree
|
|
sqlite> -- this query requires the database be built with --parse-release-tags
|
|
sqlite> select g.jira_id, g.git_tag, j.fix_version
|
|
from git_commits g
|
|
inner join jira_versions j
|
|
on g.jira_id = j.jira_id
|
|
and g.branch = 'origin/branch-2.2'
|
|
and g.git_tag is not null
|
|
and j.fix_version like '2.2.%'
|
|
and g.git_tag != j.fix_version;
|
|
HBASE-22941|2.2.2|2.2.1
|
|
|
|
sqlite> -- show jira fixVersions for all issues on branch-2.3 but not on any earlier
|
|
sqlite> -- branch; i.e., issues that are missing a fixVersion or are marked for
|
|
sqlite> -- a release other than the expected (3.0.0, 2.3.0).
|
|
sqlite> -- this query requires the database be built with --parse-release-tags
|
|
sqlite> select jira_id, fix_version
|
|
FROM jira_versions
|
|
WHERE jira_id in (
|
|
SELECT distinct jira_id
|
|
FROM git_commits
|
|
WHERE branch = 'origin/branch-2.3'
|
|
EXCEPT SELECT distinct jira_id
|
|
FROM git_commits
|
|
WHERE branch IN (
|
|
SELECT distinct branch
|
|
FROM git_commits
|
|
WHERE branch != 'origin/branch-2.3'))
|
|
AND fix_version NOT IN ('3.0.0', '2.3.0')
|
|
ORDER BY jira_id;
|
|
HBASE-22321|1.5.0
|
|
HBASE-22360|2.2.0
|
|
HBASE-22405|2.2.0
|
|
HBASE-22555|2.4.0
|
|
HBASE-23032|connector-1.0.1
|
|
HBASE-23032|hbase-filesystem-1.0.0-alpha2
|
|
HBASE-23604|HBASE-18095
|
|
HBASE-23633|2.4.0
|
|
HBASE-23647|HBASE-18095
|
|
HBASE-23648|HBASE-18095
|
|
HBASE-23731|HBASE-18095
|
|
HBASE-23741|2.4.0
|
|
HBASE-23752|HBASE-18095
|
|
HBASE-23804|HBASE-18095
|
|
HBASE-23851|master
|
|
HBASE-23936|2.4.0
|
|
HBASE-23937|2.4.0
|
|
HBASE-23977|2.4.0
|
|
HBASE-24002|2.4.0
|
|
HBASE-24033|2.4.0
|
|
HBASE-24037|2.4.0
|
|
HBASE-24073|master
|
|
HBASE-24075|2.4.0
|
|
HBASE-24080|2.4.0
|
|
HBASE-24080|master
|
|
```
|