Безопасность вашего сервиса прямо зависит от безопасности используемых в нём внешних зависимостей (библиотек, модулей, пакетов и т.д.). Поэтому при добавлении такой зависимости необходимо следовать следующим принципам:
- Количество активных майнтейнеров. Должно быть > 3
- Количество звёзд на GitHub. Должно быть > 30
- Дата последнего релиза. Должно быть не позже 180 дней назад. То есть проект должен быть активным с т.з. разработки, а не заброшенным
- Есть ли незакрытые известные уязвимости (смотрим в security.snyk.io )
- Дата релиза проекта, который затаскиваем внутрь. Он должен быть до 20.02.2022. Исключение для исправления уязвимостей.
❗ Зависимости желательно получать в докер контейнере используемом для сборки.
❗ Зависимости получать после успешной сборки приложения.
❗ Помимо зависимостей андроида также нужны зависимости прописаные в блокеbuildscript.dependencies
в файлеandroid/build.gradle
.
❗ И зависимости этих зависимостей и тп и тд.
flutter pub outdated --transitive --dev-dependencies --dependency-overrides > flutter_dependencies.txt 2>&1
gradle buildEnvironment > gradle_dependencies.txt 2>&1
cd android; ./gradlew app:androidDependencies > android_dependencies.txt 2>&1
❗ Также все зависимости можно собрать с помощью скрипта:
dart run tools/dependencies.dart > dependencies.yaml
Исходя из файла flutter.gradle:
private static final String DEFAULT_MAVEN_HOST = "https://storage.googleapis.com";
...
String hostedRepository = System.env.FLUTTER_STORAGE_BASE_URL ?: DEFAULT_MAVEN_HOST
String repository = useLocalEngine()
? project.property('local-engine-repo')
: "$hostedRepository/download.flutter.io"
rootProject.allprojects {
repositories {
maven {
url repository
}
}
}
Флатер энжайны под различные процессорные архитектуры тянутся с
storage.googleapis.com/download.flutter.io
можно переопределить host используя переменную окружения FLUTTER_STORAGE_BASE_URL
или установить свойство проекта local-engine-repo
для указания локального хранилища.
Ну или подменить сам flutter.gradle в докер образе для сборки (я выбрал этот путь).
Сервисы используемые для кэширования зависимостей:
- JFrog Artifactory
- Sonatype Nexus Repository Manager (в теории можно обойтись одним только Artifactory)
Образ для сборки строится на базе:
В pubspec.yaml
должны быть прописаны явно все dependencies
и dev_dependencies
, в тч и транзитивные.
Зависимости должны быть указаны явно: some_package: 1.2.3+4
.
Установить переменную окружения: export PUB_HOSTED_URL="https://artifactory.domain.tld/artifactory/api/pub/pub.dev"
❗ Также можно заставить работать паб через прокси сервис:
export https_proxy=username:password@hostname:port
В файле android/gradle/wrapper/gradle-wrapper.properties
прописать:
https://artifactory.domain.tld/artifactory/gradle-gradle-remote/gradle-6.7-all.zip
❗ Следующий шаг в рамках этого гайда не нужен. При его использовании будет предполагаться, что все зависимости у вас уже будут зашиты в докер образе.
Если хотите заставить работать gradle в оффлайне, необходимо изменить последнюю строку <project>/android/gradlew
при сборке на:
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain "$@" --offline
В файле android/build.gradle
должно быть прописаны локальные репозтории (в двух местах):
buildscript {
ext.kotlin_version = '1.6.10'
repositories {
// ИСПОЛЬЗОВАТЬ ПУБЛИЧНЫЕ РЕПОЗИТОРИИ
//google()
//mavenCentral()
//maven { url 'https://developer.huawei.com/repo/' }
// ИСПОЛЬЗОВАТЬ РЕПОЗИТОРИЙ ОЗОНА
maven { url 'https://nexus.domain.tld/repository/repo/' }
}
...
allprojects {
repositories {
// ИСПОЛЬЗОВАТЬ ПУБЛИЧНЫЕ РЕПОЗИТОРИИ
//google()
//mavenCentral()
//maven { url 'https://developer.huawei.com/repo/' } // HUAWEI
// ИСПОЛЬЗОВАТЬ РЕПОЗИТОРИЙ ОЗОНА
maven { url 'https://nexus.domain.tld/repository/repo/' }
}
}
❗ Со всем этим есть ньюанс: Flutter при
flutter pub get
генерирует.flutter-plugins-dependencies
В котором собраны все нейтивные плагины.
Вsettings.gradle
они подключаются черезapply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
что в свою очередь перебирает все андроид зависимости и подключает их через:
include ":${androidPlugin.name}"
project(":${androidPlugin.name}").projectDir = pluginDirectory
При таком подключении зависимости обладают собственными репозиториями (например google и mavenCentral) - их также нужно переопределить. Это можно попробывать сделать через
-
Переопределение в
settings.gradle
иinit.gradle
с помощьюpluginManagement
иdependencyResolutionManagement
-
Более радикальным путем, сделав
flutter pub get
, а затем распарсив.flutter-plugins-dependencies
, перебирая андроид зависимости и заменяя скриптом секции репозиториев на локальные. Смотри:tools/replace_android_repositories.dart
.
В dockerfile'е нужно подменить flutter.gradle:
COPY --chown=101:101 ./dockerfiles/flutter.gradle /opt/flutter/packages/flutter_tools/gradle/flutter.gradle
В котором прописано:
repositories {
maven { url 'https://nexus.domain.tld/repository/repo/' }
}
или задать расположение flutter engine через System.env.FLUTTER_STORAGE_BASE_URL
или через project.property('local-engine-repo')
В контейнере должны быть установлены все зависимости Android SDK достаточные для сборки.
Например: sdkmanager --sdk_root=${ANDROID_HOME} --install 'extras;google;instantapps' 'platforms;android-30' 'platforms;android-31' 'build-tools;29.0.2'
В файле android/app/build.gradle
Google Service должно быть прописано над Crashlytics:
// Google Service
apply plugin: 'com.google.gms.google-services'
// Firebase Crashlytics plugin
apply plugin: 'com.google.firebase.crashlytics'
А также отключено mappingFileUploadEnabled
в секции buildTypes
:
buildTypes {
release {
...
firebaseCrashlytics {
mappingFileUploadEnabled = false
}
}
debug {
...
firebaseCrashlytics {
mappingFileUploadEnabled = false
}
}
}
- в пайплайне прописать сбор артифакта получения зависимостей
time timeout 300 flutter pub get --suppress-analytics --verbose >> pub_get.txt 2>&1
(по аналогии поступить и сflutter build apk
) - скачивать и открывать архив артефактов упавшего пайплайна
- открывать файл
pub_get.txt
(по аналогии и сbuild.txt
) - смотреть на чем оно отвалилось с ошибкой таймаута (конец файла)
- сверять зависимости и их версии с одобренным списком артифактори или нексуса
- прописывать версии зависимостей и транзитивных зависимостей явно в
pubspec.yaml
в соответсвии с кэшем - репозитории подключаемых андроид плагинов из флатера также должны быть подменены на локальные
❗ Проверить наличие флаттер зависимостей в репозитории можно по адресу: artifactory.domain.tld
❗ Проверить наличие андроид зависимостей в репозитории можно по адресу: nexus.domain.tld