Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

fix!: angel emoji

fix!: angel emoji #53

name: Generate Changeset
# This workflow can be triggered in two ways:
# 1. When a pull request is merged to any branch (typically develop or main)
# 2. Manually via the GitHub Actions UI using the workflow_dispatch event
# - Go to Actions > Generate Changeset > Run workflow
# - Enter the PR number and click "Run workflow"
on:
# Using pull_request_target instead of pull_request for security reasons:
# - Runs in the context of the BASE repository, not the fork
# - Has access to repository secrets
# - Can commit changes to protected branches
# - SECURITY NOTE: Be careful when checking out PR code with this event type
pull_request_target:
types: [closed]
branches:
- develop
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to generate changeset for'
required: true
type: string
jobs:
debug-event:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request_target'
steps:
- name: Debug Event
run: |
echo "Event name: ${{ github.event_name }}"
echo "Action: ${{ github.event.action }}"
echo "PR merged: ${{ github.event.pull_request.merged }}"
echo "Base ref: ${{ github.event.pull_request.base.ref }}"
echo "Head ref: ${{ github.event.pull_request.head.ref }}"
echo "PR number: ${{ github.event.pull_request.number }}"
echo "PR title: ${{ github.event.pull_request.title }}"
generate-changeset:
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
needs: [debug-event]
if: (github.event_name == 'pull_request_target' && github.event.pull_request.merged == true) || github.event_name == 'workflow_dispatch'
env:
REPO_URL: "https://github.com/${{ github.repository }}"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.base.ref || 'develop' }}
# Use a personal access token with repo scope for better permissions
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
# Add caching for npm dependencies
- name: Cache npm dependencies
uses: actions/cache@v3
id: npm-cache
with:
path: |
**/node_modules
~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install dependencies
# Only run full install if cache miss
if: steps.npm-cache.outputs.cache-hit != 'true'
run: npm ci
# If cache hit, just check for any missing dependencies
- name: Check dependencies
if: steps.npm-cache.outputs.cache-hit == 'true'
run: npm ci --prefer-offline --no-audit
- name: Extract PR information
id: pr_info
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
PR_NUMBER="${{ github.event.inputs.pr_number }}"
else
PR_NUMBER="${{ github.event.pull_request.number }}"
fi
PR_DATA=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/pulls/${PR_NUMBER}")
PR_TITLE=$(echo "$PR_DATA" | jq -r '.title')
PR_BODY=$(echo "$PR_DATA" | jq -r '.body')
PR_AUTHOR=$(echo "$PR_DATA" | jq -r '.user.login')
echo "pr_number=${PR_NUMBER}" >> $GITHUB_OUTPUT
echo "pr_title=${PR_TITLE}" >> $GITHUB_OUTPUT
echo "pr_author=${PR_AUTHOR}" >> $GITHUB_OUTPUT
echo "pr_body=${PR_BODY}" >> $GITHUB_OUTPUT
- name: Generate changeset for current PR
run: |
# Generate a changeset for the current PR
node scripts/generate-changeset.js \
--pr="${{ steps.pr_info.outputs.pr_number }}" \
--title="${{ steps.pr_info.outputs.pr_title }}" \
--author="${{ steps.pr_info.outputs.pr_author }}" \
--body="${{ steps.pr_info.outputs.pr_body }}"
# Commit and push the changeset
git config --global user.name "GitHub Actions"
git config --global user.email "actions@github.com"
# Check if there are changes to commit
if [[ -n "$(git status --porcelain)" ]]; then
git add .changesets/
git commit -m "chore: add changeset for PR #${{ steps.pr_info.outputs.pr_number }}"
git push
echo "Changeset created and pushed for PR #${{ steps.pr_info.outputs.pr_number }}"
else
echo "No changes to commit"
fi
- name: Generate release notes from changesets
id: generate_notes
run: |
# Create a temporary directory for release notes
mkdir -p /tmp/release-notes
# Generate release notes directly to see the raw output
echo "Raw output from release:notes command:"
npm run release:notes
# Generate release notes from all changesets to a temporary file
# Don't filter with grep initially to see what we're getting
npm run release:notes > /tmp/release-notes/temp_notes_raw.md
# Show the raw content
echo "Raw content of temp_notes_raw.md:"
cat /tmp/release-notes/temp_notes_raw.md
# Now apply filtering if needed
cat /tmp/release-notes/temp_notes_raw.md | grep -v "^>" > /tmp/release-notes/temp_notes_filtered.md
# Show filtered content
echo "Filtered content:"
cat /tmp/release-notes/temp_notes_filtered.md
# Apply sed filtering
sed -n '/^Found/!p' /tmp/release-notes/temp_notes_filtered.md > /tmp/release-notes/temp_notes.md
# Show final content
echo "Final release notes content:"
cat /tmp/release-notes/temp_notes.md
# Make sure the file isn't empty
if [ ! -s /tmp/release-notes/temp_notes.md ]; then
echo "Warning: Release notes file is empty. Using fallback content."
echo "No changes documented yet. This will be updated when changesets are processed." > /tmp/release-notes/temp_notes.md
fi
- name: Check for existing release PR
id: check_pr
run: |
# Check if there's already a PR from develop to main
PR_LIST=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/pulls?state=open&head=${{ github.repository_owner }}:develop&base=main")
PR_COUNT=$(echo "$PR_LIST" | jq length)
if [[ "$PR_COUNT" -gt 0 ]]; then
PR_NUMBER=$(echo "$PR_LIST" | jq -r '.[0].number')
echo "exists=true" >> $GITHUB_OUTPUT
echo "number=${PR_NUMBER}" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
- name: Update existing release PR
if: steps.check_pr.outputs.exists == 'true'
run: |
# Update the PR body with the latest changelog
PR_NUMBER="${{ steps.check_pr.outputs.number }}"
# Get current PR data
PR_DATA=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/pulls/${PR_NUMBER}")
PR_TITLE=$(echo "$PR_DATA" | jq -r '.title')
# Check if release notes file exists and has content
if [ -s /tmp/release-notes/temp_notes.md ]; then
RELEASE_NOTES=$(cat /tmp/release-notes/temp_notes.md)
echo "Using generated release notes:"
echo "$RELEASE_NOTES"
else
RELEASE_NOTES="No changes documented yet. This will be updated when changesets are processed."
echo "Using fallback release notes"
fi
# Create the PR body with proper formatting
PR_BODY="## Upcoming Changes"
PR_BODY="${PR_BODY}"$'\n\n'
PR_BODY="${PR_BODY}${RELEASE_NOTES}"
PR_BODY="${PR_BODY}"$'\n\n'
PR_BODY="${PR_BODY}This PR contains all changes that will be included in the next release. It is automatically updated when new changesets are added to the develop branch."
# Use jq to properly escape the content
PAYLOAD=$(jq -n --arg body "$PR_BODY" --arg title "$PR_TITLE" '{body: $body, title: $title}')
# For debugging
echo "API Payload:"
echo "$PAYLOAD" | jq '.'
# Update the PR
RESPONSE=$(curl -X PATCH \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
-H "Content-Type: application/json" \
"https://api.github.com/repos/${{ github.repository }}/pulls/${PR_NUMBER}" \
-d "$PAYLOAD")
# Print full response for debugging
echo "Full API Response:"
echo "$RESPONSE" | jq '.'
echo "Updated existing release PR #${PR_NUMBER} with latest changelog"
- name: Create new release PR
if: steps.check_pr.outputs.exists == 'false'
run: |
# Create the PR body with proper formatting
PR_BODY="## Upcoming Changes"
PR_BODY="${PR_BODY}"$'\n\n'
PR_BODY="${PR_BODY}$(cat /tmp/release-notes/temp_notes.md)"
PR_BODY="${PR_BODY}"$'\n\n'
PR_BODY="${PR_BODY}This PR contains all changes that will be included in the next release. It is automatically updated when new changesets are added to the develop branch."
# Use jq to properly escape the content
PAYLOAD=$(jq -n \
--arg title "release: next version 📦" \
--arg head "develop" \
--arg base "main" \
--arg body "$PR_BODY" \
'{title: $title, head: $head, base: $base, body: $body}')
# For debugging
echo "API Payload:"
echo "$PAYLOAD" | jq '.'
# Create a new PR from develop to main
RESPONSE=$(curl -X POST \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
-H "Content-Type: application/json" \
"https://api.github.com/repos/${{ github.repository }}/pulls" \
-d "$PAYLOAD")
# Print full response for debugging
echo "Full API Response:"
echo "$RESPONSE" | jq '.'
# Check for error messages
ERROR_MESSAGE=$(echo "$RESPONSE" | jq -r '.message // "No error message"')
if [[ "$ERROR_MESSAGE" != "No error message" ]]; then
echo "Error creating PR: $ERROR_MESSAGE"
# Check for more detailed errors
ERRORS=$(echo "$RESPONSE" | jq -r '.errors // []')
if [[ "$ERRORS" != "[]" ]]; then
echo "Detailed errors: $ERRORS"
fi
exit 1
fi
PR_NUMBER=$(echo "$RESPONSE" | jq -r '.number')
if [[ -z "$PR_NUMBER" || "$PR_NUMBER" == "null" ]]; then
echo "Failed to create PR. No PR number returned."
exit 1
else
echo "Created new release PR #${PR_NUMBER} with initial changelog"
fi