From 8ca7d2f4fc8d001b0261b1572f428320b9f4cc2f Mon Sep 17 00:00:00 2001 From: Ararat Mnatsakanyan Date: Thu, 21 Nov 2024 13:20:16 +0100 Subject: [PATCH 1/4] Create a list of allowed release notes labels and fetch them in a script COAND-1016 --- .github/.release_notes_allowed_labels_list | 1 + .github/workflows/generate_release_notes.yml | 35 ++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 .github/.release_notes_allowed_labels_list create mode 100644 .github/workflows/generate_release_notes.yml diff --git a/.github/.release_notes_allowed_labels_list b/.github/.release_notes_allowed_labels_list new file mode 100644 index 0000000000..9b82debb46 --- /dev/null +++ b/.github/.release_notes_allowed_labels_list @@ -0,0 +1 @@ +Breaking changes,New,Fixed,Improved,Changed,Removed,Deprecated diff --git a/.github/workflows/generate_release_notes.yml b/.github/workflows/generate_release_notes.yml new file mode 100644 index 0000000000..10ce3b4f30 --- /dev/null +++ b/.github/workflows/generate_release_notes.yml @@ -0,0 +1,35 @@ +name: Generate release notes + +on: + workflow_call: + inputs: + version-name: + required: true + type: string + +jobs: + get_allowed_labels: + runs-on: ubuntu-latest + + outputs: + allowed-labels: ${{ steps.get_allowed_labels.outputs.allowed_labels }} + + steps: + - uses: actions/checkout@v4 + + - name: Get the list of allowed pull request labels + id: get_allowed_labels + env: + PROJECT_ROOT: ${{ github.workspace }} + run: | + RED='\033[0;31m' + FILE_NAME=.release_notes_allowed_labels_list + GITHUB_DIR=.github + FILE_PATH=$PROJECT_ROOT/$GITHUB_DIR/$FILE_NAME + if [[ ! -f "$FILE_PATH" ]]; then + echo -e "${RED}$FILE_NAME file doesn't exist in $GITHUB_DIR/" + exit 1 + fi + ALLOWED_LABELS=$(cat $FILE_PATH) + echo -e "allowed_labels=$ALLOWED_LABELS" >> $GITHUB_OUTPUT + echo -e "Allowed labels are: $ALLOWED_LABELS" From d4aec6ec81733a017bd91a3121b1e4db65dadc37 Mon Sep 17 00:00:00 2001 From: Ararat Mnatsakanyan Date: Thu, 21 Nov 2024 13:24:31 +0100 Subject: [PATCH 2/4] Create a script to generate release notes COAND-1016 --- .github/workflows/generate_release_notes.yml | 21 +++++ scripts/generate_release_notes.sh | 95 ++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 scripts/generate_release_notes.sh diff --git a/.github/workflows/generate_release_notes.yml b/.github/workflows/generate_release_notes.yml index 10ce3b4f30..24faac0b3b 100644 --- a/.github/workflows/generate_release_notes.yml +++ b/.github/workflows/generate_release_notes.yml @@ -33,3 +33,24 @@ jobs: ALLOWED_LABELS=$(cat $FILE_PATH) echo -e "allowed_labels=$ALLOWED_LABELS" >> $GITHUB_OUTPUT echo -e "Allowed labels are: $ALLOWED_LABELS" + + generate_release_notes: + runs-on: ubuntu-latest + needs: get_allowed_labels + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate release notes + id: generate_release_notes + env: + ALLOWED_LABELS: ${{ needs.get_allowed_labels.outputs.allowed-labels }} + VERSION_NAME: ${{ inputs.version-name }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_REPO: ${{ github.repository }} + run: | + chmod +x scripts/generate_release_notes.sh + RELEASE_NOTES_FILE_NAME="release-notes-${VERSION_NAME}.md" + scripts/generate_release_notes.sh $RELEASE_NOTES_FILE_NAME diff --git a/scripts/generate_release_notes.sh b/scripts/generate_release_notes.sh new file mode 100644 index 0000000000..c8b46c6a34 --- /dev/null +++ b/scripts/generate_release_notes.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +# Fetch latest release tag +fetch_latest_release_tag() { + LATEST_TAG=$(git describe --tags --abbrev=0) + echo "$LATEST_TAG" +} + +# Fetch recent commits since the last release tag +fetch_recent_commits() { + LATEST_TAG=$1 + + COMMITS=$(git log --oneline "$LATEST_TAG"..HEAD) + echo -e "$COMMITS" +} + +# Generate release notes from PRs +generate_release_notes_from_prs() { + LATEST_TAG="$(fetch_latest_release_tag)" + COMMITS="$(fetch_recent_commits "$LATEST_TAG")" + echo -e "Commits between the $LATEST_TAG and HEAD\n$COMMITS" + + # Initialize variables to hold content for each label + IFS=',' read -r -a LABELS <<< "$ALLOWED_LABELS" + declare -A LABEL_CONTENTS + for LABEL in "${LABELS[@]}"; do + LABEL_CONTENTS["$LABEL"]="" + done + + # Iterate over each commit to find PR numbers, fetch PR body and extract release notes + while IFS= read -r COMMIT; do + if [[ $COMMIT =~ Merge\ pull\ request\ \#([0-9]+) ]]; then + PR_NUMBER="${BASH_REMATCH[1]}" + echo -e "Processing PR #$PR_NUMBER" + + # Fetch PR content and extract body + API_URL="https://api.github.com/repos/$GITHUB_REPO/pulls/$PR_NUMBER" + PR_RESPONSE=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "$API_URL") + PR_BODY=$(echo "$PR_RESPONSE" | jq -r '.body') + + # Extract release notes for each label + for LABEL in "${LABELS[@]}"; do + HEADER="### $LABEL" + LABEL_CONTENT=$(echo "$PR_BODY" | awk -v header="$HEADER" ' + $0 ~ header { capture = 1; next } # Start capturing after the specified header + capture && /^[#]+[ ]/ { exit } # Stop at lines starting with one or more # followed by a space + capture { print $0 } # Continue capturing until a stopping condition + ') + if [ -n "$LABEL_CONTENT" ]; then + LABEL_CONTENTS["$LABEL"]="${LABEL_CONTENTS[$LABEL]}$LABEL_CONTENT\n" + echo -e "Generated notes for $LABEL:\n$LABEL_CONTENT" + fi + done + fi + done <<< "$COMMITS" + + # Combine notes by labels + OUTPUT="" + for LABEL in "${LABELS[@]}"; do + if [ -n "${LABEL_CONTENTS[$LABEL]}" ]; then + OUTPUT="${OUTPUT}### $LABEL\n${LABEL_CONTENTS[$LABEL]}\n" + fi + done + + # Save release notes in a file + if [ -n "$OUTPUT" ]; then + printf "Generated release notes:\n$OUTPUT" + printf "$OUTPUT" >> "$RELEASE_NOTES_FILE_NAME" + printf "$OUTPUT" >> "$GITHUB_STEP_SUMMARY" + fi +} + +# Main Execution +generate_release_notes() { + if [ -z "$ALLOWED_LABELS" ]; then + echo "ALLOWED_LABELS is not provided. Please provide it in env list. Exiting..." + exit 1 + fi + + if [ -z "$GITHUB_TOKEN" ]; then + echo "GITHUB_TOKEN is not provided. Please provide it in env list. Exiting..." + exit 1 + fi + + if [ -z "$GITHUB_REPO" ]; then + echo "GITHUB_REPO is not provided. Please provide it in env list. Exiting..." + exit 1 + fi + + generate_release_notes_from_prs +} + +RELEASE_NOTES_FILE_NAME=$1 + +generate_release_notes From 054ff5b3eaee78217a422352ec5595fe0bebbcdd Mon Sep 17 00:00:00 2001 From: Ararat Mnatsakanyan Date: Thu, 21 Nov 2024 13:54:21 +0100 Subject: [PATCH 3/4] Upload release notes artifact COAND-1016 --- .github/workflows/generate_release_notes.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/generate_release_notes.yml b/.github/workflows/generate_release_notes.yml index 24faac0b3b..d5e0bd5879 100644 --- a/.github/workflows/generate_release_notes.yml +++ b/.github/workflows/generate_release_notes.yml @@ -54,3 +54,12 @@ jobs: chmod +x scripts/generate_release_notes.sh RELEASE_NOTES_FILE_NAME="release-notes-${VERSION_NAME}.md" scripts/generate_release_notes.sh $RELEASE_NOTES_FILE_NAME + + - name: Upload release notes artifact + uses: actions/upload-artifact@v3 + env: + VERSION_NAME: ${{ inputs.version-name }} + with: + name: "release-notes-${{ env.VERSION_NAME }}" + path: "release-notes-${{ env.VERSION_NAME }}.md" + overwrite: true From a3dda1efd36c95977704a7c48162cdbd7e720979 Mon Sep 17 00:00:00 2001 From: Ararat Mnatsakanyan Date: Thu, 21 Nov 2024 13:43:41 +0100 Subject: [PATCH 4/4] Update pull request template COAND-1016 --- .github/pull_request_template.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index efef911f56..adf51783c4 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -10,3 +10,14 @@ - [ ] Related issues are linked COAND-XXX + +## Release notes +[//]: # (Use the headers listed below to organize your release notes. Each section should begin with ### followed by a valid label) +[//]: # (Allowed labels: `Breaking changes`, `New`, `Fixed`, `Improved`, `Changed`, `Removed`, `Deprecated`) +[//]: # (Content will be grouped under a specific label until the next header #, ##, or ### is found) +[//]: # (### New) +[//]: # (List any new features or enhancements) +[//]: # (e.g. - Added functionality for user authentication) +[//]: # (### Fixed) +[//]: # (List fixes here) +[//]: # (e.g. - Fixed issue with incorrect data rendering)