Skip to content
Michael Bely edited this page Apr 29, 2024 · 28 revisions

Important

ВНИМАНИЕ!
ЭТОТ РАЗДЕЛ БОЛЬШЕ НЕ ПОДДЕРЖИВАЕТСЯ!
РОАДМАП ПЕРЕЕХАЛ В NOTION

Codeowners

.github/codeowners

* @michaelbel

Pull Request Template

.github/pull_request_template

**Task:**

**Screenshots:**

Dependabot

.github/dependabot.yml

version: 2
updates:
  - package-ecosystem: gradle
    directory: "/"
    schedule:
      interval: "daily"
      time: "10:00"
    open-pull-requests-limit: 1000
    reviewers:
      - "michaelbel"
    assignees:
      - "michaelbel"

GitHub Actions

.github/workflows/action.yml

Несколько Jobs запускаются параллельно

Cancel Previews Runs

concurrency:
  group: environment-${{ github.ref }}
  cancel-in-progress: true
- name: Cancel Previous Runs
  uses: styfle/[email protected]
  with:
    access_token: ${{ github.token }}

Checkout Repo
Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it.
fetch-depth - we need to checkout with tags and commit history

- name: Checkout Repo
  uses: actions/checkout@v2
  with:
    fetch-depth: 0

Setup JDK

- name: Setup JDK 11
  uses: actions/setup-java@v1
  with:
    java-version: 1.11

Decode Keystore File

Настраиваем signinConfig в build.gradle. Берем переменные из локального файла подписи, если он есть или из Secrets, если сборка происходит удаленно. Перед этим необходимо создать переменные KEY_ALIAS, KEY_PASSWORD, KEY_STORE_PASSWORD и KEY_FILE в SettingsSecrets. Закодировать файл .jks с помощью base64

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file("config/keystore.properties")
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
} else {
    keystoreProperties["keyAlias"] = System.env.KEYSTORE_KEY_ALIAS ?: ''
    keystoreProperties["keyPassword"] = System.env.KEYSTORE_KEY_PASSWORD ?: ''
    keystoreProperties["storePassword"] = System.env.KEYSTORE_STORE_PASSWORD ?: ''
    keystoreProperties["storeFile"] = System.env.KEYSTORE_FILE ?: ''
}

signingConfigs {
    release {
        storeFile file(keystoreProperties["storeFile"])
        keyAlias keystoreProperties["keyAlias"]
        keyPassword keystoreProperties["keyPassword"]
        storePassword keystoreProperties["storePassword"]
    }
}
signingConfigs {
    val keystoreProperties = Properties()
    val keystorePropertiesFile: File = rootProject.file("config/keystore.properties")
    if (keystorePropertiesFile.exists()) {
        keystoreProperties.load(FileInputStream(keystorePropertiesFile))
    } else {
        keystoreProperties["keyAlias"] = System.getenv("KEYSTORE_KEY_ALIAS").orEmpty()
        keystoreProperties["keyPassword"] = System.getenv("KEYSTORE_KEY_PASSWORD").orEmpty()
        keystoreProperties["storePassword"] = System.getenv("KEYSTORE_STORE_PASSWORD").orEmpty()
        keystoreProperties["storeFile"] = System.getenv("KEYSTORE_FILE").orEmpty()
    }

    create("release") {
        keyAlias = keystoreProperties["keyAlias"] as String
        keyPassword = keystoreProperties["keyPassword"] as String
        storeFile = file(keystoreProperties["storeFile"] as String)
        storePassword = keystoreProperties["storePassword"] as String
    }
}
env:
  GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
  KEYSTORE_FILE: ${{secrets.KEYSTORE_FILE}}
  KEYSTORE_KEY_ALIAS: ${{secrets.KEYSTORE_KEY_ALIAS}}
  KEYSTORE_KEY_PASSWORD: ${{secrets.KEYSTORE_KEY_PASSWORD}}
  KEYSTORE_STORE_PASSWORD: ${{secrets.KEYSTORE_STORE_PASSWORD}} 

- name: Decode Keystore File
  id: decode_keystore_file
  uses: timheuer/base64-to-file@v1
  with:
    fileName: 'keystore_release.jks'
    encodedString: ${{ secrets.KEYSTORE_FILE }}

- name: Set Decoded File Location as Environment
  run: echo "KEYSTORE_FILE=${{steps.decode_keystore_file.outputs.filePath}}" >> $GITHUB_ENV

Expose Version Name

- name: Expose Version Name
  uses: michpohl/[email protected]
  with:
    path: app/build.gradle
    expose-version-name: 'true'
    expose-version-code: 'true'

Run Unit Tests

- name: Unit Tests
  run: ./gradlew testDebugUnitTest

Lint

- name: Lint
  run: ./gradlew lint

Ktlint

- name: Ktlint
  run: ./gradlew ktlintCheck

Detekt

- name: Detekt
  run: ./gradlew detekt

Spotless

- name: Spotless
  run: ./gradlew spotlessCheck

Build

- name: Build
  run: ./gradlew compileDebugKotlin

Build Debug Artifacts

- name: Build Debug Artifacts
  run: ./gradlew app:assembleDebug

Build Release Artifacts

- name: Build Release Artifacts
  run: ./gradlew app:assembleRelease

Build Bundle Artifacts

- name: Build Bundle Artifacts
  run: ./gradlew app:bundleRelease

Upload Artifacts to Outputs

- name: Upload Artifacts to Outputs
  uses: actions/upload-artifact@v2
  with:
    path: |
      app/build/outputs/apk
      app/build/outputs/bundle

Create GitHub Release

- name: Create GitHub Release
  uses: softprops/action-gh-release@v1
  with:
    name: ${{ env.ANDROID_VERSION_NAME }}
    tag_name: ${{ env.ANDROID_VERSION_NAME }}
    draft: false
    prerelease: false
    files: |
      app/build/outputs/apk/**/*.apk
      app/build/outputs/bundle/**/*.aab

Distribute APK via Firebase AppDistribution

• Получаем Firebase Token как в инструкции, в cmd печатаем команду firebase login:ci, авторизуемся в браузере и получаем токен в формате 1//0cu_SL0giwEw2CgYIARAAGAwSNwF-L9IrgUdNUyp6c649n1N5yo2ehsGnklOEXMUND2ej0bddOS5XCDi3EwE1CAgOosw71NFYgxM
• В репозитории переходим в Settings -> Secrets -> Actions и создаем переменную FIREBASE_TOKEN

- name: Distribute Artifacts via Firebase
  run: ./gradlew appDistributionUploadRelease
  env:
    FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

Upload Bundle to Google Play Console

- name: Create Service Account JSON File
  run: echo '${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}' > service_account.json

- name: Deploy to Play Store
  uses: sokchanbo/[email protected]
  with:
    service-account: service_account.json
    package-name: org.michaelbel.template
    release-file: app/build/outputs/bundle/**/*.aab
    track: internal

Push Telegram Message

• Создаем свое приложение на сайте telegram
• Используя botfather создаем бота, придумываем ему имя, генерируем токен авторизации
• Обязательно нужно отправить фиктивное сообщение боту, которое должно выглядеть как команда: /my_id @my_bot, иначе бот не сможет отправлять сообщения
• В репозитории переходим в Settings -> Secrets -> Actions и создаем 2 переменные:
TELEGRAM_TOKEN - токен бота в формате 1234567890:ABCdif1hIgkl-m2O6HKg3TOHHxEuofKB4QN
TELEGRAM_TO - id группы, в которую добавлен бот. Его можно узнать по ссылке https://api.telegram.org/botXXX:YYYY/getUpdates (заменить XXX:YYYY своим токеном бота), предварительно переслав сообщение из группы боту

- name: Push Telegram Message
  uses: appleboy/telegram-action@master
  with:
    to: ${{ secrets.TELEGRAM_TO }}
    token: ${{ secrets.TELEGRAM_TOKEN }}
    disable_notification: false
    disable_web_page_preview: true
    document: app/build/outputs/apk/**/*.apk
    message_file: ./releaseNotes.txt
Clone this wiki locally