diff --git a/.github/scripts/generate_release_notes.py b/.github/scripts/generate_release_notes.py index af1bb3911..8e20f07b8 100644 --- a/.github/scripts/generate_release_notes.py +++ b/.github/scripts/generate_release_notes.py @@ -2,9 +2,12 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # get the last release tag from git, and use it to find all merged PRs since -# that tag. extract their titles, labels and PR numbers and classify them into -# break changes, new # features, enhancements, bug fixes, and others based on -# their labels. +# that tag. Since their titles might not following the same format, we use +# gh cli to search merged PR by commit SHA. +# +# Once having those PRs' information, extract their titles, labels and PR +# numbers and classify them into break changes, new features, enhancements, +# bug fixes, and others based on their labels. # # The release version is generated based on the last release tag. The tag # should be in the format of "WAMR-major.minor.patch", where major, minor, @@ -56,25 +59,25 @@ def get_last_release_tag(): def get_merged_prs_since(tag): # Get commits since the last release tag - log_cmd = f'git log {tag}..HEAD --pretty=format:"%s"' + log_cmd = f'git log {tag}..HEAD --pretty=format:"%s %H"' logs = run_cmd(log_cmd).splitlines() print(f"Found {len(logs)} merge commits since last tag '{tag}'.") pr_numbers = [] for line in logs: - # assume the commit message ends with "(#PR_NUMBER)" - if not line.endswith(")"): - continue + _, sha = line.rsplit(" ", 1) + # Use SHA to find merged PRs + pr_cmd = f"gh pr list --search {sha} --state merged --json number,title" + pr_json = run_cmd(pr_cmd) + pr_data = json.loads(pr_json) - # Extract PR number - parts = line.split("(#") - if len(parts) < 2: - continue + for pr in pr_data: + pr_number = pr.get("number") + print(f"Found PR #{pr_number} {pr['title']}") + if pr_number and pr_number not in pr_numbers: + pr_numbers.append(f"{pr_number}") - # PR_NUMBER) -> PR_NUMBER - pr_num = parts[1][:-1] - pr_numbers.append(pr_num) return pr_numbers @@ -145,7 +148,7 @@ def format_release_notes(version, sections): else: notes.append("") notes.append("") - return "\n".join(notes) + return "\n".join(notes) + "\n" def insert_release_notes(notes, RELEASE_NOTES_FILE): diff --git a/.github/workflows/prepare_release.yml b/.github/workflows/prepare_release.yml new file mode 100644 index 000000000..ed86f7c2e --- /dev/null +++ b/.github/workflows/prepare_release.yml @@ -0,0 +1,66 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# It includes: +# - add new content into the RELEASE_NOTES.md +# - update the version in build-scripts/version.cmake and core/version.h +# +# The new content is added to the beginning of the RELEASE_NOTES.md file. +# It includes all merged PR titles since the last release(tag). +# Based on every PR's label, it will be categorized into different sections. +# +# The version number is updated to the next version. +# Based on new content in the RELEASE_NOTES.md, it will be determined +# 1. if there is breaking change or new features, the next version will be a minor version +# 2. if there is no breaking change and new features, the next version will be a patch version +# +# At the end, file a PR to update the files. + +name: preparation for a release. + +on: + workflow_dispatch: + +# Cancel any in-flight jobs for the same PR/branch so there's only one active +# at a time +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + prepare_release: + permissions: + contents: write # update files + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: prepare the release note + id: generate_release_notes + run: | + python3 ./.github/scripts/generate_release_notes.py ./RELEASE_NOTES.md" + + - name: extract next version from previous step's output + id: extract_version + run: | + echo "next_version=${{ steps.generate_release_notes.outputs.next_version }}" >> $GITHUB_ENV + + - name: update version files + run: | + python3 ./.github/scripts/update_version_files.py ${{ env.next_version }} + + - name: file a PR + id: file_pr + uses: peter-evans/create-pull-request@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + title: "Prepare for the next release" + body: | + This PR prepares for the next release. + It updates the version files and adds new content to the RELEASE_NOTES.md. + commit-message: "prepare for the next release" + branch: prepare-release-${{ github.run_id }} + paths: | + RELEASE_NOTES.md + build-scripts/version.cmake + core/version.h