-
Notifications
You must be signed in to change notification settings - Fork 0
Add GH action to auto generate blog post from release notes #56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Reshrahim
wants to merge
55
commits into
main
Choose a base branch
from
autogen
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
55 commits
Select commit
Hold shift + click to select a range
e61a30b
Add GH actions and prompt
Reshrahim 25d62b5
Add GH actions and prompt
Reshrahim d1e5c98
Update prompt
Reshrahim 937928d
Update the workflow to auto trigger after release
Reshrahim 8dbb64b
Remove contrib guide
Reshrahim 976f7f9
Upd blog prompt
Reshrahim 77521e5
Upd blog prompt
Reshrahim aa97a61
Upd blog prompt
Reshrahim 8bdfe86
Upd blog prompt
Reshrahim 18fdf82
Upd workflow to run on push to feature branch
Reshrahim 078f54e
Upd blog prompt
Reshrahim fe6e25d
Remove style refernce
Reshrahim c4b5f85
Parnetrize release url
Reshrahim fe2f347
Follow style guide exactly
Reshrahim 937b9ff
Cleanup yaml
Reshrahim b26c5c4
fix awk yaml
Reshrahim 0ae3ce0
Stricter guidance on yaml
Reshrahim 1102e1d
Stricter guidance on yaml
Reshrahim 069476d
log formatting rules
Reshrahim cf8dd77
add AI post processing for style guide compliance
Reshrahim 00ab2b2
add AI post processing for style guide compliance
Reshrahim dfb6178
Clean AI post processing for style guide compliance
Reshrahim 9abfeb0
Update model for tighter post processing
Reshrahim a254f8d
Update model to claude to see results
Reshrahim 5630b90
Update model to claude to see results
Reshrahim 37d81ba
Test wioth grok3
Reshrahim aaed609
Test with post processing
Reshrahim ecb490e
Test with post processing shell scripting'
Reshrahim de946e1
Test with post processing shell scripting'
Reshrahim 1840996
Merge branch 'main' into autogen
Reshrahim baad326
Remove intermeiate files
Reshrahim f5fab9f
Merge branch 'autogen' of https://github.com/radius-project/blog into…
Reshrahim 6262a20
Remove intermeiate files
Reshrahim d7e941d
Uodate prompt
Reshrahim d540baa
Scripting the steps in workflow
Reshrahim 073a75a
Delete scripts/temp_style_guide.md
Reshrahim 4d558a5
Delete scripts/release_body.md
Reshrahim 1f41ec9
Scripting PR creation
Reshrahim ada1ff9
Merge branch 'autogen' of https://github.com/radius-project/blog into…
Reshrahim 170906e
Fix error with workflow
Reshrahim bec8574
Merge branch 'main' into autogen
Reshrahim 950b78c
Reduce scripts
Reshrahim 04b5250
Merge branch 'autogen' of https://github.com/radius-project/blog into…
Reshrahim 4954436
make it as one script
Reshrahim 73dd238
log event
Reshrahim 2aca8a5
test empty tag logic
Reshrahim 265c0a4
Separate release tag
Reshrahim 908b483
Revert release blog
Reshrahim 022072c
Remove space
Reshrahim cc71b50
Merge branch 'main' into autogen
Reshrahim 68088d5
Merge branch 'main' into autogen
Reshrahim c4cb376
Merge branch 'main' into autogen
Reshrahim 92d9135
Apply suggestions from code review
Reshrahim b74e16d
Apply suggestions from code review
Reshrahim 9b762f4
Apply suggestions from code review
Reshrahim File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| name: Auto-generate Blog Post for New Radius Release | ||
|
|
||
| on: | ||
| repository_dispatch: | ||
| types: [radius-release-published] | ||
| workflow_dispatch: | ||
| inputs: | ||
| tag_name: | ||
| description: 'Release tag name (optional - will use latest if not provided)' | ||
| required: false | ||
| type: string | ||
| push: | ||
| branches: | ||
| - 'autogen' | ||
|
|
||
| jobs: | ||
| generate-blog-post: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| - name: Determine release tag | ||
| run: | | ||
| # Get release tag from event or use latest | ||
| INPUT_TAG="${{ github.event.client_payload.tag_name || github.event.inputs.tag_name || '' }}" | ||
|
|
||
| if [ -z "$INPUT_TAG" ]; then | ||
| echo "No tag provided, getting latest release..." | ||
| RELEASE_TAG=$(curl -s "https://api.github.com/repos/radius-project/radius/releases/latest" | jq -r '.tag_name') | ||
| else | ||
| RELEASE_TAG="$INPUT_TAG" | ||
| fi | ||
|
|
||
| echo "Using release tag: $RELEASE_TAG" | ||
| echo "RELEASE_TAG=$RELEASE_TAG" >> $GITHUB_ENV | ||
|
|
||
| - name: Generate blog post | ||
| run: | | ||
| # Generate complete blog post using determined tag | ||
| ./scripts/generate-blog-post.sh "${{ env.RELEASE_TAG }}" "${{ secrets.GITHUB_TOKEN }}" | ||
|
|
||
| - name: Create Pull Request | ||
| uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 | ||
| with: | ||
| token: ${{ secrets.GH_RAD_CI_BOT_PAT }} | ||
| commit-message: "Add blog post for Radius ${{ env.RELEASE_TAG }}" | ||
| signoff: true | ||
| title: "Add blog post for Radius ${{ env.RELEASE_TAG }}" | ||
| body: | | ||
| Auto-generated blog post for **Radius ${{ env.RELEASE_TAG }}** | ||
|
|
||
| - **Tag:** ${{ env.RELEASE_TAG }} | ||
| - **Release:** https://github.com/radius-project/radius/releases/tag/${{ env.RELEASE_TAG }} | ||
|
|
||
| 🤖 Generated automatically by GitHub Actions | ||
| branch: "blog-post-${{ env.RELEASE_TAG }}" | ||
| base: main | ||
| delete-branch: true |
This file contains hidden or 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
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| Write a technical blog post announcing Radius {RELEASE_NAME} for developers and platform engineers. | ||
|
|
||
| Release notes (YOUR ONLY SOURCE OF TRUTH): | ||
| {RELEASE_NOTES} | ||
|
|
||
| CRITICAL CONTENT CONSTRAINTS - FOLLOW EXACTLY: | ||
| - ONLY use information explicitly stated in the release notes above | ||
| - Do NOT add any information not found in the release notes | ||
| - Do NOT make up features, examples, or documentation links not present in the release notes | ||
| - ABSOLUTELY NO CODE SNIPPETS unless they are copy-pasted directly from the release notes | ||
| - DO NOT create example code, sample configurations, or illustrative commands | ||
| - DO NOT include breaking changes as a separate section | ||
| - DO NOT speculate about future features or capabilities | ||
| - ONLY include links that are explicitly mentioned in the release notes | ||
| - If no code examples exist in release notes, describe features in text only | ||
| - Verify the content thoroughly and ensure all details are accurate | ||
|
|
||
| CRITICAL STYLE CONSTRAINTS - FOLLOW EXACTLY: | ||
| {STYLE_GUIDE} | ||
|
|
||
| STRUCTURE REQUIREMENTS: | ||
| - Start immediately with introductory content, NO heading. | ||
| - Summarize the release, include a link to the release notes at {RELEASE_URL} and for new users, provide guidance on how to get started with Radius. | ||
| - Use ## headings for main features (not # headings) and summarize each feature in a concise paragraph. Include details from the linked documentation if relevant. | ||
| - Feature summary should have breaking changes as a highlight within, not a separate section | ||
| - End with the exact "Learn more and Get Involved" section below | ||
|
|
||
| REQUIRED CLOSING SECTION (copy exactly): | ||
|
|
||
| ## Learn More and Get Involved | ||
|
|
||
| We would love for you to join us to help build Radius: | ||
|
|
||
| - Try the [Radius Tutorial](https://docs.radapp.io/tutorials/) | ||
| - Checkout the Radius roadmap and influence future features at [https://aka.ms/radius-roadmap](https://aka.ms/radius-roadmap) | ||
| - Join our monthly community meeting to see demos and hear the latest updates (join the [Radius Google Group](https://groups.google.com/g/radapp_io) to get email announcements) | ||
| - Join the discussion or ask for help on the [Radius Discord server](https://aka.ms/radius/discord) | ||
| - Subscribe to the [Radius YouTube channel](https://www.youtube.com/@radapp_io) for more demos | ||
|
|
||
| Generate only the blog content (no frontmatter). Be technical, be specific, avoid fluff, check for grammatical and spelling mistakes |
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| #!/bin/bash | ||
| set -e | ||
|
|
||
| # Script to generate complete blog post from release tag | ||
| # Usage: ./generate-blog-post.sh <release_tag> <github_token> | ||
| # Outputs: Complete blog post in radblog/content/posts/ | ||
|
|
||
| RELEASE_TAG="$1" | ||
| GITHUB_TOKEN="$2" | ||
|
|
||
| if [ -z "$RELEASE_TAG" ] || [ -z "$GITHUB_TOKEN" ]; then | ||
| echo "Usage: $0 <release_tag> <github_token>" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "Generating blog post for Radius $RELEASE_TAG..." | ||
|
|
||
| # Cleanup temporary files on exit | ||
| trap 'rm -f prompt_template.md final_prompt.md temp_style_guide.txt temp_release_notes.txt release_body.md' EXIT | ||
|
|
||
| # ============================================================================= | ||
| # PREPROCESSING: Gather data | ||
| # ============================================================================= | ||
| echo "=== PREPROCESSING: Gathering data ===" | ||
|
|
||
| # Get release data | ||
| RELEASE_DATA=$(curl -s "https://api.github.com/repos/radius-project/radius/releases/tags/$RELEASE_TAG") | ||
| RELEASE_BODY=$(echo "$RELEASE_DATA" | jq -r '.body') | ||
| PUBLISHED_AT=$(echo "$RELEASE_DATA" | jq -r '.published_at') | ||
|
|
||
| # Load style guide | ||
| if [ -f "radblog/guide/contribution-guide.md" ]; then | ||
| FORMATTING_RULES=$(awk '/## Writing Guidelines/,/## Formatting Standards/ { if (!/## Formatting Standards/) print } /## Formatting Standards/,/## Submission Process/ { if (!/## Submission Process/) print }' "radblog/guide/contribution-guide.md") | ||
| STYLE_GUIDE=$(printf "CRITICAL FORMATTING REQUIREMENTS - THESE RULES ARE MANDATORY:\n%s\n\nCOMPLETE STYLE GUIDE:\n%s" "$FORMATTING_RULES" "$(cat "radblog/guide/contribution-guide.md")") | ||
| else | ||
| STYLE_GUIDE="WRITING GUIDELINES: Conversational, user-focused, technical depth, no marketing language, evidence-based content only from release notes." | ||
| fi | ||
|
|
||
| # Build AI prompt | ||
| cp scripts/blog-prompt.md prompt_template.md | ||
| sed -i.bak "s/{RELEASE_NAME}/Radius $RELEASE_TAG/g" prompt_template.md && rm -f prompt_template.md.bak | ||
| sed -i.bak "s|{RELEASE_URL}|https://github.com/radius-project/radius/releases/tag/$RELEASE_TAG|g" prompt_template.md && rm -f prompt_template.md.bak | ||
|
|
||
| echo "$STYLE_GUIDE" > temp_style_guide.txt | ||
| echo "$RELEASE_BODY" > temp_release_notes.txt | ||
|
|
||
| awk '/{RELEASE_NOTES}/ { while ((getline line < "temp_release_notes.txt") > 0) { print line } close("temp_release_notes.txt"); next } /{STYLE_GUIDE}/ { while ((getline line < "temp_style_guide.txt") > 0) { print line } close("temp_style_guide.txt"); next } /{BLOG_CONTEXT}/ { print "Previous Radius blog posts focus on technical features and developer workflows."; next } { print }' prompt_template.md > final_prompt.md | ||
|
|
||
| # ============================================================================= | ||
| # AI GENERATION: Generate content | ||
| # ============================================================================= | ||
| echo "=== AI GENERATION: Calling GitHub Models API ===" | ||
|
|
||
| RESPONSE=$(curl -s -X POST "https://models.inference.ai.azure.com/chat/completions" \ | ||
| -H "Content-Type: application/json" \ | ||
| -H "Authorization: Bearer $GITHUB_TOKEN" \ | ||
| -d "{\"model\": \"gpt-4o\", \"messages\": [{\"role\": \"system\", \"content\": \"You are a technical content writer for cloud-native application platforms. You MUST follow all formatting rules and style guidelines exactly as specified. Failure to follow formatting rules is not acceptable.\"}, {\"role\": \"user\", \"content\": \"$(cat final_prompt.md | sed 's/"/\\"/g' | tr '\n' ' ')\"}], \"max_tokens\": 3500, \"temperature\": 0.2}") | ||
|
|
||
| # ============================================================================= | ||
| # POST-PROCESSING: Create blog post | ||
| # ============================================================================= | ||
| echo "=== POST-PROCESSING: Creating blog post ===" | ||
|
|
||
| if echo "$RESPONSE" | jq -e '.choices[0].message.content' > /dev/null 2>&1; then | ||
| echo "$RESPONSE" | jq -r '.choices[0].message.content' > ai_content.md | ||
|
|
||
| # Apply style guide fixes | ||
| sed -i.bak 's/\bapplications\b/Applications/g' ai_content.md && rm -f ai_content.md.bak | ||
| sed -i.bak 's/\benvironments\b/Environments/g' ai_content.md && rm -f ai_content.md.bak | ||
| sed -i.bak 's/\brecipes\b/Recipes/g' ai_content.md && rm -f ai_content.md.bak | ||
| sed -i.bak 's/\bresource types\b/Resource Types/g' ai_content.md && rm -f ai_content.md.bak | ||
| sed -i.bak 's/ */ /g' ai_content.md && rm -f ai_content.md.bak | ||
|
|
||
| # Create blog directory | ||
| YEAR=$(date -d "$PUBLISHED_AT" "+%Y" 2>/dev/null || date -j -f "%Y-%m-%dT%H:%M:%SZ" "$PUBLISHED_AT" "+%Y") | ||
| BLOG_DIR="radblog/content/posts/$YEAR/radius-$RELEASE_TAG-release" | ||
| mkdir -p "$BLOG_DIR" | ||
|
|
||
| # Create blog post with frontmatter | ||
| BLOG_DATE=$(date -d "$PUBLISHED_AT" "+%Y-%m-%dT%H:%M:%S%z" 2>/dev/null || date -j -f "%Y-%m-%dT%H:%M:%SZ" "$PUBLISHED_AT" "+%Y-%m-%dT%H:%M:%S%z") | ||
|
|
||
| cat > "$BLOG_DIR/index.md" << EOF | ||
| --- | ||
| date: "$BLOG_DATE" | ||
| title: "Announcing Radius $RELEASE_TAG" | ||
| linkTitle: "Radius $RELEASE_TAG" | ||
| author: "Radius Team" | ||
| type: blog | ||
| --- | ||
|
|
||
| EOF | ||
|
|
||
| cat ai_content.md >> "$BLOG_DIR/index.md" | ||
| rm ai_content.md | ||
|
|
||
| echo "Blog post created successfully at: $BLOG_DIR/index.md" | ||
| echo "RELEASE_TAG=$RELEASE_TAG" | ||
| else | ||
| echo "AI generation failed, using fallback content" | ||
|
|
||
| # Create blog directory | ||
| YEAR=$(date +%Y) | ||
| BLOG_DIR="radblog/content/posts/$YEAR/radius-$RELEASE_TAG-release" | ||
| mkdir -p "$BLOG_DIR" | ||
|
|
||
| cat > "$BLOG_DIR/index.md" << EOF | ||
| --- | ||
| date: "$(date -u +%Y-%m-%dT%H:%M:%S%z)" | ||
| title: "Announcing Radius $RELEASE_TAG" | ||
| linkTitle: "Radius $RELEASE_TAG" | ||
| author: "Radius Team" | ||
| type: blog | ||
| --- | ||
|
|
||
| We're excited to announce the release of Radius $RELEASE_TAG! | ||
|
|
||
| For detailed information about this release, see the [release notes](https://github.com/radius-project/radius/releases/tag/$RELEASE_TAG). | ||
|
|
||
| ## Learn More and Get Involved | ||
|
|
||
| We would love for you to join us to help build Radius: | ||
|
|
||
| - Try the [Radius Tutorial](https://docs.radapp.io/tutorials/new-app/) | ||
| - Checkout the Radius roadmap and influence future features at [https://aka.ms/radius-roadmap](https://aka.ms/radius-roadmap) | ||
| - Join our monthly community meeting to see demos and hear the latest updates (join the [Radius Google Group](https://groups.google.com/g/radapp_io) to get email announcements) | ||
| - Join the discussion or ask for help on the [Radius Discord server](https://aka.ms/radius/discord) | ||
| - Subscribe to the [Radius YouTube channel](https://www.youtube.com/@radapp_io) for more demos | ||
| EOF | ||
|
|
||
| echo "Blog post created with fallback content at: $BLOG_DIR/index.md" | ||
| fi | ||
|
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great idea to jump start a blog post.
I have a suggestion: let's refactor all the shell commands that are embedded in the workflow yaml into individual shell scripts that can be tested on a developer machine. We have had a lot of experience on this team with bash commands embedded into GitHub workflows, and the result is a set of very brittle and difficult to maintain workflows. A main contributor to that problem is that the workflows cannot be easily written and debugged on a dev machine before publishing and running the workflow. That makes the dev/test loop very long.
There is a design doc here that describes a different way of implementing workflows. The design suggests using make commands that call shell scripts, and calling the make commands from the workflow steps. However, if make is overkill here we could just have shell scripts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Brooke for the pointer to make this better. I moved the blog generation part to a separate script. The release tag determination is still part of the workflow since that is required for the PR creation at the end. Let me know if you have suggestions to improve it. AI doesn't seem to give me a best approach there