tpmjs/.github/workflows/sync-keyword.yml
Ajax Davis fcd6667357 feat: add author name to skipped packages in Discord notifications
API Changes:
- Track author name along with package name and reason
- Extract author from pkg.author (string or object with name field)
- Default to "unknown" if author info not available

Workflow Changes:
- Display author in format: "package-name (by author) - reason"

Example Discord output:
📋 Skipped Packages
tpmjs-threejs-tool (by john-doe) - invalid tpmjs field
@scope/package-1 (by jane-smith) - missing tpmjs field

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 09:18:16 +10:00

131 lines
5.7 KiB
YAML

name: Sync NPM Keyword Search
on:
schedule:
# Run every 15 minutes
- cron: '*/15 * * * *'
workflow_dispatch:
jobs:
sync-keyword:
runs-on: ubuntu-latest
steps:
- name: Trigger keyword search sync
id: sync
run: |
# Call the sync API and capture response
response=$(curl -X POST "${{ secrets.VERCEL_PRODUCTION_URL }}/api/sync/keyword" \
-H "Authorization: Bearer ${{ secrets.CRON_SECRET }}" \
-H "Content-Type: application/json" \
-f -s -S)
echo "Response: $response"
# Extract data using jq
processed=$(echo "$response" | jq -r '.data.processed')
skipped=$(echo "$response" | jq -r '.data.skipped')
errors=$(echo "$response" | jq -r '.data.errors')
packagesFound=$(echo "$response" | jq -r '.data.packagesFound')
durationMs=$(echo "$response" | jq -r '.data.durationMs')
# Extract and display error messages
errorMessages=$(echo "$response" | jq -r '.data.errorMessages[]?' 2>/dev/null || echo "")
if [ -n "$errorMessages" ]; then
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "⚠️ SYNC ERRORS ($errors total):"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "$response" | jq -r '.data.errorMessages[]?' | while IFS= read -r error; do
echo " • $error"
done
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
fi
# Set outputs for Discord notification
echo "processed=$processed" >> $GITHUB_OUTPUT
echo "skipped=$skipped" >> $GITHUB_OUTPUT
echo "errors=$errors" >> $GITHUB_OUTPUT
echo "packagesFound=$packagesFound" >> $GITHUB_OUTPUT
echo "durationMs=$durationMs" >> $GITHUB_OUTPUT
# Store error messages for Discord (first 3, truncated)
if [ "$errors" -gt 0 ]; then
errorSummary=$(echo "$response" | jq -r '.data.errorMessages[0:3]? | join("\n• ")' 2>/dev/null || echo "")
if [ -n "$errorSummary" ]; then
# Save to file to preserve newlines
echo "• $errorSummary" > /tmp/error_summary.txt
fi
fi
# Store skipped packages for Discord
if [ "$skipped" -gt 0 ]; then
skippedList=$(echo "$response" | jq -r '.data.skippedPackages[]? | "\(.name) (by \(.author)) - \(.reason)"' 2>/dev/null | paste -sd "\n" - || echo "")
if [ -n "$skippedList" ]; then
echo "$skippedList" > /tmp/skipped_packages.txt
fi
fi
# Determine status emoji
if [ "$errors" -gt 0 ]; then
echo "status_emoji=⚠️" >> $GITHUB_OUTPUT
echo "status_color=16776960" >> $GITHUB_OUTPUT # Yellow
else
echo "status_emoji=✅" >> $GITHUB_OUTPUT
echo "status_color=5763719" >> $GITHUB_OUTPUT # Green
fi
- name: Send Discord notification
if: always()
run: |
# Format duration
duration_sec=$(echo "scale=2; ${{ steps.sync.outputs.durationMs }} / 1000" | bc)
# Build Discord payload using jq for proper JSON escaping
# Read optional data
error_text=""
skipped_text=""
if [ -f /tmp/error_summary.txt ] && [ ${{ steps.sync.outputs.errors }} -gt 0 ]; then
error_text=$(cat /tmp/error_summary.txt | head -c 800)
fi
if [ -f /tmp/skipped_packages.txt ] && [ ${{ steps.sync.outputs.skipped }} -gt 0 ]; then
skipped_text=$(cat /tmp/skipped_packages.txt)
fi
# Build fields array dynamically
base_fields='[
{ "name": "📦 Packages Found", "value": "${{ steps.sync.outputs.packagesFound }}", "inline": true },
{ "name": "✨ Processed", "value": "${{ steps.sync.outputs.processed }}", "inline": true },
{ "name": "⏭️ Skipped", "value": "${{ steps.sync.outputs.skipped }}", "inline": true },
{ "name": "❌ Errors", "value": "${{ steps.sync.outputs.errors }}", "inline": true },
{ "name": "⏱️ Duration", "value": "'"${duration_sec}s"'", "inline": true },
{ "name": "🔗 Run", "value": "[View Logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})", "inline": true }
]'
# Create payload with dynamic fields
payload=$(jq -n \
--arg title "${{ steps.sync.outputs.status_emoji }} NPM Keyword Search Sync" \
--argjson color ${{ steps.sync.outputs.status_color }} \
--argjson baseFields "$base_fields" \
--arg error_text "$error_text" \
--arg skipped_text "$skipped_text" \
--arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)" \
'
{
embeds: [{
title: $title,
color: $color,
fields: (
$baseFields +
(if $skipped_text != "" then [{ name: "📋 Skipped Packages", value: $skipped_text, inline: false }] else [] end) +
(if $error_text != "" then [{ name: "🔍 Error Details", value: ("```\n" + $error_text + "\n```"), inline: false }] else [] end)
),
timestamp: $timestamp
}]
}')
# Send to Discord
curl -X POST "${{ secrets.DISCORD_WEBHOOK }}" \
-H "Content-Type: application/json" \
-d "$payload"