Skip to content

Commit 1e305fe

Browse files
author
Sevastyan Zhukov
authored
changelog strategy to release (#6798)
1 parent 9229d38 commit 1e305fe

File tree

11 files changed

+401
-623
lines changed

11 files changed

+401
-623
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Assemble changelog
2+
on:
3+
pull_request:
4+
types: [ opened, synchronize ]
5+
jobs:
6+
process:
7+
permissions:
8+
pull-requests: write
9+
contents: write
10+
runs-on: ubuntu-20.04
11+
env:
12+
PR_NUMBER: ${{ github.event.pull_request.number }}
13+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14+
steps:
15+
- uses: actions/checkout@v3
16+
with:
17+
ref: ${{github.head_ref}}
18+
19+
- name: setup python
20+
uses: actions/setup-python@v4
21+
with:
22+
python-version: '3.7.7'
23+
24+
- name: install python packages
25+
run: |
26+
python3 -m pip install requests GitPython
27+
28+
- name: execute py script
29+
run: |
30+
python3 scripts/changelog/assemble_changelog.py
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Rename changelog files
2+
on:
3+
pull_request:
4+
types: [ opened, reopened, ready_for_review, synchronize ]
5+
jobs:
6+
process:
7+
permissions:
8+
pull-requests: write
9+
contents: write
10+
runs-on: ubuntu-20.04
11+
env:
12+
PR_NUMBER: ${{ github.event.pull_request.number }}
13+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14+
steps:
15+
- uses: actions/checkout@v3
16+
with:
17+
ref: ${{github.head_ref}}
18+
19+
- name: setup python
20+
uses: actions/setup-python@v4
21+
with:
22+
python-version: '3.7.7'
23+
24+
- name: install python packages
25+
run: |
26+
python3 -m pip install requests GitPython
27+
28+
- name: execute py script
29+
run: |
30+
python3 scripts/changelog/rename_changelog_file.py

changelog/README.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Multi-file running changelog
2+
3+
To avoid merge conflicts in the CHANGELOG.md file we accepted the multi-file running changelog strategy.
4+
5+
*This strategy works for the libnavui-androidauto project too. It works in the `libnavui-androidauto/changelog` directory*
6+
7+
To follow this strategy you should create a `.md` file for every PR. Choose a directory:
8+
9+
- `changelog/unreleased/features` for **Features** changes
10+
- `changelog/unreleased/bugfixes` for **Bug fixes and improvements** changes
11+
- `changelog/unreleased/issues` for **Known issues :warning:** changes
12+
- `changelog/unreleased/other` for other changes
13+
14+
Or you can use the helper script to do it. Just call `python3 scripts/changelog/add_changelog.py -f "I have added something special"` to create a changelog file.
15+
Call `python3 scripts/changelog/add_changelog.py -h` to get more info.
16+
17+
You can use anything that allow .md format in changelog files.
18+
19+
If you have implemented several features or bugfixes you should describe all of them:
20+
21+
```
22+
- Description of changes in md format
23+
- Description of changes in md format also
24+
```
25+
26+
You can choose any name for your changelog files because the GitHub action will rename files in
27+
`changelog/unreleased/features` and `changelog/unreleased/bugfixes` directories to `${PR_NUMBER}.md` when you open a PR.
28+
29+
For every PR the script will generate and update a comment with a changelog for the current branch in the following format:
30+
31+
```
32+
# Changelog
33+
#### Features
34+
- Feature 1 [#1234](https://github.com/mapbox/mapbox-navigation-android/pull/1234)
35+
- Feature 2 [#2345](https://github.com/mapbox/mapbox-navigation-android/pull/2345)
36+
37+
#### Bug fixes and improvements
38+
- Bugfix 3 [#3456](https://github.com/mapbox/mapbox-navigation-android/pull/3456)
39+
- Bugfix 4 [#4567](https://github.com/mapbox/mapbox-navigation-android/pull/4567)
40+
41+
#### Known issues :warning:
42+
- Issue 1
43+
- Issue 2
44+
45+
Some other changes
46+
```
47+
48+
The comment will be updated with every change.
49+
Also, a comment with a changelog will be generated and updated for the android auto project too.
50+
51+
Every release the release train app will:
52+
53+
* assemble the changelog
54+
* add information about dependencies and compile changelog like:
55+
```
56+
## Mapbox Navigation SDK 1.1.1 - 13 December, 2022
57+
### Changelog
58+
[Changes between v1.1.0 and v1.1.1](https://github.com/mapbox/mapbox-navigation-android/compare/v1.1.0...v1.1.1)
59+
60+
#### Features
61+
- Feature 1 [#1234](https://github.com/mapbox/mapbox-navigation-android/pull/1234)
62+
- Feature 2 [#2345](https://github.com/mapbox/mapbox-navigation-android/pull/2345)
63+
64+
#### Bug fixes and improvements
65+
- Bugfix 3 [#3456](https://github.com/mapbox/mapbox-navigation-android/pull/3456)
66+
- Bugfix 4 [#4567](https://github.com/mapbox/mapbox-navigation-android/pull/4567)
67+
68+
#### Known issues :warning:
69+
- Issue 1
70+
- Issue 2
71+
72+
Some other changes
73+
74+
### Mapbox dependencies
75+
This release depends on, and has been tested with, the following Mapbox dependencies:
76+
- Mapbox Maps SDK `v10.8.0` ([release notes](https://github.com/mapbox/mapbox-maps-android/releases/tag/v10.8.0))
77+
- Mapbox Navigation Native `v115.0.1`
78+
- Mapbox Core Common `v23.0.0`
79+
- Mapbox Java `v6.8.0` ([release notes](https://github.com/mapbox/mapbox-java/releases/tag/v6.8.0))
80+
- Mapbox Android Core `v5.0.2` ([release notes](https://github.com/mapbox/mapbox-events-android/releases/tag/core-5.0.2))
81+
```
82+
* add compiled changelog to `CHANGELOG.md` file
83+
* delete all files in `changelog/unreleased` dir

changelog/unreleased/CHANGELOG.md

Whitespace-only changes.

libnavui-androidauto/changelog/unreleased/CHANGELOG.md

Whitespace-only changes.

scripts/changelog/add_changelog.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import argparse
2+
import os
3+
4+
parser = argparse.ArgumentParser(description='Add a new changelog file')
5+
6+
parser.add_argument('-f', '--feature', nargs='+', help='Features')
7+
parser.add_argument('-b', '--bugfix', nargs='+', help='Bug fixes and improvements')
8+
parser.add_argument('-i', '--issue', nargs='+', help='Known issues :warning:')
9+
parser.add_argument('-o', '--other', nargs='+', help='Other changes')
10+
11+
args = parser.parse_args()
12+
13+
14+
def write_file(changes, dir):
15+
filename = 'changelog/unreleased/' + dir + '/changes.md'
16+
os.makedirs(os.path.dirname(filename), exist_ok=True)
17+
prepared_changes = ''
18+
for change in changes:
19+
prepared_changes += '- ' + change + '\n'
20+
open(filename, 'w').write(prepared_changes)
21+
22+
23+
if args.feature:
24+
write_file(args.feature, 'features')
25+
26+
if args.bugfix:
27+
write_file(args.bugfix, 'bugfixes')
28+
29+
if args.issue:
30+
write_file(args.issue, 'issues')
31+
32+
if args.other:
33+
write_file(args.other, 'other')
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import os
2+
3+
import requests
4+
5+
pr_number = os.environ['PR_NUMBER']
6+
token = os.environ['GITHUB_TOKEN']
7+
8+
9+
def get_changes(path):
10+
changes = ''
11+
if not os.path.isdir(path):
12+
return ''
13+
files = os.listdir(path)
14+
for file in files:
15+
pr_number = file.partition('.')[0]
16+
pr_changes = open(path + file, 'r').read()
17+
if path.endswith('bugfixes/') or path.endswith('features/'):
18+
pr_link = ' [#' + pr_number + '](https://github.com/mapbox/mapbox-navigation-android/pull/' + pr_number + ')' + '\n'
19+
lines_with_description = []
20+
for line in open(path + file, 'r').readlines():
21+
if line.startswith('- '):
22+
lines_with_description.append(line)
23+
for line in lines_with_description:
24+
pr_changes = pr_changes.replace(line, line.replace('\n', '') + pr_link)
25+
if not pr_changes.endswith('\n'):
26+
pr_changes += '\n'
27+
changes += pr_changes
28+
return changes.strip()
29+
30+
31+
bugfixes = get_changes('changelog/unreleased/bugfixes/')
32+
features = get_changes('changelog/unreleased/features/')
33+
issues = get_changes('changelog/unreleased/issues/')
34+
other = get_changes('changelog/unreleased/other/')
35+
36+
changelog = '#### Features\n' + features + '\n\n' + \
37+
'#### Bug fixes and improvements\n' + bugfixes + '\n\n' + \
38+
'#### Known issues :warning:\n' + issues + '\n\n' + \
39+
'#### Other changes\n' + other
40+
41+
auto_bugfixes = get_changes('libnavui-androidauto/changelog/unreleased/bugfixes/')
42+
auto_features = get_changes('libnavui-androidauto/changelog/unreleased/features/')
43+
44+
auto_changelog = '#### Features\n' + auto_features + '\n\n' + \
45+
'#### Bug fixes and improvements\n' + auto_bugfixes
46+
47+
pr_comments_url = 'https://api.github.com/repos/mapbox/mapbox-navigation-android/issues/' + pr_number + '/comments'
48+
headers = {"Authorization": "Bearer " + token}
49+
comments = requests.get(pr_comments_url, headers=headers).json()
50+
51+
full_changelog = '<details>\n<summary>Changelog</summary>\n\n' + \
52+
changelog + '</details>\n' + \
53+
'<details>\n<summary>Android Auto Changelog</summary>\n\n' + \
54+
auto_changelog + '</details>'
55+
56+
comment_with_changelog_id = None
57+
for comment in comments:
58+
if comment['body'].startswith('<details>\n<summary>Changelog</summary>\n'):
59+
comment_with_changelog_id = comment['id']
60+
61+
if comment_with_changelog_id:
62+
comments_url = 'https://api.github.com/repos/mapbox/mapbox-navigation-android/issues/comments/'
63+
comment_url = comments_url + str(comment_with_changelog_id)
64+
requests.patch(comment_url, json={'body': full_changelog}, headers=headers)
65+
else:
66+
requests.post(pr_comments_url, json={'body': full_changelog}, headers=headers)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import os
2+
import re
3+
4+
import git
5+
6+
pr_number = os.environ['PR_NUMBER']
7+
token = os.environ['GITHUB_TOKEN']
8+
9+
pattern = re.compile("^\d*.md")
10+
11+
12+
def rename_files(path):
13+
if not os.path.isdir(path):
14+
return 0
15+
16+
renamed_files_count = 0
17+
files = os.listdir(path)
18+
19+
new_md_files = list(filter(lambda file: not pattern.match(file), files))
20+
21+
if len(new_md_files) > 1:
22+
raise Exception('More than one new changelog file')
23+
24+
for file in new_md_files:
25+
if not pattern.match(file):
26+
os.rename(path + file, path + pr_number + '.md')
27+
renamed_files_count += 1
28+
29+
return renamed_files_count
30+
31+
32+
renamed_bugfixes_count = rename_files('changelog/unreleased/bugfixes/')
33+
renamed_features_count = rename_files('changelog/unreleased/features/')
34+
35+
auto_renamed_bugfixes_count = rename_files('libnavui-androidauto/changelog/unreleased/bugfixes/')
36+
auto_renamed_features_count = rename_files('libnavui-androidauto/changelog/unreleased/features/')
37+
38+
if renamed_features_count + renamed_bugfixes_count + auto_renamed_bugfixes_count + auto_renamed_features_count > 0:
39+
repository = git.Repo('.')
40+
repository.git.add('changelog/unreleased')
41+
repository.git.add('libnavui-androidauto/changelog/unreleased')
42+
repository.index.commit('Rename changelog files')
43+
repository.remotes.origin.push().raise_if_error()

0 commit comments

Comments
 (0)