Как стать автором
Обновить

Комментарии 9

Кажется стоит добавить кэширование gradle-зависимостей, иначе они скачиваются заново при каждом билде.

Проблема с необходимостью скачивать NDK, даже если она не используется, появилась с Gradle Android Plugin 3.6.
В build.gradle нужно явно указать версию NDK, например
defaultConfig {
  ndkVersion '21.2.6472646'
}

Если ее не указывать, то будет использоваться версия по-умолчанию (20.0.5594570).
В образе ubuntu-latest на данный момент предустановлена версия NDK 21.2.6472646
Если не лень, то можно собрать и использовать свой docker-image с нужной версией NDK.
Спасибо, добавил про NDK. Да, я смотрел по поводу кеширования, но много жалоб на стабильность его работы, потому я не стал настраивать кеширование. Как по мне готовый docker-image использовать будет лучше, выделю время и изучу данный вопрос, спасибо.

Вы считаете безопасно хранить my_key.jks в репозитории? Если злоумышленник получит свою копию ключа остается надеятся только на стойкость алгоритма шифрования. Я бы не стал подсаживаться на переменную github.run_number. Что делать если придется мигрировать на GitLab/TeamCity, или когда у внешнего сервиса собьется нумерация сборок? Вместо того, чтобы вручную докручивать образ ubuntu-latest, можно взять один из готовых от CircleCi. Совсем необязательно выносить работу keystore.properties на уровень всего скрипта сборки. Я предпочитаю иметь ограниченную область, в которой можно обратиться к RELEASE_STORE_PASSWORD. В репозитории на GitHub есть раздел с релизами, было бы круто автоматом отправлять туда артефакты сборки, в том числе от proguard/R8.

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

Зависит от проекта, получить ключь из кейстора не тривиальная задачка, и мало кто будет заниматься этим просто для прикола.

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

Спасибо за CircleCi, изучу.

Совсем необязательно выносить работу keystore.properties на уровень всего скрипта сборки. Я предпочитаю иметь ограниченную область, в которой можно обратиться к RELEASE_STORE_PASSWORD.

Не могли бы вы описать это по подробнее?

В репозитории на GitHub есть раздел с релизами, было бы круто автоматом отправлять туда артефакты сборки, в том числе от proguard/R8.

Да, я делал это для флаттер проекта, там нет ничего сложного, так как есть уже много разных экшенов, самое сложное это понять как получить ключи для доступа к GitHub. В этом проекте я отказался от пуша в релизную папку, так как для этого проекта было изначально излишне. По возможности, добавлю в ближайшее время. Только создавать оно будет сборку для другой ветки или даже для дева (я такую сборку рассматриваю как для внутреннего тестирования).
Вместо github.run_number можно использовать кол-во коммитов в текущей ветке.
Плюсы — это значение не зависит от используемой CI, и с любого коммита всегда собирается билд со строго фиксированным номером.
Можно воспользоваться, например, gradle-плагином grgit, чтобы во время сборки брать инфу о коммитах и заменять versionCode приложения.
С этим же плагином мы у себя на проекте еще и простенькие release-notes для тестировщиков генерим на основе имен коммитов.
Не могли бы вы описать это по подробнее?

У вас переменная release_store_password доступна во всем build.gradle. Почему бы не вынести ее в signingConfigs.release[debug]. Ключ подписи отладочной версии тоже должен оставаться постоянным, но отличаться от релизной.

По поводу номера версии – можно обойтись и без дополнительного файла version.properties. Параметры GitHub Actions доступны как переменные окружения, поэтому можно так (на .kts):


val buildNumber = (System.getenv("GITHUB_RUN_NUMBER") ?: "1").toInt()

С keystore.properties мы делали почти так же, только зачем вводить дополнительные переменные и вручную заполнять их? У нас было так:


def keystoreProperties = new Properties()   
def keystorePropsFile = rootProject.file("keystore.properties") 
if (keystorePropsFile.exists()) {   
    keystoreProperties.load(new FileInputStream(keystorePropsFile)) 
} else {    
    keystoreProperties['keyAlias'] = System.getenv('ANDROID_KEY_ALIAS') ?: ''   
    keystoreProperties['keyPassword'] = System.getenv('ANDROID_KEY_PASSWORD') ?: '' 
    keystoreProperties['storeFile'] = System.getenv('ANDROID_STORE_FILE') ?: '' 
    keystoreProperties['storePassword'] = System.getenv('ANDROID_STORE_PASSWORD') ?: '' 
}

Как вариант можно хранить всю чувствительную информацию в base64 и генерировать файлы перед сборкой


    # Env and temp files setup
    - name: Decode google-services.json
      env:
          GOOGLE_SERVICES_CONFIG: ${{ secrets.GOOGLE_SERVICES_CONFIG }}
      run: echo $GOOGLE_SERVICES_CONFIG > app/google-services.json
    - name: Decode release keystore
      env:
          APP_KEYSTORE: ${{ secrets.APP_KEYSTORE }}
      run: echo $APP_KEYSTORE | base64 --decode > app/keystore.jks
    - name: Keystore credentials
      env:
          KEYSTORE_CREDENTIALS: ${{ secrets.KEYSTORE_CREDENTIALS }}
      run: echo $KEYSTORE_CREDENTIALS | base64 --decode >> gradle.properties

На локальной машине удобно использовать глобальный конфиг gradle и хранить эти файлы отдельно от проекта.


$ more ~/.gradle/gradle.properties 
keystorePath=/Users/denys/.keys/example.keystore
storePassword=storePwd
keyAlias=example
keyPassword=keyPwd

В gradle скрипте вместо


def release_key_password

def keystoreProperties = new Properties()
if (rootProject.file("keystore.properties").exists()) {
    keystoreProperties.load(new FileInputStream(rootProject.file("keystore.properties")))
    release_key_password = keystoreProperties['DB_PASS_ALIAS']

будет


def release_key_password = properties.storePassword ?: System.env.RELEASE_STORE_PASSWORD
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории