Release Workflow #59
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Release Workflow | |
on: | |
workflow_dispatch: | |
permissions: | |
contents: write | |
jobs: | |
summarize-prs: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v3 | |
- name: Install Dependencies | |
run: | | |
sudo apt-get update | |
sudo apt-get install -y jq | |
- name: Authenticate GitHub CLI | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
gh auth status | |
- name: Get the latest tag or set initial version | |
id: get_latest_tag | |
run: | | |
git fetch --tags | |
LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1` 2>/dev/null || echo "v0.0.0") | |
echo "latest_tag=$LATEST_TAG" >> $GITHUB_ENV | |
- name: Calculate new version | |
run: | | |
echo "latest_tag=${{ env.latest_tag }}" | |
# Split version into components and increment patch | |
LATEST_TAG_NO_V="${{ env.latest_tag }}" | |
LATEST_TAG_NO_V=${LATEST_TAG_NO_V#v} # Remove 'v' prefix | |
IFS='.' read -r MAJOR MINOR PATCH <<< "$LATEST_TAG_NO_V" | |
PATCH=$((PATCH + 1)) | |
NEW_VERSION="v$MAJOR.$MINOR.$PATCH" | |
# Output the new version | |
echo "Final new version: $NEW_VERSION" | |
echo "new_version=$NEW_VERSION" >> $GITHUB_ENV | |
- name: Generate changelog | |
id: changelog | |
run: | | |
CHANGES=$(git log "${{ env.latest_tag }}"..HEAD --pretty=format:"- %s (%h) by %an") | |
echo "$CHANGES" > changes.txt | |
echo "Changes written to changes.txt" | |
- name: Fetch PR data as JSON | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
# Get the timestamp of the last tag | |
LAST_TAG_DATE=$(git log -1 --format=%ct ${{ env.latest_tag }}) | |
LAST_TAG_ISO=$(date -u --date="@$LAST_TAG_DATE" +"%Y-%m-%dT%H:%M:%SZ") | |
# Get PRs merged after the last tag | |
gh pr list --state merged --base main --search "merged:>$LAST_TAG_ISO" \ | |
--json number,title,body,author,mergedAt,labels > prs.json | |
echo "PR data saved to prs.json" | |
- name: Format PR data | |
run: | | |
jq -r '.[] | "- PR #\(.number): \(.title) by \(.author.login)\n> [!IMPORTANT]\n> \(.body // "No description provided.")\n"' prs.json > formatted_prs.txt | |
echo "Formatted PR data saved to formatted_prs.txt" | |
- name: Combine changelog and PR data | |
run: | | |
echo "Changes from git log:\n" > changelog.txt | |
cat changes.txt >> changelog.txt | |
echo "\nChanges from PRs:\n" >> changelog.txt | |
cat formatted_prs.txt >> changelog.txt | |
echo "Combined changelog written to changelog.txt" | |
- name: Extract PR titles and important lines | |
id: parse_changelog | |
run: | | |
awk -v repo_url="https://github.com/openintegrations/openint" ' | |
BEGIN { | |
last_pr_number = ""; | |
} | |
/^- PR #[0-9]+:/ { | |
match($0, /^- PR #([0-9]+):/, pr); | |
pr_title = $0; | |
pr_number = pr[1]; | |
} | |
/> \[!IMPORTANT\]/ { | |
getline; | |
important_line = $0; | |
if (pr_number != last_pr_number) { | |
last_pr_number = pr_number; | |
print pr_title " (" repo_url "/pull/" pr_number ") -- " important_line; | |
} | |
}' changelog.txt > formatted_release_notes.txt | |
echo "Formatted Release Notes:" | |
cat formatted_release_notes.txt | |
- name: Summarize PR changes with OpenAI | |
id: summarize | |
env: | |
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
run: | | |
FORMATTED_OUTPUT=$(cat formatted_release_notes.txt | jq -Rsa .) | |
RESPONSE=$(curl -s -X POST https://api.openai.com/v1/chat/completions \ | |
-H "Content-Type: application/json" \ | |
-H "Authorization: Bearer $OPENAI_API_KEY" \ | |
-d "$(jq -n --arg changelog "$FORMATTED_OUTPUT" '{ | |
model: "gpt-4", | |
messages: [ | |
{role: "system", content: "You are an assistant that generates concise and clear release summaries for software projects."}, | |
{role: "user", content: ("Summarize the following PR changes into a single two-liner summary highlighting important changes in casual tone of voice:\n\n" + $changelog)} | |
], | |
temperature: 0.7 | |
}')") | |
echo "OpenAI API Response:" | |
echo "$RESPONSE" | |
SUMMARY=$(echo "$RESPONSE" | jq -r '.choices[0].message.content // "No summary generated"') | |
echo "summary=$SUMMARY" >> $GITHUB_ENV | |
echo "$SUMMARY" > summary_output.txt | |
- name: Create Release Notes | |
run: | | |
SUMMARY=$(cat summary_output.txt) | |
echo -e "### Summary\n\n$SUMMARY\n\n### PR Breakdown:\n" > release_notes.txt | |
cat formatted_release_notes.txt >> release_notes.txt | |
echo "Release notes written to release_notes.txt" | |
- name: Create GitHub Release | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
gh release create "${{ env.new_version }}" --title "Release ${{ env.new_version }}" --notes-file release_notes.txt | |
- name: Update production branch | |
run: | | |
git config user.name "GitHub Actions Bot" | |
git config user.email "<>" | |
git fetch origin main | |
git checkout main | |
git push origin main:production -f |