mirror of
https://github.com/kemalai/FreeCrawl-SEO-Tool.git
synced 2026-10-18 00:39:38 +02:00
105 lines
3.8 KiB
YAML
105 lines
3.8 KiB
YAML
# FreeCrawl SEO — example GitHub Actions workflow
|
|
#
|
|
# Crawls your site with the headless CLI on every push and on a daily
|
|
# schedule, fails the build when broken links exceed a threshold, validates
|
|
# the sitemap, and uploads the crawl as a build artifact. Adapt TARGET_URL
|
|
# and the thresholds to your site.
|
|
#
|
|
# Save this as `.github/workflows/freecrawl-audit.yml` in your own repo.
|
|
# No FreeCrawl install is required on the runner — the workflow clones the
|
|
# source and builds the CLI (plus its workspace packages) from it.
|
|
#
|
|
# See docs/ci/README.md for the CLI exit-code contract, a zero-tolerance
|
|
# (no-script) gate variant, and how to add a regression-compare job.
|
|
|
|
name: FreeCrawl SEO Audit
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
schedule:
|
|
- cron: '0 4 * * *' # 04:00 UTC daily
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
TARGET_URL: https://example.com
|
|
MAX_URLS: '5000'
|
|
BROKEN_LINK_THRESHOLD: '10'
|
|
|
|
jobs:
|
|
audit:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
repository: kemalai/FreeCrawl-SEO-Tool
|
|
path: freecrawl
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '22'
|
|
cache: npm
|
|
cache-dependency-path: freecrawl/package-lock.json
|
|
|
|
- name: Install + build CLI
|
|
working-directory: freecrawl
|
|
run: |
|
|
# --ignore-scripts skips the Playwright browser download; the CLI's
|
|
# default crawl is undici-based and needs no Chromium. Drop the flag
|
|
# only if you enable JS rendering through a --config file.
|
|
npm ci --ignore-scripts
|
|
# Build the CLI and its workspace deps (shared-types → db → core) in
|
|
# dependency order via project references. The heavy Electron desktop
|
|
# build is intentionally skipped — `npm run build:cli` alone would
|
|
# NOT build the packages the CLI imports and the crawl would fail.
|
|
npx tsc -b apps/cli
|
|
|
|
- name: Crawl ${{ env.TARGET_URL }}
|
|
working-directory: freecrawl
|
|
run: |
|
|
# --json prints a machine-readable summary to stdout (captured for
|
|
# the gate); --out writes the full per-URL dump for the artifact.
|
|
# `|| true` hands pass/fail to the threshold gate below — the CLI
|
|
# itself exits 1 on ANY 4xx/5xx (see the zero-tolerance variant in
|
|
# docs/ci/README.md).
|
|
node apps/cli/dist/index.js "$TARGET_URL" \
|
|
--max "$MAX_URLS" \
|
|
--json \
|
|
--out "$GITHUB_WORKSPACE/crawl.json" \
|
|
> "$GITHUB_WORKSPACE/summary.json" || true
|
|
cat "$GITHUB_WORKSPACE/summary.json"
|
|
|
|
- name: Gate on broken links
|
|
run: |
|
|
# Count 4xx/5xx from the summary's byStatus map — robust against the
|
|
# full dump's column layout, and cheap (no multi-MB file parse).
|
|
BROKEN=$(node -e "
|
|
const s = require('$GITHUB_WORKSPACE/summary.json');
|
|
const by = (s.summary && s.summary.byStatus) || {};
|
|
let n = 0;
|
|
for (const [code, count] of Object.entries(by)) {
|
|
if (Number(code) >= 400) n += count;
|
|
}
|
|
console.log(n);
|
|
")
|
|
echo "Broken-URL count: $BROKEN (threshold: $BROKEN_LINK_THRESHOLD)"
|
|
if [ "$BROKEN" -gt "$BROKEN_LINK_THRESHOLD" ]; then
|
|
echo "::error::Broken-URL count $BROKEN exceeds threshold $BROKEN_LINK_THRESHOLD"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Validate sitemap (non-blocking)
|
|
working-directory: freecrawl
|
|
continue-on-error: true
|
|
run: node apps/cli/dist/index.js validate-sitemap "$TARGET_URL/sitemap.xml"
|
|
|
|
- uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: freecrawl-audit-${{ github.run_number }}
|
|
path: |
|
|
crawl.json
|
|
summary.json
|
|
retention-days: 30
|