diff --git a/.github/workflows/lint.yml b/.github/workflows/code-analysis.yml similarity index 81% rename from .github/workflows/lint.yml rename to .github/workflows/code-analysis.yml index 0ff24742..187a319e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/code-analysis.yml @@ -12,15 +12,21 @@ on: permissions: contents: read +env: + # Do code analysis with latest SDK. + # Pick a concrete version instead of "latest" to avoid builds breaking due to changes in new SDKs. + FLUTTER_VERSION: 3.29.2 # Available versions: https://docs.flutter.dev/release/archive + DART_VERSION: 3.7.2 # Available versions: https://dart.dev/get-dart/archive + jobs: - analyze: + analyze-and-format: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - # Prefer running on Ubuntu over Dart Docker image - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 # v1.6.5 + - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 # v2.16.0 with: - sdk: 3.5.2 + flutter-version: ${{ env.FLUTTER_VERSION }} + cache: true - name: Get dependencies run: | dart pub get --directory=benchmark @@ -40,7 +46,12 @@ jobs: dart analyze objectbox dart analyze objectbox_test - name: Check formatting of all packages - run: dart format --set-exit-if-changed --fix . + # Since Dart 3.7, dart format needs pub get to run before formatting, + # so to check formatting of Flutter packages run pub get for them first. + run: | + flutter pub get --directory=flutter_libs + flutter pub get --directory=sync_flutter_libs + dart format --set-exit-if-changed . pana: runs-on: ubuntu-24.04 @@ -63,7 +74,7 @@ jobs: exit 1 fi - coverage: + test-coverage: runs-on: ubuntu-24.04 permissions: checks: write # to publish the report @@ -72,7 +83,7 @@ jobs: # Prefer running on Ubuntu over Dart Docker image - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 # v1.6.5 with: - sdk: 3.5.2 + sdk: ${{ env.DART_VERSION }} - name: Install coverage tools run: | ./tool/apt-install.sh lcov diff --git a/.github/workflows/dart.yml b/.github/workflows/test.yml similarity index 63% rename from .github/workflows/dart.yml rename to .github/workflows/test.yml index dcb82995..1196fc19 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Build and test +name: Test # Avoid duplicate builds for pull requests, allow manual trigger. on: @@ -8,40 +8,53 @@ on: pull_request: workflow_dispatch: +# Minimal access by default +permissions: + contents: read + defaults: run: shell: bash -# Minimal access by default -permissions: - contents: read +env: + # Run generator integration tests and init script with latest SDK. + # Pick a concrete version instead of "latest" to avoid builds breaking due to changes in new SDKs. + # NOTE: also update matrix configurations below! + FLUTTER_VERSION: 3.29.2 # Available versions: https://docs.flutter.dev/release/archive + DART_VERSION: 3.7.2 # Available versions: https://dart.dev/get-dart/archive jobs: - generator: + + # Runs generator integration tests, e.g. ensures generator works as expected. + # Note: no need to test oldest SDK here, generator package is also built as part of unit-tests job. + generator-integ-tests: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 # Prefer running on Ubuntu over Dart Docker image - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 # v1.6.5 with: - sdk: 3.5.2 + sdk: ${{ env.DART_VERSION }} - name: Install ObjectBox C library run: ./install.sh --install # Install globally for generator integration tests - name: Integration test run: ./generator/test.sh - # make sure the init script doesn't stop working - it's not something we usually run during normal development + # Check the init script works - it's not something we usually run during normal development. + # The init script gets dependencies for all packages and runs code generation for those that + # need it. init-script: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 # v2.16.0 with: - flutter-version: 3.24.2 + flutter-version: ${{ env.FLUTTER_VERSION }} cache: true - run: ./tool/init.sh - lib: + # Runs generator and objectbox unit tests + unit-tests: strategy: fail-fast: false # To see all Dart SDKs that fail, also sometimes with more helpful errors. matrix: @@ -50,11 +63,12 @@ jobs: - macos-13 - ubuntu-24.04 sdk: - # Always include lowest supported version (see sdk key in objectbox and generator - # pubspec.yaml, but may be higher due to dependencies). - - 3.5.2 - - 3.4.4 - - 2.18.6 + # Test latest available and lowest supported SDK (see dev-doc/updating-dart-flutter-and-dependencies.md). + # Pick a concrete version instead of "latest" to avoid builds breaking due to changes in new SDKs. + # Can not use env variables here, only within 'steps'. + # For available versions see https://dart.dev/get-dart/archive + - 3.7.2 + - 2.18.6 # Use latest bugfix release to get tooling fixes runs-on: ${{ matrix.os }} steps: - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 # v1.6.5 @@ -82,20 +96,22 @@ jobs: export OBX_IN_MEMORY=true ../tool/pub.sh run test --concurrency=1 - flutter-integration-test: + # Builds a mobile and a desktop release of the main Flutter examples + flutter-examples: strategy: fail-fast: false matrix: os: - macos-13 - ubuntu-24.04 - - windows-2022 # Flutter 2.9 and newer need Visual Studio 2022 to build desktop. + - windows-2022 # Flutter 2.9 and newer need Visual Studio 2022 to build for desktop flutter-version: - # Include lowest working version (use lowest tested Dart SDK as a guideline, see lib tests - # above; but may be higher due to dependency conflicts) - # https://docs.flutter.dev/development/tools/sdk/releases lists included Dart SDK. - - 3.24.2 - - 3.7.12 + # Test latest available and lowest supported SDK (see dev-doc/updating-dart-flutter-and-dependencies.md). + # Pick a concrete version instead of "latest" to avoid builds breaking due to changes in new SDKs. + # Can not use env variables here, only within 'steps'. + # For available versions see https://docs.flutter.dev/release/archive + - 3.29.2 + - 3.7.12 # Use latest bugfix release to get tooling fixes runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a3fe8be0..209986ed 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,17 +1,26 @@ stages: - - analyze + - code-analysis - test + - test-coverage variables: - # Note: use specific tags as docker images may not always be pulled due to "if-not-present" pull policy. - # Thus, do not use tags like latest/beta, but check https://hub.docker.com/_/dart?tab=tags for latest. - DART_VERSION: '3.5.2' + # Test latest available and lowest supported SDK (see dev-doc/updating-dart-flutter-and-dependencies.md). + # # Pick a concrete version instead of "latest" to avoid builds breaking due to changes in new + # SDKs. For available versions see https://hub.docker.com/_/dart?tab=tags + DART_VERSION_LATEST: '3.7.2' + DART_VERSION_LOWEST: '2.18.6' # Use latest bugfix release to get tooling fixes + DART_VERSION: $DART_VERSION_LATEST # Also used for caching, see .cache template + +.common: + image: dart:$DART_VERSION # Official Dart Docker image https://hub.docker.com/_/dart + tags: [ x64, linux, docker ] # Jobs use shell commands and scripts, so only run on Linux # Make PUB_CACHE cacheable in GitLab; # see also https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77791/diffs and # https://dikman.medium.com/optimising-flutter-ci-by-caching-packages-8a1d537e0b23 # Requires extending job to set DART_VERSION variable. .cache: + extends: .common before_script: - export PUB_CACHE="$CI_PROJECT_DIR/.pub-cache" # https://dart.dev/tools/pub/environment-variables - export PATH="$PATH":"$PUB_CACHE/bin" @@ -23,11 +32,9 @@ variables: key: "linux-x64-dart-$DART_VERSION-pub-cache" # Analyze (only) Dart packages, check formatting in Dart and Flutter packages. -analyze: +analyze-and-format: extends: .cache - stage: analyze - tags: [ x64, linux, docker ] - image: dart:$DART_VERSION + stage: code-analysis script: # Get dependencies - dart pub get --directory=benchmark @@ -49,23 +56,29 @@ analyze: - dart analyze objectbox - dart analyze objectbox_test - dart analyze objectbox/example/dart-native/vectorsearch_cities - # Check formatting of all packages - - dart format --set-exit-if-changed --fix . + # Since Dart 3.7, dart format needs pub get to run before formatting, + # so can no longer check formatting of Flutter packages (would require Flutter SDK): + # Check formatting only for Dart packages + - dart format --set-exit-if-changed benchmark + - dart format --set-exit-if-changed generator + - dart format --set-exit-if-changed objectbox + - dart format --set-exit-if-changed objectbox_test + - dart format --set-exit-if-changed objectbox/example/dart-native # Runs generator integration tests, e.g. ensures generator works as expected. -test-generator:linux:x64: +# Note: no need to test oldest SDK here, generator package is also built as part of unit-tests job. +generator-integ-tests: extends: .cache stage: test - tags: [ x64, linux, docker ] - image: dart:$DART_VERSION script: - ./install.sh --install # Install globally for generator integration tests - ./generator/test.sh # Runs generator and objectbox unit tests. -.test: +.unit-tests-template: extends: .cache stage: test + needs: ["generator-integ-tests"] # Wait for generator integration tests script: # Generator tests - cd generator @@ -84,28 +97,33 @@ test-generator:linux:x64: - export OBX_IN_MEMORY=true - dart test --concurrency=1 --reporter expanded -test-lib:linux:x64: - extends: .test - tags: [ x64, linux, docker ] - image: dart:$DART_VERSION - needs: ["test-generator:linux:x64"] # Wait for generator test +unit-tests: + extends: .unit-tests-template parallel: matrix: - # Note: use specific versions instead of latest/beta tags as Docker images may not always be - # pulled due to "if-not-present" pull policy. Check https://hub.docker.com/_/dart?tab=tags. - # Always include lowest supported version (see sdk key in objectbox and generator - # pubspec.yaml, but may be higher due to dependencies). - - DART_VERSION: [ '2.18.6', '3.4.4', '3.5.2' ] + - DART_VERSION: [ $DART_VERSION_LOWEST, $DART_VERSION_LATEST ] + +# For the Dart Native example compiles and runs the executable (analysis and code formatting is +# checked by analyze job). +vectorsearch-example: + extends: .cache + stage: test + needs: ["generator-integ-tests"] # Wait for generator integration tests + script: + - cd objectbox/example/dart-native/vectorsearch_cities + - dart pub get + - dart run build_runner build + - ../../../../install.sh + - dart compile exe bin/vectorsearch_cities.dart + - ./bin/vectorsearch_cities.exe # Runs tests with coverage on the objectbox package. # Note: As this requires to run tests, make sure this does not block the actual test jobs so test # issues can be seen. -coverage: +test-coverage: extends: .cache - stage: test - needs: ["test-lib:linux:x64"] # Get test results first - tags: [ x64, linux, docker ] - image: dart:$DART_VERSION + stage: test-coverage + needs: ["unit-tests"] # Get test results first script: # Install coverage tools - apt-get update @@ -124,18 +142,3 @@ coverage: artifacts: paths: - objectbox/coverage/html/ - -# For the Dart Native example compiles and runs the executable (analysis and code formatting is -# checked by analyze job). -dart-examples-test: - extends: .cache - stage: test - tags: [ x64, linux, docker ] - image: dart:$DART_VERSION - script: - - cd objectbox/example/dart-native/vectorsearch_cities - - dart pub get - - dart run build_runner build - - ../../../../install.sh - - dart compile exe bin/vectorsearch_cities.dart - - ./bin/vectorsearch_cities.exe diff --git a/dev-doc/updating-dart-flutter-and-dependencies.md b/dev-doc/updating-dart-flutter-and-dependencies.md new file mode 100644 index 00000000..14bfa27b --- /dev/null +++ b/dev-doc/updating-dart-flutter-and-dependencies.md @@ -0,0 +1,40 @@ +# Testing and updating Dart and Flutter SDKs and dependencies + +## Testing SDKs + +Officially the Dart developers only [commit to release security fixes](https://dart.dev/security) +for the latest version of the Dart SDK. The Flutter developers have so far not released fixes for a +previous minor version of the Flutter SDK. + +[Packages specify](https://dart.dev/tools/pub/pubspec#sdk-constraints) a minimum supported Dart and +optionally Flutter SDK. And allow any new not major Dart SDK (and technically +[any new Flutter SDK](https://dart.dev/tools/pub/pubspec#flutter-sdk-constraints)). + +So packages should work with the latest allowed SDKs (tools, APIs), but remain compatible with the +lowest allowed SDKs (APIs, language features). + +Based on that, the ObjectBox packages should be + +- **tested with the latest available Flutter and Dart SDK** and +- SDKs matching **the lowest supported Dart and Flutter version**. + +Note: regarding API compatibility, the issue is that the tools won't error if an API is used that +is not available in the lowest supported SDK. Testing with an older SDK is a workaround for this. + +## Updating required SDKs and dependencies + +The pub tool prevents upgrading a dependency of an application or library when + +- its highest allowed Dart or Flutter SDK, or +- the highest allowed version of one of its shared transitive dependencies + +is too low. So assume that applications or libraries may not support the most recent SDKs and +dependencies, but are safe from breaking changes. + +Based on that, ObjectBox packages + +- may require the latest, but **should require at most the latest major version of a dependency** + and +- may require the latest, but **should require the lowest version of the Dart and Flutter SDK + required by dependencies** and +- to simplify testing, **all packages should require the same SDK versions**.