├── .github
├── FUNDING.yml
└── workflows
│ └── create-release.yml
├── .releasezri
└── template.md
├── CHANGELOG.md
├── LICENSE
├── README.md
└── scripts
└── rz.py
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: shalithasuranga
4 | patreon: shalithasuranga
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/workflows/create-release.yml:
--------------------------------------------------------------------------------
1 | name: Create release
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | version:
6 | type: text
7 | description: 'Version number Eg: 4.2.0'
8 |
9 | jobs:
10 | create-release:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v2
15 |
16 | - name: Create Release Notes
17 | run: |
18 | chmod +x ./scripts/rz.py
19 | ./scripts/rz.py create ${{github.event.inputs.version}}
20 |
21 | - name: Commit and Push Changelog
22 | uses: EndBug/add-and-commit@v7.4.0
23 | with:
24 | default_author: github_actions
25 | message: 'Update changelog for v${{github.event.inputs.version}}'
26 | add: 'CHANGELOG.md'
27 | tag: v${{github.event.inputs.version}}
28 |
29 | - name: Create a GitHub release
30 | uses: ncipollo/release-action@v1
31 | with:
32 | tag: v${{github.event.inputs.version}}
33 | name: ReleaseZri v${{github.event.inputs.version}} released!
34 | bodyFile: ./.tmprz/release_notes.md
35 |
36 | - name: Clean Release Notes
37 | run: |
38 | ./scripts/rz.py cleanup
39 |
--------------------------------------------------------------------------------
/.releasezri/template.md:
--------------------------------------------------------------------------------
1 | {RZ_TOP}
2 |
3 | ## What's new
4 | {RZ_CHANGELOG}
5 |
6 | Update your `scripts/rz.py` to use v{RZ_VERSION} (Released on {RZ_DATE}).
7 |
8 | Get started: https://github.com/codezri/releasezri
9 |
10 |
11 |
12 |
13 | This release was auto-generated by [ReleaseZri {RZ_RZVERSION}](https://github.com/codezri/releasezri) :rocket:
14 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | Add all code changes (features, deprecations, and enhancements) under the `Unreleased` topic to track changes for
4 | the next release. Once the changes are released,
5 | rename `Unreleased` topic with the new version tag. Finally, create a new `Unreleased` topic for future changes.
6 |
7 | Wait!, you don't need to do this manually - use [ReleaseZri](https://github.com/codezri/releasezri)
8 |
9 | ## Unreleased
10 |
11 | ### Core: script
12 |
13 | - Add the `--no-changes` flag to the `create` command to continue the release note generation without change logs in
14 | the unreleased section.
15 |
16 | ## v1.3.0
17 |
18 | ### Core: script
19 | - Add `RZ_TOP` template variable and set it via `--top=`. This feature is helpful for adding
20 | important messages about releases. i.e, Nightly build warning.
21 |
22 | ## v1.2.0
23 |
24 | ### Core: script
25 | - Remove `v` from `RZ_VERSION` template variable.
26 | - Add new template variables `RZ_RZVERSION`, `RZ_DATE`, and `RZ_TIME`.
27 |
28 | ## v1.1.0
29 |
30 | ### Core: script
31 | - Add `Unreleased` while updating the changelog with the latest version
32 |
33 | ## v1.0.3
34 |
35 | ### Core: template
36 | - Updated local sample template
37 |
38 | ## v1.0.2
39 |
40 | ### Core: script
41 | - Initial version
42 |
43 | ### Spec: changelog
44 | - Initial version
45 |
46 | ### Core: template
47 | - Initial version
48 |
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 codezri
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ```
2 | ____ __ _____ _
3 | / __ \___ / /__ ____ ________/__ / _____(_)
4 | / /_/ / _ \/ / _ \/ __ `/ ___/ _ \/ / / ___/ /
5 | / _, _/ __/ / __/ /_/ (__ ) __/ /__/ / / /
6 | /_/ |_|\___/_/\___/\__,_/____/\___/____/_/ /_/
7 |
8 | ReleaseZri - Meaningful and minimalist release notes for developers
9 | ```
10 |
11 | Managing manual release notes is hard. Therefore, everyone tends to generate release notes from commit messages. But, you won't get a meaningful release note at the end. ReleaseZri offers you a simple strategy to maintain a human-friendly changelog and generate release notes automatically. It also gives you GitHub Action steps that you can simply copy-paste into your projects.
12 |
13 | ## Simple steps
14 |
15 | - Use ReleaseZri's simple [changelog](CHANGELOG.md) format
16 | - Create your own release note template in `.releasezri/template.md` (Supports [template variables](https://codezri.org/docs/releasezri/integrate#supported-template-variables))
17 | - Copy-paste the `scripts/rz.py` script
18 | - Update your DevOps workflow to generate release notes via `scripts/rz.py create ` command
19 |
20 | This project itself is maintained with ReleaseZri. Read documentation here: https://codezri.org/docs/releasezri/intro
21 |
22 | ## Who use ReleaseZri?
23 |
24 | - [ReleaseZri](https://github.com/codezri/releasezri)
25 | - [Neutralinojs](https://neutralino.js.org)
26 |
27 | ## Case studies
28 |
29 | - [DevOps culture at Neutralinojs](https://codezri.org/blog/how-we-save-our-time-with-devops)
30 |
31 | ## License
32 |
33 | [MIT](LICENSE)
34 |
--------------------------------------------------------------------------------
/scripts/rz.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import sys
4 | import os
5 | import shutil
6 | from datetime import datetime
7 |
8 | RZ_DIR = './.releasezri'
9 | TEMPLATE_FILE = './.releasezri/template.md'
10 | CHANGELOG_FILE = './CHANGELOG.md'
11 | TMP_DIR = './.tmprz'
12 | RELEASE_NOTE_FILE = './.tmprz/release_notes.md'
13 | RZ_VERSION = '1.3.0'
14 | VERSION = ''
15 | VERSION_WITH_V = ''
16 |
17 | def get_cli_option_value(option):
18 | for arg in sys.argv:
19 | if option in arg:
20 | return arg.split('=')[1]
21 | return ''
22 |
23 | def apply_notes_to_template(note):
24 | md = ''
25 | today = datetime.today()
26 | with open(TEMPLATE_FILE, 'r') as tf:
27 | md = tf.read() \
28 | .replace('{RZ_RZVERSION}', RZ_VERSION) \
29 | .replace('{RZ_VERSION}', VERSION) \
30 | .replace('{RZ_DATE}', today.strftime('%Y-%m-%d')) \
31 | .replace('{RZ_TIME}', today.strftime('%H:%M:%S')) \
32 | .replace('{RZ_CHANGELOG}', note) \
33 | .replace('{RZ_TOP}', get_cli_option_value('--top')) \
34 | .strip()
35 | return md
36 |
37 | def parse_release_note():
38 | note = ''
39 | collect = False
40 | updated_changelog = ''
41 |
42 | with open(CHANGELOG_FILE, 'r') as cf:
43 | for line in cf:
44 | if '## Unreleased' in line:
45 | collect = True
46 | continue
47 | if '## v' in line:
48 | break
49 | if collect:
50 | note += line
51 | return note
52 |
53 | def save_release_note(note):
54 | os.makedirs(TMP_DIR, exist_ok = True)
55 |
56 | with open(RELEASE_NOTE_FILE, 'w') as rf:
57 | rf.write(note)
58 |
59 | def update_changelog():
60 | updated_changelog = ''
61 | pre_replace = '''## Unreleased
62 |
63 | '''
64 | with open(CHANGELOG_FILE, 'r') as cf:
65 | replace_text = pre_replace + '## ' + VERSION_WITH_V
66 | updated_changelog = cf.read().replace('## Unreleased', replace_text)
67 |
68 | with open(CHANGELOG_FILE, 'w') as cf:
69 | cf.write(updated_changelog)
70 |
71 | def create_note():
72 | print('INFO: Preparing release notes...')
73 | note = parse_release_note()
74 | if note.strip() == '':
75 | if '--no-changes' in sys.argv:
76 | note = 'No changes — this version is similar to the previous version'
77 | else:
78 | print('ERROR: No changes so far.')
79 | sys.exit(1)
80 | print('---- Release note for %s (parsed) ----' % VERSION_WITH_V)
81 | print('----')
82 |
83 | note = apply_notes_to_template(note)
84 | print('---- Release note for %s (applied to template) ----' % VERSION_WITH_V)
85 | print(note)
86 | print('----')
87 | save_release_note(note)
88 |
89 | print('INFO: Updating change log...')
90 | update_changelog()
91 |
92 | print('OK: All done. Run "cleanup" command after using release note.')
93 |
94 | def cleanup():
95 | shutil.rmtree(TMP_DIR)
96 | print('OK: All done.')
97 |
98 | def print_art():
99 | print('''
100 | ____ __ _____ _
101 | / __ \___ / /__ ____ ________/__ / _____(_)
102 | / /_/ / _ \/ / _ \/ __ `/ ___/ _ \/ / / ___/ /
103 | / _, _/ __/ / __/ /_/ (__ ) __/ /__/ / / /
104 | /_/ |_|\___/_/\___/\__,_/____/\___/____/_/ /_/
105 | ''')
106 |
107 | if __name__ == '__main__':
108 | print_art()
109 | if len(sys.argv) < 2:
110 | print('ERROR: Missing command (create or cleanup)')
111 | sys.exit(1)
112 |
113 | command = sys.argv[1]
114 |
115 | if command == 'create':
116 | if len(sys.argv) < 3:
117 | print('ERROR: Missing version argument')
118 | sys.exit(1)
119 | VERSION = sys.argv[2]
120 | VERSION_WITH_V = 'v' + VERSION
121 | create_note()
122 |
123 | elif command == 'cleanup':
124 | cleanup()
125 |
126 | else:
127 | print('ERROR: Invalid command!')
128 |
--------------------------------------------------------------------------------