GitHub

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/cancel-workflow-action@0.9.1
  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 17
  uses: actions/setup-java@v1
  with:
    java-version: 1.17

Decode Keystore File

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

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/android-expose-version-name-action@v1.0.0
  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/android-upload-google-play@v1.0.0
  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:ABCdif2hIgkl-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

Подключить Github Pages

Включить развертывание сайта на github.io. Например проект KMP WASM.

• В репозитории перейти SettingsPagesBranch выбрать Deploy from a branch. Проект должен лежать в /root.

• В репозитории перейти SettingsPagesBranch выбрать GitHub Actions. Проект должен собираться с помощью CI.