HBASE-24136 Add release branch report to git-jira-release-audit tool
* enhancements to git_jira_release_audit.py * add aforementioned release branch report * include default values in help doc output * swap default db to a file on disk instead of in memory * set logger to match file name * add separate sql query log at DEBUG level * more detailed usage info in README.md, including example audit query * update entries in fallback_actions.csv Signed-off-by: stack <stack@apache.org> Signed-off-by: Jan Hentschel <jan.hentschel@ultratendency.com>
This commit is contained in:
parent
1fb693b998
commit
b4af0a0943
|
@ -2,3 +2,4 @@
|
|||
*.log
|
||||
*.svg
|
||||
venv
|
||||
new_for_*.csv
|
||||
|
|
|
@ -43,7 +43,7 @@ $ ./venv/bin/pip install -r ./requirements.txt
|
|||
Successfully installed...
|
||||
```
|
||||
|
||||
## Usage
|
||||
## Basic Usage
|
||||
|
||||
The tool provides basic help docs.
|
||||
|
||||
|
@ -54,6 +54,7 @@ usage: git_jira_release_audit.py [-h] [--populate-from-git POPULATE_FROM_GIT]
|
|||
[--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]
|
||||
|
@ -61,7 +62,9 @@ usage: git_jira_release_audit.py [-h] [--populate-from-git POPULATE_FROM_GIT]
|
|||
[--release-line-regexp RELEASE_LINE_REGEXP]
|
||||
[--parse-release-tags PARSE_RELEASE_TAGS]
|
||||
[--fallback-actions-path FALLBACK_ACTIONS_PATH]
|
||||
[--jira-url JIRA_URL]
|
||||
[--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
|
||||
|
@ -69,90 +72,169 @@ optional arguments:
|
|||
Building the audit database:
|
||||
--populate-from-git POPULATE_FROM_GIT
|
||||
When true, populate the audit database from the Git
|
||||
repository.
|
||||
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.
|
||||
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,...})
|
||||
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.
|
||||
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'
|
||||
branches. Default: 'origin' (default: origin)
|
||||
--development-branch DEVELOPMENT_BRANCH
|
||||
The name of the branch from which all release lines
|
||||
originate. Default: 'master'
|
||||
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'
|
||||
committed to the development branch. (default: 3.0.0)
|
||||
--release-line-regexp RELEASE_LINE_REGEXP
|
||||
A regexp used to identify release lines.
|
||||
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.
|
||||
calculation, disabled by default. (default: False)
|
||||
--fallback-actions-path FALLBACK_ACTIONS_PATH
|
||||
Path to a file containing _DB.Actions applicable to
|
||||
specific git shas.
|
||||
specific git shas. (default: fallback_actions.csv)
|
||||
--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.
|
||||
--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 \
|
||||
--remote-name=apache-rw \
|
||||
--development-branch-fix-version=3.0.0 \
|
||||
--branch-1-fix-version=1.5.0 \
|
||||
--branch-2-fix-version=2.3.0
|
||||
INFO:root:apache-rw/branch-1 has 4046 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
||||
INFO:root:apache-rw/branch-1.0 has 1433 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
||||
INFO:root:apache-rw/branch-1.1 has 2111 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
||||
INFO:root:apache-rw/branch-1.2 has 2738 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
||||
INFO:root:apache-rw/branch-1.3 has 3287 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
||||
INFO:root:apache-rw/branch-1.4 has 3912 commits since its origin at 0167558eb31ff48308d592ef70b6d005ba6d21fb.
|
||||
INFO:root:apache-rw/branch-2 has 3080 commits since its origin at 0d0c330401ade938bf934aafd79ec23705edcc60.
|
||||
INFO:root:apache-rw/branch-2.0 has 2194 commits since its origin at 0d0c330401ade938bf934aafd79ec23705edcc60.
|
||||
INFO:root:apache-rw/branch-2.1 has 2705 commits since its origin at 0d0c330401ade938bf934aafd79ec23705edcc60.
|
||||
INFO:root:apache-rw/branch-2.2 has 2927 commits since its origin at 0d0c330401ade938bf934aafd79ec23705edcc60.
|
||||
INFO:root:retrieving 5653 jira_ids from the issue tracker
|
||||
--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
|
||||
|
||||
apache-rw/branch-1 100%|██████████████████████████████████████████████████████| 4046/4046 [08:23<00:00, 8.04 commit/s]
|
||||
apache-rw/branch-1.0 100%|████████████████████████████████████████████████████| 1433/1433 [03:49<00:00, 6.26 commit/s]
|
||||
apache-rw/branch-1.1 100%|████████████████████████████████████████████████████| 2111/2111 [05:16<00:00, 6.68 commit/s]
|
||||
apache-rw/branch-1.2 100%|████████████████████████████████████████████████████| 2738/2738 [06:26<00:00, 7.10 commit/s]
|
||||
apache-rw/branch-1.3 100%|████████████████████████████████████████████████████| 3287/3287 [07:21<00:00, 7.46 commit/s]
|
||||
apache-rw/branch-1.4 100%|████████████████████████████████████████████████████| 3912/3912 [08:08<00:00, 8.02 commit/s]
|
||||
apache-rw/branch-2 100%|█████████████████████████████████████████████████████| 3080/3080 [03:29<00:00, 14.74 commit/s]
|
||||
apache-rw/branch-2.0 100%|████████████████████████████████████████████████████| 2194/2194 [04:56<00:00, 7.42 commit/s]
|
||||
apache-rw/branch-2.1 100%|███████████████████████████████████████████████████| 2705/2705 [03:17<00:00, 13.75 commit/s]
|
||||
apache-rw/branch-2.2 100%|███████████████████████████████████████████████████| 2927/2927 [03:28<00:00, 14.09 commit/s]
|
||||
fetch from Jira 100%|█████████████████████████████████████████████████████████| 5653/5653 [00:58<00:00, 98.29 issue/s]
|
||||
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]
|
||||
```
|
||||
|
||||
With a populated database, query with sqlite:
|
||||
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. 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
|
||||
|
@ -160,56 +242,71 @@ 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;
|
||||
3406|apache-rw/branch-1
|
||||
1189|apache-rw/branch-1.0
|
||||
1728|apache-rw/branch-1.1
|
||||
2289|apache-rw/branch-1.2
|
||||
2779|apache-rw/branch-1.3
|
||||
3277|apache-rw/branch-1.4
|
||||
2666|apache-rw/branch-2
|
||||
1809|apache-rw/branch-2.0
|
||||
2289|apache-rw/branch-2.1
|
||||
2511|apache-rw/branch-2.2
|
||||
|
||||
sqlite> -- count the number of issues that will be in 2.3.0 that have not been released on any earlier
|
||||
sqlite> -- version.
|
||||
sqlite> select count(1) from (
|
||||
select distinct jira_id from git_commits where branch = 'apache-rw/branch-2' except
|
||||
select distinct jira_id from git_commits where branch in
|
||||
('apache-rw/branch-2.0', 'apache-rw/branch-2.1', 'apache-rw/branch-2.2'));
|
||||
169
|
||||
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 = 'apache-rw/branch-2.2'
|
||||
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 non-1.x fixVersions for all issues on branch-2 but not on any
|
||||
sqlite> -- branch-2.x release branch; i.e., issues that are missing a fixVersion or
|
||||
sqlite> -- are marked for a release other than (3.0.0, 2.3.0)
|
||||
sqlite> select g.jira_id, j.fix_version
|
||||
from (
|
||||
select distinct jira_id from git_commits where branch = 'apache-rw/branch-2' except
|
||||
select distinct jira_id from git_commits where branch in
|
||||
(select distinct branch from git_commits where branch like 'apache-rw/branch-2.%')) g
|
||||
left join jira_versions j
|
||||
on g.jira_id = j.jira_id
|
||||
and j.fix_version not like '1.%'
|
||||
where (
|
||||
j.fix_version is null
|
||||
OR j.fix_version not in ('3.0.0', '2.3.0'))
|
||||
order by g.jira_id desc;
|
||||
HBASE-23683|2.2.4
|
||||
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-22405|2.2.0
|
||||
HBASE-22360|2.2.0
|
||||
HBASE-22321|
|
||||
HBASE-22283|2.2.0
|
||||
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
|
||||
```
|
||||
|
|
|
@ -27,8 +27,10 @@ hexsha,action,jira_id
|
|||
05f8e94191ef6a63baadf56d6114d7d0317796f2,SKIP,
|
||||
0791b878422eadf00b55076338f09bf059f39f0c,SKIP,
|
||||
07f9f3d38cf4d0d01044ab28d90a50a1a009f6b8,SKIP,
|
||||
0bff1305134b9c3a0bcad21900f5af68a8aedb4a,SKIP,
|
||||
10f00547627076d79d77cf58dd2deaece2287084,ADD,HBASE-22330
|
||||
10f3b77748a02a2c11635c33964929c0474e890d,SKIP,
|
||||
1196e42362312080d3c523c107b5e8fefef9e57e,SKIP,
|
||||
1404d5a97331ecc63db53971f5cb7329cb40ce67,ADD,HBASE-15203
|
||||
14a869828fe481697d29b2d6e4135e8026039a38,SKIP,
|
||||
1546613e76b1013a08ebc179c2c22bfeb44f3a4a,SKIP,
|
||||
|
@ -42,6 +44,7 @@ hexsha,action,jira_id
|
|||
1b3557649c9ee682c7f135ca52a0e3cd10cb9219,SKIP,
|
||||
1c46250bef9ef9be9c255d61bda69ff7792ed551,SKIP,
|
||||
1cb7d0e82ad64f37fbd6de950b74081b0d5eddf3,SKIP,
|
||||
1d988afc9d2065a51fe74d0553f0943ef540dfaa,SKIP,
|
||||
1eaef185327171b3dd3edb303e08cfe85186e745,SKIP,
|
||||
1eb8ac6fe9dd0c15cdb52f66ced4136316c06465,SKIP,
|
||||
2068804d7510e8c1f822b5db3cd4585455f6e7e7,SKIP,
|
||||
|
@ -52,6 +55,7 @@ hexsha,action,jira_id
|
|||
259d12f7397679c6b0d0a4788e5a37f65fd49f20,SKIP,
|
||||
267bce0590c39570ddb935921e34bda35e3aa44c,SKIP,
|
||||
278828333c44493ccbaa7db26a788b2756632034,SKIP,
|
||||
27c1f2f978142b7bb4135e53c3ae067c5608c9fb,SKIP,
|
||||
288794d68ba5bd4d1fd8d5c315cee972019dcb3d,ADD,HBASE-22330
|
||||
28f07451a5dddf0ab3988b32b8672654fdbc5b58,SKIP,
|
||||
2ba542d74c2d9e78332c8c94289d1295752d8072,SKIP,
|
||||
|
@ -97,7 +101,9 @@ hexsha,action,jira_id
|
|||
4eb84651a2b6d02d2074143308cef5d0f4b856a3,SKIP,
|
||||
4f5b22bc19cb8d24ced5d42ebd9794cfd83bae85,SKIP,
|
||||
54337870eda5649ab7bb81ed01c9dd25d59204f2,SKIP,
|
||||
558ee079fd04dfab8e61eca10ee98ab5bac89dfa,SKIP,
|
||||
58ab201be341f02829286f036a7401d0806eb999,SKIP,
|
||||
58b63e04c4af99a5730efb0a7e553be4d950e6a5,SKIP,
|
||||
5a16c15d7f51087a50511a2e0730f547c97a033f,SKIP,
|
||||
5b5ff1d8b2cc43f78acaf9bc960be382dc6c34f7,SKIP,
|
||||
5fa15dd7488433ea610ff5e92161409d20565690,SKIP,
|
||||
|
@ -170,6 +176,7 @@ b3d55441b8174c704ada4585603f6bcfca298843,SKIP,
|
|||
b65231d04dbc565a578ce928e809aa51f5439857,SKIP,
|
||||
b6549007b313e8f3aa993d5c1ebd29c84ccb7b7b,SKIP,
|
||||
b6d4fc955fe0fc41f5225f1cc2e3e4b92029251c,SKIP,
|
||||
b9c676cdc048c52f927cfa906fd18ff412e4ca20,SKIP,
|
||||
b9f5c6b065ebd572193c1fdc9d38557320b42fe6,SKIP,
|
||||
bcadcef21048e4764f7ae8dec3ce52884f20c02c,SKIP,
|
||||
bcdc56ac76e4a26e53faa8301a441e94ee8614d7,SKIP,
|
||||
|
@ -178,9 +185,11 @@ bd4e14db07ea32a45c3ef734e06d195a405da67c,SKIP,
|
|||
bd4eba2b53b7af738fd9584511d737c4393d0855,SKIP,
|
||||
bef0616ef33306afca3060b96c2cba5f9762035d,SKIP,
|
||||
c100fb835a54be6002fe9704349e726f27b15b7a,SKIP,
|
||||
c5e0a1397b3c6a14612e4c5b66f995c02de4310b,SKIP,
|
||||
c71da858ada94e1b93065f0b7caf3558942bc4da,SKIP,
|
||||
c89cfd3406823cf05fa83464c5ddee16bf0d473f,ADD,HBASE-17248
|
||||
c89cfd3406823cf05fa83464c5ddee16bf0d473f,ADD,HBASE-17248
|
||||
c8c2a875056f27c9af81293a504d75634cbc1fa5,SKIP,
|
||||
c97905a962b88a0c68ca8a51c2e507daec81ca6d,SKIP,
|
||||
c9f506a2973e0acbd0d2df7b9353c9291f6c94a8,SKIP,
|
||||
cbb2c7e00d0c0b3f641250d981b9c87286d31058,ADD,HBASE-23069
|
||||
|
@ -209,6 +218,7 @@ e40fcee6b54712b76d702af6937c3320c60df2b9,SKIP,
|
|||
e501fe1a296be8fec0890e7e15414683aa3d933b,SKIP,
|
||||
e5349d589c000e395e12340e003aa9e2153afea6,SKIP,
|
||||
e5fb8214b2bfd6396539a4e8b6cf5f3cc5e9c06f,REVERT,HBASE-21874
|
||||
e869a20123afe326e198d35d110f5c0360ea244f,SKIP,
|
||||
e8e45ef8f2fb91a870399636b492d5cee58a4c39,SKIP,
|
||||
e92a147e1961366e36a39577816994566e1e21c5,SKIP,
|
||||
eacf3cb29641af1a68978d9bd7654f643a3aa3a1,SKIP,
|
||||
|
|
Can't render this file because it contains an unexpected character in line 7 and column 3.
|
|
@ -30,12 +30,16 @@ import pathlib
|
|||
import re
|
||||
import sqlite3
|
||||
import time
|
||||
import os
|
||||
|
||||
import enlighten
|
||||
import git
|
||||
import jira
|
||||
|
||||
|
||||
LOG = logging.getLogger(os.path.basename(__file__))
|
||||
|
||||
|
||||
class _DB:
|
||||
"""Manages an instance of Sqlite on behalf of the application.
|
||||
|
||||
|
@ -46,6 +50,9 @@ class _DB:
|
|||
Attributes:
|
||||
conn (:obj:`sqlite3.db2api.Connection`): The underlying connection object.
|
||||
"""
|
||||
|
||||
SQL_LOG = LOG.getChild("sql")
|
||||
|
||||
class Action(enum.Enum):
|
||||
"""Describes an action to be taken against the database."""
|
||||
ADD = 'ADD'
|
||||
|
@ -54,6 +61,7 @@ class _DB:
|
|||
|
||||
def __init__(self, db_path, initialize_db, **_kwargs):
|
||||
self._conn = sqlite3.connect(db_path)
|
||||
self._conn.set_trace_callback(_DB.log_query)
|
||||
|
||||
if initialize_db:
|
||||
for table in 'git_commits', 'jira_versions':
|
||||
|
@ -81,6 +89,10 @@ class _DB:
|
|||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self._conn.close()
|
||||
|
||||
@staticmethod
|
||||
def log_query(query):
|
||||
_DB.SQL_LOG.debug(re.sub(r'\s+', ' ', query).strip())
|
||||
|
||||
@property
|
||||
def conn(self):
|
||||
""":obj:`sqlite3.db2api.Connection`: Underlying database handle."""
|
||||
|
@ -324,7 +336,7 @@ class _RepoReader:
|
|||
|
||||
def _resolve_ambiguity(self, commit):
|
||||
if commit.hexsha not in self._fallback_actions:
|
||||
logging.warning('Unable to resolve action for %s: %s', commit.hexsha, commit.summary)
|
||||
LOG.warning('Unable to resolve action for %s: %s', commit.hexsha, commit.summary)
|
||||
return _DB.Action.SKIP, None
|
||||
action, jira_id = self._fallback_actions[commit.hexsha]
|
||||
if not jira_id:
|
||||
|
@ -354,7 +366,7 @@ class _RepoReader:
|
|||
global MANAGER
|
||||
commits = list(self._repo.iter_commits(
|
||||
"%s...%s" % (origin_commit.hexsha, release_branch), reverse=True))
|
||||
logging.info("%s has %d commits since its origin at %s.", release_branch, len(commits),
|
||||
LOG.info("%s has %d commits since its origin at %s.", release_branch, len(commits),
|
||||
origin_commit)
|
||||
counter = MANAGER.counter(total=len(commits), desc=release_branch, unit='commit')
|
||||
commits_since_release = list()
|
||||
|
@ -404,7 +416,7 @@ class _JiraReader:
|
|||
database."""
|
||||
global MANAGER
|
||||
jira_ids = self._db.unique_jira_ids_from_git()
|
||||
logging.info("retrieving %s jira_ids from the issue tracker", len(jira_ids))
|
||||
LOG.info("retrieving %s jira_ids from the issue tracker", len(jira_ids))
|
||||
counter = MANAGER.counter(total=len(jira_ids), desc='fetch from Jira', unit='issue')
|
||||
chunk_size = 50
|
||||
chunks = [jira_ids[i:i + chunk_size] for i in range(0, len(jira_ids), chunk_size)]
|
||||
|
@ -429,7 +441,7 @@ class _JiraReader:
|
|||
def fetch_issues(self, jira_ids):
|
||||
"""Retrieve the specified jira Ids."""
|
||||
global MANAGER
|
||||
logging.info("retrieving %s jira_ids from the issue tracker", len(jira_ids))
|
||||
LOG.info("retrieving %s jira_ids from the issue tracker", len(jira_ids))
|
||||
counter = MANAGER.counter(total=len(jira_ids), desc='fetch from Jira', unit='issue')
|
||||
chunk_size = 50
|
||||
chunks = [jira_ids[i:i + chunk_size] for i in range(0, len(jira_ids), chunk_size)]
|
||||
|
@ -501,17 +513,17 @@ class Auditor:
|
|||
writer.writeheader()
|
||||
for issue in issues:
|
||||
writer.writerow(issue)
|
||||
logging.info('generated report at %s', filename)
|
||||
LOG.info('generated report at %s', filename)
|
||||
|
||||
def report_new_for_release_line(self, 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,...})"""
|
||||
matches = [x for x in self._repo_reader.release_line_refs
|
||||
if x.name == release_line or x.name.endswith('/%s' % release_line)]
|
||||
if x.name == release_line or x.remote_head == release_line]
|
||||
release_line_ref = next(iter(matches), None)
|
||||
if not release_line_ref:
|
||||
logging.error('release line %s not found. available options are %s.',
|
||||
LOG.error('release line %s not found. available options are %s.',
|
||||
release_line, [x.name for x in self._repo_reader.release_line_refs])
|
||||
return
|
||||
cursor = self._db.conn.execute("""
|
||||
|
@ -525,6 +537,31 @@ class Auditor:
|
|||
filename = 'new_for_%s.csv' % release_line.replace('/', '-')
|
||||
Auditor._write_report(filename, issues)
|
||||
|
||||
def report_new_for_release_branch(self, 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,...})"""
|
||||
matches = [x for x in self._repo_reader.release_branch_refs
|
||||
if x.name == release_branch or x.remote_head == release_branch]
|
||||
release_branch_ref = next(iter(matches), None)
|
||||
if not release_branch_ref:
|
||||
LOG.error('release branch %s not found. available options are %s.',
|
||||
release_branch, [x.name for x in self._repo_reader.release_branch_refs])
|
||||
return
|
||||
previous_branches = [x.name for x in self._repo_reader.release_branch_refs
|
||||
if x.remote_head != release_branch_ref.remote_head]
|
||||
query = (
|
||||
"SELECT distinct jira_id FROM git_commits"
|
||||
" WHERE branch = ?"
|
||||
" EXCEPT SELECT distinct jira_id FROM git_commits"
|
||||
f" WHERE branch IN ({','.join('?' for _ in previous_branches)})"
|
||||
)
|
||||
cursor = self._db.conn.execute(query, tuple([release_branch_ref.name] + previous_branches))
|
||||
jira_ids = [x[0] for x in cursor.fetchall()]
|
||||
issues = self._jira_reader.fetch_issues(jira_ids)
|
||||
filename = 'new_for_%s.csv' % release_branch.replace('/', '-')
|
||||
Auditor._write_report(filename, issues)
|
||||
|
||||
@staticmethod
|
||||
def _str_to_bool(val):
|
||||
if not val:
|
||||
|
@ -548,7 +585,7 @@ class Auditor:
|
|||
building_group.add_argument(
|
||||
'--db-path',
|
||||
help='Path to the database file, or leave unspecified for a transient db.',
|
||||
default=':memory:')
|
||||
default='audit.db')
|
||||
building_group.add_argument(
|
||||
'--initialize-db',
|
||||
help='When true, initialize the database tables. This is destructive to the contents'
|
||||
|
@ -561,6 +598,11 @@ class Auditor:
|
|||
help=Auditor.report_new_for_release_line.__doc__,
|
||||
type=str,
|
||||
default=None)
|
||||
report_group.add_argument(
|
||||
'--report-new-for-release-branch',
|
||||
help=Auditor.report_new_for_release_branch.__doc__,
|
||||
type=str,
|
||||
default=None)
|
||||
git_repo_group = parser.add_argument_group('Interactions with the Git repo')
|
||||
git_repo_group.add_argument(
|
||||
'--git-repo-path',
|
||||
|
@ -580,7 +622,7 @@ class Auditor:
|
|||
git_repo_group.add_argument(
|
||||
'--development-branch-fix-version',
|
||||
help='The Jira fixVersion used to indicate an issue is committed to the development'
|
||||
+ ' branch. Default: \'3.0.0\'',
|
||||
+ ' branch.',
|
||||
default='3.0.0')
|
||||
git_repo_group.add_argument(
|
||||
'--release-line-regexp',
|
||||
|
@ -612,7 +654,10 @@ class Auditor:
|
|||
help='The Jira fixVersion used to indicate an issue is committed to the specified '
|
||||
+ 'release line branch',
|
||||
required=True)
|
||||
return argparse.ArgumentParser(parents=[parent_parser])
|
||||
return argparse.ArgumentParser(
|
||||
parents=[parent_parser],
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter
|
||||
)
|
||||
|
||||
|
||||
MANAGER = None
|
||||
|
@ -621,11 +666,11 @@ MANAGER = None
|
|||
def main():
|
||||
global MANAGER
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
first_pass_parser, git_repo_group = Auditor._build_first_pass_parser()
|
||||
first_pass_args, extras = first_pass_parser.parse_known_args()
|
||||
first_pass_args_dict = vars(first_pass_args)
|
||||
with _DB(**first_pass_args_dict) as db:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
repo_reader = _RepoReader(db, **first_pass_args_dict)
|
||||
jira_reader = _JiraReader(db, **first_pass_args_dict)
|
||||
second_pass_parser = Auditor._build_second_pass_parser(
|
||||
|
@ -641,6 +686,9 @@ def main():
|
|||
if second_pass_args.report_new_for_release_line:
|
||||
release_line = second_pass_args.report_new_for_release_line
|
||||
auditor.report_new_for_release_line(release_line)
|
||||
if second_pass_args.report_new_for_release_branch:
|
||||
release_branch = second_pass_args.report_new_for_release_branch
|
||||
auditor.report_new_for_release_branch(release_branch)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Reference in New Issue