ci: split CI by area with path filters and speed up releases
ci / api / api (push) Successful in 54s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 54s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 53s
ci / recommender / recommender (push) Successful in 38s
ci / ts / ts (packages + web) (push) Successful in 37s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m47s
release / release (версия и заметки) (push) Successful in 7s
release / android (APK в релиз) (push) Canceled after 4m25s
ci / api / api (push) Successful in 54s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 54s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 53s
ci / recommender / recommender (push) Successful in 38s
ci / ts / ts (packages + web) (push) Successful in 37s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m47s
release / release (версия и заметки) (push) Successful in 7s
release / android (APK в релиз) (push) Canceled after 4m25s
- ci.yml becomes ci-api, ci-contract, ci-recommender, ci-ts, ci-mobile and docker workflows, each filtered by paths; docs-only commits run nothing - docker builds all four images in one job with plain docker build on the runner host, so the layer cache survives between runs - release no longer re-runs the test suite (the tagged commit already passed CI on main); version and release notes are one job - the android job mounts persistent Gradle and Android SDK caches from /opt/ci-cache (when the runner allows the volumes) and uses --build-cache - RELEASE_TOKEN is optional: fall back to the built-in job token - docs: CI layout and act_runner settings (capacity, cache, valid_volumes) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d3b2e7bfc3
commit
718125b719
11 files changed
+358
-180
No files matched your search
@@ -1,10 +1,10 @@
|
||||
# Релиз по тегу vMAJOR.MINOR.PATCH[-rc.N] (docs/ci-cd.md): проверки → Gitea Release с заметками → APK.
|
||||
# Релиз создаётся сразу после проверок (статус Android — «собирается»); сборка APK докладывает в него файлы
|
||||
# Релиз по тегу vMAJOR.MINOR.PATCH[-rc.N] (docs/ci-cd.md): Gitea Release с заметками → APK.
|
||||
# Релиз создаётся сразу (статус Android — «собирается»); сборка APK докладывает в него файлы
|
||||
# и переписывает статус: собран / не удалась (scripts/release.mjs).
|
||||
# Docker-образы не публикуются: сервер собирает их сам из клонированного репозитория (deploy/update.sh).
|
||||
#
|
||||
# Секреты (Settings → Actions → Secrets):
|
||||
# RELEASE_TOKEN — создание релиза и загрузка ассетов (scope: write:repository)
|
||||
# RELEASE_TOKEN (необязательно) — токен для релиза; без него — встроенный токен job (права на запись в репозиторий)
|
||||
# ANDROID_KEYSTORE_BASE64, ANDROID_KEYSTORE_PASSWORD, ANDROID_KEY_ALIAS, ANDROID_KEY_PASSWORD — подпись APK
|
||||
name: release
|
||||
|
||||
@@ -13,69 +13,56 @@ on:
|
||||
tags: ["v*.*.*"]
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.24"
|
||||
NODE_VERSION: "22"
|
||||
|
||||
jobs:
|
||||
verify:
|
||||
# Тесты здесь не повторяются: тот же коммит уже проверен CI в main (ci-*.yml). Ставьте тег после зелёного CI.
|
||||
release:
|
||||
name: release (версия и заметки)
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.v.outputs.PIPU_VERSION }}
|
||||
version_code: ${{ steps.v.outputs.PIPU_VERSION_CODE }}
|
||||
prerelease: ${{ steps.v.outputs.PIPU_PRERELEASE }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- id: v
|
||||
run: node scripts/version.mjs "${GITHUB_REF_NAME}" | tee -a "$GITHUB_OUTPUT"
|
||||
- uses: actions/setup-go@v5
|
||||
with: { go-version: "${{ env.GO_VERSION }}", cache-dependency-path: services/api/go.sum }
|
||||
- uses: astral-sh/setup-uv@v6
|
||||
with: { version: "0.10.2" }
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with: { node-version: "${{ env.NODE_VERSION }}", cache: pnpm }
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- name: Go
|
||||
working-directory: services/api
|
||||
run: go vet ./... && go test ./...
|
||||
- name: Python
|
||||
working-directory: services/recommender
|
||||
run: uv sync --frozen && uv run ruff check . && uv run mypy pipu_rec && uv run pytest -q
|
||||
- name: TypeScript
|
||||
run: pnpm i18n:check && pnpm test:scripts && pnpm typecheck && pnpm test
|
||||
|
||||
release:
|
||||
name: release (заметки)
|
||||
needs: verify
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# вся история и теги: заметки строятся по коммитам с прошлого релиза
|
||||
with: { fetch-depth: 0 }
|
||||
- uses: actions/setup-node@v4
|
||||
with: { node-version: "${{ env.NODE_VERSION }}" }
|
||||
- id: v
|
||||
name: Версия из тега
|
||||
run: node scripts/version.mjs "${GITHUB_REF_NAME}" | tee -a "$GITHUB_OUTPUT"
|
||||
- name: Gitea Release
|
||||
env:
|
||||
GITEA_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
TAG: ${{ github.ref_name }}
|
||||
VERSION: ${{ needs.verify.outputs.version }}
|
||||
PRERELEASE: ${{ needs.verify.outputs.prerelease }}
|
||||
VERSION: ${{ steps.v.outputs.PIPU_VERSION }}
|
||||
PRERELEASE: ${{ steps.v.outputs.PIPU_PRERELEASE }}
|
||||
run: node scripts/release.mjs create
|
||||
|
||||
android:
|
||||
name: android (APK в релиз)
|
||||
needs: [verify, release]
|
||||
needs: release
|
||||
runs-on: ubuntu-latest
|
||||
# Постоянные кэши на хосте раннера: дистрибутив и зависимости Gradle, его build cache, Android SDK и NDK
|
||||
# переживают job (−4 мин на релиз). Работают, если в config.yaml раннера разрешены тома
|
||||
# (container.valid_volumes: ['/opt/ci-cache/**'], docs/ci-cd.md); иначе раннер их пропускает и всё качается заново.
|
||||
container:
|
||||
image: docker.gitea.com/runner-images:ubuntu-latest
|
||||
volumes:
|
||||
- /opt/ci-cache/gradle:/root/.gradle
|
||||
- /opt/ci-cache/android:/root/.android
|
||||
env:
|
||||
PIPU_VERSION: ${{ needs.verify.outputs.version }}
|
||||
PIPU_VERSION_CODE: ${{ needs.verify.outputs.version_code }}
|
||||
PIPU_VERSION: ${{ needs.release.outputs.version }}
|
||||
PIPU_VERSION_CODE: ${{ needs.release.outputs.version_code }}
|
||||
# для scripts/release.mjs
|
||||
GITEA_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
TAG: ${{ github.ref_name }}
|
||||
VERSION: ${{ needs.verify.outputs.version }}
|
||||
VERSION_CODE: ${{ needs.verify.outputs.version_code }}
|
||||
VERSION: ${{ needs.release.outputs.version }}
|
||||
VERSION_CODE: ${{ needs.release.outputs.version_code }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# при перезапуске одной этой сборки статус «не удалась» сменится на «собирается»
|
||||
@@ -109,7 +96,7 @@ jobs:
|
||||
run: |
|
||||
npx expo prebuild --platform android --clean --no-install
|
||||
cd android
|
||||
./gradlew --no-daemon --max-workers=2 assembleRelease -PreactNativeArchitectures=arm64-v8a -Pkotlin.compiler.execution.strategy=in-process -Dorg.gradle.jvmargs="-Xmx2560m -XX:MaxMetaspaceSize=512m"
|
||||
./gradlew --no-daemon --max-workers=2 assembleRelease -PreactNativeArchitectures=arm64-v8a -Pkotlin.compiler.execution.strategy=in-process -Dorg.gradle.jvmargs="-Xmx2560m -XX:MaxMetaspaceSize=512m" --build-cache
|
||||
|
||||
- name: Свободное место после сбоя
|
||||
if: failure()
|
||||
@@ -120,7 +107,7 @@ jobs:
|
||||
|
||||
- name: Подпись APK
|
||||
env:
|
||||
PRERELEASE: ${{ needs.verify.outputs.prerelease }}
|
||||
PRERELEASE: ${{ needs.release.outputs.prerelease }}
|
||||
KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
|
||||
KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
|
||||
KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
||||
|
||||
Reference in new issue
Block a user