Skip to content

operator: make v1alpha1 CRD lifecycle executable #476

operator: make v1alpha1 CRD lifecycle executable

operator: make v1alpha1 CRD lifecycle executable #476

Workflow file for this run

name: CI
on:
push:
branches: [main, master]
pull_request:
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'pull_request' && github.ref || github.sha }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
changes:
name: changes
runs-on: ubuntu-24.04
timeout-minutes: 5
outputs:
continuity: ${{ steps.classify.outputs.continuity }}
cluster: ${{ steps.classify.outputs.cluster }}
official_omp_gate0: ${{ steps.classify.outputs.official_omp_gate0 }}
tooling: ${{ steps.classify.outputs.tooling }}
android_debug: ${{ steps.classify.outputs.android_debug }}
flutter: ${{ steps.classify.outputs.flutter }}
flutter_android: ${{ steps.classify.outputs.flutter_android }}
flutter_apple: ${{ steps.classify.outputs.flutter_apple }}
steps:
- name: Check out source and base history
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
- name: Install Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 24.13.1
- name: Test path classification
run: node --test scripts/ci-paths.test.mjs
- name: Classify affected CI legs
id: classify
shell: bash
env:
EVENT_NAME: ${{ github.event_name }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
if [[ "$EVENT_NAME" != pull_request ]]; then
node scripts/ci-paths.mjs --all >> "$GITHUB_OUTPUT"
exit 0
fi
[[ "$BASE_SHA" =~ ^[0-9a-f]{40}$ ]]
[[ "$HEAD_SHA" =~ ^[0-9a-f]{40}$ ]]
git diff --name-only -z "$BASE_SHA...$HEAD_SHA" | node scripts/ci-paths.mjs >> "$GITHUB_OUTPUT"
core:
runs-on: ubuntu-24.04
timeout-minutes: 25
steps:
- name: Check out source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- 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
cache: pnpm
- name: Install Bun for the T4 host packages
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.14
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Install browser for end-to-end tests
run: pnpm exec playwright install --with-deps chromium
- name: Check source and types
run: pnpm check:release && pnpm check:provenance && pnpm lint && pnpm --filter '!@t4-code/flutter' -r typecheck
- name: Run tests
run: pnpm --filter '!@t4-code/flutter' -r test
- name: Build all workspaces
run: pnpm --filter '!@t4-code/flutter' -r build
- name: Run built-app end-to-end tests
run: pnpm test:e2e
- name: Check packaging contract
run: pnpm test:packaging
legacy-bridge-continuity:
needs: changes
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.continuity == 'true' }}
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- name: Check out exact T4 source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- 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
cache: pnpm
- name: Install Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.14
- name: Install continuity prerequisites
run: sudo apt-get update && sudo apt-get install --yes expect
- name: Install T4 dependencies
run: pnpm install --frozen-lockfile
- name: Resolve pinned OMP authority source
id: authority
shell: bash
run: |
set -euo pipefail
source_repository="$(jq -er '.sourceRepository' provenance/omp-host-migration.json)"
test "$source_repository" = "https://github.com/lyc-aon/oh-my-pi"
sha="$(jq -er '.inputs.operationsContinuity' provenance/omp-host-migration.json)"
[[ "$sha" =~ ^[0-9a-f]{40}$ ]]
echo "repository=lyc-aon/oh-my-pi" >> "$GITHUB_OUTPUT"
echo "sha=$sha" >> "$GITHUB_OUTPUT"
- name: Check out pinned OMP authority source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
repository: ${{ steps.authority.outputs.repository }}
ref: ${{ steps.authority.outputs.sha }}
path: .continuity/omp
- name: Install OMP authority dependencies
working-directory: .continuity/omp
run: bun install --frozen-lockfile
- name: Build OMP native addon
working-directory: .continuity/omp
run: bun run build:native
- name: Run legacy bridge continuity gate
env:
T4_OMP_SOURCE_DIR: ${{ github.workspace }}/.continuity/omp
run: pnpm test:legacy-bridge-continuity
- name: Upload continuity evidence
if: ${{ always() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: legacy-bridge-continuity-${{ github.run_id }}
path: artifacts/legacy-bridge-continuity/
if-no-files-found: error
retention-days: 14
official-omp-gate0:
needs: changes
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.official_omp_gate0 == 'true' }}
strategy:
fail-fast: false
matrix:
include:
- platform: linux-x64
runner: ubuntu-24.04
- platform: linux-arm64
runner: ubuntu-24.04-arm
- platform: darwin-arm64
runner: macos-15
name: official-omp-gate0 (${{ matrix.platform }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 10
steps:
- name: Check out exact T4 source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- 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 Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.14
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Prove the pinned unmodified official OMP runtime
run: pnpm --filter @t4-code/host-service verify:official-omp-lifecycle
- name: Prove the packaged T4 host against official OMP
run: pnpm --filter @t4-code/host-daemon verify:official-omp-packaged
- name: Upload official OMP Gate 0 evidence
if: ${{ success() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: official-omp-gate0-${{ matrix.platform }}-${{ github.run_id }}
path: |
artifacts/official-omp-gate0/${{ matrix.platform }}.json
artifacts/official-omp-packaged-host/${{ matrix.platform }}.json
if-no-files-found: error
retention-days: 14
cluster:
needs: changes
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.cluster == 'true' }}
runs-on: ubuntu-24.04
timeout-minutes: 25
steps:
- name: Check out source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- 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
cache: pnpm
- name: Install Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.14
- name: Install Go
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6
with:
go-version: "1.25.5"
cache-dependency-path: packages/cluster-operator/go.sum
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Install pinned Helm
shell: bash
run: |
set -euo pipefail
curl -fsSLo /tmp/helm.tar.gz https://get.helm.sh/helm-v3.19.0-linux-amd64.tar.gz
echo "a7f81ce08007091b86d8bd696eb4d86b8d0f2e1b9f6c714be62f82f96a594496 /tmp/helm.tar.gz" | sha256sum -c -
tar -xzf /tmp/helm.tar.gz -C /tmp
sudo install -m 0755 /tmp/linux-amd64/helm /usr/local/bin/helm
- name: Run cluster CI proof contracts
run: pnpm test:cluster:ci
- name: Run cluster server tests
run: pnpm --filter @t4-code/cluster-server test
- name: Typecheck cluster server
run: pnpm --filter @t4-code/cluster-server typecheck
- name: Run cluster protocol contracts
run: |
pnpm --filter @t4-code/host-wire exec bun test test/cluster-operator.test.ts
pnpm --filter @t4-code/host-service exec bun test test/cluster-default-off.test.ts
- name: Run operator tests
working-directory: packages/cluster-operator
env:
GOFLAGS: -mod=readonly
run: go test ./...
- name: Lint cluster chart
run: helm lint deploy/charts/t4-cluster
tooling:
needs: changes
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.tooling == 'true' }}
runs-on: ubuntu-24.04
timeout-minutes: 25
steps:
- name: Check out source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- 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
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run tooling regression tests
run: pnpm test:tooling
android-debug:
needs: changes
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.android_debug == 'true' }}
runs-on: ubuntu-24.04
timeout-minutes: 35
steps:
- name: Check out source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- 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
cache: pnpm
- name: Install Java
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4
with:
distribution: temurin
java-version: "21"
cache: gradle
- name: Install Android SDK
uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3
- name: Install pinned Android platform and build tools
run: sdkmanager --install "platforms;android-36" "build-tools;36.0.0"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build web application
run: pnpm build:web
- name: Verify unsigned Android debug application
run: pnpm --filter @t4-code/mobile check:android:debug
flutter:
needs: changes
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.flutter == 'true' }}
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- name: Check out source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- 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
cache: pnpm
- 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: Check Flutter source
run: pnpm check:flutter
- name: Run Flutter tests with coverage gate
run: pnpm --filter @t4-code/flutter test:coverage
- name: Build Flutter web application
run: pnpm build:flutter:web
flutter-android:
needs: changes
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.flutter_android == 'true' }}
runs-on: ubuntu-24.04
timeout-minutes: 35
steps:
- name: Check out source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Install Java
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4
with:
distribution: temurin
java-version: "21"
cache: gradle
- name: Install Flutter
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
flutter-version: 3.44.6
channel: stable
cache: true
- name: Build Flutter Android application
working-directory: apps/flutter
run: flutter build apk --debug
- name: Run Flutter Android native tests
working-directory: apps/flutter/android
run: ./gradlew app:testDebugUnitTest
- name: Enable Android emulator acceleration
run: sudo chmod 666 /dev/kvm
- name: Run Flutter Android device smoke test
uses: ReactiveCircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2
with:
api-level: 35
arch: x86_64
profile: pixel_6
script: cd apps/flutter && flutter test integration_test/app_smoke_test.dart -d emulator-5554
flutter-apple:
needs: changes
if: ${{ github.event_name != 'pull_request' || needs.changes.outputs.flutter_apple == 'true' }}
runs-on: macos-15
timeout-minutes: 40
steps:
- name: Check out source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Install Flutter
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
with:
flutter-version: 3.44.6
channel: stable
cache: true
- name: Build Flutter iOS simulator application
working-directory: apps/flutter
run: flutter build ios --simulator --debug
- name: Run Flutter iOS launch smoke test
working-directory: apps/flutter
shell: bash
run: |
set -euo pipefail
DEVICE_ID="$(xcrun simctl list devices available -j | python3 -c 'import json,sys; data=json.load(sys.stdin); print(next(device["udid"] for devices in data["devices"].values() for device in devices if device["name"].startswith("iPhone")))')"
BUNDLE_ID="com.lycaonsolutions.t4code"
xcrun simctl boot "$DEVICE_ID" 2>/dev/null || true
xcrun simctl bootstatus "$DEVICE_ID" -b
xcrun simctl install "$DEVICE_ID" build/ios/iphonesimulator/Runner.app
trap 'xcrun simctl terminate "$DEVICE_ID" "$BUNDLE_ID" 2>/dev/null || true' EXIT
launch_output="$(xcrun simctl launch --terminate-running-process "$DEVICE_ID" "$BUNDLE_ID")"
app_pid="$(sed -nE 's/^.*: ([0-9]+)$/\1/p' <<<"$launch_output" | tail -n 1)"
[[ "$app_pid" =~ ^[0-9]+$ ]]
sleep 5
kill -0 "$app_pid"
- 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
cache: pnpm
- name: Install Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: 1.3.14
- name: Install T4 dependencies
run: pnpm install --frozen-lockfile
- name: Build standalone T4 host for Flutter macOS
run: pnpm build:host
- name: Build Flutter macOS application
working-directory: apps/flutter
run: flutter build macos --debug
- name: Verify bundled Flutter macOS host
run: test -x apps/flutter/build/macos/Build/Products/Debug/t4code.app/Contents/Resources/runtime/t4-host
- name: Run Flutter macOS native tests
working-directory: apps/flutter/macos
run: xcodebuild test -workspace Runner.xcworkspace -scheme Runner -configuration Debug -destination 'platform=macOS' CODE_SIGNING_ALLOWED=NO
verify:
name: verify
if: ${{ always() }}
needs: [changes, core, legacy-bridge-continuity, official-omp-gate0, cluster, tooling, android-debug, flutter, flutter-android, flutter-apple]
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- name: Require every selected CI leg
shell: bash
env:
CHANGES_RESULT: ${{ needs.changes.result }}
CORE_RESULT: ${{ needs.core.result }}
CONTINUITY_RESULT: ${{ needs.legacy-bridge-continuity.result }}
OFFICIAL_OMP_GATE0_RESULT: ${{ needs.official-omp-gate0.result }}
CLUSTER_RESULT: ${{ needs.cluster.result }}
TOOLING_RESULT: ${{ needs.tooling.result }}
ANDROID_RESULT: ${{ needs.android-debug.result }}
FLUTTER_RESULT: ${{ needs.flutter.result }}
FLUTTER_ANDROID_RESULT: ${{ needs.flutter-android.result }}
FLUTTER_APPLE_RESULT: ${{ needs.flutter-apple.result }}
run: |
set -euo pipefail
test "$CHANGES_RESULT" = success
test "$CORE_RESULT" = success
for result in \
"$CONTINUITY_RESULT" \
"$OFFICIAL_OMP_GATE0_RESULT" \
"$CLUSTER_RESULT" \
"$TOOLING_RESULT" \
"$ANDROID_RESULT" \
"$FLUTTER_RESULT" \
"$FLUTTER_ANDROID_RESULT" \
"$FLUTTER_APPLE_RESULT"
do
case "$result" in
success|skipped) ;;
*) exit 1 ;;
esac
done