ビルド環境（Androidアプリ）を作る : pull_policy = "if-not-present"

# はじめに

dockerでAndroidビルドをする環境構築について、です。

`pull_policy = "if-not-present"`
使ったことありますか？
runnerに設定するパラメータで動作させるdockerに登録済みのimageを優先して使う設定です。

3日目にあったーと今気づいて編集し直してます。
https://qiita.com/South_/items/f9cc9f1413d52c076fd2

homeにある.gitlab-runnerフォルダのtomlファイルはこんな感じです

```toml

concurrent = 1
check_interval = 0
[[runners]]
 -- (略)---

[[runners]]
  name = "ci-mac-docker"
  url = "https://[gitlabのあるURL]/"
  token = "xxxxxxxxxxxxxxxxxxxxxx"
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "android-build:1.0.0"
    privileged = false
    disable_cache = false
    volumes = ["/cache"]
    pull_policy = "if-not-present"
    shm_size = 0
  [runners.cache]

```

gitlab-ci.ymlに一連のイメージからの構築を記載して動作して
ものすごく時間がかかる。。。と思ったら見つけたのですが、あんまり書いてるサイトがなく。
私メモからの転載で申し訳ないんですが、dockerでgitlab-ciと繋げるところは他の方の記述を参考にした上で読んでいただけると。

# 環境

## gitlab-runner

```bash
$ gitlab-runner -v
Version:      10.8.0
Git revision: 079aad9e
Git branch:   
GO version:   go1.8.7
Built:        2018-05-22T03:23:18+00:00
OS/Arch:      darwin/amd64
```

## Dockerイメージの準備

Macで動かしています。
image上にkeystoreを埋めて置きます。

```
├── DockerFile
├── androidApp_release_keystore.jks
├── licenses
│      ├── android-sdk-license
│      └── intel-android-extra-license
└──  packages.txt
```
### licenses
licenseファイルは、~/Library/Android/sdk/licenses/のフォルダから持ってきたものを配置しています

### packages.txt
一例です。最新のバージョンを指定してsdkmanagerを実行するとエラーで進まなかったので
記載しているバージョンは古めにしています。

```
platform-tools
build-tools;25.0.0
platforms;android-24
platforms;android-25
extras;android;m2repository
extras;google;m2repository
extras;google;google_play_services
extras;m2repository;com;android;support;constraint;constraint-layout-solver;1.0.2
extras;m2repository;com;android;support;constraint;constraint-layout;1.0.2
```
### DockerFile 

sdkmanagerでpackages.txtを読み込ませるときに
最新のバージョンを指定すると失敗したので、記載しているバージョンはやや古くして、インストール完了後にupdateをかけるようにしました。

```dockerfile

FROM openjdk:8-jdk

MAINTAINER      hogehoge

ENV SDK_ROOT "/sdk"
ENV ANDROID_COMPILE_SDK "24"
ENV ANDROID_BUILD_TOOLS "25.0.2"
ENV ANDROID_SDK_TOOLS "3859397"
ENV ANDROID_HOME $SDK_ROOT

ENV PATH $PATH:$SDK_ROOT/platform-tools/

# Install Java.
ADD licenses $SDK_ROOT/licenses
ADD packages.txt ./packages.txt

# keystore
ADD androidApp_release_keystore.jks /jks/androidApp_release_keystore.jks

RUN \
  apt-get --quiet update --yes && \
  wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/sdk-tools-linux-$ANDROID_SDK_TOOLS.zip && \
  unzip -q android-sdk.zip -d $SDK_ROOT && \
  mkdir -p /root/.android && \
  touch /root/.android/repositories.cfg && \
  $SDK_ROOT/tools/bin/sdkmanager --package_file=./packages.txt && \
  $SDK_ROOT/tools/bin/sdkmanager --update && \
  touch local.properties && \
  echo "sdk.dir=$ANDROID_HOME" >> local.properties && \
  rm android-sdk.zip

```
## docker imageを作る
`docker build .`カレントと同じフォルダにあるDockerFileを読み込んでimageを作成し
`docker images` 作成した [IMAGE ID]を見つけて

> dockerhub名/なんとか:バージョン

みたいにタグ名をつけます。dockerhubにアップする気はないので適当につけます

```
$ docker build .
$ docker images
$ docker tag [IMAGE ID] hoge/android-build:1.0.0
```
作業後に一時ファイルがたくさんできているので削除するものは削除しましょう。慎重に。

SHOW UNTAGGED IMAGES (DANGLING)
https://docs.docker.com/engine/reference/commandline/images/#filtering

# gitlab

## .gitlab-ci.yml

```yml

.job_template: &job_build
  image: hogehoge /android-build:1.0.0
  tags:
    - docker
  before_script:
    - chmod +x ./gradlew
  artifacts:
    expire_in: 5 hrs
    paths:
    - app/build/outputs/apk
    - app/build/outputs/logs
    - app/build/outputs/mapping
  only:
    - feature/#CI

stages:
  - build

build-Debug:
  <<: *job_build
  stage: build
  script:
    - ./gradlew clean assembleDebug

build-Release:
  <<: *job_build
  stage: build
  script:
    - ./gradlew clean assembleRelease
```

# Android

## build.gradle

リリース用のkeystoreはビルド用のimageに埋めているのでこんな感じです。

```gradle

 -- (略)---
android {
    dataBinding {
        enabled = true
    }
    compileSdkVersion 28
    defaultConfig {
        applicationId "jp.hoge.test.testApp"
        minSdkVersion 26
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    //キーストア設定
    signingConfigs {
        release {
            storeFile file('/jks/androidApp_release_keystore.jks')
            storePassword 'xxxxxxx'
            keyAlias 'xxxxxxxxx'
            keyPassword 'xxxxxxxxxx'
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }
}
 -- (略)---

```

# さいごに
dockerImageとして作成するものは、Androidのビルド環境以外に色々作れます。

オンプレミスで動かす必要のあるもの
データを取りに行ったり、溜まったデータを処理したり、今時な用途で
自分の作業環境と分離して実行して、快適に作業しましょう。

# 参考

imageにタグをつける
http://docs.docker.jp/linux/step_six.html

Using the if-not-present pull policy
https://docs.gitlab.com/runner/executors/docker.html#using-the-if-not-present-pull-policy

sdkmanager
https://developer.android.com/studio/command-line/sdkmanager