Skip to content

Commit

Permalink
Merge pull request #1898 from Adyen/chore/release_process_changes_gen…
Browse files Browse the repository at this point in the history
…erate_release_notes

Release process - Generate release notes from PRs
  • Loading branch information
araratthehero authored Nov 22, 2024
2 parents 17af293 + a3dda1e commit fd27c24
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/.release_notes_allowed_labels_list
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Breaking changes,New,Fixed,Improved,Changed,Removed,Deprecated
11 changes: 11 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
65 changes: 65 additions & 0 deletions .github/workflows/generate_release_notes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
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"
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
- 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
95 changes: 95 additions & 0 deletions scripts/generate_release_notes.sh
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit fd27c24

Please sign in to comment.