feat(client): complete native source and release boundary

Complete the Native Client source/audio boundary, strict v5 loopback contract, Browser media lifecycle handling, and non-blocking release checks. Keep unverified platform/physical gates explicit; do not rewrite the Go Server.
This commit is contained in:
AAA authored and GitHub committed 2026-09-04 03:42:54 +08:00
1 parent 3583e92938
commit 5781d6bbfa
194 files changed
+19199 -10342

No files matched your search

+116 -20
View File
@@ -7,8 +7,8 @@ on:
- main
workflow_dispatch:
inputs:
native_checks:
description: Run the optional Native sender research checks
client_checks:
description: Run the optional Screener Client checks
required: false
default: false
type: boolean
@@ -19,6 +19,8 @@ permissions:
jobs:
validate:
runs-on: ubuntu-latest
outputs:
client_scope: ${{ steps.client-scope.outputs.run }}
steps:
- name: Check out repository
uses: actions/checkout@v6
@@ -33,16 +35,16 @@ jobs:
run: sh scripts/check-project-state.sh
env:
SCREENER_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
- name: Detect Native sender scope
id: native-scope
- name: Detect Screener Client scope
id: client-scope
shell: bash
env:
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
EXPLICIT_NATIVE_CHECKS: ${{ inputs.native_checks || false }}
EXPLICIT_CLIENT_CHECKS: ${{ inputs.client_checks || false }}
run: |
run_native=false
if [ "$EXPLICIT_NATIVE_CHECKS" = "true" ]; then
run_native=true
run_client=false
if [ "$EXPLICIT_CLIENT_CHECKS" = "true" ]; then
run_client=true
elif [ "$GITHUB_EVENT_NAME" != "workflow_dispatch" ]; then
base="$BASE_SHA"
case "$base" in
@@ -50,25 +52,119 @@ jobs:
base=$(git rev-parse HEAD^ 2>/dev/null || true)
;;
esac
if [ -n "$base" ] && ! git diff --quiet "$base" HEAD -- native/sender; then
run_native=true
if [ -n "$base" ] && ! git diff --quiet "$base" HEAD -- \
.github/workflows/repository-hygiene.yml \
.node-version \
index.html \
native/client \
package.json \
package-lock.json \
public \
src \
tsconfig.json \
tsconfig.app.json \
tsconfig.server.json \
vite.config.ts \
scripts/assemble-client.mjs \
scripts/package-app-release.mjs \
scripts/package-client-candidate.mjs \
scripts/client-package-targets.mjs \
scripts/check-client.mjs \
scripts/client-local-gate.ts \
scripts/client-loopback-gate.ts \
scripts/client-media-gate.ts; then
run_client=true
fi
fi
echo "run=$run_native" >> "$GITHUB_OUTPUT"
echo "run=$run_client" >> "$GITHUB_OUTPUT"
- name: Set up Go
if: steps.native-scope.outputs.run == 'true'
if: steps.client-scope.outputs.run == 'true'
uses: actions/setup-go@v6
with:
go-version: 1.26.6
cache-dependency-path: native/sender/go.sum
- name: Check native sender
if: steps.native-scope.outputs.run == 'true'
working-directory: native/sender
run: |
go test ./...
go vet ./...
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o "$RUNNER_TEMP/screener-sender.exe" ./cmd/screener-sender
cache-dependency-path: native/client/go.sum
- name: Check Screener Client
if: steps.client-scope.outputs.run == 'true'
run: npm run check:client-core
- name: Install dependencies
run: npm ci
- name: Type-check, test, and build
run: npm run check
release-application:
needs: validate
if: >-
(github.event_name == 'push' && github.ref == 'refs/heads/main') ||
needs.validate.outputs.client_scope == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version-file: .node-version
cache: npm
- name: Install dependencies
run: npm ci
- name: Package application release
run: node scripts/package-app-release.mjs "$RUNNER_TEMP/app-release"
- name: Upload application release
uses: actions/upload-artifact@v7
with:
name: screener-app-${{ github.sha }}
path: ${{ runner.temp }}/app-release/*
if-no-files-found: error
retention-days: 14
release-clients:
needs:
- validate
- release-application
if: >-
(github.event_name == 'push' && github.ref == 'refs/heads/main') ||
needs.validate.outputs.client_scope == 'true'
strategy:
fail-fast: false
matrix:
include:
- target: windows-amd64
runner: windows-latest
- target: linux-amd64
runner: ubuntu-latest
- target: darwin-arm64
runner: macos-15
runs-on: ${{ matrix.runner }}
timeout-minutes: 20
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version-file: .node-version
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: 1.26.6
cache-dependency-path: native/client/go.sum
- name: Download application release
uses: actions/download-artifact@v8
with:
name: screener-app-${{ github.sha }}
path: ${{ runner.temp }}/app-release
- name: Build and verify Client candidate
run: >-
node scripts/package-client-candidate.mjs
"${{ runner.temp }}/app-release"
"${{ matrix.target }}"
"${{ runner.temp }}/client-release"
- name: Upload Client release candidate
uses: actions/upload-artifact@v7
with:
name: screener-client-${{ matrix.target }}-${{ github.sha }}
path: ${{ runner.temp }}/client-release/*
if-no-files-found: error
compression-level: 0
retention-days: 14