Skip to content

sync

sync #75

Workflow file for this run

name: CI
on:
push:
branches: [master, develop]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
PUB_ENVIRONMENT: bot.github
jobs:
dependency_review:
name: Dependency Review
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Dependency Review
uses: actions/dependency-review-action@v5
analysis:
name: Analysis
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Flutter Version Info
run: flutter doctor -v
- name: Cache Pub Dependencies
uses: actions/cache@v6
with:
path: |
~/.pub-cache
.dart_tool
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.yaml') }}
restore-keys: |
${{ runner.os }}-pub-
- name: Install Workspace Dependencies
run: flutter pub get
- name: Lint Code
run: dart run melos exec -- flutter analyze
formatting:
name: Formatting
needs: analysis
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Cache Pub Dependencies
uses: actions/cache@v6
with:
path: |
~/.pub-cache
.dart_tool
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.yaml') }}
restore-keys: |
${{ runner.os }}-pub-
- name: Install Workspace Dependencies
run: flutter pub get
- name: Check Code Formatting
run: dart run melos format --output none --set-exit-if-changed
unit_tests:
name: Unit Tests
needs: formatting
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Cache Pub Dependencies
uses: actions/cache@v6
with:
path: |
~/.pub-cache
.dart_tool
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.yaml') }}
restore-keys: |
${{ runner.os }}-pub-
- name: Install Workspace Dependencies
run: flutter pub get
- name: Run Unit Tests with Coverage
working-directory: flutter_secure_storage
run: flutter test --coverage
- name: Upload Coverage Report
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: flutter_secure_storage/coverage/lcov.info
- name: Upload Flutter Coverage to Codecov
uses: codecov/codecov-action@v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: flutter_secure_storage/coverage/lcov.info
flags: flutter
name: codecov-flutter
fail_ci_if_error: true
unit_tests_android:
name: Android Unit Tests
needs: formatting
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up JDK 17
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "17"
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Install Workspace Dependencies
run: flutter pub get
- name: Build Example App (generates native build files)
working-directory: flutter_secure_storage/example
run: flutter build apk --debug
- name: Run Android Unit Tests with Coverage
working-directory: flutter_secure_storage/example/android
run: ./gradlew :flutter_secure_storage:jacocoTestReport
- name: Upload Android Coverage to Codecov
uses: codecov/codecov-action@v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: flutter_secure_storage/android/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml
flags: android
name: codecov-android
fail_ci_if_error: true
unit_tests_web:
name: Web Unit Tests
needs: formatting
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Install Workspace Dependencies
run: flutter pub get
- name: Run Web Unit Tests
working-directory: flutter_secure_storage_web
run: flutter test --platform chrome
unit_tests_windows:
name: Windows Unit Tests
needs: formatting
runs-on: windows-latest
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Install Workspace Dependencies
run: flutter pub get
- name: Run Windows Unit Tests with Coverage
working-directory: flutter_secure_storage_windows
run: flutter test --coverage
- name: Upload Windows Coverage to Codecov
uses: codecov/codecov-action@v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: flutter_secure_storage_windows/coverage/lcov.info
flags: windows
name: codecov-windows
fail_ci_if_error: true
native_tests_windows:
name: Windows Native Tests
needs: formatting
runs-on: windows-latest
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Install Melos
shell: pwsh
run: |
flutter pub global activate melos
Add-Content $env:GITHUB_PATH "$env:PUB_CACHE\bin"
- name: Bootstrap Workspace with Melos
shell: pwsh
run: melos bootstrap
- name: Build Windows Example and Native Tests
working-directory: flutter_secure_storage/example
run: flutter build windows --debug
- name: Run Native Windows Tests
working-directory: flutter_secure_storage/example
shell: pwsh
run: |
ctest --test-dir build/windows/x64/plugins/flutter_secure_storage_windows `
--output-on-failure `
-C Debug
integration_tests_windows:
name: Windows Integration Tests
needs: [unit_tests, unit_tests_windows]
runs-on: windows-latest
timeout-minutes: 20
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Install Melos
shell: pwsh
run: |
flutter pub global activate melos
Add-Content $env:GITHUB_PATH "$env:PUB_CACHE\bin"
- name: Bootstrap Workspace with Melos
shell: pwsh
run: melos bootstrap
- name: Build Windows Example App
working-directory: flutter_secure_storage/example
run: flutter build windows --debug
- name: Run Windows Integration Tests
working-directory: flutter_secure_storage/example
run: flutter test integration_test/windows_test.dart -d windows
native_tests_linux:
name: Linux Native Tests
needs: formatting
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Install Linux Build Dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y clang cmake ninja-build pkg-config \
libgtk-3-dev libblkid-dev liblzma-dev libsecret-1-dev \
gnome-keyring dbus-x11
- name: Install Melos
run: |
flutter pub global activate melos
echo "$HOME/.pub-cache/bin" >> $GITHUB_PATH
- name: Bootstrap Workspace with Melos
run: melos bootstrap
- name: Build Linux Example and Native Tests
working-directory: flutter_secure_storage/example
run: flutter build linux --debug
- name: Start D-Bus Session and Unlock Keyring
run: |
eval $(dbus-launch --sh-syntax)
echo "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS" >> $GITHUB_ENV
echo "DBUS_SESSION_BUS_PID=$DBUS_SESSION_BUS_PID" >> $GITHUB_ENV
echo "" | gnome-keyring-daemon --unlock --daemonize --components=secrets
- name: Run Native Linux Tests
working-directory: flutter_secure_storage/example/build/linux/x64/debug/plugins/flutter_secure_storage_linux
run: ctest --output-on-failure
integration_tests_linux:
name: Linux Integration Tests
needs: [unit_tests, native_tests_linux]
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Install Linux Build Dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y clang cmake ninja-build pkg-config \
libgtk-3-dev libblkid-dev liblzma-dev libsecret-1-dev \
libsecret-tools gnome-keyring dbus-x11 xvfb
- name: Install Melos
run: |
flutter pub global activate melos
echo "$HOME/.pub-cache/bin" >> $GITHUB_PATH
- name: Bootstrap Workspace with Melos
run: melos bootstrap
- name: Start D-Bus Session and Keyring Daemon (no default collection)
run: |
eval $(dbus-launch --sh-syntax)
echo "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS" >> $GITHUB_ENV
echo "DBUS_SESSION_BUS_PID=$DBUS_SESSION_BUS_PID" >> $GITHUB_ENV
gnome-keyring-daemon --daemonize --components=secrets
- name: Verify Default Collection Is Missing
run: |
alias_path=$(gdbus call --session \
--dest org.freedesktop.secrets \
--object-path /org/freedesktop/secrets \
--method org.freedesktop.Secret.Service.ReadAlias default)
test "$alias_path" = "(objectpath '/',)"
gdbus call --session \
--dest org.freedesktop.secrets \
--object-path /org/freedesktop/secrets \
--method org.freedesktop.DBus.Properties.Get \
org.freedesktop.Secret.Service Collections \
> "$RUNNER_TEMP/secret-service-collections-before.txt"
env DISPLAY= dbus-update-activation-environment DISPLAY
- name: Run Linux Missing-Collection Integration Tests
working-directory: flutter_secure_storage/example
run: xvfb-run flutter test integration_test/linux_missing_default_collection_test.dart -d linux
- name: Verify Missing-Collection Operations Did Not Create a Collection
run: |
alias_path=$(gdbus call --session \
--dest org.freedesktop.secrets \
--object-path /org/freedesktop/secrets \
--method org.freedesktop.Secret.Service.ReadAlias default)
test "$alias_path" = "(objectpath '/',)"
gdbus call --session \
--dest org.freedesktop.secrets \
--object-path /org/freedesktop/secrets \
--method org.freedesktop.DBus.Properties.Get \
org.freedesktop.Secret.Service Collections \
> "$RUNNER_TEMP/secret-service-collections-after.txt"
diff -u \
"$RUNNER_TEMP/secret-service-collections-before.txt" \
"$RUNNER_TEMP/secret-service-collections-after.txt"
- name: Unlock Keyring
run: echo "" | gnome-keyring-daemon --unlock --replace --components=secrets
- name: Run Linux Integration Tests
working-directory: flutter_secure_storage/example
run: xvfb-run flutter test integration_test/linux_test.dart -d linux
- name: Run Linux Nonmatching-Secret Integration Tests
working-directory: flutter_secure_storage/example
run: |
service=/org/freedesktop/secrets
fixture_attr=fss-test-fixture
fixture_id=unrelated
fixture_value=preserve-me
cleanup() {
status=$?
trap - EXIT
if ! secret-tool clear "$fixture_attr" "$fixture_id" >/dev/null 2>&1; then
test "$status" -ne 0 || status=1
fi
if ! echo "" | gnome-keyring-daemon \
--unlock --replace --components=secrets >/dev/null; then
test "$status" -ne 0 || status=1
fi
exit "$status"
}
trap cleanup EXIT
alias_call=$(gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$service" \
--method org.freedesktop.Secret.Service.ReadAlias default)
alias_path=$(printf '%s' "$alias_call" | \
sed -n "s/.*objectpath '\([^']*\)'.*/\1/p")
test -n "$alias_path"
test "$alias_path" != "/"
gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$service" \
--method org.freedesktop.Secret.Service.SetAlias \
default /org/freedesktop/secrets/collection/session >/dev/null
printf '%s' "$fixture_value" | secret-tool store \
--label='flutter_secure_storage unrelated integration fixture' \
"$fixture_attr" "$fixture_id"
test "$(secret-tool lookup "$fixture_attr" "$fixture_id")" = \
"$fixture_value"
gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$service" \
--method org.freedesktop.Secret.Service.SetAlias \
default "$alias_path" >/dev/null
gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$alias_path" \
--method org.freedesktop.Secret.Collection.Delete >/dev/null
test "$(gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$service" \
--method org.freedesktop.Secret.Service.ReadAlias default)" = \
"(objectpath '/',)"
collections_before=$(gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$service" \
--method org.freedesktop.DBus.Properties.Get \
org.freedesktop.Secret.Service Collections)
xvfb-run flutter test \
integration_test/linux_missing_default_collection_test.dart -d linux
test "$(gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$service" \
--method org.freedesktop.Secret.Service.ReadAlias default)" = \
"(objectpath '/',)"
collections_after=$(gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$service" \
--method org.freedesktop.DBus.Properties.Get \
org.freedesktop.Secret.Service Collections)
test "$collections_after" = "$collections_before"
test "$(secret-tool lookup "$fixture_attr" "$fixture_id")" = \
"$fixture_value"
- name: Lock Default Collection
run: |
alias_call=$(gdbus call --session \
--dest org.freedesktop.secrets \
--object-path /org/freedesktop/secrets \
--method org.freedesktop.Secret.Service.ReadAlias default)
alias_path=$(printf '%s' "$alias_call" | \
sed -n "s/.*objectpath '\([^']*\)'.*/\1/p")
test -n "$alias_path"
test "$alias_path" != "/"
gdbus call --session \
--dest org.freedesktop.secrets \
--object-path /org/freedesktop/secrets \
--method org.freedesktop.Secret.Service.Lock \
"[objectpath '$alias_path']"
locked=$(gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$alias_path" \
--method org.freedesktop.DBus.Properties.Get \
org.freedesktop.Secret.Collection Locked)
test "$locked" = "(<true>,)"
env DISPLAY= dbus-update-activation-environment DISPLAY
- name: Run Linux Locked-Keyring Integration Tests
working-directory: flutter_secure_storage/example
run: xvfb-run flutter test integration_test/linux_locked_keyring_test.dart -d linux
- name: Unlock Keyring After Locked-Keyring Tests
run: echo "" | gnome-keyring-daemon --unlock --replace --components=secrets
- name: Run Linux Orphaned-Collection Integration Tests
working-directory: flutter_secure_storage/example
run: |
service=/org/freedesktop/secrets
login_call=$(gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$service" \
--method org.freedesktop.Secret.Service.ReadAlias login)
login_path=$(printf '%s' "$login_call" | \
sed -n "s/.*objectpath '\([^']*\)'.*/\1/p")
test -n "$login_path"
test "$login_path" != "/"
test "$login_path" != "/org/freedesktop/secrets/collection/session"
gdbus call --session \
--dest org.freedesktop.secrets \
--object-path "$service" \
--method org.freedesktop.Secret.Service.SetAlias \
default "$login_path" >/dev/null
xvfb-run flutter test \
--dart-define=FSS_DESTRUCTIVE_KEYRING_TESTS=true \
integration_test/linux_orphaned_collection_test.dart -d linux
integration_tests_android:
name: Android Tests
needs: [unit_tests, unit_tests_android]
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
matrix:
include:
- api-level: 24
target: default
arch: x86_64
- api-level: 36
target: google_apis
arch: x86_64
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Free Disk Space
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
df -h
- name: Set Up JDK 17
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "17"
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Install Workspace Dependencies
run: flutter pub get
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
# - name: Cache Gradle
# uses: gradle/actions/setup-gradle@v5
- name: Pre-build APK
working-directory: flutter_secure_storage/example
run: flutter build apk --debug
- name: Cache AVD
uses: actions/cache@v6
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ matrix.api-level }}-${{ matrix.arch }}
- name: Create AVD Snapshot
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: ${{ matrix.arch }}
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: false
script: >-
echo "Generated AVD snapshot for caching.";
pkill -SIGTERM crashpad_handler || true;
sleep 2;
pkill -SIGKILL crashpad_handler || true
- name: Run Integration Tests
id: integration_tests
continue-on-error: true
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: ${{ matrix.arch }}
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: >-
flutter test integration_test/app_test.dart;
test_exit_code=$?;
pkill -SIGTERM crashpad_handler || true;
sleep 2;
pkill -SIGKILL crashpad_handler || true;
exit $test_exit_code
working-directory: flutter_secure_storage/example
# Retry once in case the run still fails for unrelated infra reasons.
- name: Run Integration Tests (retry)
if: steps.integration_tests.outcome == 'failure'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: ${{ matrix.arch }}
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: >-
flutter test integration_test/app_test.dart;
test_exit_code=$?;
pkill -SIGTERM crashpad_handler || true;
sleep 2;
pkill -SIGKILL crashpad_handler || true;
exit $test_exit_code
working-directory: flutter_secure_storage/example
integration_tests_web:
name: Web Integration Tests
needs: [unit_tests, unit_tests_web]
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Setup ChromeDriver
uses: nanasess/setup-chromedriver@v3
- name: Start ChromeDriver
run: chromedriver --port=4444 &
- name: Install Workspace Dependencies
run: flutter pub get
- name: Run Web Integration Tests
working-directory: flutter_secure_storage/example
run: |
flutter drive \
--driver=test_driver/app_test_test.dart \
--target=integration_test/web_test.dart \
-d web-server
typecheck_swift_ios:
name: Swift iOS Typecheck
runs-on: macos-latest
timeout-minutes: 5
needs: [unit_tests, unit_tests_android]
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Typecheck Swift against iOS 12 minimum
run: |
swiftc -typecheck \
-target arm64-apple-ios12.0 \
-sdk "$(xcrun --sdk iphoneos --show-sdk-path)" \
flutter_secure_storage_darwin/darwin/flutter_secure_storage_darwin/Sources/flutter_secure_storage_darwin/FlutterSecureStorage.swift
- name: Typecheck Swift against latest iOS SDK
run: |
SDK_PATH="$(xcrun --sdk iphoneos --show-sdk-path)"
SDK_VERSION="$(xcrun --sdk iphoneos --show-sdk-version)"
swiftc -typecheck \
-target "arm64-apple-ios${SDK_VERSION}" \
-sdk "$SDK_PATH" \
flutter_secure_storage_darwin/darwin/flutter_secure_storage_darwin/Sources/flutter_secure_storage_darwin/FlutterSecureStorage.swift
native_tests_darwin:
name: Darwin Native Tests
runs-on: macos-latest
timeout-minutes: 20
needs: formatting
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Install Melos
run: flutter pub global activate melos
- name: Bootstrap Melos
run: melos bootstrap
- name: Configure macOS Project
working-directory: flutter_secure_storage/example
run: flutter build macos --config-only --no-pub
- name: Run Darwin Native Tests
working-directory: flutter_secure_storage/example/macos
run: |
xcodebuild test \
-workspace Runner.xcworkspace \
-scheme Runner \
-destination 'platform=macOS' \
-only-testing RunnerTests \
CODE_SIGNING_ALLOWED=NO
integration_tests_ios:
name: iOS Tests
runs-on: macos-latest
timeout-minutes: 30
needs: [typecheck_swift_ios]
env:
SIM_OS: iOS
SIM_OS_VERSION: "26.2"
SIM_DEVICE: "iPhone 17"
steps:
- name: Checkout Repository
uses: actions/checkout@v7
- name: Set Up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Set Up Simulator
id: simulator
uses: futureware-tech/simulator-action@v5
with:
os: ${{ env.SIM_OS }}
os_version: ${{ env.SIM_OS_VERSION }}
model: ${{ env.SIM_DEVICE }}
erase_before_boot: true
wait_for_boot: true
boot_timeout_seconds: 300
boot_retries: 3
- name: Install Workspace Dependencies
run: flutter pub get
- name: Run Integration Tests
uses: nick-fields/retry@v4
env:
DEVICE_ID: ${{ steps.simulator.outputs.udid }}
with:
timeout_minutes: 5
max_attempts: 3
command: cd flutter_secure_storage/example && flutter test integration_test/app_test.dart -d "$DEVICE_ID" --verbose --dart-define=IS_SIMULATOR=true