Skip to content

Scheduled SEO Tasks #72

Scheduled SEO Tasks

Scheduled SEO Tasks #72

Workflow file for this run

name: Scheduled SEO Tasks
on:
schedule:
# Run daily at 2 AM UTC
- cron: '0 2 * * *'
workflow_dispatch:
jobs:
# =========================================
# Health Check - Skip if site not deployed
# =========================================
health-check:
name: Check Site Availability
runs-on: ubuntu-latest
outputs:
site_available: ${{ steps.check.outputs.available }}
steps:
- name: Check if production site is available
id: check
run: |
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://synthstack.app/ --max-time 30 || echo "000")
echo "HTTP Status: $HTTP_STATUS"
if [ "$HTTP_STATUS" = "200" ] || [ "$HTTP_STATUS" = "301" ] || [ "$HTTP_STATUS" = "302" ]; then
echo "available=true" >> $GITHUB_OUTPUT
echo "Site is available (HTTP $HTTP_STATUS)"
else
echo "available=false" >> $GITHUB_OUTPUT
echo "Site is not available (HTTP $HTTP_STATUS) - skipping SEO tasks"
fi
# =========================================
# Generate & Submit Sitemap
# =========================================
sitemap:
name: Update Sitemap
runs-on: ubuntu-latest
needs: health-check
if: needs.health-check.outputs.site_available == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Sitemap
run: pnpm --filter @synthstack/web generate:sitemap
continue-on-error: true
- name: Submit to Google Search Console
run: |
curl -s "https://www.google.com/ping?sitemap=https://synthstack.app/sitemap.xml" || true
- name: Submit to Bing Webmaster
run: |
curl -s "https://www.bing.com/ping?sitemap=https://synthstack.app/sitemap.xml" || true
- name: Submit to Yandex
run: |
curl -s "https://webmaster.yandex.com/ping?sitemap=https://synthstack.app/sitemap.xml" || true
# =========================================
# Check Broken Links
# =========================================
link-check:
name: Check Broken Links
runs-on: ubuntu-latest
needs: health-check
if: needs.health-check.outputs.site_available == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check for Broken Links
uses: lycheeverse/lychee-action@v1
with:
args: --verbose --no-progress 'https://synthstack.app/**/*.html'
fail: false
- name: Create Issue on Broken Links
if: env.lychee_exit_code != 0
uses: peter-evans/create-issue-from-file@v5
with:
title: Broken Links Detected
content-filepath: ./lychee/out.md
labels: seo, bug
# =========================================
# Performance & SEO Audit
# =========================================
lighthouse:
name: Lighthouse Audit
runs-on: ubuntu-latest
needs: health-check
if: needs.health-check.outputs.site_available == 'true'
continue-on-error: true
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Lighthouse
uses: treosh/lighthouse-ci-action@v11
with:
urls: |
https://synthstack.app
https://synthstack.app/features
https://synthstack.app/pricing
https://synthstack.app/about
https://synthstack.app/blog
budgetPath: ./apps/web/lighthouse-budget.json
uploadArtifacts: true
temporaryPublicStorage: true
- name: Check Performance Scores
run: |
# Parse lighthouse results and alert if scores drop below threshold
echo "Lighthouse audit complete"
# =========================================
# Monitor Core Web Vitals
# =========================================
web-vitals:
name: Check Core Web Vitals
runs-on: ubuntu-latest
needs: health-check
if: needs.health-check.outputs.site_available == 'true'
continue-on-error: true
steps:
- name: Check PageSpeed Insights
run: |
# Check key pages via PageSpeed Insights API
if [ -n "${{ secrets.GOOGLE_API_KEY }}" ]; then
curl -s "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=https://synthstack.app&strategy=mobile&key=${{ secrets.GOOGLE_API_KEY }}" | jq '.lighthouseResult.categories.performance.score' || echo "PageSpeed check skipped"
else
echo "GOOGLE_API_KEY not set - skipping PageSpeed Insights check"
fi
# =========================================
# Summary Job
# =========================================
summary:
name: SEO Tasks Summary
runs-on: ubuntu-latest
needs: [health-check, sitemap, link-check, lighthouse, web-vitals]
if: always()
steps:
- name: Report Status
run: |
echo "## SEO Tasks Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.health-check.outputs.site_available }}" = "true" ]; then
echo "Site was available - SEO tasks executed" >> $GITHUB_STEP_SUMMARY
echo "- Sitemap: ${{ needs.sitemap.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Link Check: ${{ needs.link-check.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Lighthouse: ${{ needs.lighthouse.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Web Vitals: ${{ needs.web-vitals.result }}" >> $GITHUB_STEP_SUMMARY
else
echo "Site was NOT available (503/unreachable) - SEO tasks skipped" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "This is expected if the production site is not yet deployed." >> $GITHUB_STEP_SUMMARY
fi