mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
Collapse duplicate CI spend while keeping each gate's existence reason: - quality.yml: TIA __RUN_ALL__ defers full unit to fast-unit 4-shard (#6781); path filters via classify-pr-changes; docs-gates split; draft skip - ci.yml: wire docs/i18n/code path filters; ESLint JSON artifact for quality-gate; drop advisory typecheck:noimplicit; float actions/cache@v6 - TIA parity: memory/usage/combo/serial; **/*.test.mjs any depth; electron/bin no longer force unit __RUN_ALL__ - check:complexity-ratchets: one ESLint walk, ruleId-isolated baselines + cache - check:api-docs-refs + lib/apiRoutes: shared API route inventory - husky pre-push: intentionally light (gates live in pre-commit); CLAUDE.md + QUALITY_GATES.md docs synced - collect-metrics / lint:json: path.resolve cache path; Windows-safe eslint bin - env-doc allowlist for ESLINT_RESULTS_JSON / COMPLEXITY_ESLINT_REPORT - release-green --full-ci expects check:api-docs-refs (not docs-symbols alone) Tests: select-impacted, classify-pr-changes, api-routes lib, complexity-rule-count, validate-release-green. Reconciled after #6781 (fast-unit 2→4 shards) per maintainer request on #6716. Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com>
152 lines
6.3 KiB
YAML
152 lines
6.3 KiB
YAML
name: Nightly Release-Green
|
|
|
|
# Solution D — continuous, NON-BLOCKING drift signal for the active release branch.
|
|
#
|
|
# WHY: the full gate (ci.yml) only runs on the release PR (PR → main), so reds
|
|
# accrue silently on release/** and explode — in layers — at release time. This
|
|
# nightly reproduces the release-equivalent validation on the active release branch
|
|
# HEAD and, when there are HARD failures, opens/updates a single tracking issue.
|
|
#
|
|
# It is NOT a required status check and never touches a contributor PR — it only
|
|
# reports. Ratchet drift (eslint warnings / cognitive-complexity / file-size) is
|
|
# expected mid-cycle and is reported but never raises the alarm on its own; only
|
|
# real defects (typecheck / lint errors / unit / vitest / db-rules / public-creds /
|
|
# package-artifact) flip the issue open.
|
|
|
|
on:
|
|
schedule:
|
|
- cron: "23 5 * * *" # 05:23 UTC daily — off-peak, distinct from other nightlies
|
|
workflow_dispatch:
|
|
inputs:
|
|
branch:
|
|
description: "Release branch to validate (default: highest release/vX.Y.Z)"
|
|
required: false
|
|
type: string
|
|
|
|
permissions:
|
|
contents: read
|
|
issues: write
|
|
|
|
concurrency:
|
|
group: nightly-release-green
|
|
cancel-in-progress: true
|
|
|
|
env:
|
|
OMNIROUTE_SKIP_SYSTEM_TRUST: "1"
|
|
|
|
jobs:
|
|
release-green:
|
|
name: Validate active release branch
|
|
# Dynamic runner: with USE_VPS_RUNNER=true (release window / on-demand pre-flight)
|
|
# this runs on the dedicated VPS runner — clean env (no operator OMNIROUTE_API_KEY,
|
|
# no local noauth CLIs => zero machine-specific false positives) and no contention.
|
|
# Nightly cron normally finds the var false (VM off) and falls back to hosted.
|
|
runs-on: ${{ (vars.USE_VPS_RUNNER == 'true' && fromJSON('["self-hosted","omni-release"]')) || 'ubuntu-latest' }}
|
|
env:
|
|
JWT_SECRET: ci-nightly-secret-with-sufficient-length-for-validation
|
|
API_KEY_SECRET: ci-nightly-api-key-secret-long
|
|
DISABLE_SQLITE_AUTO_BACKUP: "true"
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Resolve active release branch
|
|
id: branch
|
|
env:
|
|
INPUT_BRANCH: ${{ github.event.inputs.branch }}
|
|
run: |
|
|
set -euo pipefail
|
|
if [ -n "${INPUT_BRANCH:-}" ]; then
|
|
TARGET="$INPUT_BRANCH"
|
|
else
|
|
# highest release/vX.Y.Z by semver among remote branches
|
|
TARGET=$(git for-each-ref --format='%(refname:short)' 'refs/remotes/origin/release/v*' \
|
|
| sed 's#origin/##' \
|
|
| sort -t/ -k2 -V \
|
|
| tail -1)
|
|
fi
|
|
if [ -z "$TARGET" ]; then echo "No release/v* branch found"; exit 1; fi
|
|
# Strict format guard — reject anything that isn't release/vX.Y.Z (blocks
|
|
# ref/command injection via the workflow_dispatch input).
|
|
if ! printf '%s' "$TARGET" | grep -qE '^release/v[0-9]+\.[0-9]+\.[0-9]+$'; then
|
|
echo "Refusing non-canonical branch name: $TARGET"; exit 1
|
|
fi
|
|
echo "target=$TARGET" >> "$GITHUB_OUTPUT"
|
|
echo "Active release branch: $TARGET"
|
|
|
|
- name: Checkout the release branch
|
|
env:
|
|
TARGET: ${{ steps.branch.outputs.target }}
|
|
run: |
|
|
set -euo pipefail
|
|
git checkout "$TARGET"
|
|
git log -1 --oneline
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version: "24"
|
|
cache: npm
|
|
|
|
- uses: ./.github/actions/npm-ci-retry
|
|
|
|
- name: Release-green validation (full)
|
|
id: validate
|
|
run: |
|
|
set +e
|
|
# --hermetic: scrub live-test trigger vars (self-hosted runner may carry
|
|
# operator env; hosted ignores the unknown flag before #6300 lands).
|
|
# --full-ci: ALSO run every static gate from ci.yml's gate jobs (lint,
|
|
# quality-gate, quality-extended, docs-sync-strict, pr-test-policy). PRs into
|
|
# release/** only get the fast-gates, so these accrue silently and explode in
|
|
# layers on the release PR (v3.8.46: 11 static base-reds leaked). Running them
|
|
# nightly opens the tracking issue the moment one lands, not at release time.
|
|
node scripts/quality/validate-release-green.mjs --json --with-build --hermetic --full-ci \
|
|
1> release-green.json 2> release-green.log
|
|
echo "exit=$?" >> "$GITHUB_OUTPUT"
|
|
echo "------- report -------"
|
|
cat release-green.log
|
|
|
|
- name: Open / update tracking issue on HARD failure
|
|
if: steps.validate.outputs.exit != '0'
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
TARGET: ${{ steps.branch.outputs.target }}
|
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
run: |
|
|
set -euo pipefail
|
|
TITLE="🔴 Release branch not green: ${TARGET}"
|
|
{
|
|
echo "The nightly **release-green** validation found HARD failures on \`${TARGET}\`."
|
|
echo "These are real defects that would block the release PR — fix them in the"
|
|
echo "originating PR branch (via co-authorship), not by demanding it from contributors."
|
|
echo ""
|
|
echo "**Run:** ${RUN_URL}"
|
|
echo ""
|
|
echo '```'
|
|
sed -n '/──────── verdict ────────/,$p' release-green.log || tail -40 release-green.log
|
|
echo '```'
|
|
echo ""
|
|
echo "_Ratchet drift (eslint warnings / cognitive-complexity / file-size) listed above is expected mid-cycle and is rebaselined at release — it is NOT a contributor concern and did not, on its own, open this issue._"
|
|
} > issue-body.md
|
|
|
|
EXISTING=$(gh issue list --repo "$GITHUB_REPOSITORY" --state open \
|
|
--search "in:title $TITLE" --json number --jq '.[0].number' 2>/dev/null || echo "")
|
|
if [ -n "$EXISTING" ]; then
|
|
gh issue comment "$EXISTING" --repo "$GITHUB_REPOSITORY" --body-file issue-body.md
|
|
echo "Updated existing issue #$EXISTING"
|
|
else
|
|
gh issue create --repo "$GITHUB_REPOSITORY" --title "$TITLE" --body-file issue-body.md
|
|
fi
|
|
|
|
- name: Upload report artifact
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: release-green-report
|
|
path: |
|
|
release-green.json
|
|
release-green.log
|
|
if-no-files-found: ignore
|