Files
cinny/.gitea/workflows/ci.yml
T
jaredandClaude Opus 4.8 a631e90ea2
CI / Build & Quality Checks (push) Canceled after 4m44s
CI / Trigger Desktop Build (push) Canceled after 0s
ci: re-enable npm/node_modules cache — runner cache network fixed
The act_runner cache server is now reachable from job containers: jobs were
landing on isolated per-job docker networks and couldn't reach the runner's
cache server on docker0 (getCacheEntry ETIMEDOUT, ~5 min wasted/build). Fixed
runner-side by putting the runner + all job containers on a shared dedicated
network (`act-cache-net`, runner at 172.30.0.2) and pointing cache.host at it —
verified a container on that network reaches the cache port.

Restores `cache: npm` on Setup Node and the actions/cache node_modules step
(restore + save-on-miss-and-success). Reverts 10270b75 now that the underlying
network issue is resolved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-02 23:18:00 -04:00

158 lines
6.7 KiB
YAML

name: CI
on:
push:
branches: [lotus]
pull_request:
branches: [lotus]
# Only the newest commit per ref needs to build: a superseded push cancels its
# in-flight run. This keeps the shared act_runner free (web CI otherwise queues
# behind long Tauri desktop builds) and — since `trigger-desktop` is `needs:
# build` — means only the latest lotus commit ever kicks a desktop build,
# instead of one per rapid push. Cancelling a superseded run is deploy-safe
# ONLY because lotus_deploy.sh re-resolves origin/lotus each poll iteration and
# retargets its CI gate to HEAD — otherwise a run cancelled mid-poll would
# strand the newest commit undeployed. Keep those two in sync.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build & Quality Checks
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
cache: npm
# Cache node_modules keyed on the lockfile + Node version: an unchanged
# lockfile skips `npm ci` (extraction + postinstall folds patch) and just
# restores the tree. Save runs only on a miss AND only if install
# succeeded (`success()`), so a failed `npm ci` can't poison the cache.
# The act_runner cache server is reached over the dedicated `act-cache-net`
# docker network (runner cache.host 172.30.0.2) — jobs previously landed on
# isolated per-job networks and ETIMEDOUT on it (~5 min wasted per build).
- name: Restore node_modules
id: node-modules
uses: actions/cache/restore@v4
with:
path: node_modules
key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json', '.node-version') }}
- name: Install dependencies
if: steps.node-modules.outputs.cache-hit != 'true'
# Harden against transient registry network failures (ECONNRESET etc.):
# raise npm's built-in fetch retries/timeouts and retry `npm ci` up to
# 3 times with backoff before failing the build.
run: |
npm config set fetch-retries 5
npm config set fetch-retry-mintimeout 20000
npm config set fetch-retry-maxtimeout 120000
npm config set fetch-timeout 600000
for attempt in 1 2 3; do
echo "npm ci attempt $attempt…"
npm ci && break
if [ "$attempt" = "3" ]; then
echo "npm ci failed after 3 attempts" >&2
exit 1
fi
echo "npm ci failed; retrying in $((attempt * 15))s…" >&2
sleep $((attempt * 15))
done
- name: Save node_modules
if: steps.node-modules.outputs.cache-hit != 'true' && success()
uses: actions/cache/save@v4
with:
path: node_modules
key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json', '.node-version') }}
# ── Quality gates run BEFORE the slow build so a format/lint/type/test
# error fails in seconds instead of after the ~minutes-long build. All are
# hard gates — any failure fails the job and blocks the deploy. The tree is
# held clean (prettier formatted, eslint 0 errors, typecheck 0), so these
# gate real regressions. NOTE: the lotus-build.sh upstream-merge path can
# deploy without CI; a later normal push surfaces any introduced issue here
# — fix forward (or briefly re-soften a gate) rather than deploy broken.
# eslint gates on errors only (existing no-explicit-any warnings stay
# informational — check:eslint has no --max-warnings).
- name: Prettier
run: npm run check:prettier
- name: ESLint
run: npm run check:eslint
- name: TypeScript
run: npm run typecheck
# Deterministic pure-logic tests on Node's built-in runner via tsx (no
# vitest — Vite 8 is ahead of vitest's range). A failure blocks the deploy.
- name: Unit tests
run: npm test
# ── Critical gate — if this fails, nothing deploys. Produces dist/. ──
- name: Build
run: npm run build
env:
NODE_OPTIONS: '--max_old_space_size=4096'
VITE_APP_VERSION: ${{ github.sha }}
# ── Security (informational — findings shouldn't block a deploy) ─────
- name: Audit (high/critical)
run: npm audit --audit-level=high --omit=dev
continue-on-error: true
# ── Bundle size report (informational — never blocks a deploy) ───────
- name: Report bundle sizes
continue-on-error: true
run: |
echo "### Bundle sizes" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| File | Size | Gzip |" >> $GITHUB_STEP_SUMMARY
echo "|------|------|------|" >> $GITHUB_STEP_SUMMARY
find dist/assets -name "*.js" -not -name "*.map" | sort | while read f; do
name=$(basename "$f")
size=$(du -sh "$f" | cut -f1)
gzip_size=$(gzip -c "$f" | wc -c | awk '{printf "%.1f kB", $1/1024}')
echo "| $name | $size | $gzip_size |" >> $GITHUB_STEP_SUMMARY
done
# ── Desktop build trigger ──────────────────────────────────────────────
# Gated on `build` succeeding so a broken push (e.g. failing `npm ci` or
# `npm run build`) never bumps the cinny-desktop submodule and kicks off the
# slow Tauri release builds, which would only error out downstream. Only
# runs on a real push to lotus — not on pull_request CI runs.
trigger-desktop:
name: Trigger Desktop Build
needs: build
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/lotus' }}
runs-on: ubuntu-latest
steps:
- name: Bump cinny submodule
env:
TOKEN: ${{ secrets.RELEASE_TOKEN }}
run: |
CINNY_SHA="${{ github.sha }}"
git clone "https://x-access-token:$TOKEN@code.lotusguild.org/LotusGuild/cinny-desktop.git" desktop
cd desktop
git config user.email "ci@lotusguild.org"
git config user.name "Lotus CI"
git submodule update --init cinny
git -C cinny fetch origin
git -C cinny checkout "$CINNY_SHA"
git add cinny
if git diff --cached --quiet; then
echo "Submodule already at $CINNY_SHA, nothing to do"
else
git commit -m "chore: bump cinny submodule to ${CINNY_SHA:0:8}"
git push origin main
echo "Pushed — cinny-desktop release.yml will start via on:push trigger"
fi