mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-08-24 15:53:29 +00:00
Prevent duplicate workspace ownership, bound concurrent creation and cleanup, and preserve canonical Windows and WSL identity while using the shared OpenCode V2 service. Keep session history directory-scoped for global projects, serialize native event projection, restore prompts and pending requests safely, expose interrupted generations, and remove unsupported direct Google credential handling. Make Electron and Tauri server resources reproducible from the root lockfile, retain the pinned beta SDK contract, and update CI and architecture documentation for the shared-service model. Validated with full UI, server, Electron, Rust, packaging, typecheck, Tauri build, and live prompt, permission, Form, compaction, and interruption smoke coverage.
216 lines
8.2 KiB
YAML
216 lines
8.2 KiB
YAML
name: PR Build Validation
|
|
|
|
on:
|
|
pull_request:
|
|
types:
|
|
- opened
|
|
- edited
|
|
- synchronize
|
|
- reopened
|
|
- ready_for_review
|
|
|
|
permissions:
|
|
contents: read
|
|
actions: write
|
|
|
|
concurrency:
|
|
group: pr-build-${{ github.event.pull_request.number }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
authorize:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
allowed: ${{ steps.auth.outputs.allowed }}
|
|
env:
|
|
ALLOWED_ACTORS: ${{ vars.ALLOWED_NON_DEV_PR_ACTORS }}
|
|
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
|
BASE_REF: ${{ github.event.pull_request.base.ref }}
|
|
steps:
|
|
- name: Check PR authorization
|
|
id: auth
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
if [ "$BASE_REF" = "dev" ] || [ "$BASE_REF" = "DEV-v2" ]; then
|
|
echo "allowed=true" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
|
|
normalized=",${ALLOWED_ACTORS},"
|
|
if [[ "$normalized" == *",${PR_AUTHOR},"* ]]; then
|
|
echo "allowed=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "allowed=false" >> "$GITHUB_OUTPUT"
|
|
echo "Skipping builds for PR by unauthorized author targeting $BASE_REF" >&2
|
|
fi
|
|
|
|
build:
|
|
needs:
|
|
- authorize
|
|
- tests
|
|
- tests-tauri-windows
|
|
if: ${{ needs.authorize.outputs.allowed == 'true' && !github.event.pull_request.draft }}
|
|
uses: ./.github/workflows/build-and-upload.yml
|
|
with:
|
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
upload: false
|
|
upload_actions_artifacts: true
|
|
actions_artifacts_retention_days: 7
|
|
actions_artifacts_name_prefix: pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}-
|
|
set_versions: false
|
|
|
|
tests:
|
|
needs: authorize
|
|
if: ${{ needs.authorize.outputs.allowed == 'true' && !github.event.pull_request.draft }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
cache: npm
|
|
|
|
- name: Setup Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Install Linux test dependencies (Tauri)
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
build-essential \
|
|
pkg-config \
|
|
libgtk-3-dev \
|
|
libglib2.0-dev \
|
|
libwebkit2gtk-4.1-dev \
|
|
libsoup-3.0-dev \
|
|
libayatana-appindicator3-dev \
|
|
librsvg2-dev
|
|
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Typecheck desktop clients
|
|
run: npm run typecheck
|
|
|
|
- name: Test desktop packaging invariants
|
|
run: node --test scripts/desktop-server-resources.test.cjs
|
|
|
|
- name: Test Electron client state
|
|
run: npm run test:native --workspace @neuralnomads/codenomad-electron-app
|
|
|
|
- name: Test changed runnable UI behavior
|
|
run: >-
|
|
node --import tsx --test
|
|
packages/ui/src/components/browser-frame-security.test.ts
|
|
packages/ui/src/components/message-history-pagination.test.ts
|
|
packages/ui/src/components/message-timeline-v2.test.ts
|
|
packages/ui/src/components/provider-auth/provider-options.test.ts
|
|
packages/ui/src/components/session/session-bottom-pin-intent.test.ts
|
|
packages/ui/src/components/session/session-idle-attention.test.ts
|
|
packages/ui/src/components/session-list-visibility.test.ts
|
|
packages/ui/src/components/unified-picker-path.test.ts
|
|
packages/ui/src/components/virtual-follow-behavior.test.ts
|
|
packages/ui/src/lib/client-identity.test.ts
|
|
packages/ui/src/lib/filesystem-events.test.ts
|
|
packages/ui/src/lib/hooks/use-app-session-capture.test.ts
|
|
packages/ui/src/lib/hooks/use-instance-metadata.test.ts
|
|
packages/ui/src/lib/hooks/use-foreground-refresh.test.ts
|
|
packages/ui/src/lib/hooks/use-electron-folder-launch.test.ts
|
|
packages/ui/src/lib/launch-errors.test.ts
|
|
packages/ui/src/lib/message-selection-position.test.ts
|
|
packages/ui/src/lib/model-visibility.test.ts
|
|
packages/ui/src/lib/runtime-env.test.ts
|
|
packages/ui/src/lib/trailing-resync.test.ts
|
|
packages/ui/src/stores/abort-created-workspace-cleanup.test.ts
|
|
packages/ui/src/stores/app-session-reconciliation.test.ts
|
|
packages/ui/src/stores/app-session-restore-queue.test.ts
|
|
packages/ui/src/stores/app-session-restore-timeout.test.ts
|
|
packages/ui/src/stores/app-session-snapshot-merge.test.ts
|
|
packages/ui/src/stores/restore-workspace-commit-gates.test.ts
|
|
packages/ui/src/stores/client-state-codec.test.ts
|
|
packages/ui/src/stores/client-state-partitions.test.ts
|
|
packages/ui/src/stores/client-state.test.ts
|
|
packages/ui/src/stores/form-settlements.test.ts
|
|
packages/ui/src/stores/message-prompt-display.test.ts
|
|
packages/ui/src/stores/message-v2/instance-store.test.ts
|
|
packages/ui/src/stores/message-v2/message-hydration-authority.test.ts
|
|
packages/ui/src/stores/message-v2/message-status.test.ts
|
|
packages/ui/src/stores/message-v2/message-window.test.ts
|
|
packages/ui/src/stores/message-v2/normalizers.test.ts
|
|
packages/ui/src/stores/shell-store.test.ts
|
|
packages/ui/src/stores/session-generation-recovery.test.ts
|
|
packages/ui/src/stores/session-pagination.test.ts
|
|
packages/ui/src/stores/session-pending-state.test.ts
|
|
packages/ui/src/stores/workspace-load-readiness.test.ts
|
|
packages/ui/src/types/session.test.ts
|
|
packages/ui/src/stores/workspace-list-reconciliation-fence.test.ts
|
|
|
|
- name: Test restore ownership integration
|
|
run: >-
|
|
node --conditions=browser --import tsx --test --test-force-exit
|
|
packages/ui/src/components/form-request-tool-target.test.ts
|
|
packages/ui/src/components/form-request.test.ts
|
|
packages/ui/src/lib/hooks/use-active-session-message-load.test.ts
|
|
packages/ui/src/stores/app-tabs.test.ts
|
|
packages/ui/src/stores/forms.test.ts
|
|
packages/ui/src/stores/instances-restore-ownership.test.ts
|
|
packages/ui/src/stores/opencode-data.test.ts
|
|
packages/ui/src/stores/permission-lifecycle.test.ts
|
|
packages/ui/src/stores/shell-store-reactivity.test.ts
|
|
packages/ui/src/stores/session-actions.test.ts
|
|
packages/ui/src/stores/session-native-events.test.ts
|
|
packages/ui/src/stores/session-request-authority.test.ts
|
|
packages/ui/src/stores/session-send-lifecycle.test.ts
|
|
packages/ui/src/stores/session-status.test.ts
|
|
|
|
- name: Test server
|
|
run: node --import tsx --test "packages/server/src/**/*.test.ts"
|
|
|
|
- name: Prepare Tauri test resources
|
|
run: >-
|
|
npm run dev:prep --workspace @codenomad/tauri-app &&
|
|
node -e "require('fs').mkdirSync('packages/tauri-app/src-tauri/resources/server',{recursive:true})"
|
|
|
|
- name: Test Tauri crate
|
|
working-directory: packages/tauri-app/src-tauri
|
|
run: cargo test --locked
|
|
|
|
tests-tauri-windows:
|
|
needs: authorize
|
|
if: ${{ needs.authorize.outputs.allowed == 'true' && !github.event.pull_request.draft }}
|
|
runs-on: windows-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22
|
|
cache: npm
|
|
|
|
- name: Setup Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Test Windows server spawn behavior
|
|
run: node --import tsx --test packages/server/src/workspaces/__tests__/spawn.test.ts
|
|
|
|
- name: Prepare Tauri test resources
|
|
run: >-
|
|
npm run dev:prep --workspace @codenomad/tauri-app &&
|
|
node -e "require('fs').mkdirSync('packages/tauri-app/src-tauri/resources/server',{recursive:true})"
|
|
|
|
- name: Test Tauri crate on Windows
|
|
working-directory: packages/tauri-app/src-tauri
|
|
run: cargo test --locked -- --test-threads=1
|