mirror of
https://github.com/KytyPS5/kytyps5.github.io.git
synced 2026-10-09 08:49:37 -07:00
148 lines
5.9 KiB
YAML
148 lines
5.9 KiB
YAML
name: CI
|
|
|
|
# Two gate levels keep report PRs cheap:
|
|
# - Report-only PRs (from compat-report.yml — changes limited to
|
|
# src/content/compat/**, public/screenshots/** or public/data/**) run only
|
|
# npm ci + typecheck + report validation. Report merges don't rebuild the
|
|
# site (deploy.yml republishes with fresh runtime data), so a full build
|
|
# and test suite add nothing on the PR branch.
|
|
# - Everything else (code, scripts, games database, pushes to main) runs the
|
|
# full pipeline: typecheck, tests, report validation and the production
|
|
# build (prebuild also regenerates the GitHub snapshot + compat JSONs).
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
|
|
permissions:
|
|
contents: read
|
|
issues: write
|
|
pull-requests: write
|
|
actions: write
|
|
|
|
concurrency:
|
|
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
# Full history so report-only PRs can be detected by diffing against
|
|
# the PR base (same allowlist as deploy.yml's content-only scope).
|
|
fetch-depth: 0
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
cache: npm
|
|
|
|
- name: Detect change scope
|
|
id: scope
|
|
shell: bash
|
|
env:
|
|
EVENT_NAME: ${{ github.event_name }}
|
|
BASE: ${{ github.event.pull_request.base.sha }}
|
|
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
run: |
|
|
# Pushes to main are always the full pipeline.
|
|
if [ "$EVENT_NAME" = "push" ]; then
|
|
echo "scope=full" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
if [ -z "$BASE" ] || [ -z "$HEAD_SHA" ]; then
|
|
echo "::warning::Missing PR base or head SHA; treating as full."
|
|
echo "scope=full" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
CHANGED="$(git diff --name-only "$BASE" "$HEAD_SHA" 2>/dev/null || true)"
|
|
if [ -z "$CHANGED" ]; then
|
|
echo "scope=full" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
# Report-only = every changed file is a compat report, a screenshot
|
|
# or generated data (mirrors deploy.yml). Anything else → full.
|
|
if printf '%s\n' "$CHANGED" | grep -vqE '^(src/content/compat/|public/screenshots/|public/data/)'; then
|
|
echo "scope=full" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "scope=report" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- run: npm ci
|
|
|
|
- run: npm run typecheck
|
|
|
|
# Report validation is cheap and dependency-free — gate it on every run.
|
|
- name: Validate compatibility reports
|
|
run: node scripts/validate-compat.mjs
|
|
|
|
- name: Validate compatibility exports & sitemap
|
|
run: |
|
|
node scripts/export-compat-json.mjs
|
|
node scripts/export-site-compat-json.mjs
|
|
node scripts/generate-sitemap.mjs
|
|
|
|
- name: Test
|
|
if: steps.scope.outputs.scope != 'report'
|
|
env:
|
|
CHECK_SEED_SYNC: ${{ github.head_ref == 'data/games-refresh' }}
|
|
run: npm test
|
|
|
|
# prebuild validates compat reports and regenerates the GitHub snapshot,
|
|
# the GUI + site compat JSON and the sitemap (GITHUB_TOKEN avoids rate
|
|
# limits on the API fetches). Skipped for report-only PRs — report merges
|
|
# don't rebuild the site, so the full build adds nothing on the branch.
|
|
- name: Build
|
|
if: steps.scope.outputs.scope != 'report'
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: npm run build
|
|
|
|
- name: Reopen mirror issue if tests failed on a compat PR
|
|
if: failure() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && startsWith(github.head_ref, 'compat/')
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
GH_REPO: ${{ github.repository }}
|
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
PR_BODY: ${{ github.event.pull_request.body }}
|
|
run: |
|
|
gh pr merge "$PR_NUMBER" --disable-auto || true
|
|
ISSUE_NUM="$(printf '%s' "$PR_BODY" | sed -n 's/.*<!-- mirror-issue: \([0-9]\+\) -->.*/\1/p' | head -1)"
|
|
if [ -n "$ISSUE_NUM" ]; then
|
|
gh issue reopen "$ISSUE_NUM" || true
|
|
gh issue comment "$ISSUE_NUM" -b "⚠️ Checks failed on report PR #$PR_NUMBER. Auto-merge disabled; please fix the report or tests." || true
|
|
fi
|
|
|
|
auto-deploy:
|
|
needs: [test]
|
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && (startsWith(github.head_ref, 'compat/') || github.head_ref == 'data/games-refresh')
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Trigger deploy if auto-merged
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
GH_REPO: ${{ github.repository }}
|
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
run: |
|
|
for i in {1..36}; do
|
|
STATE="$(gh pr view "$PR_NUMBER" --json state --jq .state 2>/dev/null || true)"
|
|
if [ "$STATE" = "MERGED" ]; then
|
|
echo "PR #$PR_NUMBER merged successfully."
|
|
MERGE_SHA="$(gh pr view "$PR_NUMBER" --json mergeCommit --jq '.mergeCommit.oid // empty' 2>/dev/null || true)"
|
|
if [ -n "$MERGE_SHA" ]; then
|
|
EXISTING="$(gh run list --workflow=deploy.yml --commit="$MERGE_SHA" --json databaseId -q '.[0].databaseId // empty' 2>/dev/null || true)"
|
|
if [ -n "$EXISTING" ]; then
|
|
echo "Deploy already queued or running for commit $MERGE_SHA. Skipping manual dispatch."
|
|
exit 0
|
|
fi
|
|
fi
|
|
echo "Dispatching deploy.yml for main..."
|
|
gh workflow run deploy.yml --ref main
|
|
exit 0
|
|
fi
|
|
sleep 5
|
|
done
|
|
echo "PR #$PR_NUMBER was not merged within 180s."
|