Разработка
GitHub Actions для Android-разработки
Если вы разрабатываете приложения для Android, скорее всего, в какой-то момент своей карьеры вы столкнетесь с тем или иным видом CI. Если вы знакомы с фрагментацией Android, то большой выбор систем CI будет вам знаком.
GitHub Actions был запущен в ноябре 2019 года, и с тех пор зарекомендовал себя как надежное для производственной среды решение (одно из наших требований перед переходом к любой программной системе). Как и многие другие системы CI/CD, GitHub Actions в конечном итоге позволяет нам определять рабочие процессы для приложений, чтобы автоматически создавать, тестировать и развертывать их.
Одним из самых ярких аспектов GitHub Actions является его интеграция с GitHub. Для репозиториев, которые уже размещены на GitHub, GitHub Actions позволяет автоматизировать процесс на одной единой платформе без необходимости полагаться на какие-либо внешние инструменты. Ваш код находится на GitHub, ваш CI/CD работает на GitHub, и вы также можете разместить свой дистрибутив на GitHub, если хотите.
Теперь GitHub Actions предоставляет подробные руководства и документацию, хотя первый переход к нему может быть несколько ошеломительным для людей, не имеющих опыта работы с платформой. В документации приведен пример базовой настройки для разработчиков Android, но вы можете спросить: «Где мне найти вдохновение в том, что я могу делать с помощью GitHub Actions?». Этот пост призван дать несколько ответов, основанных на моем личном опыте использования GitHub Actions. Я использую его для Android-проектов, поэтому мой опыт (и этот пост) ограничен этой платформой. Без дальнейших промедлений, начнем.
Структура нашего конфигурационного файла
Для GitHub Actions требуется файл .yml, в котором указаны все шаги для CI/CD. Файлы YAML неудобны, особенно когда они становятся большими (проблемы с отступами могут остаться незамеченными, а поддержка со стороны IDE встречается редко). Файлы хранятся в папке .github/workflows/file.yml. Вот минимальный пример того, как они выглядят:
# Workflow name name: Buildon: # When it will be triggered # And in which branch pull_request: push: branches: - main # Where will they run jobs: build: runs-on: ubuntu-latest
Действия (Actions)
Действия — это особый тип шагов, которые помогают нам автоматизировать CI/CD. Кто угодно может опубликовать свои действия с открытым исходным кодом, и их можно просматривать через GitHub. Многие функции, которые мы могли бы реализовать, скорее всего, уже здесь есть, поэтому стоит сначала посмотреть, чтобы не изобретать велосипед заново. И, конечно же, можно форкнуть и изменить существующие действия или создать свои собственные.
Ниже список некоторых операций, которые мы можем выполнять в ходе Android-разработки. Исходя изназвания CI/CD, мы обычно хотим создавать и развертывать приложения, но есть некоторые полезности, которые мы можем применить (уведомить определенные каналы или платформы и т.д.). Давайте начнем.
Настройка нашего приложения для Android
Первоначально мы настроим нашу среду, и для этого нам нужно проверить наш проект и настроить наш JDK. Здесь мы будем использовать наше первое Действие, Checkout v2, чтобы выполнить git checkout нашего репозитория, и setup-java для подготовки нашей Java-среды .
## Checkout our repository ### - name: Checkout uses: actions/checkout@v2.3.3 - name: Set up our JDK environment uses: actions/setup-java@v1.4.3 with: java-version: 1.8
Создание наших артефактов
Фундаментом каждого проекта является компиляция всех наших артефактов для загрузки и/или распространения. Разные версии часто имеют свои особенности, и мы можем сгенерировать несколько APK на основе нашего Flavor или BuildTypes. Некоторые из них актуальны (наш артефакт для релиза, который может быть передан непосредственно нашей группе тестирования), некоторые из них менее актуальны (наши тестовые артефакты, предназначенные только для использования в разработке) — в зависимости от структуры вашей команды. К счастью, мы можем напрямую вызывать команды Gradle и генерировать необходимое количество артефактов. Мы будем использовать Действие gradle-command-action для выполнения нашей команды Gradle. Примером может послужить следующее:
## Build all our Build Types at once ## - name: Build all artifacts id: buildAllApks uses: eskatos/gradle-command-action@v1.3.3 with: gradle-version: current wrapper-cache-enabled: true dependencies-cache-enabled: true configuration-cache-enabled: true arguments: assembleRelease
Здесь интересна строка arguments: assembleRelease. Мы можем легко заменить в ней команду Gradle, которую хотим выполнить.
Тестирование
Есть несколько инструментов для тестирования или анализа, которые мы могли бы использовать в нашей среде CI/CD. К счастью, с помощью GitHub Actions мы можем напрямую запускать наши команды Gradle. Например, можно легко запустить наши тесты или Lint, напрямую вызвав соответствующую команду Gradle:
- name: Run Kotlin Linter run: ./gradlew ktlintStagingDebugCheck - name: Run Unit Tests run: ./gradlew testStagingDebugUnitTest
Мы также можем запускать наши тесты Espresso через GitHub Actions. Есть несколько действий, которые позволяют нам запускать их, мы продемонстрируем android-emulator-runner от Reactive Circus:
uses: reactivecircus/android-emulator-runner@v2 with: api-level: 23 target: default arch: x86 profile: Nexus 6 script: ./gradlew connectedCheck --stacktrace
Подписание артефактов
Подписание артефактов — это следующий естественный шаг при создании нашего Android-проекта, чтобы их можно было установить на устройстве.
## Sign our artifact## - name: Sign artifact id: signArtifact uses: r0adkll/sign-android-release@v1.0.1 with: releaseDirectory: app/build/outputs/apk/ourbuildtype/release alias: ${{ secrets.KEYALIAS }} signingKeyBase64: ${{ secrets.KEYSTORE }} keyStorePassword: ${{ secrets.KEYSTORE_PASSWORD }} keyPassword: ${{ secrets.KEY_PASSWORD }} - name: Upload our APK uses: actions/upload-artifact@v2.2.0 with: name: Release artifact path: app/build/outputs/apk/ourbuildtype/release/app-artifact-*.apk
Некоторые дополнительные объяснения того, что здесь происходит:
- Задача «Подписать артефакт» использует Действие sign-android-release. Это довольно просто: нам нужно указать информацию, связанную с ключом, чтобы APK был подписан. При необходимости можно указать разные задачи (например, что нам нужно подписывать APK разными ключами).
- Задача «Загрузить наш APK» загружает артефакты из нашего рабочего процесса, позволяя нам обмениваться данными между заданиями и сохранять данные после завершения рабочего процесса. Она использует Действие upload-artifact. Обратите внимание, что в поле пути мы используем подстановочный знак app-artifact-*.apk.
С помощью Gradle мы можем настроить наш файл конфигурации, чтобы определить имя нашего результирующего APK. Это приводит к гораздо более читабельному выводу, вместо того, чтобы всегда использовать имя APK по умолчанию. Например, следующий блок кода изменяет имя нашего файла Gradle на более читаемый формат:
android.applicationVariants.all { variant -> variant.outputs.all { outputFileName = "app-${variant.productFlavors[0].name}-${variant.buildType.name}-${variant.versionName}.apk" } }
Создание выпуска
Интересно, что GitHub сам может создавать внутри Release, который мы позже можем использовать для распространения наших артефактов. Например, посмотрите, как выглядит страница Release для версии 1.4.2 корутин Kotlin:
Каждый из этих релизов может содержать ряд артефактов, исходный код, документацию и т.д. Также можно опубликовать CHANGELOG или примечания для конкретного выпуска (подробнее об автоматическом создании этого позже). Конечно, полезно, чтобы это автоматически создавалось вместе со всем процессом. Соответствующий раздел, который создаст релиз в GitHub.
- name: Create Release id: create_release uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} release_name: Release ${{ github.ref }} draft: false prerelease: false
Загрузка ассетов на GitHub
С созданием релиза пришло время загрузить наши собственные ресурсы. Мы собираемся использовать вспомогательную задачу, чтобы собрать наши имена APK и пути (предположим, что у нас есть собственные имена для них, как было сделано ранее).
- name: Save name of our Artifact id: set-result-artifact run: | ARTIFACT_PATHNAME_APK=$(ls app/build/outputs/apk/ourbuildtype/release/*.apk | head -n 1) ARTIFACT_NAME_APK=$(basename $ARTIFACT_PATHNAME_APK) echo "ARTIFACT_NAME_APK is " ${ARTIFACT_NAME_APK} echo "ARTIFACT_PATHNAME_APK=${ARTIFACT_PATHNAME_APK}" >> $GITHUB_ENV echo "ARTIFACT_NAME_APK=${ARTIFACT_NAME_APK}" >> $GITHUB_ENV Обратите внимание на несколько важных моментов в этом блоке кода:
- Мы устанавливаем имя нашего PATH и артефакта в переменных среды, которые позже сохраняются на GitHub. Это отличный способ хранить информацию в GitHub Actions.
- Мы запускаем команду для определения имени APK (ls app/build/outputs/apk/ourbuildtype/release/*.apk | head -n 1). Это очень универсально, поскольку мы можем по существу использовать команды Unix/Mac для определения множества вещей (а позже сохранять их в нашем PATH и повторно использовать на других этапах).
Поскольку имена и PATH уже сохранены в переменной среды, мы приступим к их загрузке на нашу страницу выпуска. Здесь используется действие upload-release-asset:
- name: Upload our Artifact Assets id: upload-release-asset uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: ${{ env.ARTIFACT_PATHNAME_APK }} asset_name: ${{ env.ARTIFACT_NAME_APK }} asset_content_type: application/zip
Это создало наши артефакты на GitHub, и мы готовы их распространять. Мы можем использовать множество механизмов уведомления. Например, если у нас есть группа в Slack, мы можем уведомить определенный канал о том, что наш релиз готов, используя act10ns/slack:
- name: Notify on Slack uses: act10ns/slack@v1.0.9 with: status: ${{ job.status }} steps: ${{ toJson(steps) }} if: always()
В Действиях GitHub уже доступно большое количество опций, включая уведомления в Telegram, по электронной почте или в Discord. Если вы можете придумать конкретную платформу, которая вам нужна, скорее всего, она уже есть в GitHub Actions.
Мы могли бы придать последний штрих релизу, автоматически заполнив CHANGELOG, используя некоторую информацию, которая уже доступна. Как вы понимаете, на GitHub уже есть Действие, которое решает эту проблему. Конкретно это берет информацию из файла CHANGELOG.md согласно keepchangelog.com, но не составит труда изменить это с помощью git log —pretty=oneline или аналогичного формата.
Резюме
GitHub Actions — еще один движок Continuous Integration/Continuous Delivery. Если вы уже используете GitHub, он обеспечивает очень приличную интеграцию с вашим кодом, задачами и рабочим процессом. Он обладает широкими возможностями настройки, предоставляя API-интерфейсы для создания ваших собственных действий по мере необходимости или доступ к ним из маркетплейса GitHub. Как и в случае с любым облачным решением (или любым техническим решением), есть несколько факторов, которые необходимо взвесить, прежде чем решить, имеет ли смысл его использовать или нет.
Я считаю, что это удобное решение, отвечающее широкому кругу требований.
-
Видео и подкасты для разработчиков1 месяц назад
Особенности сервиса Яндекс Про и будущее Flutter
-
Исследования1 месяц назад
Результаты опроса разработчиков Stack Overflow 2024
-
Видео и подкасты для разработчиков1 месяц назад
Вам не нужно хранилище в приложении
-
Видео и подкасты для разработчиков1 месяц назад
Нужно ли учить Java для Android-разработки в 2024