Skip to content

Commit ef5cb3f

Browse files
committed
feat: implement content sync workflow with summary reporting and README badge updates
1 parent dd28561 commit ef5cb3f

1 file changed

Lines changed: 193 additions & 0 deletions

File tree

.github/workflows/content-sync.yml

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
name: Content Sync
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths: ['Content/**']
7+
workflow_dispatch:
8+
schedule:
9+
- cron: '0 0 * * *' # Run daily at midnight UTC
10+
11+
jobs:
12+
sync-content:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: write
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Count Content Articles
21+
id: count-articles
22+
shell: pwsh
23+
run: |
24+
$count = (Get-ChildItem -Path "Content" -Recurse -File -Filter "*.md").Count
25+
"article-count=$count" >> $env:GITHUB_OUTPUT
26+
27+
- uses: actions/setup-dotnet@v4
28+
with:
29+
dotnet-version: '9.0.x'
30+
31+
- name: Build ContentLoader
32+
run: dotnet build ContentLoader/ContentLoader.csproj --configuration Release
33+
34+
- name: Upload Content
35+
id: upload-content
36+
env:
37+
AZURE_STORAGE_CONNECTION_STRING: ${{ secrets.CONTENT_STORAGE_CONNECTION_STRING }}
38+
run: |
39+
# Capture the output from the ContentLoader
40+
output=$(dotnet run --project ContentLoader/ContentLoader.csproj --configuration Release -- Content 2>&1)
41+
echo "$output"
42+
43+
# Extract sync summary numbers using grep and sed
44+
added=$(echo "$output" | grep "Added:" | sed 's/Added: *\([0-9]*\)/\1/')
45+
updated=$(echo "$output" | grep "Updated:" | sed 's/Updated: *\([0-9]*\)/\1/')
46+
unchanged=$(echo "$output" | grep "Unchanged:" | sed 's/Unchanged: *\([0-9]*\)/\1/')
47+
failed=$(echo "$output" | grep "Failed:" | sed 's/Failed: *\([0-9]*\)/\1/')
48+
total=$(echo "$output" | grep "Total:" | sed 's/Total: *\([0-9]*\)/\1/')
49+
50+
# Set outputs for the next steps
51+
echo "added=$added" >> $GITHUB_OUTPUT
52+
echo "updated=$updated" >> $GITHUB_OUTPUT
53+
echo "unchanged=$unchanged" >> $GITHUB_OUTPUT
54+
echo "failed=$failed" >> $GITHUB_OUTPUT
55+
echo "total=$total" >> $GITHUB_OUTPUT
56+
57+
# Check if upload failed
58+
if [ "$failed" != "0" ]; then
59+
echo "Content upload failed with $failed failures"
60+
exit 1
61+
fi
62+
63+
- name: Create Content Sync Summary
64+
if: always()
65+
run: |
66+
# Create a beautiful summary with emojis and markdown formatting
67+
cat >> $GITHUB_STEP_SUMMARY << 'EOF'
68+
## 📝 Content Sync Report
69+
70+
| Status | Count | Description |
71+
|--------|-------|-------------|
72+
| ✅ Added | ${{ steps.upload-content.outputs.added }} | New content files uploaded |
73+
| 🔄 Updated | ${{ steps.upload-content.outputs.updated }} | Existing content updated |
74+
| ⚪ Unchanged | ${{ steps.upload-content.outputs.unchanged }} | Files with no changes |
75+
| ❌ Failed | ${{ steps.upload-content.outputs.failed }} | Upload failures |
76+
| 📊 **Total** | **${{ steps.upload-content.outputs.total }}** | **Total files processed** |
77+
78+
### 🎯 Summary
79+
80+
- **Success Rate**: $(( (${{ steps.upload-content.outputs.total }} - ${{ steps.upload-content.outputs.failed }}) * 100 / ${{ steps.upload-content.outputs.total }} ))%
81+
- **Content Articles**: ${{ steps.count-articles.outputs.article-count }} total files in repository
82+
- **Sync Status**: ${{ steps.upload-content.outputs.failed == '0' && '🟢 All Good!' || '🔴 Some Issues' }}
83+
84+
> 🚀 **Copilot That Jawn** content is now synced and ready to help developers level up their AI game!
85+
EOF
86+
87+
- name: Refresh Web App Cache
88+
if: success()
89+
env:
90+
CACHE_REFRESH_API_KEY: ${{ secrets.CACHE_REFRESH_API_KEY }}
91+
run: |
92+
echo "Refreshing web application cache..."
93+
# Wait a moment for the content to be fully uploaded
94+
sleep 5
95+
96+
# Call the cache refresh endpoint with API key authentication
97+
response=$(curl -s -w "%{http_code}" -X POST "https://copilotthatjawn.com/api/cache/refresh" \
98+
-H "X-API-Key: $CACHE_REFRESH_API_KEY" \
99+
-o /tmp/cache_response.json)
100+
101+
if [ "$response" = "200" ]; then
102+
echo "Cache refresh successful"
103+
cat /tmp/cache_response.json
104+
else
105+
echo "Cache refresh failed with HTTP status: $response"
106+
cat /tmp/cache_response.json || echo "No response body"
107+
# Don't fail the workflow if cache refresh fails - it's not critical
108+
echo "Continuing workflow despite cache refresh failure..."
109+
fi
110+
111+
- name: Handle Failure
112+
if: failure()
113+
run: |
114+
echo "Content sync failed. Check the build output and Azure Storage connection string."
115+
exit 1
116+
117+
- name: Update README Badges
118+
if: success()
119+
shell: pwsh
120+
run: |
121+
$date = Get-Date -Format "yyyy--MM--dd"
122+
$articleCount = "${{ steps.count-articles.outputs.article-count }}"
123+
124+
# Create badge URLs using shields.io
125+
$lastUpdateBadge = "![Content Last Updated](https://img.shields.io/badge/Content%20Last%20Updated-${date}-blue)"
126+
$articleCountBadge = "![Content Articles](https://img.shields.io/badge/Content%20Articles-${articleCount}-green)"
127+
128+
# Read current README content
129+
$readmeContent = Get-Content README.md -Raw
130+
131+
# Replace existing badges or add new ones at the top of the file
132+
$badgeSection = "${lastUpdateBadge}`n${articleCountBadge}`n"
133+
134+
if ($readmeContent -match "!\[Content Last Updated\].*`n!\[Content Articles\].*`n") {
135+
$readmeContent = $readmeContent -replace "!\[Content Last Updated\].*`n!\[Content Articles\].*`n", $badgeSection
136+
} else {
137+
$readmeContent = $badgeSection + $readmeContent
138+
}
139+
140+
# Write updated content back to README
141+
$readmeContent | Set-Content README.md -NoNewline
142+
143+
- name: Commit README Changes
144+
if: success()
145+
run: |
146+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
147+
git config --local user.name "github-actions[bot]"
148+
git add README.md
149+
git commit -m "docs: update content sync badges [skip ci]" || exit 0
150+
git push
151+
152+
- name: Comment on PR
153+
if: github.event_name == 'pull_request' && always()
154+
uses: actions/github-script@v7
155+
with:
156+
script: |
157+
const added = '${{ steps.upload-content.outputs.added }}';
158+
const updated = '${{ steps.upload-content.outputs.updated }}';
159+
const unchanged = '${{ steps.upload-content.outputs.unchanged }}';
160+
const failed = '${{ steps.upload-content.outputs.failed }}';
161+
const total = '${{ steps.upload-content.outputs.total }}';
162+
const success = failed === '0';
163+
164+
const successRate = total > 0 ? Math.round(((total - failed) * 100) / total) : 0;
165+
166+
const body = `## 📝 Content Sync Results
167+
168+
| Status | Count | Description |
169+
|--------|-------|-------------|
170+
| ✅ Added | ${added} | New content files uploaded |
171+
| 🔄 Updated | ${updated} | Existing content updated |
172+
| ⚪ Unchanged | ${unchanged} | Files with no changes |
173+
| ❌ Failed | ${failed} | Upload failures |
174+
| 📊 **Total** | **${total}** | **Total files processed** |
175+
176+
### 🎯 Results Summary
177+
178+
- **Success Rate**: ${successRate}%
179+
- **Sync Status**: ${success ? '🟢 All content synced successfully!' : '🔴 Some content failed to sync'}
180+
181+
${success
182+
? '> 🚀 **Great job!** All content changes have been successfully synced to the cloud storage.'
183+
: `> ⚠️ **Attention needed:** ${failed} file(s) failed to sync. Please check the workflow logs for details.`
184+
}
185+
186+
*This comment was automatically generated by the Content Sync workflow.*`;
187+
188+
github.rest.issues.createComment({
189+
issue_number: context.issue.number,
190+
owner: context.repo.owner,
191+
repo: context.repo.repo,
192+
body: body
193+
});

0 commit comments

Comments
 (0)