diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ca5f69bb11e..1d66deb357e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -18,8 +18,19 @@ on: workflow_dispatch: inputs: version: - description: 'The version to release, without prefix v (e.g. 1.1.0)' + description: 'The version to release, without prefix v (e.g. 1.1.0-rc10)' required: true + previous_version: + description: 'The previous version, without prefix v (e.g. 1.1.0-rc9)' + required: true + pre_release: + description: 'Whether to mark release as pre-release or not (default: false)' + required: false + default: 'true' + generate_release_notes: + description: 'Whether to generate release notes or not (default: true)' + required: false + default: 'true' skip_images: description: 'Comma separated list of images to skip building, example with all possible images: mlrun,ui,api,base,models,models-gpu,jupyter,test' required: false @@ -96,9 +107,31 @@ jobs: tag: v${{ github.event.inputs.version }} commit: ${{ github.ref_name }} token: ${{ secrets.RELEASE_GITHUB_ACCESS_TOKEN }} + prerelease: ${{ github.event.inputs.pre_release }} - uses: ncipollo/release-action@v1 with: repo: ui tag: v${{ github.event.inputs.version }} commit: ${{ github.ref_name }} token: ${{ secrets.RELEASE_GITHUB_ACCESS_TOKEN }} + prerelease: ${{ github.event.inputs.pre_release }} + + update-release-notes: + name: Update release notes + runs-on: ubuntu-latest + if: github.event.inputs.generate_release_notes == 'true' + needs: create-releases + steps: + - uses: actions/checkout@v3 + - name: Generate release notes + id: release-notes + run: | + - echo "body=$(make release-notes MLRUN_OLD_VERSION=v${{ github.event.inputs.previous_version }} MLRUN_NEW_VERSION=v${{ github.event.inputs.version }} MLRUN_RELEASE_BRANCH=${{ github.ref_name }} MLRUN_RAISE_ON_ERROR=false MLRUN_RELEASE_NOTES_OUTPUT_PATH=release_notes.md || cat release_notes.md)" >> $GITHUB_OUTPUT + - uses: ncipollo/release-action@v1 + with: + tag: v${{ github.event.inputs.version }} + commit: ${{ github.ref_name }} + token: ${{ secrets.RELEASE_GITHUB_ACCESS_TOKEN }} + allowUpdates: true + prerelease: ${{ github.event.inputs.pre_release }} + body: ${{ steps.release-notes.outputs.body }} diff --git a/Makefile b/Makefile index 2e1d7bb655b..c730702769c 100644 --- a/Makefile +++ b/Makefile @@ -55,6 +55,8 @@ MLRUN_DOCKER_CACHE_FROM_REGISTRY ?= $(MLRUN_DOCKER_REGISTRY) MLRUN_PUSH_DOCKER_CACHE_IMAGE ?= MLRUN_GIT_ORG ?= mlrun MLRUN_RELEASE_BRANCH ?= master +MLRUN_RAISE_ON_ERROR ?= true +MLRUN_RELEASE_NOTES_OUTPUT_FILE ?= MLRUN_SYSTEM_TESTS_CLEAN_RESOURCES ?= true MLRUN_CUDA_VERSION = 11.7.0 MLRUN_TENSORFLOW_VERSION = 2.9.0 @@ -659,7 +661,7 @@ endif ifndef MLRUN_RELEASE_BRANCH $(error MLRUN_RELEASE_BRANCH is undefined) endif - python ./automation/release_notes/generate.py run $(MLRUN_VERSION) $(MLRUN_OLD_VERSION) $(MLRUN_RELEASE_BRANCH) + python ./automation/release_notes/generate.py run $(MLRUN_VERSION) $(MLRUN_OLD_VERSION) $(MLRUN_RELEASE_BRANCH) $(MLRUN_RAISE_ON_ERROR) $(MLRUN_RELEASE_NOTES_OUTPUT_FILE) .PHONY: pull-cache diff --git a/automation/release_notes/generate.py b/automation/release_notes/generate.py index b7b580dad02..cbe6af9863f 100644 --- a/automation/release_notes/generate.py +++ b/automation/release_notes/generate.py @@ -40,17 +40,22 @@ class ReleaseNotesGenerator: r"\)" r"$" ) + bug_fixes_words = ["fix", "bug"] def __init__( self, release: str, previous_release: str, release_branch: str, + raise_on_failed_parsing: bool = True, + tmp_file_path: str = None, ): self._logger = logger self._release = release self._previous_release = previous_release self._release_branch = release_branch + self._raise_on_failed_parsing = raise_on_failed_parsing + self.tmp_file_path = tmp_file_path # adding a map with the common contributors to prevent going to github API on every commit (better performance, # and prevent rate limiting) self._git_to_github_usernames_map = { @@ -121,20 +126,26 @@ def _generate_release_notes_from_commits( self, commits_for_highlights, commits_for_pull_requests ): ( - highlight_notes, + feature_notes, + bug_fixes_notes, failed_parsing_commits, ) = self._generate_highlight_notes_from_commits(commits_for_highlights) - # currently we just put everything under features / enhancements # TODO: enforce a commit message convention which will allow to parse whether it's a feature/enhancement or # bug fix failed_commits = "\n".join(failed_parsing_commits) + ui_feature_notes = ( + f"* **UI**: [Features & enhancement](https://github.com/mlrun/ui/releases/tag/" + f"{self._release}#features-and-enhancements)" + ) + ui_bug_fix_notes = f"* **UI**: [Bug fixes](https://github.com/mlrun/ui/releases/tag/{self._release}#bug-fixes)" + feature_notes += ui_feature_notes + bug_fixes_notes += ui_bug_fix_notes release_notes = f""" ### Features / Enhancements -{highlight_notes} -* **UI**: [Features & enhancement](https://github.com/mlrun/ui/releases/tag/{self._release}#features-and-enhancements) +{feature_notes} ### Bug fixes -* **UI**: [Bug fixes](https://github.com/mlrun/ui/releases/tag/{self._release}#bug-fixes) +{bug_fixes_notes} #### Pull requests: @@ -146,16 +157,25 @@ def _generate_release_notes_from_commits( #### Failed parsing: {failed_commits} """ + release_notes += failed_parsing_template + if self._raise_on_failed_parsing: + self.output_release_notes(release_notes) + raise ValueError( + "Failed parsing some of the commits, added them at the end of the release notes" + ) - print(release_notes + failed_parsing_template) - raise ValueError( - "Failed parsing some of the commits, added them at the end of the release notes" - ) + self.output_release_notes(release_notes) + def output_release_notes(self, release_notes: str): print(release_notes) + if self.tmp_file_path: + logger.info("Writing release notes to file", path=self.tmp_file_path) + with open(self.tmp_file_path, "w") as f: + f.write(release_notes) def _generate_highlight_notes_from_commits(self, commits: str): - highlighted_notes = "" + feature_notes = "" + bug_fixes_notes = "" failed_parsing_commits = [] if commits: for commit in commits.split("\n"): @@ -167,11 +187,22 @@ def _generate_highlight_notes_from_commits(self, commits: str): commit_id = match.groupdict()["commitId"] username = match.groupdict()["username"] github_username = self._resolve_github_username(commit_id, username) - highlighted_notes += f"* **{scope}**: {message}, {pull_request_number}, @{github_username}\n" + message_note = f"* **{scope}**: {message}, {pull_request_number}, @{github_username}\n" + if self._is_bug_fix(message_note): + bug_fixes_notes += message_note + else: + feature_notes += message_note elif commit: failed_parsing_commits.append(commit) - return highlighted_notes, failed_parsing_commits + return feature_notes, bug_fixes_notes, failed_parsing_commits + + def _is_bug_fix(self, note: str): + for bug_fix_word in self.bug_fixes_words: + if bug_fix_word in note.lower(): + return True + + return False def _resolve_github_username(self, commit_id, username): """ @@ -230,13 +261,21 @@ def main(): @click.argument("release", type=str, required=True) @click.argument("previous-release", type=str, required=True) @click.argument("release-branch", type=str, required=False, default="master") +@click.argument("raise-on-failed-parsing", type=bool, required=False, default=True) +@click.argument("tmp-file-path", type=str, required=False, default=None) def run( release: str, previous_release: str, release_branch: str, + raise_on_failed_parsing: bool, + tmp_file_path: str = None, ): release_notes_generator = ReleaseNotesGenerator( - release, previous_release, release_branch + release, + previous_release, + release_branch, + raise_on_failed_parsing, + tmp_file_path, ) try: release_notes_generator.run() diff --git a/tests/automation/release_notes/test_generate.py b/tests/automation/release_notes/test_generate.py index 44fd8990826..4f2820014f6 100644 --- a/tests/automation/release_notes/test_generate.py +++ b/tests/automation/release_notes/test_generate.py @@ -115,25 +115,28 @@ def test_generate_release_notes(): "_run_command": [ None, "fd6c5a86 {Gal Topper} [Requirements] Bump storey to 0.8.15 and v3io-frames to 0.10.2 (#1553)\n" - "985d7cb8 {Saar Cohen} [Secrets] Verify project secrets do not exist when deleting a project (#1552)", + "985d7cb8 {Saar Cohen} [Secrets] Verify project secrets do not exist when deleting a project (#1552)\n" + "5633cf68 {Liran BG} [Chief] Fix double quoting cookies (#2942)\n", "fd6c5a86 [Requirements] Bump storey to 0.8.15 and v3io-frames to 0.10.2 (#1553)\n" - "985d7cb8 [Secrets] Verify project secrets do not exist when deleting a project (#1552)", + "985d7cb8 [Secrets] Verify project secrets do not exist when deleting a project (#1552)\n" + "5633cf68 [Chief] Fix double quoting cookies (#2942)", ], - "_resolve_github_username": ["gtopper", "theSaarco"], + "_resolve_github_username": ["gtopper", "theSaarco", "liranbg"], "expected_response": f""" ### Features / Enhancements * **Requirements**: Bump storey to 0.8.15 and v3io-frames to 0.10.2, #1553, @gtopper * **Secrets**: Verify project secrets do not exist when deleting a project, #1552, @theSaarco - * **UI**: [Features & enhancement](https://github.com/mlrun/ui/releases/tag/{release}#features-and-enhancements) ### Bug fixes +* **Chief**: Fix double quoting cookies, #2942, @liranbg * **UI**: [Bug fixes](https://github.com/mlrun/ui/releases/tag/{release}#bug-fixes) #### Pull requests: fd6c5a86 [Requirements] Bump storey to 0.8.15 and v3io-frames to 0.10.2 (#1553) 985d7cb8 [Secrets] Verify project secrets do not exist when deleting a project (#1552) +5633cf68 [Chief] Fix double quoting cookies (#2942) """, }, @@ -153,7 +156,6 @@ def test_generate_release_notes(): ### Features / Enhancements * **Requirements**: Bump storey to 0.8.15 and v3io-frames to 0.10.2, #1553, @gtopper * **Secrets**: Verify project secrets do not exist when deleting a project, #1552, @theSaarco - * **UI**: [Features & enhancement](https://github.com/mlrun/ui/releases/tag/{release}#features-and-enhancements) ### Bug fixes @@ -176,7 +178,6 @@ def test_generate_release_notes(): "expect_failure": False, "expected_response": f""" ### Features / Enhancements - * **UI**: [Features & enhancement](https://github.com/mlrun/ui/releases/tag/{release}#features-and-enhancements) ### Bug fixes