mirror of
https://github.com/hectorqin/reader.git
synced 2026-11-10 21:11:08 +08:00
ci: release only for v* tags or manual runs; CI on main; Android SDK packages
- main is the long-lived development branch: release.yml no longer runs on a push to it, only on v* tags and workflow_dispatch. ci.yml now runs on every branch push, main included. - android-actions/setup-android's default package list includes `tools`, which current command-line tools no longer carry, so sdkmanager failed; install exactly platform-tools, android-35 and build-tools 35.0.1. - reader-chrome.test.ts left its React roots mounted; a scheduled commit could land after jsdom teardown and fail the run with an unhandled "Right-hand side of 'instanceof' is not an object" (all tests passing). Unmount in afterEach. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5ce7b2f682
commit
4e149c73d7
4 files changed
+22
-11
No files matched your search
@@ -1,14 +1,14 @@
|
||||
# Build and test: server (Node/TypeScript), web client, UI review, Android shell.
|
||||
#
|
||||
# Runs on pull requests and on pushes to any branch except main. Pushes to main and
|
||||
# release tags run it through release.yml (workflow_call), before any image is
|
||||
# published, so main is tested exactly once per push.
|
||||
# Runs on pull requests and on pushes to every branch, main included (main is the
|
||||
# long-lived development branch). Release tags and manual releases run it through
|
||||
# release.yml (workflow_call) before any image is published.
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches-ignore: [main]
|
||||
branches: ['**']
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -112,9 +112,12 @@ jobs:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
cache: gradle
|
||||
# The hosted runner ships the Android SDK; this only accepts and adds what the
|
||||
# build asks for (platform 35, build-tools 35.0.1).
|
||||
# The hosted runner ships the Android SDK; this accepts the licences and adds
|
||||
# exactly what the build asks for. The action's default package list includes
|
||||
# `tools`, which current command-line tools no longer carry (sdkmanager fails).
|
||||
- uses: android-actions/setup-android@v3
|
||||
with:
|
||||
packages: platform-tools platforms;android-35 build-tools;35.0.1
|
||||
- run: ./gradlew --no-daemon :app:assembleDebug
|
||||
working-directory: android
|
||||
- uses: actions/upload-artifact@v4
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Release the single-container image (server + web) to Docker Hub for amd64 and arm64.
|
||||
#
|
||||
# push to main -> hectorqin/reader-pro:main, :sha-<short>
|
||||
# tag v1.2.3 -> hectorqin/reader-pro:1.2.3, :1.2, :latest, :sha-<short>
|
||||
# manual run -> tags for the chosen ref, as above
|
||||
# manual run -> the chosen branch's name (e.g. :main) and :sha-<short>
|
||||
#
|
||||
# Never on a plain push: main is the long-lived development branch, and a release
|
||||
# is a decision (a tag, or "Run workflow" in the Actions tab), not a side effect.
|
||||
#
|
||||
# CI (ci.yml) runs first; nothing is published from a red build. Each architecture
|
||||
# is built on its own native runner — the arm64 image under QEMU would run npm ci
|
||||
@@ -15,7 +17,6 @@ name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
tags: ['v*']
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Docs (mostly Chinese) live in `docs/`; `docs/architecture.md` explains *why* thi
|
||||
|
||||
## Commands
|
||||
|
||||
Run from repo root (or `cd` into the package). CI runs install → typecheck → test → build per package: GitHub Actions `.github/workflows/ci.yml` (PRs and non-main pushes; also server, UI review, Android shell check + debug APK) and CNB `.cnb.yml`. `.github/workflows/release.yml` runs CI on main pushes and `v*` tags, then publishes the multi-arch (amd64 + arm64, native runners) image to Docker Hub `hectorqin/reader-pro` (`main`/`sha-*`, or `x.y.z`/`x.y`/`latest` for tags); it needs the `DOCKER_USERNAME`/`DOCKER_PASSWORD` secrets. `android/scripts/check-shell.sh` checks the JS bridge contract: only `@JavascriptInterface` methods count, and each must be declared in `web/src/android-bridge.d.ts` (method syntax, `name?(): T` for optional).
|
||||
Run from repo root (or `cd` into the package). CI runs install → typecheck → test → build per package: GitHub Actions `.github/workflows/ci.yml` (PRs and every branch push; also UI review, Android shell check + debug APK) and CNB `.cnb.yml`. `main` is the long-lived development branch and never releases on push: `.github/workflows/release.yml` runs only for `v*` tags or a manual run, runs CI first, then publishes the multi-arch (amd64 + arm64, native runners) image to Docker Hub `hectorqin/reader-pro` (`x.y.z`/`x.y`/`latest` + `sha-*` for tags; branch name + `sha-*` for manual runs); it needs the `DOCKER_USERNAME`/`DOCKER_PASSWORD` secrets. `android/scripts/check-shell.sh` checks the JS bridge contract: only `@JavascriptInterface` methods count, and each must be declared in `web/src/android-bridge.d.ts` (method syntax, `name?(): T` for optional).
|
||||
|
||||
```sh
|
||||
npm ci --prefix server && npm ci --prefix web
|
||||
|
||||
@@ -12,7 +12,7 @@ import { render } from '../src/shared/ui/render-root.ts';
|
||||
* of them — stop — was pushed off the right edge and the reader could not stop
|
||||
* the voice at all (没法停止).
|
||||
*/
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
||||
import { createElement as h } from 'react';
|
||||
import { ReaderChrome, type ChromeState, type ChromeHandlers, type ReaderThemeState } from '../src/ui/reader-chrome.tsx';
|
||||
import { defaultThemePreference, type ThemePreference } from '../src/shared/theme/theme.ts';
|
||||
@@ -124,6 +124,13 @@ describe('ReaderChrome', () => {
|
||||
container = document.createElement('div');
|
||||
document.body.append(container);
|
||||
});
|
||||
// Unmount before jsdom is torn down: a root left mounted can still commit a
|
||||
// scheduled update afterwards, which surfaced in CI as an unhandled
|
||||
// "Right-hand side of 'instanceof' is not an object" from react-dom.
|
||||
afterEach(() => {
|
||||
render(null, container);
|
||||
container.remove();
|
||||
});
|
||||
|
||||
function paint(state: Partial<ChromeState>): HTMLElement {
|
||||
const stage = document.createElement('div');
|
||||
|
||||
Reference in new issue
Block a user