├── .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 | --------------------------------------------------------------------------------