food-market/.forgejo/workflows/ci.yml
nns 71b749fb35 ci: path filters + buildkit cache для ускорения сборки
Цель: типичный push должен катиться за 30-60 сек вместо 3-5 мин.

docker.yml — две оптимизации:
1. Job changes детектит что изменилось (api/web) через `git diff
   HEAD~1 HEAD`. Образ пересобирается только если затронуты его
   директории; `paths-ignore` отсекает docs/*.md/.github/**.
2. Сборка через `docker buildx build` с registry-cache:
   --cache-from / --cache-to type=registry,ref=...:buildcache,mode=max.
   Локальный 127.0.0.1:5001 уже разрешает DELETE, так что mutable
   buildcache работает. dotnet restore / pnpm install теперь почти
   мгновенные при отсутствии изменений в *.csproj / pnpm-lock.yaml.
3. deploy-stage запускается только если api или web реально
   пересобирался; для пропущенного образа в .env пишется :latest,
   compose pull тянет последний успешный slim. Telegram-сообщение
   указывает что именно деплоилось ([api web] / [web] / только compose).

ci.yml — actions/cache для NuGet (~/.nuget/packages по hash *.csproj)
и pnpm store (по hash pnpm-lock.yaml). paths-ignore такое же.

POS-job (windows-latest) не трогаем — он и так fires только на
тег v* / workflow_dispatch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 12:54:57 +05:00

114 lines
3.5 KiB
YAML

name: CI
on:
push:
branches: [main]
tags: ['v*']
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/**'
pull_request:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/**'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
backend:
name: Backend (.NET 8)
runs-on: [self-hosted, linux]
services:
postgres:
image: 127.0.0.1:5001/mirror/postgres:16-alpine
env:
POSTGRES_DB: food_market_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5441:5432
steps:
- uses: actions/checkout@v4
# dotnet 8 SDK is pre-installed on the self-hosted runner host.
- name: Dotnet version
run: dotnet --version
# Кэшируем NuGet-пакеты по hash *.csproj — restore становится мгновенным,
# если зависимости не менялись.
- name: Cache NuGet
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj', 'food-market.sln') }}
restore-keys: |
nuget-${{ runner.os }}-
- name: Restore
run: dotnet restore food-market.sln
- name: Build
run: dotnet build food-market.sln --no-restore -c Release
- name: Test
env:
ConnectionStrings__Default: Host=localhost;Port=5441;Database=food_market_test;Username=postgres;Password=postgres
run: dotnet test food-market.sln --no-build -c Release --verbosity normal || echo "No tests yet"
web:
name: Web (React + Vite)
runs-on: [self-hosted, linux]
defaults:
run:
working-directory: src/food-market.web
steps:
- uses: actions/checkout@v4
# node 20 + pnpm are pre-installed on the self-hosted runner host.
- name: Node + pnpm version
run: node --version && pnpm --version
# Кэшируем pnpm store по hash pnpm-lock.yaml — install становится мгновенным
# при отсутствии изменений в зависимостях.
- name: Resolve pnpm store path
id: pnpm-store
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-store.outputs.path }}
key: pnpm-${{ runner.os }}-${{ hashFiles('src/food-market.web/pnpm-lock.yaml') }}
restore-keys: |
pnpm-${{ runner.os }}-
- name: Install
run: pnpm install --frozen-lockfile
- name: Build (tsc + vite)
run: pnpm build
# POS build requires Windows — no Forgejo runner for it; skipped silently.
pos:
name: POS (WPF, Windows)
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Build POS
run: |
dotnet restore src/food-market.pos/food-market.pos.csproj
dotnet build src/food-market.pos/food-market.pos.csproj --no-restore -c Release
dotnet publish src/food-market.pos/food-market.pos.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o publish