Skip to content
Open
Show file tree
Hide file tree
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 Sep 11, 2025
25d62b5
Add GH actions and prompt
Reshrahim Sep 11, 2025
d1e5c98
Update prompt
Reshrahim Sep 11, 2025
937928d
Update the workflow to auto trigger after release
Reshrahim Sep 11, 2025
8dbb64b
Remove contrib guide
Reshrahim Sep 11, 2025
976f7f9
Upd blog prompt
Reshrahim Sep 11, 2025
77521e5
Upd blog prompt
Reshrahim Sep 11, 2025
aa97a61
Upd blog prompt
Reshrahim Sep 12, 2025
8bdfe86
Upd blog prompt
Reshrahim Sep 12, 2025
18fdf82
Upd workflow to run on push to feature branch
Reshrahim Sep 12, 2025
078f54e
Upd blog prompt
Reshrahim Sep 12, 2025
fe6e25d
Remove style refernce
Reshrahim Sep 12, 2025
c4b5f85
Parnetrize release url
Reshrahim Sep 12, 2025
fe2f347
Follow style guide exactly
Reshrahim Sep 12, 2025
937b9ff
Cleanup yaml
Reshrahim Sep 12, 2025
b26c5c4
fix awk yaml
Reshrahim Sep 12, 2025
0ae3ce0
Stricter guidance on yaml
Reshrahim Sep 12, 2025
1102e1d
Stricter guidance on yaml
Reshrahim Sep 12, 2025
069476d
log formatting rules
Reshrahim Sep 12, 2025
cf8dd77
add AI post processing for style guide compliance
Reshrahim Sep 12, 2025
00ab2b2
add AI post processing for style guide compliance
Reshrahim Sep 12, 2025
dfb6178
Clean AI post processing for style guide compliance
Reshrahim Sep 12, 2025
9abfeb0
Update model for tighter post processing
Reshrahim Sep 12, 2025
a254f8d
Update model to claude to see results
Reshrahim Sep 12, 2025
5630b90
Update model to claude to see results
Reshrahim Sep 12, 2025
37d81ba
Test wioth grok3
Reshrahim Sep 12, 2025
aaed609
Test with post processing
Reshrahim Sep 12, 2025
ecb490e
Test with post processing shell scripting'
Reshrahim Sep 15, 2025
de946e1
Test with post processing shell scripting'
Reshrahim Sep 15, 2025
1840996
Merge branch 'main' into autogen
Reshrahim Sep 16, 2025
baad326
Remove intermeiate files
Reshrahim Sep 17, 2025
f5fab9f
Merge branch 'autogen' of https://github.com/radius-project/blog into…
Reshrahim Sep 17, 2025
6262a20
Remove intermeiate files
Reshrahim Sep 17, 2025
d7e941d
Uodate prompt
Reshrahim Sep 17, 2025
d540baa
Scripting the steps in workflow
Reshrahim Sep 24, 2025
073a75a
Delete scripts/temp_style_guide.md
Reshrahim Sep 24, 2025
4d558a5
Delete scripts/release_body.md
Reshrahim Sep 24, 2025
1f41ec9
Scripting PR creation
Reshrahim Sep 24, 2025
ada1ff9
Merge branch 'autogen' of https://github.com/radius-project/blog into…
Reshrahim Sep 24, 2025
170906e
Fix error with workflow
Reshrahim Sep 24, 2025
bec8574
Merge branch 'main' into autogen
Reshrahim Sep 24, 2025
950b78c
Reduce scripts
Reshrahim Sep 24, 2025
04b5250
Merge branch 'autogen' of https://github.com/radius-project/blog into…
Reshrahim Sep 24, 2025
4954436
make it as one script
Reshrahim Sep 24, 2025
73dd238
log event
Reshrahim Sep 24, 2025
2aca8a5
test empty tag logic
Reshrahim Sep 24, 2025
265c0a4
Separate release tag
Reshrahim Sep 24, 2025
908b483
Revert release blog
Reshrahim Sep 24, 2025
022072c
Remove space
Reshrahim Sep 24, 2025
cc71b50
Merge branch 'main' into autogen
Reshrahim Oct 13, 2025
68088d5
Merge branch 'main' into autogen
Reshrahim Nov 17, 2025
c4cb376
Merge branch 'main' into autogen
Reshrahim Dec 17, 2025
92d9135
Apply suggestions from code review
Reshrahim Dec 17, 2025
b74e16d
Apply suggestions from code review
Reshrahim Dec 17, 2025
9b762f4
Apply suggestions from code review
Reshrahim Dec 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/auto-blog-post.yaml
Copy link
Member

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.

Copy link
Contributor Author

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

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
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ We would love for you to join us to help build Radius:
- 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
- Subscribe to the [Radius YouTube channel](https://www.youtube.com/@radapp_io) for more demos
40 changes: 40 additions & 0 deletions scripts/blog-prompt.md
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
132 changes: 132 additions & 0 deletions scripts/generate-blog-post.sh
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

Loading