Вероятно, вы используете Github для управления своим Android-проектом. Все мы знаем, что выпуск вручную может быть очень утомительным и утомительным. От запуска некоторых тестов, создания APK или AAB, его подписания, входа в консоль AppGallery, заполнения информации, ее загрузки и т. Д.

С помощью этой серии руководств мы автоматизируем процесс выпуска самым простым способом, делая некоторые вещи на низком уровне, чтобы понять их, используя Publising API для публикации нашего APK или AAB в AppGallery. Но сначала мы предпримем все меры предосторожности для управления некоторыми секретными файлами, такими как хранилище ключей для подписи приложения и файл agconnect-services.json. Конечно, мы сделаем это для проекта, в котором используются мобильные службы Huawei, и с учетом тех соображений, которые необходимо учитывать.

Действия GitHub

GitHub Actions позволяет нам автоматизировать рабочий процесс разработки и, конечно же, создать CI / CD для нашего проекта Android.

Нашим первым шагом будет размещение нашего Android-проекта на GitHub, а затем в репозитории перейдите в раздел «Действия».

В Github есть несколько шаблонов быстрого запуска для разных процессов в разных технологиях, чтобы иметь базовый код, мы можем выбрать шаблон Android CI.

Это сгенерирует файл YAML, в котором мы будем писать все, что мы хотим сделать, когда в главной ветке выполняется модификация либо из фиксации, либо из утверждения запроса на вытягивание.

Этот шаблон уже может быть выполнен, за исключением модификации, разрешающей выполнение gradlew. Это необходимо, чтобы избежать проблем с разрешением на выполнение.

chmod +x gradlew

Наш базовый код YAML будет следующим:

name: Android CI

on:

push:

branches: [ master ]

pull_request:

branches: [ master ]

jobs:

build:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v2

- name: set up JDK 1.8

uses: actions/setup-java@v1

with:

java-version: 1.8

- name: Build with Gradle

run: |

chmod +x gradlew

./gradlew build

Любое изменение, внесенное в файл YAML, позволит нам выполнить рабочий процесс, его также можно выполнить вручную и, очевидно, увидеть весь журнал процесса.

Защита конфиденциальных данных и файлов

Если мы хотим, чтобы наш рабочий процесс генерировал APK или AAB, подписанный и готовый к загрузке в AppGallery, нам нужны некоторые файлы, но эти файлы должны быть безопасными и не должны иметь версии в репозитории. Их даже следует поместить в .gitignore, чтобы избежать их ошибочной загрузки.

Большинство разработчиков в большинстве случаев рекомендуют соблюдать осторожность со следующими файлами в проекте Android, использующем мобильные службы Huawei.

  • Файл хранилища ключей
  • Значения пароля хранилища ключей и псевдонима пароля хранилища ключей
  • Файл agconnect-services.json

Нам нужна эта информация, но она не может быть видна в файле YAML, потому что она видна тем, у кого есть доступ к репозиторию. На GitHub есть специальное пространство для этой конфиденциальной информации, Secrets.

Проблема здесь в том, что можно загружать только пары "ключ-значение", а не файлы.

Чтобы загрузить наш файл хранилища ключей (он необходим для подписи приложения), мы получим его строковое представление, то же самое с файлом конфигурации agconnect-services.json.

Мы сделаем это из командной строки с помощью gpg.

gpg -c --armor mykeystore.jks

Будет запрошена кодовая фраза, которую мы должны ввести, и будет создан файл mykeystore.jks.asc. Этот файл содержит строку Base64, и это значение мы можем сохранить в Secrets.

Мы должны сделать это для каждого файла, который мы считаем разумным и необходимым в нашем рабочем процессе. Мы также должны сохранить парольную фразу каждого из них, потому что мы будем использовать ее для повторной генерации файла из значения base64 при выполнении нашего CI / CD.

Мы получим что-то вроде этого: (учитывая, что мы добавили разные парольные фразы, это может быть только одна)

Обратите внимание, что у нас есть файл keystore.properties, в котором хранятся значения паролей и псевдонимы хранилища ключей.

Идея состоит в том, чтобы использовать эти значения в рабочем процессе для создания подписанного APK.

Мы собираемся создать новый шаг в нашем YAML и сделать все наоборот. Сначала мы генерируем файл .asc, а затем с помощью ключевой фразы генерируем окончательный файл в соответствующем каталоге.

- name: Prepare Secret Files

run: |

echo "${{ secrets.KEYSTORE }}" > alvareztech.jks.asc

gpg -d --passphrase "${{ secrets.KEYSTORE_PASSPHRASE }}" --batch alvareztech.jks.asc > app/alvareztech.jks

echo "${{ secrets.KEYSTORE_PROPERTIES }}" > keystore.properties.asc

gpg -d --passphrase "${{ secrets.KEYSTORE_PROPERTIES_PASSPHRASE }}" --batch keystore.properties.asc > keystore.properties

echo "${{ secrets.AGCONNECT_SERVICES }}" > agconnect-services.json.asc

gpg -d --passphrase "${{ secrets.AGCONNECT_SERVICES_PASSPHRASE }}" --batch agconnect-services.json.asc > app/agconnect-services.json

Создание подписанного приложения

Создать APK легко с помощью команды gradle после того, как у вас будут все необходимые файлы и конфигурация подписи в том же build.gradle модуля приложения, как показано ниже.

signingConfigs {

release {

storeFile file(keystoreProperties['storeFile'])

storePassword keystoreProperties['storePassword']

keyAlias keystoreProperties['keyAlias']

keyPassword keystoreProperties['keyPassword']

v2SigningEnabled true

}

}

Таким образом, создание подписанного APK - это только:

1

./gradlew assembleRelease

Получить подписанный APK-файл

На данный момент мы загрузим файл результатов рабочего процесса, идея состоит в том, чтобы загрузить этот файл в AppGallery через API публикации, предоставляемый AppGallery Connect, но теперь мы решим проблему, загрузив этот артефакт.

- name: Publish APK

uses: actions/upload-artifact@v2

with:

name: app-release

path: app/build/outputs/apk/release/

У нас есть рабочий процесс, который автоматически генерирует подписанный APK для изменений, которые мы вносим в основную ветку автоматически. Мы можем скачать артефакт, пока Github позволяет скачивать только в формате ZIP.

Вывод

У нас есть все готово для использования Publish API, мы уже принимаем во внимание конфиденциальные файлы в проекте с Huawei Mobile Services. Цель состоит в том, чтобы продолжить работу над CI / CD на низком уровне, чтобы понять весь процесс.

На данный момент полный файл:

копировать

name: Android CI

on:

push:

branches: [ master ]

pull_request:

branches: [ master ]

jobs:

build:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v2

- name: set up JDK 1.8

uses: actions/setup-java@v1

with:

java-version: 1.8

- name: Prepare Secret Files

run: |

echo "${{ secrets.KEYSTORE }}" > alvareztech.jks.asc

gpg -d --passphrase "${{ secrets.KEYSTORE_PASSPHRASE }}" --batch alvareztech.jks.asc > app/alvareztech.jks

echo "${{ secrets.KEYSTORE_PROPERTIES }}" > keystore.properties.asc

gpg -d --passphrase "${{ secrets.KEYSTORE_PROPERTIES_PASSPHRASE }}" --batch keystore.properties.asc > keystore.properties

echo "${{ secrets.AGCONNECT_SERVICES }}" > agconnect-services.json.asc

gpg -d --passphrase "${{ secrets.AGCONNECT_SERVICES_PASSPHRASE }}" --batch agconnect-services.json.asc > app/agconnect-services.json

- name: Build with Gradle

run: |

chmod +x gradlew

./gradlew assembleRelease

- name: Publish APK

uses: actions/upload-artifact@v2

with:

name: app-release

path: app/build/outputs/apk/release/

Реализованные в реальном проекте можно увидеть в:

Https://github.com/alvareztech/facts-android

API публикации

Https://developer.huawei.com/consumer/en/doc/development/AppGallery-connect-Guides/agcapi-publish_api_overview