$30 off During Our Annual Pro Sale. View Details »

ZOZOTOWNの開発で試したUIの確認/検証の効率化 / Efficiency of UI checks/verifications tried in the development of ZOZOTOWN Apps

ZOZOTOWNの開発で試したUIの確認/検証の効率化 / Efficiency of UI checks/verifications tried in the development of ZOZOTOWN Apps

Ryosuke Horie

October 21, 2020
Tweet

More Decks by Ryosuke Horie

Other Decks in Programming

Transcript

  1. ZOZOTOWNの開発で試した

    UIの確認/検証の効率化

    2020/10/21(Wed)
    Chatwork Tech Talk #1

    株式会社ZOZOテクノロジーズ

    ZOZOTOWN部 Androidチーム Tech Lead

    堀江 亮介

    Copyright © ZOZO Technologies, Inc.

    View Slide

  2. © ZOZO Technologies, Inc.
    株式会社ZOZOテクノロジーズ

    ZOZOTOWN部 Androidチーム

    Tech Lead
    堀江 亮介

    ● 自動化とビールが好き
    ● @Horie1024
    ● 昔Androidテスト全書という本を書きました

    2

    View Slide

  3. © ZOZO Technologies, Inc.
    開発中のUIの確認/検証をどう行っていますか?

    3

    View Slide

  4. © ZOZO Technologies, Inc.
    4
    1. 開発

    2. 確認/検証用アプリの用意と配布

    3. デザイナーへ確認/検証の依頼

    4. 問題があれば修正、なければ完了

    ZOZOTOWN Androidの場合


    View Slide

  5. © ZOZO Technologies, Inc.
    5
    1. 問題の把握と修正

    2. 確認/検証用アプリの用意と配布

    3. デザイナーへ確認/検証の依頼

    4. 問題があれば修正、なければ完了

    もし問題があれば・・

    問題の把握と修正から再開


    View Slide

  6. © ZOZO Technologies, Inc.
    6
    1. 問題の把握と修正

    2. 確認/検証用アプリの用意と配布

    3. デザイナーへ確認/検証の依頼

    4. 問題があれば修正、なければ完了

    もし問題があれば・・

    問題の把握と修正から再開

    問題の修正から完了までのフローを効率化したい

    View Slide

  7. © ZOZO Technologies, Inc.
    7
    1. 問題の把握と修正

    2. 確認/検証用アプリの用意と配布

    3. デザイナーへ確認/検証の依頼

    4. 問題があれば修正、なければ完了

    効率化するポイントを探す


    View Slide

  8. © ZOZO Technologies, Inc.
    8
    1. 問題の把握と修正

    2. 確認/検証用アプリの用意と配布

    3. デザイナーへ確認/検証の依頼

    4. 問題があれば修正、なければ完了

    効率化するポイントを探す

    手動でAPKのビルドと配布を行っていた


    View Slide

  9. © ZOZO Technologies, Inc.
    9
    APKのビルド
    Googleドライブへの
    アップロード
    デザイナーへリンクを共有
    確認/検証用アプリの用意と配布の自動化


    View Slide

  10. © ZOZO Technologies, Inc.
    10
    APKのビルド
    Googleドライブへの
    アップロード
    デザイナーへリンクを共有
    確認/検証用アプリの用意と配布の自動化


    この部分を自動化する


    View Slide

  11. © ZOZO Technologies, Inc.
    11
    APKのビルド
    Googleドライブへの
    アップロード
    デザイナーへリンクを共有
    確認/検証用アプリの用意と配布の自動化


    CIサーバー + アプリ配布サービス で容易に自動化


    View Slide

  12. © ZOZO Technologies, Inc.
    12
    APKのビルド
    Googleドライブへの
    アップロード
    デザイナーへリンクを共有
    確認/検証用アプリの用意と配布の自動化


    GitHub Actions

    DeployGate

    GitHub Actions + DeployGate で実現


    View Slide

  13. © ZOZO Technologies, Inc.
    13
    確認/検証用アプリの用意と配布の自動化


    ● デザイナーへの共有にはDeployGateの配布ページを利用

    ● 2次元バーコードの読み取りでインストールできるので簡単

    ● 簡単なのがとても重要


    View Slide

  14. © ZOZO Technologies, Inc.
    14
    確認/検証用アプリの用意と配布の自動化


    ● デザイナーへの共有にはDeployGateの配布ページを利用

    ● 2次元バーコードの読み取りでインストールできるので簡単

    ● 簡単なのがとても重要

    複雑・煩雑だと使われなくなってしまう


    View Slide

  15. © ZOZO Technologies, Inc.
    15
    1. 問題の把握と修正

    2. 確認/検証用アプリの用意と配布

    3. デザイナーへ確認/検証の依頼

    4. 問題があれば修正、なければ完了

    確認/検証用アプリの用意と配布の自動化


    GitHub Actions + DeployGateで自動化


    View Slide

  16. © ZOZO Technologies, Inc.
    16
    1. 問題の把握と修正

    2. 確認/検証用アプリの用意と配布

    3. デザイナーへ確認/検証の依頼

    4. 問題があれば修正、なければ完了

    確認/検証用アプリの用意と配布の自動化


    GitHub Actions + DeployGateで自動化

    GitHub Actionsのビルドトリガーをどこに置くか?

    View Slide

  17. © ZOZO Technologies, Inc.
    17
    GitHub Actionsのビルドトリガー

    何らかのイベント

    View Slide

  18. © ZOZO Technologies, Inc.
    18
    GitHub Actionsのビルドトリガー

    何らかのイベント
    GitHub上で発生するイベントと相性が良い


    View Slide

  19. © ZOZO Technologies, Inc.
    GitHub上で発生するイベント = 開発で発生するイベント

    19

    View Slide

  20. © ZOZO Technologies, Inc.
    20
    1. 問題の把握と修正

    2. 確認/検証用アプリの用意と配布

    3. デザイナーへ確認/検証の依頼

    4. 問題があれば修正、なければ完了

    確認/検証用アプリの用意と配布の自動化


    開発で行っている作業(GitHubを使用する作業)を書き出す


    View Slide

  21. © ZOZO Technologies, Inc.
    21
    1. 問題の把握と修正

    2. Pull Requestのオープン

    3. 確認/検証用アプリの用意と配布

    4. デザイナーへ確認/検証の依頼

    5. 問題があれば修正、なければ完了

    6. Pull Requestのクローズ

    確認/検証用アプリの用意と配布の自動化


    View Slide

  22. © ZOZO Technologies, Inc.
    22
    1. 問題の把握と修正

    2. Pull Requestのオープン

    3. 確認/検証用アプリの用意と配布

    4. デザイナーへ確認/検証の依頼

    5. 問題があれば修正、なければ完了

    6. Pull Requestのクローズ

    確認/検証用アプリの用意と配布の自動化


    View Slide

  23. © ZOZO Technologies, Inc.
    23
    ● 配布のライフサイクル

    ○ Pull Requestのオープン → APKをビルドし配布開始

    ○ Pull Requestのクローズ → APKの配布終了

    確認/検証用アプリの用意と配布の自動化


    View Slide

  24. © ZOZO Technologies, Inc.
    24
    1. 問題の把握と修正

    2. Pull Requestのオープン → APKのビルドと配布ページ作成

    3. デザイナーへ確認/検証の依頼 → 配布ページのURLを共有

    4. 問題があれば修正、なければ完了

    5. Pull Requestのクローズ → 配布ページ削除

    実現したいUIの確認/検証フロー


    これを実現するようGitHub ActionsのWorkflowを組む


    View Slide

  25. © ZOZO Technologies, Inc.
    デモ

    サンプルプロジェクトで実際にPull Requestを作成し、

    配布ページが自動で作られる様子を紹介します。

    25

    View Slide

  26. © ZOZO Technologies, Inc.
    GitHub Actionsの設定

    26

    View Slide

  27. © ZOZO Technologies, Inc.
    27
    ● 2つのWorkflowを用意

    ○ Pull Request作成時に実行

    ○ Pull Requestクローズ時に実行

    GitHub Actionsの設定


    View Slide

  28. © ZOZO Technologies, Inc.
    28
    ● 2つのWorkflowを用意

    ○ Pull Request作成時に実行

    ■ APKのビルド

    ■ DeployGateへAPKのアップロード・配布ページの作成

    ■ Pull Requestへ配布ページURLをコメント

    ○ Pull Requestクローズ時に実行

    ■ DeployGate配布ページを削除

    GitHub Actionsの設定


    View Slide

  29. © ZOZO Technologies, Inc.
    Pull Request作成時に実行されるWorkflow

    29

    View Slide

  30. © ZOZO Technologies, Inc.
    30
    name: Android CI on Pull Request Open
    on: [pull_request]
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url"
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n${{ steps.distribute_app.outputs.distribution_page_url }}'
    })

    View Slide

  31. © ZOZO Technologies, Inc.
    31
    name: Android CI on Pull Request Open
    on: [pull_request]
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url"
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n${{ steps.distribute_app.outputs.distribution_page_url }}'
    })

    View Slide

  32. © ZOZO Technologies, Inc.
    on: [pull_request]
    32
    Pull Requestが作成されたタイミングでWorkflowをトリガー

    View Slide

  33. © ZOZO Technologies, Inc.
    33
    name: Android CI on Pull Request Open
    on: [pull_request]
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url"
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n${{ steps.distribute_app.outputs.distribution_page_url }}'
    })

    View Slide

  34. © ZOZO Technologies, Inc.
    34
    name: Android CI on Pull Request Open
    on: [pull_request]
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url"
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n${{ steps.distribute_app.outputs.distribution_page_url }}'
    })

    View Slide

  35. © ZOZO Technologies, Inc.
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | \
    jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url" 35

    View Slide

  36. © ZOZO Technologies, Inc.
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | \
    jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url" 36
    配布ページURLを下流のstepに共有する設定

    View Slide

  37. © ZOZO Technologies, Inc.
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | \
    jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url" 37

    View Slide

  38. © ZOZO Technologies, Inc.
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | \
    jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url" 38
    ビルドを実行してAPKを生成

    View Slide

  39. © ZOZO Technologies, Inc.
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | \
    jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url" 39

    View Slide

  40. © ZOZO Technologies, Inc.
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | \
    jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url" 40
    DeployGateへAPKをアップロード/配布ページ作成

    View Slide

  41. © ZOZO Technologies, Inc.
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | \
    jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url" 41
    ブランチ名で配布ページを作成

    View Slide

  42. © ZOZO Technologies, Inc.
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | \
    jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url" 42
    レスポンスから配布ページURLを取得
    jqがデフォルトで使えるので利用

    View Slide

  43. © ZOZO Technologies, Inc.
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | \
    jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url" 43
    配布ページURLを下流のstepで利用できるようset

    View Slide

  44. © ZOZO Technologies, Inc.
    44
    name: Android CI on Pull Request Open
    on: [pull_request]
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url"
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n${{ steps.distribute_app.outputs.distribution_page_url }}'
    })

    View Slide

  45. © ZOZO Technologies, Inc.
    45
    name: Android CI on Pull Request Open
    on: [pull_request]
    jobs:
    build:
    runs-on: ubuntu-latest
    outputs:
    distribution_page_url: ${{ steps.distribute_app.outputs.distribution_page_url }}
    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: ./gradlew assembleDebug
    - name: Distribute App
    id: distribute_app
    run: |
    distribution_page_url=$(curl \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "file=@app/build/outputs/apk/debug/app-debug.apk" \
    -F "message=git-hash:`git rev-parse --short $GITHUB_SHA`" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/apps | jq -r .results.distribution.url)
    echo "::set-output name=distribution_page_url::$distribution_page_url"
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n${{ steps.distribute_app.outputs.distribution_page_url }}'
    })

    View Slide

  46. © ZOZO Technologies, Inc.
    46
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n' +
    '${{ steps.distribute_app.outputs.distribution_page_url }}'
    })

    View Slide

  47. © ZOZO Technologies, Inc.
    47
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n' +
    '${{ steps.distribute_app.outputs.distribution_page_url }}'
    })
    octokit/rest.jsをstep内から実行可能にするaction
    JavaScriptでGitHub APIを制御

    View Slide

  48. © ZOZO Technologies, Inc.
    48
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n' +
    '${{ steps.distribute_app.outputs.distribution_page_url }}'
    })

    View Slide

  49. © ZOZO Technologies, Inc.
    49
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n' +
    '${{ steps.distribute_app.outputs.distribution_page_url }}'
    })
    配布ページURLをPull Requestへコメント

    View Slide

  50. © ZOZO Technologies, Inc.
    50

    View Slide

  51. © ZOZO Technologies, Inc.
    51
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n' +
    '${{ steps.distribute_app.outputs.distribution_page_url }}'
    })

    View Slide

  52. © ZOZO Technologies, Inc.
    52
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n' +
    '${{ steps.distribute_app.outputs.distribution_page_url }}'
    })
    Pull Requestへのコメント一覧を取得

    View Slide

  53. © ZOZO Technologies, Inc.
    53
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n' +
    '${{ steps.distribute_app.outputs.distribution_page_url }}'
    })

    View Slide

  54. © ZOZO Technologies, Inc.
    54
    - name: Comment to Pull Request
    uses: actions/github-script@v3
    with:
    github-token: ${{secrets.GITHUB_TOKEN}}
    script: |
    const comments = await github.paginate(github.issues.listComments, {
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    })
    for (const comment of comments) {
    if (comment.body.includes("https://deploygate.com/distributions/")) {
    return // The URL for the distribution page has already been posted.
    }
    }
    github.issues.createComment({
    issue_number: context.issue.number,
    owner: context.repo.owner,
    repo: context.repo.repo,
    body: '配布ページを作成しました\n' +
    '${{ steps.distribute_app.outputs.distribution_page_url }}'
    })
    コメントに配布ページURLが含まれているか確認
    含まれていればreturn

    View Slide

  55. © ZOZO Technologies, Inc.
    Pull Requestクローズ時に実行されるWorkflow

    55

    View Slide

  56. © ZOZO Technologies, Inc.
    56
    name: Android CI on Pull Request Close
    on:
    pull_request:
    types: [closed]
    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: Delete distribution page
    run: |
    curl \
    -X DELETE \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/platforms/android/apps/com.horie1024.githubactionssample/distributions

    View Slide

  57. © ZOZO Technologies, Inc.
    57
    name: Android CI on Pull Request Close
    on:
    pull_request:
    types: [closed]
    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: Delete distribution page
    run: |
    curl \
    -X DELETE \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/platforms/android/apps/com.horie1024.githubactionssample/distributions

    View Slide

  58. © ZOZO Technologies, Inc.
    on:
    pull_request:
    types: [closed]
    58
    Pull Requestがクローズされたタイミングで
    Workflowをトリガー

    View Slide

  59. © ZOZO Technologies, Inc.
    59
    name: Android CI on Pull Request Close
    on:
    pull_request:
    types: [closed]
    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: Delete distribution page
    run: |
    curl \
    -X DELETE \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/platforms/android/apps/com.horie1024.githubactionssample/distributions

    View Slide

  60. © ZOZO Technologies, Inc.
    60
    name: Android CI on Pull Request Close
    on:
    pull_request:
    types: [closed]
    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: Delete distribution page
    run: |
    curl \
    -X DELETE \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/platforms/android/apps/com.horie1024.githubactionssample/distributions

    View Slide

  61. © ZOZO Technologies, Inc.
    61
    name: Android CI on Pull Request Close
    on:
    pull_request:
    types: [closed]
    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: Delete distribution page
    run: |
    curl \
    -X DELETE \
    -F "token=${{secrets.DEPLOYGATE_TOKEN}}" \
    -F "distribution_name=$GITHUB_HEAD_REF" \
    https://deploygate.com/api/users/${{secrets.DEPLOYGATE_USER}}/platforms/android/apps/com.horie1024.githubactionssample/distributions
    ブランチ名を指定して配布ページを削除

    View Slide

  62. © ZOZO Technologies, Inc.
    62
    ● これでGitHub Actionsの設定は完了

    ● サンプルリポジトリはこちら

    ● https://github.com/horie1024/github_actions_android_sample

    GitHub Actionsの設定


    View Slide

  63. © ZOZO Technologies, Inc.
    導入した結果

    63

    View Slide

  64. © ZOZO Technologies, Inc.
    64
    ● ZOZOTOWNアプリチームではKPTを定期的に行っている

    ○ iOS/Android/API/デザインの各チーム毎のKPT

    ○ 各チームを横断した全体のKPT

    ● 配布ページの件はデザイナーチームからKeepとしてフィードバック

    KPT(Keep Problem Try)


    View Slide

  65. © ZOZO Technologies, Inc.
    65
    「AndroidアプリのDeployGateによるデザイン確認を、2次元バーコードでインス
    トール画面に飛べるようにしてもらったので大変楽になりました。」

    デザイナーからのフィードバック


    View Slide

  66. © ZOZO Technologies, Inc.
    まとめ

    66

    View Slide

  67. © ZOZO Technologies, Inc.
    67
    まとめ

    ● GitHub Actions + DeployGateでAPKのビルドと配布を自動化

    ● デザイナーチームからポジティブなフィードバックを得た

    ● UIの確認/検証の効率化につながっている


    View Slide

  68. View Slide