Skip to content

fix(brand): size large CodeNomad logos by their title #3014

fix(brand): size large CodeNomad logos by their title

fix(brand): size large CodeNomad logos by their title #3014

Workflow file for this run

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
- tests-opencode-compatibility
- tests-session-pruning-native
- tests-runtime-contracts
- tests-tauri-macos
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-session-pruning-native:
needs: authorize
if: ${{ needs.authorize.outputs.allowed == 'true' && !github.event.pull_request.draft }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
timeout-minutes: 15
steps:
- uses: actions/checkout@v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v7.1.0
with:
node-version-file: .node-version
cache: npm
- run: npm ci --ignore-scripts
- name: Install browser for native pruning UI checks
run: npx --workspace @codenomad/ui playwright install --with-deps chromium
- name: Pack and install outside the checkout
shell: pwsh
run: |
$sandbox = Join-Path $env:RUNNER_TEMP 'pruning-native-install'
New-Item -ItemType Directory -Force $sandbox | Out-Null
$package = npm pack ./packages/server/src/opencode/session-pruning --pack-destination $sandbox --json | ConvertFrom-Json
if ($LASTEXITCODE) { exit $LASTEXITCODE }
npm install --prefix $sandbox (Join-Path $sandbox $package.filename) '@opencode/cli@latest' --ignore-scripts --no-audit --no-fund
if ($LASTEXITCODE) { exit $LASTEXITCODE }
"PRUNING_NATIVE_INSTALL=$sandbox" >> $env:GITHUB_ENV
- name: Test the installed plugin with an isolated official runtime
shell: pwsh
run: |
$platform = node -p "process.platform === 'win32' ? 'windows' : process.platform"
$arch = node -p "process.arch"
$extension = node -p "process.platform === 'win32' ? '.exe' : ''"
$cli = Join-Path $env:PRUNING_NATIVE_INSTALL "node_modules/@opencode/cli-$platform-$arch/bin/opencode$extension"
& $cli --version
if ($LASTEXITCODE) { exit $LASTEXITCODE }
$plugin = Join-Path $env:PRUNING_NATIVE_INSTALL 'node_modules/@neuralnomads/codenomad-session-pruning'
$fixtures = node -p "require('node:path').join(require('node:fs').realpathSync(require('node:os').tmpdir()), 'opencode')"
"PRUNING_NATIVE_FIXTURES=$fixtures" >> $env:GITHUB_ENV
node scripts/run-session-pruning-native.mjs $cli $plugin
if ($LASTEXITCODE) { exit $LASTEXITCODE }
npm run build:pruning --workspace @neuralnomads/codenomad
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node --import tsx --test packages/server/src/opencode/pruning-installation.test.ts
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node scripts/run-session-pruning-native.mjs $cli --ui
- name: Upload isolated native failure diagnostics
if: ${{ failure() && env.PRUNING_NATIVE_FIXTURES != '' }}
uses: actions/upload-artifact@v7.0.2
with:
name: session-pruning-failure-${{ matrix.os }}
path: |
${{ env.PRUNING_NATIVE_FIXTURES }}/codenomad-pruning-native-*/server.log
${{ env.PRUNING_NATIVE_FIXTURES }}/codenomad-pruning-native-*/before-restart.log
${{ env.PRUNING_NATIVE_FIXTURES }}/codenomad-pruning-native-*/discovery.json
${{ env.PRUNING_NATIVE_FIXTURES }}/codenomad-pruning-native-*/ui-*.png
${{ env.PRUNING_NATIVE_FIXTURES }}/codenomad-pruning-native-*/test-diagnostics.jsonl
${{ env.PRUNING_NATIVE_FIXTURES }}/native-fixture-run-*/
if-no-files-found: ignore
retention-days: 7
- name: Upload opt-in plugin package
if: success()
uses: actions/upload-artifact@v7.0.2
with:
name: session-pruning-plugin-${{ matrix.os }}
path: ${{ runner.temp }}/pruning-native-install/*.tgz
if-no-files-found: error
retention-days: 7
tests-runtime-contracts:
needs: authorize
if: ${{ needs.authorize.outputs.allowed == 'true' && !github.event.pull_request.draft }}
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
runtime: [minimum, latest]
timeout-minutes: 25
steps:
- uses: actions/checkout@v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-node@v7.1.0
with:
node-version-file: .node-version
cache: npm
- run: npm ci --ignore-scripts
- run: npm run build:pruning --workspace @neuralnomads/codenomad
- run: npm run build:automation --workspace @neuralnomads/codenomad
- run: npm run build:missions --workspace @neuralnomads/codenomad
- name: Qualify the pinned client against the technical minimum and latest stable
shell: pwsh
run: |
$sandbox = Join-Path $env:RUNNER_TEMP 'opencode-contract-runtime'
$version = '${{ matrix.runtime }}'
if ($version -eq 'minimum') {
$version = node --import tsx --input-type=module -e "import { MINIMUM_OPENCODE_VERSION } from './packages/server/src/opencode/runtime-support.ts'; console.log(MINIMUM_OPENCODE_VERSION)"
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
npm install --prefix $sandbox "@opencode/cli@$version" --ignore-scripts --no-audit --no-fund
if ($LASTEXITCODE) { exit $LASTEXITCODE }
$cli = Join-Path $sandbox 'node_modules/@opencode/cli-windows-x64/bin/opencode.exe'
& $cli --version
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node --test packages/server/scripts/native-plugin-build.test.mjs
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node scripts/test-plugin-runtime-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node scripts/test-automation-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node scripts/test-session-pruning-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
# Shipped Missions bundle: loading, model-visible tools through the
# ordinary prompt loop, journal RPC and recurrence capability.
node scripts/test-missions-native-contract.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node scripts/test-missions-native-family-control.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
# The fixtures' own test-harness plugins drive tool executors through
# ctx.tool.list (available at the minimum); the product does not consume it.
node scripts/test-missions-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
# Parallel siblings, a recursive grandchild and coordinator readout.
node scripts/test-missions-native-trajectory.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
if ('${{ matrix.runtime }}' -eq 'latest') {
# Missions Preferences' Location subagent-depth editor against the
# native config schema and production JSONC document admission.
node --import tsx scripts/test-subagent-depth-settings-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
node scripts/test-session-environment-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node scripts/test-session-fork-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node scripts/test-session-aside-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node --conditions=browser --import tsx scripts/test-blank-session-cleanup-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
# Recurring schedule journeys (~6.5 min) qualify the latest stable
# only; the contract fixture qualifies the recurrence graph on both.
if ('${{ matrix.runtime }}' -eq 'latest') {
node scripts/test-recurring-simple-native.mjs $cli ABCD
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
tests:
needs: authorize
if: ${{ needs.authorize.outputs.allowed == 'true' && !github.event.pull_request.draft }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup Node
uses: actions/setup-node@v7.1.0
with:
node-version-file: .node-version
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 \
zsh \
xvfb \
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: Build bundled automation integration
run: npm run build:automation --workspace @neuralnomads/codenomad
- name: Build bundled mission integration
run: npm run build:missions --workspace @neuralnomads/codenomad
- name: Test desktop packaging invariants
run: node --test scripts/desktop-server-resources.test.cjs scripts/prepare-node-runtime.test.cjs packages/tauri-app/scripts/configure-updater.test.mjs packages/tauri-app/scripts/updater-artifacts.test.mjs
- name: Test CI fixture diagnostics and artifact announcements
run: node --test scripts/native-fixture-diagnostics.test.mjs .github/scripts/comment-pr-artifacts.test.cjs .github/scripts/runtime-maintenance.test.cjs .github/scripts/binary-build-order.test.cjs
- name: Test Electron client state
env:
CODENOMAD_TEST_ZSH: /bin/zsh
run: |
npm run test:native --workspace @neuralnomads/codenomad-electron-app
node --import tsx --test packages/electron-app/electron/main/view-menu.test.ts
- name: Test changed runnable UI behavior
run: >-
node --import tsx --test --test-force-exit
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/session-outline-projection.test.ts
packages/ui/src/components/provider-auth/provider-options.test.ts
packages/ui/src/components/prompt-input/device-file-selection.test.ts
packages/ui/src/components/prompt-input/height-state.test.ts
packages/ui/src/components/prompt-input/type-to-focus.test.ts
packages/ui/src/components/user-message-navigation.test.ts
packages/ui/src/lib/hotkey-bindings.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/tool-call/permission-block.test.ts
packages/ui/src/components/tool-call/render-memory.test.ts
packages/ui/src/lib/render-text-window.test.ts
packages/ui/src/components/settings/info-settings-diagnostics.test.ts
packages/ui/src/components/settings/client-os.test.ts
packages/ui/src/lib/native/menu-labels.test.ts
packages/ui/src/lib/message-timing.test.ts
packages/ui/src/lib/bug-report.test.ts
packages/ui/src/components/tool-call/tool-presentation.test.ts
packages/ui/src/components/transcript-visibility.test.ts
packages/ui/src/components/unified-picker-path.test.ts
packages/ui/src/components/virtual-follow-behavior.test.ts
packages/ui/src/components/virtual-follow-measurements.test.ts
packages/ui/src/components/virtual-reader-settlement.test.ts
packages/ui/src/lib/height-delta.test.ts
packages/ui/src/lib/scroll-gesture-routing.test.ts
packages/ui/src/lib/client-identity.test.ts
packages/ui/src/lib/filesystem-events.test.ts
packages/ui/src/lib/global-cache.test.ts
packages/ui/src/lib/monaco/model-cache.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/i18n/messages/missions.test.ts
packages/ui/src/lib/clipboard.test.ts
packages/ui/src/lib/message-selection-position.test.ts
packages/ui/src/lib/model-visibility.test.ts
packages/ui/src/lib/notification-routing.test.ts
packages/ui/src/lib/retained-size.test.ts
packages/ui/src/lib/provider-auth.test.ts
packages/ui/src/lib/remote-pairing-link.test.ts
packages/ui/src/lib/native/browser.test.ts
packages/ui/src/lib/runtime-env.test.ts
packages/ui/src/lib/session-transcript-lru.test.ts
packages/ui/src/lib/server-meta.test.ts
packages/ui/src/lib/theme-scheme.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/compaction-notice.test.ts
packages/ui/src/stores/form-settlements.test.ts
packages/ui/src/stores/instance-invalidation.test.ts
packages/ui/src/stores/plugin-controls.test.ts
packages/ui/src/stores/plugin-controls-demand.test.ts
packages/ui/src/stores/plugin-controls-events.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/mission-store.test.ts
packages/ui/src/stores/request-locations.test.ts
packages/ui/src/stores/shell-store.test.ts
packages/ui/src/stores/session-generation-recovery.test.ts
packages/ui/src/stores/session-outline-persistence.test.ts
packages/ui/src/stores/session-pagination.test.ts
packages/ui/src/stores/session-fork.test.ts
packages/ui/src/stores/workspace-session-scope.test.ts
packages/ui/src/stores/session-pending-state.test.ts
packages/ui/src/stores/session-tree.test.ts
packages/ui/src/stores/session-previews.test.ts
packages/ui/src/lib/browser-history.test.ts
packages/ui/src/lib/keyboard-offset.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 Missions UI units
run: >-
node --conditions=browser --import tsx --test --test-force-exit
packages/ui/src/components/mission-attention.test.ts
packages/ui/src/lib/native/preferences-window.test.ts
packages/ui/src/components/mission-briefing-locales.test.ts
packages/ui/src/components/mission-briefing-model.test.ts
packages/ui/src/components/mission-execution.test.ts
packages/ui/src/components/mission-native-execution-locales.test.ts
packages/ui/src/components/mission-native-execution.test.ts
packages/ui/src/components/mission-picker-model.test.ts
packages/ui/src/components/mission-profile-controls-data.test.ts
packages/ui/src/components/mission-profile-summary-data.test.ts
packages/ui/src/components/mission-progress-model.test.ts
packages/ui/src/components/mission-reader-locales.test.ts
packages/ui/src/components/mission-task-navigation.test.ts
packages/ui/src/lib/compatibility-click.test.ts
packages/ui/src/lib/event-refresh-scheduler.test.ts
packages/ui/src/lib/i18n/messages/missions-panel.test.ts
packages/ui/src/lib/mission-cleanup.test.ts
packages/ui/src/lib/mission-defaults.test.ts
packages/ui/src/lib/mission-display.test.ts
packages/ui/src/lib/mission-lifecycle-request.test.ts
packages/ui/src/lib/mission-markdown-pages.test.ts
packages/ui/src/lib/mission-model-library.test.ts
packages/ui/src/lib/mission-mutation-locales.test.ts
packages/ui/src/lib/mission-mutation.test.ts
packages/ui/src/lib/mission-preferences-document.test.ts
packages/ui/src/lib/mission-recurrence-control.test.ts
packages/ui/src/lib/mission-view-fence.test.ts
packages/ui/src/lib/native-mission-preferences.test.ts
packages/ui/src/lib/storage-owner-read-fence.test.ts
packages/ui/src/stores/mission-creation-drafts.test.ts
packages/ui/src/stores/mission-lifecycle-intents.test.ts
packages/ui/src/stores/mission-task-session-reads.test.ts
packages/ui/src/stores/missions.test.ts
packages/ui/src/stores/session-generation-recovery-integration.test.ts
packages/ui/src/stores/session-list-restoration.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/components/instance/shell/useSessionCache.test.ts
packages/ui/src/components/instance/shell/drawer-orientation.test.ts
packages/ui/src/components/permission-diff-review.test.ts
packages/ui/src/components/tool-call/renderers/task-copy.test.ts
packages/ui/src/components/tool-call/renderer-copy.test.ts
packages/ui/src/components/tool-call/diff-payload.test.ts
packages/ui/src/components/tool-call/renderers/edit.test.ts
packages/ui/src/components/tool-call/renderers/task-title.test.ts
packages/ui/src/components/prompt-input/usePromptState.test.ts
packages/ui/src/components/session/provider-usage-panel.test.ts
packages/ui/src/lib/hooks/use-active-session-message-load.test.ts
packages/ui/src/lib/sdk-manager.test.ts
packages/ui/src/lib/background-read-queue.test.ts
packages/ui/src/lib/prioritized-read.test.ts
packages/ui/src/stores/instance-startup-priority.test.ts
packages/ui/src/stores/session-list-startup.test.ts
packages/ui/src/stores/app-tabs.test.ts
packages/ui/src/stores/forms.test.ts
packages/ui/src/stores/preferences-favorites-mode.test.ts
packages/ui/src/stores/instances-restore-ownership.test.ts
packages/ui/src/stores/instances-pending-compaction.test.ts
packages/ui/src/stores/instances-pending-requests.test.ts
packages/ui/src/stores/pending-recovery-cause.test.ts
packages/ui/src/stores/message-v2/bus.test.ts
packages/ui/src/stores/message-v2/transcript-eviction.test.ts
packages/ui/src/stores/opencode-data.test.ts
packages/ui/src/stores/opencode-data-idle.test.ts
packages/ui/src/stores/opencode-data-settlement.test.ts
packages/ui/src/stores/opencode-data-reconnect.test.ts
packages/ui/src/stores/opencode-transcript-replay.test.ts
packages/ui/src/stores/opencode-compaction.test.ts
packages/ui/src/lib/message-part-grouping.test.ts
packages/ui/src/lib/settings/behavior-registry.test.ts
packages/ui/src/components/instance/shell/right-panel/core-plugin.test.ts
packages/ui/src/stores/message-v2/empty-content.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-model-reconciliation.test.ts
packages/ui/src/stores/session-pruning-events.test.ts
packages/ui/src/stores/session-pruning-projection.test.ts
packages/ui/src/stores/session-pruning-pagination.test.ts
packages/ui/src/stores/permission-receipt-cache.test.ts
packages/ui/src/stores/session-native-events.test.ts
packages/ui/src/stores/session-outline.test.ts
packages/ui/src/stores/runtime-contract.test.ts
packages/ui/src/stores/session-lifecycle-signals.test.ts
packages/ui/src/stores/session-usage-contract.test.ts
packages/ui/src/stores/session-move-restore.test.ts
packages/ui/src/stores/session-request-authority.test.ts
packages/ui/src/stores/session-default-agent.test.ts
packages/ui/src/stores/history-search-sessions.test.ts
packages/ui/src/stores/session-git-degraded.test.ts
packages/ui/src/stores/session-send-lifecycle.test.ts
packages/ui/src/stores/blank-session-cleanup.test.ts
packages/ui/src/stores/session-status.test.ts
packages/ui/src/stores/session-subsession-activity.test.ts
packages/ui/src/stores/worktree-ready.test.ts
packages/ui/src/stores/worktrees-delete.test.ts
packages/ui/src/stores/project-names.test.ts
packages/ui/src/stores/temporary-instances.test.ts
- name: Test server
run: node --import tsx --test "packages/server/src/**/*.test.ts"
- name: Test Stats restoration and connection fences explicitly
run: node --import tsx --test packages/server/src/opencode/service-usage.test.ts
- name: Install Chromium for UI rendering regressions
run: npx playwright install --with-deps chromium
- name: Test browser transcript rendering and navigation
run: xvfb-run -a npm run test:browser --workspace @codenomad/ui
- 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: CODENOMAD_TEST_ZSH=/bin/zsh CODENOMAD_TEST_NODE="$(command -v node)" cargo test --locked
- name: Test owned Tauri zoom input script
run: node --test packages/tauri-app/tests/window-zoom-script.test.mjs
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@v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup Node
uses: actions/setup-node@v7.1.0
with:
node-version-file: .node-version
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
- name: Test updater installer launch handoff
working-directory: packages/tauri-app
run: cargo test --locked -p tauri-plugin-updater windows_launch_tests
- name: Test owned Tauri zoom input script
run: node --test packages/tauri-app/tests/window-zoom-script.test.mjs
- name: Reproduce and prevent Tao input deadlocks
run: node scripts/test-tauri-input-deadlock.mjs --baseline
- name: Reproduce and prevent Windows runtime handle corruption
run: node scripts/test-tauri-runner-refcount.mjs --baseline
# Exercise the selected-CLI contract on the reported macOS ARM64 platform as
# well as both other hosts, independently of unrelated server-suite failures.
tests-opencode-compatibility:
needs: authorize
if: ${{ needs.authorize.outputs.allowed == 'true' && !github.event.pull_request.draft }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-26]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup Node
uses: actions/setup-node@v7.1.0
with:
node-version-file: .node-version
cache: npm
- name: Install dependencies
run: npm ci
- name: Test binary compatibility and shared lifecycle
run: >-
node --import tsx --test
packages/server/src/workspaces/__tests__/spawn.test.ts
packages/server/src/workspaces/__tests__/binary-probe.test.ts
packages/server/src/workspaces/session-environment.test.ts
packages/server/src/workspaces/git-requirement.test.ts
packages/server/src/server/__tests__/session-environment.test.ts
"packages/server/src/workspaces/*opencode*.test.ts"
packages/server/src/server/routes/binary-validation.test.ts
"packages/server/src/opencode-update/*.test.ts"
packages/ui/src/lib/launch-errors.test.ts
- name: Test first installation without system Node
timeout-minutes: 10
run: node scripts/test-opencode-install-native.mjs
- name: Test migration failure guards
run: node --test scripts/native-fixture-guards.test.mjs "scripts/fixtures/wsl-*.test.mjs"
- name: Certify native migration and Git-degraded conversations at the minimum and latest stable
timeout-minutes: 20
shell: pwsh
run: |
$platform = node -p "process.platform === 'win32' ? 'windows' : process.platform"
$arch = node -p "process.arch"
$extension = node -p "process.platform === 'win32' ? '.exe' : ''"
$seeds = @(
@{ scope = '@opencode'; version = '2.0.3'; command = 'opencode' },
@{ scope = '@opencode-ai'; version = '0.0.0-beta-19271'; command = 'opencode2' },
# The last release before the 2.1 native replay contract: the usual upgrade path.
@{ scope = '@opencode'; version = '2.0.32'; command = 'opencode' }
)
$oldClis = foreach ($entry in $seeds) {
$seed = Join-Path $env:RUNNER_TEMP "opencode-migration-seed-$($entry.version)"
npm install --prefix $seed "$($entry.scope)/cli@$($entry.version)" --ignore-scripts --no-audit --no-fund | Out-Host
if ($LASTEXITCODE) { exit $LASTEXITCODE }
Join-Path $seed "node_modules/$($entry.scope)/cli-$platform-$arch/bin/$($entry.command)$extension"
}
$minimum = node --import tsx --input-type=module -e "import { MINIMUM_OPENCODE_VERSION } from './packages/server/src/opencode/runtime-support.ts'; console.log(MINIMUM_OPENCODE_VERSION)"
if ($LASTEXITCODE) { exit $LASTEXITCODE }
foreach ($version in @($minimum, 'latest')) {
$target = Join-Path $env:RUNNER_TEMP "opencode-migration-$version"
npm install --prefix $target "@opencode/cli@$version" --ignore-scripts --no-audit --no-fund
if ($LASTEXITCODE) { exit $LASTEXITCODE }
$cli = Join-Path $target "node_modules/@opencode/cli-$platform-$arch/bin/opencode$extension"
foreach ($oldCli in $oldClis) {
node scripts/test-opencode-history-migration.mjs $oldCli $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
node scripts/test-codemode-jobs-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
node scripts/test-git-degraded-native.mjs $cli
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
# Exercise the window persistence regressions on the architecture reported in
# #676, independently of the Linux server gate. Packaging alone cannot test them.
tests-tauri-macos:
needs: authorize
if: ${{ needs.authorize.outputs.allowed == 'true' && !github.event.pull_request.draft }}
runs-on: macos-26
steps:
- name: Checkout
uses: actions/checkout@v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup Node
uses: actions/setup-node@v7.1.0
with:
node-version-file: .node-version
cache: npm
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: npm ci
- 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 macOS ARM64
working-directory: packages/tauri-app/src-tauri
run: CODENOMAD_TEST_ZSH=/bin/zsh CODENOMAD_TEST_NODE="$(command -v node)" cargo test --locked -- --test-threads=4
- name: Reproduce and prevent macOS window event feedback
timeout-minutes: 10
run: |
node --test scripts/test-tauri-macos-window-result.test.mjs
node scripts/test-tauri-macos-window.mjs --baseline
node scripts/test-tauri-macos-window.mjs --baseline
- name: Test owned Tauri zoom input script
run: node --test packages/tauri-app/tests/window-zoom-script.test.mjs
- name: Test desktop shell startup on macOS
env:
CODENOMAD_TEST_ZSH: /bin/zsh
run: node --import tsx --test packages/electron-app/electron/main/user-shell.test.ts