Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
tails
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
947
Issues
947
List
Boards
Labels
Service Desk
Milestones
Merge Requests
13
Merge Requests
13
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tails
tails
Commits
8e0865e6
Commit
8e0865e6
authored
Aug 24, 2020
by
intrigeri
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add PoC script that generates a changelog from GitLab MRs
refs
#17886
parent
42e8edee
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
184 additions
and
0 deletions
+184
-0
bin/generate-changelog
bin/generate-changelog
+163
-0
config/release_management/templates/changelog.jinja2
config/release_management/templates/changelog.jinja2
+21
-0
No files found.
bin/generate-changelog
0 → 100755
View file @
8e0865e6
#! /usr/bin/python3
import
datetime
import
email.utils
import
functools
import
gitlab
import
jinja2
import
logging
import
os
import
pprint
import
re
from
pathlib
import
Path
PYTHON_GITLAB_CONFIG_FILE
=
os
.
getenv
(
'PYTHON_GITLAB_CONFIG_FILE'
,
default
=
Path
.
home
()
/
'.python-gitlab.cfg'
)
PYTHON_GITLAB_NAME
=
os
.
getenv
(
'GITLAB_NAME'
,
default
=
'Tails'
)
GROUP_NAME
=
'tails'
# Only changes in these projects are considered
PROJECTS
=
[
GROUP_NAME
+
'/'
+
project
for
project
in
[
'chutney'
,
'installer'
,
'tails'
,
'whisperback'
,
'workarounds'
,
]
]
# Merge requests that modify only files whose path match one of IGNORED_PATHS
# are ignored.
# Patterns will be passed to re.fullmatch().
IGNORED_PATHS
=
[
r
'po/.*'
,
r
'wiki/.*'
,
]
LOG_FORMAT
=
"%(asctime)-15s %(levelname)s %(message)s"
log
=
logging
.
getLogger
()
class
GitLabWrapper
(
gitlab
.
Gitlab
):
@
functools
.
lru_cache
def
project
(
self
,
project_id
):
return
self
.
projects
.
get
(
project_id
)
@
functools
.
lru_cache
def
project_path_with_namespace
(
self
,
project_id
):
return
self
.
project
(
project_id
).
path_with_namespace
class
ChangelogGenerator
(
object
):
def
__init__
(
self
,
gl
,
group
,
version
:
str
):
self
.
gl
=
gl
self
.
group
=
group
self
.
version
=
version
def
merge_requests
(
self
,
milestone
)
->
list
:
mrs
=
[]
gl_mrs
=
[
mr
for
mr
in
milestone
.
merge_requests
(
all
=
True
,
state
=
'merged'
)
if
self
.
gl
.
project_path_with_namespace
(
mr
.
target_project_id
)
in
PROJECTS
]
for
mr
in
gl_mrs
:
project
=
self
.
gl
.
project
(
mr
.
target_project_id
)
mr
=
project
.
mergerequests
.
get
(
mr
.
iid
)
if
ignore_merge_request
(
mr
):
continue
# yapf: disable
mrs
.
append
({
"ref"
:
mr
.
references
[
'full'
],
"title"
:
mr
.
title
,
"web_url"
:
mr
.
web_url
,
"closes_issues"
:
[
{
"ref"
:
project
.
issues
.
get
(
issue
.
iid
).
references
[
'full'
],
"title"
:
issue
.
title
,
}
for
issue
in
mr
.
closes_issues
()
],
"commit_messages"
:
[
commit
.
title
for
commit
in
mr
.
commits
()],
})
# yapf: enable
return
mrs
def
changes
(
self
)
->
dict
:
milestone_title
=
"Tails_"
+
self
.
version
milestone
=
[
m
for
m
in
self
.
group
.
milestones
.
list
(
search
=
milestone_title
)
# Disambiguate between milestones whose names share a common prefix
if
m
.
title
==
milestone_title
][
0
]
assert
isinstance
(
milestone
,
gitlab
.
v4
.
objects
.
GroupMilestone
)
return
{
"merge_requests"
:
self
.
merge_requests
(
milestone
),
"issues"
:
{},
# XXX: do we we really want this?
}
def
ignore_merge_request
(
mr
)
->
bool
:
for
change
in
mr
.
changes
()[
'changes'
]:
for
path
in
[
change
[
'old_path'
],
change
[
'new_path'
]]:
if
all
([
re
.
fullmatch
(
ignored_path
,
path
)
is
None
for
ignored_path
in
IGNORED_PATHS
]):
log
.
debug
(
"Returning false"
)
return
False
log
.
debug
(
"Returning true"
)
return
True
def
changelog_entry
(
version
:
str
,
date
:
datetime
,
changes
:
dict
):
jinja2_env
=
jinja2
.
Environment
(
loader
=
jinja2
.
FileSystemLoader
(
'config/release_management/templates'
),
trim_blocks
=
True
,
lstrip_blocks
=
True
,
)
return
jinja2_env
.
get_template
(
'changelog.jinja2'
).
render
(
merge_requests
=
changes
[
'merge_requests'
],
issues
=
changes
[
'issues'
],
date
=
email
.
utils
.
format_datetime
(
date
),
version
=
version
,
)
if
__name__
==
'__main__'
:
import
argparse
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
'--version'
,
required
=
True
)
parser
.
add_argument
(
"--debug"
,
action
=
"store_true"
,
help
=
"debug output"
)
args
=
parser
.
parse_args
()
if
args
.
debug
:
logging
.
basicConfig
(
level
=
logging
.
DEBUG
,
format
=
LOG_FORMAT
)
else
:
logging
.
basicConfig
(
level
=
logging
.
INFO
,
format
=
LOG_FORMAT
)
gl
=
GitLabWrapper
.
from_config
(
PYTHON_GITLAB_NAME
,
config_files
=
[
PYTHON_GITLAB_CONFIG_FILE
])
gl
.
auth
()
group
=
gl
.
groups
.
list
(
search
=
GROUP_NAME
)[
0
]
assert
isinstance
(
group
,
gitlab
.
v4
.
objects
.
Group
)
changes
=
ChangelogGenerator
(
gl
,
group
,
args
.
version
).
changes
()
log
.
debug
(
pprint
.
PrettyPrinter
().
pformat
(
changes
))
print
(
changelog_entry
(
version
=
args
.
version
,
date
=
datetime
.
datetime
.
now
(
datetime
.
timezone
.
utc
),
changes
=
changes
))
config/release_management/templates/changelog.jinja2
0 → 100644
View file @
8e0865e6
{# Jinja2 template used by bin/generate-changelog -#}
tails ({{version}}) unstable; urgency=medium
{% for mr in merge_requests %}
{% set mr_desc = mr.title + " (" + mr.ref + ")" %}
* {{ mr_desc|wordwrap(wrapstring="\n ")}}
{% if mr.closes_issues %}
Closes issues:
{% for issue in mr.closes_issues %}
{% set issue_desc = issue.title + " (" + issue.ref + ")" %}
- {{ issue_desc|wordwrap(wrapstring="\n ") }}
{% endfor %}
{% endif %}
Commits:
{% for commit_message in mr.commit_messages %}
- {{ commit_message|wordwrap(wrapstring="\n ") }}
{% endfor %}
{% endfor %}
-- Tails developers <tails@boum.org> {{date}}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment