ハトネコエ Web がくしゅうちょう

プログラミングやサーバー・Web制作、チームマネジメントなど得た技術のまとめ

シードって何? VC関連のメモ

スタートアップ界隈で仕事をしていれば、ジャフコとかインキュベイトファンドとか、
VC(ベンチャーキャピタル)の名前はよく聞く。

けれど彼らが何をしているのか私はよくわかっていない。
中の人に聞いてみるのが良さそうだけれど、まずは周辺知識についてまとめておく。

むっちゃわかりやすい参考記事 : 起業したてのシードスタートアップに投資する日本のVC(シードアクセラレーター/インキュベーター)さんをまとめました | TURN YOUR IDEAS INTO REALITY.

スタートアップのフェーズ

これについては調べるといろいろな区分けがあるが、
海外の記事を見るとだいたいこの4つだったので以下のまとめとする。(解説文は私の肌感)

  • シード (seed) : プロダクト作成のため、資金や協力者集めの段階。社員(?) 1〜2人程度
  • シリーズA : プロダクトは出来たがまだまだ会社は不安定。社員3〜10人程度
  • シリーズB : 資金繰りに安定が見えてきた。買収を持ちかけられることも。社員10〜30人程度
  • シリーズC : 事業の拡大が見えてきて、上場準備をおこなうため外部から積極的に役員を入れ始めたりする。社員50人〜程度

pre-seed, seed, post-seed, pre-A, Early A, A, Late A, B, ... などなど、細分化するといろんな呼び名がある。

参考: There are only three startup stages – Angular Ventures – Medium

……が、まあ、参考として貼った記事のタイトルが
『There are only three startup stages』であるように、大事なのは3つだ。
シード期シリーズAシリーズAを越えた後 の3つ。

実際、ベンチャー界隈の人と話すときは「シード」と「シリーズA」という言葉を覚えておけばなんとかなる。

シードからシリーズAあたりのことを「スタートアップ」と呼ぶこともあるので、
「『スタートアップ』の時期を乗り越えて……」という発言は「お金のない時期を乗り越えて……」という意味に解釈すればOK。
「スタートアップ界隈」と言うときは「ベンチャー界隈」と同義。
「スタートアップ」という言葉の範囲は広いのだ……。

ピッチイベント(ビジネスコンテスト)

IVS LaunchPadTechCrunch Tokyo などが有名なピッチイベント。
(参考: ピッチイベントまとめてみました。 | 起業サプリジャーナル

「起業したい、こんなアイディアがある!」という人たちの発表の場で、ここから投資が決まることも多い。
起業家からしてみれば、「このアイディア良さそうだけど、すでにありきたりなものじゃないか」「資金調達できるだろうか……」などの不安がある中で揉んでもらえるし、
投資家からしてみれば有望な投資先の発見につながるのでまさに Win-Win なイベント。

ピッチ (pitch) というのは短いプレゼンを指すらしい。
ピッチと言うと「ピッチャー(ボールを投げる人)」を連想するけど、「言葉を投げる」の意味合いもあるようで…。
(参考: 現役商社マンによる実践ビジネス英会話 #6 Pitch|WEBマガジンKEY-PRESS《キープレス》by三鬼商事

ピッチイベントへの参加を考えるなら、このテンプレートが役に立ちそう。
どのようなことをスライドに盛り込むべきか、わかりやすくまとめられている。↓

[スライド] スタートアップの 3 分ピッチテンプレート – Taka Umada – Medium

デット, エクイティ

デット (debt) は「負債」エクイティ (equity) は「株式」

参考: 投資の基礎知識「デット」と「エクイティ」の違いとは? | 富裕層向け資産防衛メディア | 幻冬舎ゴールドオンライン

起業家から見て日本政策金融公庫からの借り入れは debt で、
VCからの資金提供は equity 。

「エクイティ」という単語は、投資会社出身の人と話すとそこそこ出るワードなので覚えておくと便利。

VCの種類

ざっくり分けた。

例を挙げればキリがないのでかなり絞ったぞ!
思っていたよりいっぱいあるぞ!

ジャフコ野村證券系だったけれど、2017年7月に野村の持っていた株を買い*1
今は独立系となった様子。

CVCとして2019年2月に『DMM VENTURES』が誕生したのが最近のニュース。
( 「40以上の事業を持つ強みを生かせ」DMMがCVCをつくる理由 | STARTUP DB MEDIA | 日々進化する、成長産業領域に特化した情報プラットフォーム )

基本的にVCは資産運用を目的とするが、
CVCは事業シナジーを目的とする面もあるのが異なるところ。
(参考: 001 Startupの資金調達 — ピッチの相手はVCそれともCVC? – S. Nishimura – Medium

参考記事に

スタートアップからすると、特定の企業の資金を受け入れ、「色がつく」ことを避けたいという場合もある

とあるが、この「(資金調達により)色がつく」という表現を使うことはあるので覚えておくといい。

資金調達を受けるというのは、自分の会社の決定権の一部を売ることでもあるので、
どこから投資を受けるかというのは思いのほかセンシティブ。
(お金を調達できればいいじゃん、くらいに安直に考えていた……)

VCの資金をどうとらえるか、銀行融資ではないので返済する必要はありませんが、出資を受けることはある意味自分の株という魂の一部を渡すことと同じです。なので、それに対して何を求めるか、本当にお金なのか、一緒に経営していくことなのか、ノウハウなのか、よく判断したほうが良いとは思います。

http://www.jafco.co.jp/case/uuum より引用)

という一文がよく表している。


夜も遅くなってきたのでここまで。
ファンドの資金集め手法とか、1号, 2号とか、実際どのような業務が行われているのかとか、まだまだ謎が多い。

ベンチャーに投資して投資の運用益で食っていると思われがちなベンチャー・キャピタルのお仕事は意外にもファンドの固定手数料が食い扶持のメインなビジネス

http://www.turnyourideasintoreality.com/2013/12/vcinjapan より引用)

というのも実際そうなのか気になるところ。

VCやってる人に、どういう思いで何をして、どうやりくりをしているのか聞いてみたいなぁ。

CircleCI 2.0 で deploygate に Android アプリをアップロード

Android アプリを DeployGate
CircleCI を使って簡単にデプロイしたいな〜、と記事を探したら、
1.0 の記事が多かったので CircleCI 2.0 向けの記事を書くことにしました。

異なる証明書で署名されたアプリと言われ、deploygate に毎回アンインストールを求められる件についても、
「6. 異なる証明書で署名されたアプリと言われないために」の項で解決策を記しています。

実験台となったのは、
前回の『AndroidのgRPCクライアントをKotlinで実装しました』の記事で取り扱ったこちらのリポジトリ

1. config.yml はこうなった

まずは出来上がりから。
.circleci ディレクトリを作った上で、その中に config.yml という名前で保存します。

ただ、このあとの解説で書きますが、 DG_API_KEY を設定しないといけないので、
このままだとまだデプロイが出来ません。

aliases:
  android_docker: &android_docker
    docker:
      - image: circleci/android:api-28
        environment:
          TZ: Asia/Tokyo
  steps:
    - restore_cache: &restore_cache
        key: &jars_key jars-{{ checksum "build.gradle.kts" }}-{{ checksum "app/build.gradle.kts" }}
    - run: &download_deps
        name: Download dependencies
        command: ./gradlew androidDependencies
    - save_cache: &save_cache
        paths:
          - ~/.gradle
        key: *jars_key
    - run: &build_debug_apk
        name: Build debug APK
        command: ./gradlew assembleDebug
    - run: &test
        name: test
        command: ./gradlew test
    - run: &upload_to_deploy_gate
        name: Upload to DeployGate # Set DG_API_KEY in CircleCI
        command: |
          APK_PATH=app/build/outputs/apk/debug/app-debug.apk
          TIME=$(date "+%Y/%m/%d %H:%M")
          COMMIT_HASH=$(git log --format="%H" -n 1 | cut -c 1-8)
          USERNAME=nekonenene
          curl -F "file=@${APK_PATH}" -F "token=${DG_API_KEY}" -F "message=Build by CircleCI <${COMMIT_HASH}> (${TIME})" https://deploygate.com/api/users/${USERNAME}/apps

version: 2
jobs:
  build:
    <<: *android_docker
    steps:
      - checkout
      - restore_cache: *restore_cache
      - run: *download_deps
      - save_cache: *save_cache
      - run: *build_debug_apk
  test:
    <<: *android_docker
    steps:
      - checkout
      - restore_cache: *restore_cache
      - run: *download_deps
      - save_cache: *save_cache
      - run: *test
  deploy:
    <<: *android_docker
    steps:
      - checkout
      - restore_cache: *restore_cache
      - run: *download_deps
      - save_cache: *save_cache
      - run: *build_debug_apk
      - run: *upload_to_deploy_gate

workflows:
  version: 2
  build_and_deploy:
    jobs:
      - build
      - test
      - deploy:
          requires:
            - build
            - test
          filters:
            branches:
              only: master
          context: deploygate

(長いので gist で見たい人用リンク)

あとで再び書きますが、このリポジトリでは gradle 設定を Kotlin で書いているために、
「build.gradle.kts」と書いている箇所があります。
たいていの方は「build.gradle」と書き直してください。

また、docker image は「circleci/android:api-28」を使っていますが、
compileSdkVersion に合わせたものをお使いください。

2. master 以外のブランチではデプロイしない

他のブランチで push されたときもテストはしたいけど、
deploygate にアップロードするのは master ブランチへコミットがあったときに限定したいな〜
という希望があると思います。

それを実現しているのが workflows の部分です。

workflows:
  version: 2
  build_and_deploy:
    jobs:
      - build
      - test
      - deploy:
          requires:
            - build
            - test
          filters:
            branches:
              only: master
          context: deploygate

workflows としてはこうなっています。
ここの jobs で、実行する job を指定でき、各々にはさらに設定を書くことが出来ます。

- deploy:
    requires:
      - build
      - test
    filters:
      branches:
        only: master
    context: deploygate

filters: に branches: only: master と書かれていることによって、
master ブランチへコミットがあったときだけ、deploy job は実行されるようになっています。

また、 requires: に build と test が書かれていることによって、
build job と test job の両方が終わった後に deploy job が走るようになっています。

これを書かなかった場合、他の job と deploy job がパラレルに(並行して)走ります。

つまり、フローとしては以下のようになっています。

build ──┬── deploy (only: master)
test  ──┘

context については後で説明します。

3. 各 job を定義する

workflows から先に説明しましたが、もっとも大事なのは jobs の部分です。
ここで、何がおこなわれるかを定義します。

version: 2
jobs:
  build:
    <<: *android_docker
    steps:
      - checkout
      - restore_cache: *restore_cache
      - run: *download_deps
      - save_cache: *save_cache
      - run: *build_debug_apk

と書かれている部分ですね。

簡潔に書くため、YAMLのAnchors and Aliases 機能を使って書きましたが、
省略せずに書くと以下のようになっています。

jobs:
  build:
    docker:
      - image: circleci/android:api-28
        environment:
          TZ: Asia/Tokyo
    steps:
      - checkout
      - restore_cache:
          key: jars-{{ checksum "build.gradle.kts" }}-{{ checksum "app/build.gradle.kts" }}
      - run:
          name: Download dependencies
          command: ./gradlew androidDependencies
      - save_cache:
          paths:
            - ~/.gradle
          key: jars-{{ checksum "build.gradle.kts" }}-{{ checksum "app/build.gradle.kts" }}
      - run:
          name: Build debug APK
          command: ./gradlew assembleDebug

今回はビルドに使う Android SDK が 28 であるため、
使用する Docker image も circleci/android:api-28 を使用しています。

他のバージョンもありますので、ふさわしいものを探してください。
https://hub.docker.com/r/circleci/android/tags

restore_cache では、
build.gradle.kts および app/build.gradle.kts が更新されているかを確認し、
変更がなければ以前 save_cache で保存した .gradle を使用します。
これにより、2回目以降の CircleCI の実行時間が短くなります。

前回の記事でも触れましたが、 Gradle Kotlin DSL により
gradle 設定を Kotlin で書いているためにファイル名が「build.gradle.kts」になっています。

Gradle Kotlin DSL を使っていない場合は、 key: のところは
jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} と書きましょう。

4. deploygate にアップロード

肝心の deploygate へのアップロードですね!

このようにコマンドを作成しました。

- run: &upload_to_deploy_gate
    name: Upload to DeployGate # Set DG_API_KEY in CircleCI
    command: |
      APK_PATH=app/build/outputs/apk/debug/app-debug.apk
      TIME=$(date "+%Y/%m/%d %H:%M")
      COMMIT_HASH=$(git log --format="%H" -n 1 | cut -c 1-8)
      USERNAME=nekonenene
      curl -F "file=@${APK_PATH}" -F "token=${DG_API_KEY}" -F "message=Build by CircleCI <${COMMIT_HASH}> (${TIME})" https://deploygate.com/api/users/${USERNAME}/apps

deploygate の API ドキュメント によれば、
アプリのアップロードは

curl \
  -F "token=xxx" \
  -F "file=@sample.apk" \
  -F "message=sample" \
  https://deploygate.com/api/users/_your_name_/apps

で出来ると書かれていますのでそれに従っています。

変数 APK_PATH にデバッグビルドで作られるアプリのパスを指定、
message に入れる文字列として変数 TIME, COMMIT_HASH を定義、
変数 USERNAME には deploygate のユーザー名を代入したあと、API を叩いています。

"message=Build by CircleCI <${COMMIT_HASH}> (${TIME})" となっていますので、
「Build by CircleCI <02f18181> (2019/02/23 19:07)」のようなメッセージが付けられることになります。

deploygate の管理画面のスクリーンショット
deploygate の管理画面

メッセージに日時を入れているのは、
deploygate アプリからバージョン一覧を見たときに、どれが何か全然わからなかったためですね…。

↓ 入れないとこんな感じ

deploygate の Android アプリのスクリーンショット
deploygate の Android アプリのスクリーンショット

コミットメッセージを入れようかとも思いましたが、
コミットメッセージに特殊文字が含まれる場合に curl が失敗しないよう
処理を考えなくては…なので今回はやりませんでした。

5. deploygate API Key の指定

さて、上のコマンドで "token=${DG_API_KEY}" となっている箇所がありました。
ここの変数にどうやって値を入れているかの話をします。

CircleCI には、設定画面からプロジェクトごと、もしくは Context ごとに環境変数を設定できるようになっています。
今回はそれの後者、Context を使った環境変数の設定をおこなっています。
参考 : https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-context

以下の画像のように、「SETTINGS」の「Contexts」へと進みます。

CircleCI の設定ページ
SETTINGS → Contexts

右上に「Create Context」のボタンがあると思いますので、それを押して Context の新規作成をします。
Name はわかりやすく「deploygate」としておきましょう。

f:id:nekonenene:20190223202240p:plain
「deploygate」の名前で CircleCI Context を作成

すると、以下の画面が出ますので「Add Environment Variable」ボタンから環境変数の追加をおこないます。

f:id:nekonenene:20190223202531p:plain

入力画面が出たら、Nameに「DG_API_KEY」、Valueに deploygate の API キーを入力します。

API キーは https://deploygate.com/settings の下の方に書かれています。

f:id:nekonenene:20190223202942p:plain
DG_API_KEY として deploygate の API key を設定

この設定を完了させたことにより、
(2. で説明を省きました) context: deploygate のコンフィグにより、
deploy job の実行時にいま設定した環境変数が読み込まれるようになります。

これで、 deploygate へ Android アプリを永遠にアップロードすることができる
CircleCI config が完成しました! おつかれさまです!!

6. 異なる証明書で署名されたアプリと言われないために

これで一件落着かと思いきや罠があります。

異なる証明書で署名されたアプリ (バージョン 1.0=1) が既にインストールされています。新しいアプリをインストールする前に、一度アンインストールしてください。

と、アンインストールが毎回求められてしまうことが発生します。

f:id:nekonenene:20190223203807j:plain
異なる証明書で署名されたアプリが既にインストールされています

なんで起きるかというと、デバッグビルドの署名は通常 ~/.android/debug.keystore にある証明書が使われるのですが、
CircleCI が使う Docker イメージが毎回異なるため、署名に使う証明書も一致しないのです。

ということで、 デバッグビルドに使う証明書を指定しましょう!!

まずはプロジェクトのルートディレクトリにて以下のコマンドを実行します。

keytool -v -genkey -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US" -keyalg RSA -validity 36500

これで 36500 日(およそ100年)有効の証明書が作成できます。

次に app ディレクトリの build.gradle.kts に以下のような設定が含まれるよう修正します。
参照: https://github.com/nekonenene/grpc_android_client/blob/master/app/build.gradle.kts

android {
    // 中略
    signingConfigs {
        getByName("debug") {
            storeFile = rootProject.file("debug.keystore")
            storePassword = "android"
            keyAlias = "androiddebugkey"
            keyPassword = "android"
        }
    }

    buildTypes {
        getByName("debug") {
            isMinifyEnabled = false
            signingConfig = signingConfigs.getByName("debug")
        }
    }
}

Gradle Kotlin DSL を使わない場合の書き方は異なります。公式のドキュメントなどを参照してください。
storePassword, keyAlias, keyPassword は、さっきのコマンドで指定した値(-storepass android -alias androiddebugkey -keypass android)と一致するように気を付けてください。

これにより、デバッグビルド時に、プロジェクトのルートディレクトリに作った
debug.keystore が毎回使われ、同一の証明書による署名となってくれるため、
deploygate にアンインストールが毎回求められる問題はなくなります。

7. おしまい

しっかり書いたらけっこう長くなりましたが、以上!
Android アプリを deploygate にデプロイし続ける方法でしたー!

異なる証明書で署名されたアプリ 問題は、昔「毎回アンインストールはめんどいな〜」って思いながらも
しぶしぶやっていましたが、今回調べたらちゃんと対処法が発見できてよかったです。

DroidKaigi 2018 のアプリ もよく見ると、
debug.keystore がトップディレクトリに置いてありますね。なるほどなー。

らくらく実機テストをして、楽しいアンドロイド開発ライフをお過ごしください!