Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 60 additions & 15 deletions .github/workflows/deploy-site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ on:
branches: [main, master]
paths:
- "apps/site/**"
- "apps/web/**"
- "apps/flutter/**"
- "packages/**"
- "scripts/check-release-publication.mjs"
- "scripts/build-demo.mjs"
- "scripts/deploy-site.mjs"
- "scripts/deploy-demo.mjs"
- "scripts/deploy-site-bundle.mjs"
- "scripts/dispatch-site-deployment.mjs"
- "scripts/generate-release-manifest.mjs"
- "scripts/inspect-linux-update.mjs"
Expand Down Expand Up @@ -41,6 +41,61 @@ concurrency:
cancel-in-progress: false

jobs:
demo:
if: ${{ github.event_name == 'push' }}
runs-on: ubuntu-24.04
timeout-minutes: 30
environment:
name: production
url: https://t4code.net/demo
steps:
- name: Check out current demo source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ github.sha }}
persist-credentials: false

- name: Install pnpm
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
with:
version: 11.10.0

- name: Install Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 24.13.1

- name: Install Flutter
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
flutter-version: 3.44.6
channel: stable
cache: true

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Authenticate to AWS with GitHub OIDC
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4
with:
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
aws-region: us-east-1

- name: Confirm the live demo permits the Flutter renderer
shell: bash
run: |
set -euo pipefail
curl --fail --silent --show-error --head https://t4code.net/demo \
| tr -d '\r' \
| grep -i '^content-security-policy:' \
| grep -Fq "'wasm-unsafe-eval'"

- name: Build and deploy current Flutter demo
env:
T4_SITE_BUCKET: ${{ vars.T4_SITE_BUCKET }}
T4_CLOUDFRONT_DISTRIBUTION_ID: ${{ vars.T4_CLOUDFRONT_DISTRIBUTION_ID }}
run: pnpm deploy:demo

deploy:
if: ${{ github.event_name != 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') }}
runs-on: ubuntu-24.04
Expand Down Expand Up @@ -157,18 +212,9 @@ jobs:
ref: ${{ steps.immutable_source.outputs.source_sha }}
persist-credentials: false

- name: Check out trusted demo source
if: ${{ steps.published_release.outcome == 'success' || steps.existing_release.outcome == 'success' }}
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ steps.source.outputs.trusted_sha }}
path: .trusted-demo-source
persist-credentials: false
- name: Install dependencies
if: ${{ steps.published_release.outcome == 'success' || steps.existing_release.outcome == 'success' }}
run: |
pnpm install --frozen-lockfile
pnpm --dir .trusted-demo-source install --frozen-lockfile
run: pnpm install --frozen-lockfile

- name: Authenticate to AWS with GitHub OIDC
if: ${{ steps.published_release.outcome == 'success' || steps.existing_release.outcome == 'success' }}
Expand All @@ -177,11 +223,10 @@ jobs:
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
aws-region: us-east-1

- name: Build and deploy static site
- name: Build and deploy immutable release site
if: ${{ steps.published_release.outcome == 'success' || steps.existing_release.outcome == 'success' }}
env:
GH_TOKEN: ${{ github.token }}
T4_SITE_BUCKET: ${{ vars.T4_SITE_BUCKET }}
T4_IMMUTABLE_SITE_SOURCE: ${{ github.workspace }}
T4_CLOUDFRONT_DISTRIBUTION_ID: ${{ vars.T4_CLOUDFRONT_DISTRIBUTION_ID }}
run: pnpm --dir .trusted-demo-source deploy:site-bundle
run: pnpm deploy:site
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ dist-electron/
coverage/
playwright-report/
test-results/
/output/playwright/
*.log
.todos/
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ native release checks.
```
apps/desktop Electron main process: window, local OMP discovery,
host lifecycle, pairing, credential storage
apps/web React UI (Vite): sessions, composer, panes, settings
apps/flutter Native Android/iOS/macOS client: responsive UI,
apps/flutter Canonical Android/iOS/macOS/web UI: responsive workspace,
secure credentials, lifecycle, updates, OMP service controls
apps/web Legacy React compatibility UI for the Electron client
packages/ client, protocol, host-wire, host-service, remote,
service-manager, ui
```
Expand Down
6 changes: 6 additions & 0 deletions apps/flutter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ flutter test integration_test/app_smoke_test.dart -d <device-id>
build directly to a host. Development credentials are intentionally volatile.
Release builds use platform secure storage.

The public `https://t4code.net/demo/` preview is a read-only Flutter build with
local display data. From the repository root, `pnpm build:demo` creates that
subpath build in `apps/site/dist/demo`; it does not connect to a host or store
credentials. Demo publication follows current `main` independently of desktop
release tags.

The device smoke harness launches the real native shell, waits for persistent
storage and platform initialization, and opens host management. CI runs it on
an Android emulator and an iOS simulator; local device IDs come from
Expand Down
6 changes: 6 additions & 0 deletions apps/flutter/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ import 'package:flutter/foundation.dart';
import 'src/client/app_state.dart';
import 'src/client/t4_client_controller.dart';
import 'src/client/transcript_tail_store.dart';
import 'src/demo/demo_app.dart';
import 'src/host/app_preferences.dart';
import 'src/host/persistent_host_stores.dart';
import 'src/platform/platform_lifecycle_controller.dart';
import 'src/ui/t4_app.dart';

void main() {
const demoMode = bool.fromEnvironment('T4_DEMO_MODE');
if (demoMode) {
runApp(T4DemoApp());
return;
}
runApp(T4Bootstrap(developmentEndpoint: _developmentEndpoint()));
}

Expand Down
Loading
Loading