The Dart suite spent 77% of its cost compiling one isolate per test file while `flutter test` used half the cores, and every Maestro flow replayed a full Jellyfin onboarding before its first real assertion. - Add scripts/run_tests.sh, which runs `flutter test` with -j set to the cores the process may actually use instead of the ncpu/2 default. Measured on 8 cores: 190s -> 136s; -j 12 regresses to 165s, so it scales to the core count rather than hard-coding one. CI and CONTRIBUTING use it. A cgroup v2 quota, a cgroup v1 quota, and the cpuset/affinity nproc reports can each be the binding limit independently, so the detector takes the smallest; trusting whichever it found first would oversubscribe 4x on a container holding an 8-CPU quota while pinned to 2. Covered by scripts/test_run_tests.py, which the ci_guard_checks.sh glob picks up. - Add .maestro/subflows/ensure_onboarded.yaml: cold-start the app and only onboard when no session is stored. Flows that just need a signed-in Home use it; 02_onboarding_home, 08_logout, 09_download_offline_playback and the profile regressions keep clearing state. 59s -> 16s per flow. - Guard onboarding's two optional taps behind visibility checks. A missed `optional: true` tap still runs the full element search, costing 3.0s and 7.8s per onboarding to find nothing. - Disable device animation scales in run_maestro.py, restored by the existing cleanup path. CI's emulator got this from the runner flag; physical devices never did. - Shorten the watch_together setup-timeout replacement from 500ms to the 10ms the same file already proves sufficient, and shorten the retry backoff at the one site that missed it: 8.04s -> 1.59s of execution. - Make the LAN discovery waits deadline-based and resend the beacon while polling. Loopback UDP drops datagrams under load, which timed out a wait that could never be satisfied; this was the suite's one flaky test. - Fix 08_logout, which searched for "Logout" and "Are you sure you want to logout?" after both strings became "Log out". The flow had been failing and aborting the suite before 09 ever ran. flutter test 190s -> 131s. Maestro's Android suite 621s -> 385s across the eight flows the baseline reached, and now runs all nine green.
578 lines
18 KiB
YAML
578 lines
18 KiB
YAML
name: CI - Sanity Checks
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
# Keep untrusted code on the read-only pull_request event. Never use pull_request_target here.
|
|
pull_request:
|
|
branches:
|
|
- main
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
# Only place this workflow names the SDK; .github/actions/setup-flutter-git pins the same release.
|
|
FLUTTER_VERSION: "3.44.0"
|
|
|
|
jobs:
|
|
analyze:
|
|
name: Code Analysis
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Flutter
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
cache: true
|
|
pub-cache: false
|
|
|
|
- name: Cache Pub dependencies
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
|
|
with:
|
|
path: |
|
|
~/.pub-cache
|
|
key: ${{ runner.os }}-pub-v3-${{ hashFiles('**/pubspec.yaml', '**/pubspec.lock') }}
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
|
|
flutter pub get
|
|
|
|
- name: Install wakelock_plus development dependencies
|
|
working-directory: packages/wakelock_plus
|
|
run: flutter pub get --enforce-lockfile --no-example
|
|
|
|
- name: Verify generated files committed
|
|
run: scripts/codegen.sh --check
|
|
|
|
- name: Verify translation hygiene
|
|
run: python3 scripts/clean_translations.py --check --strict
|
|
|
|
- name: Verify workflow and script guards
|
|
run: bash scripts/ci_guard_checks.sh
|
|
|
|
- name: Verify formatting
|
|
run: |
|
|
paths=(lib)
|
|
[ ! -d test ] || paths+=(test)
|
|
find "${paths[@]}" -name "*.dart" ! -name "*.g.dart" ! -name "*.freezed.dart" -type f -print0 |
|
|
xargs -0 -r dart format --output=none --set-exit-if-changed
|
|
|
|
- name: Verify icon consistency
|
|
run: dart run scripts/check_icon_consistency.dart
|
|
|
|
- name: Analyze code
|
|
run: dart run scripts/check_analyzer.dart
|
|
|
|
- name: Check for unused code
|
|
run: |
|
|
echo "🔍 Checking for unused code..."
|
|
dart run dart_code_linter:metrics check-unused-code lib 2>&1 | tee unused_code.txt
|
|
if grep -qi "no unused code found" unused_code.txt; then
|
|
echo "✅ No unused code found"
|
|
else
|
|
echo "❌ Found unused code:"
|
|
cat unused_code.txt
|
|
exit 1
|
|
fi
|
|
|
|
- name: Check for unused files
|
|
run: |
|
|
echo "🔍 Checking for unused files..."
|
|
dart run dart_code_linter:metrics check-unused-files lib 2>&1 | tee unused_files.txt
|
|
if grep -qi "no unused files found" unused_files.txt; then
|
|
echo "✅ No unused files found"
|
|
else
|
|
echo "❌ Found unused files:"
|
|
cat unused_files.txt
|
|
exit 1
|
|
fi
|
|
|
|
test:
|
|
name: Unit Tests
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Flutter
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
cache: true
|
|
pub-cache: false
|
|
|
|
- name: Cache Pub dependencies
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
|
|
with:
|
|
path: |
|
|
~/.pub-cache
|
|
key: ${{ runner.os }}-pub-v3-${{ hashFiles('**/pubspec.yaml', '**/pubspec.lock') }}
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
flutter clean
|
|
flutter pub get
|
|
|
|
- name: Run tests
|
|
run: |
|
|
if [ -d "test" ] && [ "$(find test -name '*_test.dart' | wc -l)" -gt 0 ]; then
|
|
scripts/run_tests.sh
|
|
else
|
|
echo "No tests found, skipping test execution"
|
|
fi
|
|
|
|
- name: Install wakelock_plus test dependencies
|
|
working-directory: packages/wakelock_plus
|
|
run: flutter pub get --enforce-lockfile
|
|
|
|
- name: Run wakelock_plus VM tests
|
|
working-directory: packages/wakelock_plus
|
|
run: flutter test test/wakelock_plus_linux_plugin_test.dart
|
|
|
|
- name: Run wakelock_plus Chrome tests
|
|
working-directory: packages/wakelock_plus
|
|
run: flutter test --platform chrome --dart-define=WEB_PLUGIN_TESTS=true test/wakelock_plus_web_plugin_test.dart
|
|
|
|
android-test:
|
|
name: Android JVM and Native Tests
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Java
|
|
uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5
|
|
with:
|
|
distribution: "temurin"
|
|
java-version: "21"
|
|
|
|
- name: Setup Flutter
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
cache: true
|
|
pub-cache: false
|
|
|
|
- name: Cache Pub dependencies
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
|
|
with:
|
|
path: |
|
|
~/.pub-cache
|
|
key: ${{ runner.os }}-pub-v3-${{ hashFiles('**/pubspec.yaml', '**/pubspec.lock') }}
|
|
|
|
- name: Cache Gradle
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
|
|
with:
|
|
path: |
|
|
~/.gradle/caches
|
|
~/.gradle/wrapper
|
|
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-gradle-
|
|
|
|
- name: Install dependencies
|
|
run: flutter pub get
|
|
|
|
- name: Configure Android local properties
|
|
run: printf 'flutter.sdk=%s\nsdk.dir=%s\n' "$FLUTTER_ROOT" "$ANDROID_HOME" > android/local.properties
|
|
|
|
- name: Configure Android host native tests
|
|
run: |
|
|
cmake -S android/app/src/test/cpp -B build/android-host-tests \
|
|
-DCMAKE_BUILD_TYPE=Debug
|
|
|
|
- name: Build Android host native tests
|
|
run: cmake --build build/android-host-tests --parallel 2
|
|
|
|
- name: Run Android host native tests
|
|
run: |
|
|
ctest --test-dir build/android-host-tests \
|
|
--output-on-failure --no-tests=error
|
|
|
|
- name: Run Android JVM unit tests
|
|
working-directory: android
|
|
run: ./gradlew :app:testDebugUnitTest :saf_util:testDebugUnitTest :libass:testDebugUnitTest -x :app:compileFlutterBuildDebug --continue
|
|
|
|
- name: Check Android API compatibility
|
|
working-directory: android
|
|
run: ./gradlew :app:lintDebug
|
|
|
|
native-format:
|
|
name: Native Formatting
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Java
|
|
uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5
|
|
with:
|
|
distribution: "temurin"
|
|
java-version: "17"
|
|
|
|
- name: Verify native formatting
|
|
run: scripts/format_native.sh --check
|
|
|
|
- name: Verify Linux native acquisition integrity
|
|
run: bash linux/packaging/build-libmpv_test.sh
|
|
|
|
linux-native-test:
|
|
name: Linux native reliability (${{ matrix.sanitizer }})
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- sanitizer: address
|
|
lifecycle_sanitizers: ON
|
|
- sanitizer: thread
|
|
lifecycle_sanitizers: OFF
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Flutter
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
cache: true
|
|
pub-cache: false
|
|
|
|
- name: Install Linux native test dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y --no-install-recommends \
|
|
clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev \
|
|
libstdc++-12-dev libmpv-dev libepoxy-dev libcurl4-openssl-dev libevdev-dev
|
|
|
|
- name: Prepare Flutter Linux configuration
|
|
run: |
|
|
flutter pub get --enforce-lockfile --no-example
|
|
flutter build linux --debug --config-only --no-pub
|
|
|
|
- name: Configure Linux native reliability tests
|
|
run: |
|
|
cmake -S linux -B build/linux-native-${{ matrix.sanitizer }} -G Ninja \
|
|
-DCMAKE_BUILD_TYPE=Debug \
|
|
-DPLEZY_BUILD_MPV_PLAYER_LIFECYCLE_TESTS=ON \
|
|
-DPLEZY_MPV_LIFECYCLE_SANITIZERS=${{ matrix.lifecycle_sanitizers }} \
|
|
-DPLEZY_BUILD_MPV_RELIABILITY_TESTS=ON \
|
|
-DPLEZY_MPV_RELIABILITY_SANITIZER=${{ matrix.sanitizer }}
|
|
|
|
- name: Build Linux native reliability tests
|
|
run: |
|
|
cmake --build build/linux-native-${{ matrix.sanitizer }} --parallel 2 --target \
|
|
mpv_player_lifecycle_test \
|
|
mpv_property_result_contract_test \
|
|
mpv_gpu_bootstrap_test
|
|
|
|
- name: Run Linux native reliability tests
|
|
run: |
|
|
ctest --test-dir build/linux-native-${{ matrix.sanitizer }} \
|
|
--output-on-failure --no-tests=error
|
|
|
|
apple-native-test:
|
|
name: Apple native reliability (${{ matrix.platform }})
|
|
runs-on: macos-26
|
|
permissions:
|
|
contents: read
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- platform: iOS
|
|
project_directory: ios
|
|
workspace: ios/Runner.xcworkspace
|
|
simulator_runtime: iOS
|
|
simulator_platform: iOS
|
|
static_destination: ""
|
|
- platform: macOS
|
|
project_directory: macos
|
|
workspace: macos/Runner.xcworkspace
|
|
simulator_runtime: ""
|
|
simulator_platform: ""
|
|
static_destination: platform=macOS
|
|
- platform: tvOS
|
|
project_directory: tvos
|
|
workspace: tvos/Runner.xcworkspace
|
|
simulator_runtime: tvOS
|
|
simulator_platform: tvOS
|
|
static_destination: ""
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Flutter
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
cache: true
|
|
pub-cache: false
|
|
|
|
- name: Install locked Dart dependencies
|
|
run: flutter pub get --enforce-lockfile --no-example
|
|
|
|
- name: Record committed CocoaPods lockfile
|
|
if: matrix.platform != 'tvOS'
|
|
env:
|
|
PODFILE_LOCK: ${{ matrix.project_directory }}/Podfile.lock
|
|
run: |
|
|
test -f "$PODFILE_LOCK"
|
|
shasum -a 256 "$PODFILE_LOCK" > "$RUNNER_TEMP/plezy-podfile-lock.sha256"
|
|
|
|
- name: Prepare iOS Flutter build settings
|
|
if: matrix.platform == 'iOS'
|
|
run: flutter build ios --config-only --simulator --debug --no-pub
|
|
|
|
- name: Prepare macOS Flutter build settings
|
|
if: matrix.platform == 'macOS'
|
|
run: flutter build macos --config-only --debug --no-pub
|
|
|
|
- name: Prepare tvOS Flutter engine
|
|
if: matrix.platform == 'tvOS'
|
|
run: tvos/scripts/fetch_engine.sh
|
|
|
|
- name: Verify Flutter configuration preserved CocoaPods lockfile
|
|
if: matrix.platform != 'tvOS'
|
|
run: shasum -a 256 --check "$RUNNER_TEMP/plezy-podfile-lock.sha256"
|
|
|
|
- name: Install locked CocoaPods dependencies
|
|
if: matrix.platform != 'tvOS'
|
|
working-directory: ${{ matrix.project_directory }}
|
|
run: pod install --deployment
|
|
|
|
- name: Install tvOS CocoaPods dependencies
|
|
if: matrix.platform == 'tvOS'
|
|
run: tvos/scripts/pod_install.sh
|
|
|
|
- name: Verify tvOS project wiring
|
|
if: matrix.platform == 'tvOS'
|
|
run: ruby tvos/scripts/test_wire_mpv.rb
|
|
|
|
- name: Select Apple test destination
|
|
env:
|
|
SIMULATOR_RUNTIME: ${{ matrix.simulator_runtime }}
|
|
SIMULATOR_PLATFORM: ${{ matrix.simulator_platform }}
|
|
STATIC_DESTINATION: ${{ matrix.static_destination }}
|
|
run: |
|
|
python3 - <<'PY'
|
|
import json
|
|
import os
|
|
import subprocess
|
|
|
|
destination = os.environ["STATIC_DESTINATION"]
|
|
if not destination:
|
|
runtime_name = os.environ["SIMULATOR_RUNTIME"]
|
|
payload = json.loads(
|
|
subprocess.check_output(
|
|
["xcrun", "simctl", "list", "devices", "available", "-j"],
|
|
text=True,
|
|
)
|
|
)
|
|
devices = [
|
|
device
|
|
for runtime, candidates in payload["devices"].items()
|
|
if f".{runtime_name}-" in runtime
|
|
for device in candidates
|
|
if device.get("isAvailable", False)
|
|
]
|
|
if not devices:
|
|
raise SystemExit(f"no available {runtime_name} simulator")
|
|
destination = (
|
|
f"platform={os.environ['SIMULATOR_PLATFORM']} Simulator,"
|
|
f"id={devices[0]['udid']}"
|
|
)
|
|
with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as output:
|
|
output.write(f"APPLE_TEST_DESTINATION={destination}\n")
|
|
PY
|
|
|
|
- name: Run Apple native reliability tests
|
|
run: |
|
|
xcodebuild test \
|
|
-workspace "${{ matrix.workspace }}" \
|
|
-scheme Runner \
|
|
-configuration Debug \
|
|
-destination "$APPLE_TEST_DESTINATION" \
|
|
-disableAutomaticPackageResolution \
|
|
CODE_SIGNING_ALLOWED=NO \
|
|
COMPILER_INDEX_STORE_ENABLE=NO
|
|
|
|
windows-native-test:
|
|
name: Windows native reliability (${{ matrix.arch }})
|
|
runs-on: ${{ matrix.runner }}
|
|
permissions:
|
|
contents: read
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- arch: x64
|
|
runner: windows-latest
|
|
flutter_setup: action
|
|
- arch: arm64
|
|
runner: windows-11-arm
|
|
flutter_setup: git
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Install 7-Zip
|
|
if: matrix.arch == 'arm64'
|
|
shell: pwsh
|
|
run: choco install 7zip -y
|
|
|
|
- name: Setup Flutter
|
|
if: matrix.flutter_setup == 'action'
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
cache: true
|
|
pub-cache: false
|
|
|
|
- name: Set up Flutter from its pinned commit
|
|
if: matrix.flutter_setup == 'git'
|
|
uses: ./.github/actions/setup-flutter-git
|
|
|
|
- name: Install locked Dart dependencies
|
|
shell: pwsh
|
|
run: flutter pub get --enforce-lockfile --no-example
|
|
|
|
- name: Install patched Flutter engine
|
|
shell: pwsh
|
|
run: |
|
|
flutter precache --windows
|
|
.\windows\tool\install-patched-engine.ps1
|
|
|
|
- name: Prepare Flutter Windows configuration
|
|
shell: pwsh
|
|
run: flutter build windows --debug --config-only --no-pub
|
|
|
|
- name: Configure Windows native reliability tests
|
|
shell: pwsh
|
|
run: |
|
|
$buildDir = "build/windows/${{ matrix.arch }}"
|
|
cmake -S windows -B $buildDir `
|
|
-DPLEZY_BUILD_MPV_PROPERTY_CONTRACT_TESTS=ON `
|
|
-DPLEZY_BUILD_DISPLAY_RECOVERY_TESTS=ON
|
|
|
|
- name: Build Windows native reliability tests
|
|
shell: pwsh
|
|
run: |
|
|
$buildDir = "build/windows/${{ matrix.arch }}"
|
|
cmake --build $buildDir --config Debug --parallel 2 --target `
|
|
mpv_property_result_contract_test `
|
|
mpv_player_property_contract_test `
|
|
display_mode_manager_test
|
|
|
|
- name: Run Windows native reliability tests
|
|
shell: pwsh
|
|
run: |
|
|
$buildDir = "build/windows/${{ matrix.arch }}"
|
|
ctest --test-dir "$buildDir/runner" -C Debug --output-on-failure --no-tests=error
|
|
|
|
dependency-check:
|
|
name: Dependency Validation
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Flutter
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
cache: true
|
|
pub-cache: false
|
|
|
|
- name: Cache Pub dependencies
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
|
|
with:
|
|
path: |
|
|
~/.pub-cache
|
|
key: ${{ runner.os }}-pub-v3-${{ hashFiles('**/pubspec.yaml', '**/pubspec.lock') }}
|
|
|
|
- name: Verify dependencies
|
|
run: |
|
|
flutter clean
|
|
flutter pub get
|
|
flutter pub outdated
|
|
|
|
server:
|
|
name: Server checks
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Go
|
|
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6
|
|
with:
|
|
go-version-file: server/go.mod
|
|
cache-dependency-path: server/go.sum
|
|
|
|
- name: Run server checks
|
|
run: scripts/ci_server_checks.sh
|
|
|
|
|
|
website:
|
|
name: Website checks
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
|
with:
|
|
bun-version: "1.3.14"
|
|
|
|
- name: Run website checks
|
|
run: scripts/ci_website_checks.sh
|