「NO RULES(ノー・ルールズ) 世界一『自由』な会社、NETFLIX」を読んだ

f:id:shoheikawano:20210122093430j:plain

同僚に勧められて読んだ本。本を読み切るまでに(文字を読むのが遅くて)どうしても時間がかかるが、ちょっとずつ読み進めてようやく読み終えた。

ざっくり書いてあること

NETFLIXがイノベーションを生み出すために「自由と責任」のある文化を作り担保していることについて、その文化とはどういうものか、どのように作ったか、どのように担保しているか、などがCEOや現or元社員へのインタビューを元に書いてある。またそのような文化を醸成したいと思うなら、「あなたの会社ではまずこういうことをやってみたらよい」というようなことも書いてある。自由も責任も与えています、みたいな単純な話では全くなかった。全体的に赤裸々&詳細にエピソードであったりが書かれていて、参考になることが多かった。

3ハイライト

  • "「反対意見があるのに表明しないのは、ネットフリックスに対する裏切りだ」とはっきり言っている。意見を口に出さないのは、会社に貢献しないことを選択するのに等しい。"
  • "「自由と責任」が非常にうまく機能している一因は、社員が自由に付随する責任の重さを痛感し、並々ならぬ努力をすることにある。"
  • "たいていの会社は社員の離職率をできるだけ抑えようと努力する。新たな社員を探し、訓練するにはコストがかかるので、既存の社員を抱え込んでおいたほうが安上がりなのは常識だ。しかしリードは離職率はあまり気にしていない。すべてのポジションに最適な人材がいることのほうが、代わりを見つける費用よりも重要だと考えているからだ。"

ハイライトが大量にあり(たぶんしすぎた)、「特に良かった」というハイライトをピックアップできていない感がすごい...。が、ピックアップしすぎも良くないと思ったので3つに。4Aの話、転職活動の話、360度評価などの話など取り上げたいものはたくさんあるけど今の自分に刺さったのはこれ、というふうに選んだ。

まとめ

すぐに作れる文化などでは全くなさそうだということと、アメリカ(の雇用形態の仕組みや文化など)だからできるみたいなところも正直ありそうだったが、すぐに実践できそうな考え方や内容などもたくさんあった。

仕事に関わる内容を抜きにして読んでいて特に面白いなと感じたところは、本の最後のほうにあるNETFLIXがグローバル企業になる上で、育ってきた国の文化によってNETFLIXの醸成した文化を受け入れやすい、にくいなどがあったことのエピソードなどだった。「面白い」というより、試行錯誤している内容が、自分の日常だったりと一番かけ離れているようなところだなと感じた。また、日本の文化についての話や日本採用された社員のエピソードなどもあって、色々と客観的に読めたのも楽しかった。

興味が湧いた方はこちらをどうぞ。(※アフィリエイトリンクになっています)

「一兆ドルコーチ」を読んだ

f:id:shoheikawano:20210106083942p:plain

本は、途中まで読んでそのまま内容を忘却することが多いので、積まれているものをまずは消化して、今年はたくさん本を読む。

「一兆ドルコーチ」は、休み中にまず読んだ本。(去年買って積まれていた)

2016年に亡くなったBill Campbellの振る舞いや、そこからの学びについて書いてある。 Billに関わった方々に対してのインタビュー内容をもとにまとめてある。 マネジメントを業務の一つとして行っていることと、昨年SNSでこの本について紹介している投稿をよく見かけていたこともあり気になっていた本。

ハイライトをいくつか振り返って、最後に自分なりにふんわりまとめる。

共感、そうだよなぁ〜、と思ったハイライト

  • "人がすべて あらゆるマネジャーの最優先課題は、部下のしあわせと成功"
  • "誠意と献身を保つのは、勝っているときは簡単でも、負けているときはずっとむずかしい"
  • "リーダーが先陣に立たなくてどうする。迷っている暇はない、本気でやるんだ。失敗するのはいいが、中途半端はダメだ。君が本気で取り組まなかったら、誰が本気を出すというのか。"

(゚д゚)ハッとさせられたハイライト

  • "リーダーシップとは会社やチームという、自分より大きなものに献身すること"
  • "リーダーにふさわしいのは好奇心旺盛で、新しいことを学ぶ意欲にあふれた人物だ。利口ぶった傲慢な野郎は願い下げ"
  • "すぐれたコーチは言いにくいことを胸にしまいこんだりしない——むしろズバリと切り込む。痛いところを突いてくるのだ"
  • "「すべきこと」を指図するな 物語を語り、自力で最適解にたどりつけるように"
  • "自分のために働いてくれた人や、自分が何らかのかたちで助けた人のうち、すぐれたリーダーになった人は何人いるだろうと考える。それが自分の成功を測るものさし
  • 勝利をめざせ。 だが献身、チームワーク、 誠実さをもって、つねに正しく勝利"
  • "マネジャーの仕事は、すべての意見を吸い上げ、 すべての見解を検討するための意思決定プロセスを実行し、 必要な場合にはみずから議論に決着をつけ、決定を下すこと"

まとめ

寄り添う/奉仕する優しさと、相手を思った叱咤激励の優しさ深く行使していくことと、目を凝らして仲間がどちらかの優しさを必要としていないか?というのを気にかけてあげるということ。あとは決めるときにきちんと決めること。ビルのマネをせず、これらを自分なりに練習すること。

本が伝えたいこととは関係ないかもしれないですが、ハグだったりアメリカンなやりとりだったり、アメリカン文化や人柄の良さみたいなものも現れていて、個人的にはそこも好きだった。

興味の湧いた方はこちらをどうぞ。(※アフィリエイトリンクになっています)

2020年12月を振り返る

12/29に書いています。

🎧ヘッドフォンゲットした

クリスマスプレゼントに妻からいただきました、感謝🙏

f:id:shoheikawano:20201229093803p:plain

去年はAirPodsをいただいたんですが、自分の耳との相性が良くないのか、耳の中の調子が悪くなってしまったので、 耳の中に入れるのではなく覆い被せる形式のものを。

カップ部分をタップして再生・停止とかするんだけどまだ慣れない。ノイズキャンセリングは良い! Alexaはぜんぜん使っていない。

個人アプリリリースした

前に作ったことあるFeedlyのクライアントアプリの機能は全く同じ。 新しい技術周り触らないとと思ったのが作り直そうと思ったきっかけです。 ダークモード・Paging 3・hiltまわりは触れたけど、まだCompose入れたり、KMM化をこれからやっていくので、たぶん実質また作り直す感じになる気がする。

ハウステンボス行った

小さいときに一度行ったきりぶりで、アトラクションとかあったっけ!?となった。 シューティングゲームとか佐世保バーガーとかを楽しみました。

佐世保バーガーおいしかった🍔 f:id:shoheikawano:20201229095303p:plain

その他

寒くなってきたので備え付けのエアコンをつけてみるも、冷房のような冷たい風しか来ず。。 夏は普通に動くエアコンだと思っていたが、、

すぐみてもらったところ、「暖かくする装置が壊れていて、いまは外気を家に取り込んでいるだけになっちゃっていますね、、」と、、 取り替えしてくださるとのことで、この記事を書いているいま、まさに取替工事が行われている。

ウルトラライトダウンジャケットを纏っています。はやく暖かくなりますように。

それでは、12月の振り返りは以上です。

12月も、お疲れさまでした!

2020年を振り返る

2020年をブログ記事で振り返ります。

(過去記事: 2018, 2019)

1月

blog.shoheikawano.com

帰省してあとは映画をたくさんみていたっぽい。 The Frozen 2面白かったな〜

2月

blog.shoheikawano.com

ぷーちゃんと旅行いったり、妻と山梨いったり、しほしゃんカフェラテをいただいたりしていた。 結構、いろんなとこ行ったりしたなあ。

3月

blog.shoheikawano.com

劇場版SHIROBAKO、戸越銀座の焼き小龍包!!

ここらへんから自粛などで家にいる時間が長くなってきた。

焼き小龍包がほんと美味しかった。昼から天気の良い外で飲みてぇ。

4月

blog.shoheikawano.com

自粛。ここらへんからほぼずっと家。 UofPeopleトライしたり(1 termやって続かなかった)、ネギ育てたりしはじめた。 ネギは可愛い。

5月

blog.shoheikawano.com

バジルとかルッコラとか育ててみたり、NINTENDO SWITCHがきて、テトリスやりはじめたり。最近またテトリス熱がきてます。

DFM対応とかやっていて、機能開発が特に忙しかった月。

6月

blog.shoheikawano.com

競馬やったり、映画みたり、登壇資料作ったりしていたっぽい。 ここらへんから気がつく。6月の(家にいることが多かった)記憶より、1、2月の(自粛等前の)記憶のほうが鮮明に残っている、と。。

7月

blog.shoheikawano.com

もののけ姫を見に行ったり、DFMの発表したりしていた。

8月

blog.shoheikawano.com

DTM、ソフトウェアのトライアルの終了とともに終了してしまった。 宮崎駿のアトリエはオーラが違った。外から眺めただけだけど、行けてよかった。

9月

blog.shoheikawano.com

引っ越しをした月。引っ越しはバタバタだったけど、無事にできてよかった。 福岡生活は少しずつ慣れてきた。自炊がかなり増えて、お店開拓はまだあんまりできていないけど。

10月

blog.shoheikawano.com

洗濯機とかインターネットとかが来て自宅でのリモートワークがようやく整った月。(それまではコワーキングスペースとかいろんなところを転々としていた。)

鬼滅見に行ったり、車久しぶりに乗ったり。

11月

blog.shoheikawano.com

GoToで沖縄行ったり、会社の先輩方が福岡遊びに来てくれたりした。 沖縄はホテルの近くの居酒屋で店長さんと仲良くなって飲み食いしてた。

あとは雲丹がうますぎた。

12月

blog.shoheikawano.com

ハウステンボス行って花火見たり、個人アプリ出したりとかをした月。 あと書いてなかったけどリングフィットアドベンチャーのミニゲーム・リズムゲームを最近やりはじめた。 面白いしよい感じに汗かくのでおすすめです。健康第一。

来年はもっと在宅での習慣づけをもっと行って効率を上げたりしたいというのと、 海外とかも行きたいけど、どうなることやらーと思っています。

あとなんだかんだ結婚式関係のことは延期したままなので、まだどうなるかはわかりませんが、来年こそは、と思ったりもしています。

以上です。2020年もおつかれさまでした!2021年もどうぞよろしくおねがいします!

AutoCompleteTextViewの要素選択時の処理

Exposed dropdown menus UIを個人アプリで取り入れる際、AutoCompleteTextViewを使った要素選択時の処理実装で少しだけ迷ったのでメモ程度に調べたことを記述します。

TL;DR

クリックによる要素選択時の処理にはonItemSelectedListenerではなくonItemClickListenerを使う

AutoCompleteTextView

AutoCompleteTextViewというViewがあります。 これは、複数の選択肢を表示するようなメニュー要素のUIを作りたい場合に活用できます。

Menus

Material Design Componentsの「Menus」の項目に詳細があります。

上記material.ioのサイトによると、メニューには二種類のタイプがあります。

  1. Dropdown menus
  2. Exposed dropdown menus

Dropdown menusはいろいろな形があるようですが、「選択肢のみを一覧で表示するような形のメニュー」という理解をしています。

一方、Exposed dropdown menusとは、「現在選択中の選択肢が一番上に表示され、その下に選択肢の一覧が表示される形のメニュー」という理解をしています。

個人アプリでは現在選択中の要素も表示したかったので、Exposed dropdown menusを作りたいと思い、AutoCompleteTextViewを使うことにしました。

詳細や適切な説明については上記公式サイトをご確認ください。

実装例

material.ioにも実装例のコードが載っているのでそちらもご覧ください。 公式サイトを参考に、個人アプリではこのようなXMLを記述しました。 AutoCompleteTextViewは、styleを適用したTextInputLayoutで囲うことでExposedDropdownMenuの見た目にすることができます。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/dropDownRoot"
        style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <AutoCompleteTextView
            android:id="@+id/dropDown"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="none"
            tools:ignore="LabelFor" />
    </com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

このような見た目になっています。

f:id:shoheikawano:20201231181627p:plain

AutoCompleteTextViewの要素選択時の処理

個人アプリでは、要素を選択するたびにDBに選択肢を保存するような処理を行うよくあるような実装をするために、listenerをセットしました。

もともと、setOnItemSelectedListenerを呼び出してlistenerをセットしていましたが、なぜか要素を選択しても、リスナーが発火されませんでした。

原因を探すとそれっぽいものが

stackoverflow.com

setOnItemSelectedListenerではなくsetOnItemClickListenerを利用するべきだというようなものでした。 実際にsetOnItemClickListenerを利用することで問題は解決しました。

AutoCompleteTextViewのjavadocを見てもどちらを使うべきかぱっと見ではわからないので、気をつけてください、という話でした。

    /**
     * <p>Sets the listener that will be notified when the user clicks an item
     * in the drop down list.</p>
     *
     * @param l the item click listener
     */
    public void setOnItemClickListener(AdapterView.OnItemClickListener l) {
        mItemClickListener = l;
    }
    /**
     * <p>Sets the listener that will be notified when the user selects an item
     * in the drop down list.</p>
     *
     * @param l the item selected listener
     */
    public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener l) {
        mItemSelectedListener = l;
    }

以上となります。 誤った情報などもしありましたらコメントやツイッターにてご連絡いただけますと幸いです🙏

Reference

2020年11月を振り返る

もう師走ですね。あっという間だ〜〜。 では2020年11月を振り返ります。

沖縄行った

11月半ばの土日に行ってきました。

第一牧志公設市場で飲んだ🍻と雲丹 f:id:shoheikawano:20201206122351p:plain

f:id:shoheikawano:20201206122357p:plain

地元の人達みなさん優しくて、控えめに言って最高だった。

福岡に来てくれた人たちと遊んだ

沢山の人が来てくれた!現同僚、元同僚! ご飯食べに行ったりとか家でわいわいしたりとか。 控えめに言って最高だった。

その他

  • 休みでちょっとずつ作っている個人アプリは進捗よろしくない。悲しい。今年中には出したい。
  • 梨泰院クラス見終わった。(ちょっと遅れてる?w)面白かった。今度はスタートアップを見る。
  • あとはブリ🐟を食べた。

仕事では、小さいところだとあんまり触ったことなかったGitHub Actions使ってごにょごにょGitHub Packages作って配布するとかの設定したりとか、 企画進める動きやってみたりとか、少しずつチャレンジしたりした月でした。 まだ途中のものが多いので、今年でガッヽ(# ゚Д゚)ノ┌┛∑(ノ´д`)ノと終わらせたい。

以上です。 11月もお疲れさまでした!

maven-publish plugin + GitHub Actions + GitHub Packagesでライブラリモジュールを公開する

最近タイトルのようなことを行ったので、備忘録としてメモ程度にまとめます。自分は今回このように設定してみたよーという紹介になりますので、他にも方法は色々あるかと思います。 あくまで一例として参考程度に見ていただければと思います。

今回行いたかったことは以下です:

  • いくつかの.ktファイルを含んだlibraryモジュール(Androidモジュールではない)をpublishする
  • GitHub Packagesを利用するためのgithub username, tokenはGitHub Actions経由で渡す
  • ライブラリのバージョンはtagの名前に合わせる

maven-publishのセットアップ

まずはpublishするための設定を行います。 今回はmaven-publish pluginを利用しました。このプラグイン以外にも、サードパーティ製のプラグインがあるようです。

Maven Publish Plugin

publishしたいlibraryモジュールのbuild.gradleに以下を記述します(今回はGroovyで記述しましたが、きっと.ktsでも似たような記述になると思います)

// library/build.gradle

plugins {
    id 'kotlin'
    id 'maven-publish'
}

また、maven-publishのセットアップも同様のbuild.gradle内に記述します。

// library/build.gradle

// GitHub Actions経由で動的に値をセットします(動的に値をセットする必要がない場合には直接gradle内に記述します)
def releaseVersion = System.getenv("RELEASE_VERSION")
def credentialUserName = System.getenv("GITHUB_PACKAGE_USER_NAME")
def credentialPassword = System.getenv("GITHUB_PACKAGE_TOKEN")

publishing {
    publications {
        maven(MavenPublication) {
            groupId "YOUR_GROUP_ID"
            artifactId "YOUR_ARTIFACT_ID"
            version releaseVersion
            from components.java
        }
    }
    repositories {
        maven {
            name = "GitHubPackages"
            url = uri("https://maven.pkg.github.com/YOUR_ORG_NAME/YOUR_REPOSITORY_NAME")
            credentials {
                username = credentialUserName
                password = credentialPassword
            }
        }
    }
}

余談ですが、これらの設定は、別ファイルに切り出しておくことも可能です。 たとえば、publish.gradleという名前の別のgradleファイルに設定を記述し、apply を用いてbuild.gradleに適用することができます。

// library/build.gradle

plugins {
    id 'kotlin'
    id 'maven-publish'
}

apply from: "./publish.gradle" // build.gradleと同階層のpublish.gradleを読み込みたい場合

maven-publishプラグインのセットアップを行いGradle Syncが正しく完了すると、publish というGradleコマンドが利用できるようになります。 最終的には、このコマンドを使ってmavenにライブラリを公開します。

maven-publishのセットアップTips or 注意点

Androidモジュールをpublishする

自分は試せていませんが、aarをpublishする場合にはいくつか追加でセットアップが必要かもしれません。

Android LibraryをGitHub ActionsでビルドしGitHub Packagesで公開する - Qiita

GitHubユーザーの権限

GitHub Packagesに公開するための設定で、usernameを指定する箇所がありますが、指定したユーザーがRepositoryへのアクセス権限(もしかしたら不要かも?)と、GitHub PackagesへのWrite権限を持っていることを確認してください。(権限が付与されていない場合にどのようなエラーになるかは失念してしまいました、すみません、、)

// library/build.gradle
    repositories {
        maven {
            name = "GitHubPackages"
            url = uri("https://maven.pkg.github.com/YOUR_ORG_NAME/YOUR_REPOSITORY_NAME")
            credentials {
                username = YOUR_USER_NAME // 指定したユーザーがリポジトリへのアクセス権限があることを確認してください
                password = YOUR_PASSWORD
            }
        }
    }

GitHub Actionsのセットアップ

次にGitHub Actionsの設定です。 以下のYAMLでは、ざっくりこのような処理を順番に行っています

  1. mainブランチにpush
  2. tagのバージョンアップ
  3. バージョンアップされたtagの値をreleaseバージョンとして、publish

それぞれのstepの中で利用しているActionの詳細について気になる方は、Action名で検索するとドキュメントが出てくると思いますので調べてみてください。

name: Publish library module
on:
  push:
    branches:
      - main
jobs:
  publish-library:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout library repository
        uses: actions/checkout@v2
      - name: Bump up tag version # tagのバージョンアップ
        id: bump_tag_version
        uses: anothrNick/github-tag-action@1.26.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          RELEASE_BRANCHES: main
      - name: Prepare for gradle command execution
        uses: actions/setup-java@v1
        with:
          java-version: 11
      - name: Execute gradle command to publish
        env: # libraryモジュールのgradleファイル内で利用する環境変数の値を設定
          RELEASE_VERSION: ${{ steps.bump_tag_version.outputs.new_tag }}
          GITHUB_PACKAGE_USER_NAME: YOUR_USER_NAME
          GITHUB_PACKAGE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        uses: eskatos/gradle-command-action@v1
        with:
          arguments: library:assemble library:publish # maven-publishのコマンドを実行

(もしかしたら最後の assemble のコマンドは不要かもしれません)

GitHub Actions全般については、公式ドキュメントやチュートリアルが充実していますのでこちらを参照するのが良いと思います: GitHub Actions Documentation - GitHub Docs

正しくGitHub PackagesにPublishされると、リポジトリの画面で公開されたPackageを確認できます。

f:id:shoheikawano:20201206203017p:plain

f:id:shoheikawano:20201206203032p:plain

GitHub ActionsのセットアップTips

workflow_dispatch

GitHub Actionsでは、基本的にpushなどのgitのイベントに応じて処理が実行されます。ただ、workflow_dipsatch というイベントをworkflow YAMLに定義しておくことで、手動で特定のworkflowを実行することができるようになります。デバッグなどで処理を実行したい場合には便利です。

リポジトリ>Actionsタブ>All Workflowsの下の個別のWorkflow詳細ページから実行できます。わかりにくい場合はスクリーンショットを参考にしてみてください。

f:id:shoheikawano:20201206203045p:plain

Events that trigger workflows - GitHub Docs

Library Module読み込みのセットアップ

次に、公開されたPackageを利用するための設定です。この記事ではAndroidアプリで利用する前提で説明をします。

プロジェクトルートのbuild.gradleに以下を追加します:

allprojects {
  repositories {
    ...
    maven {
        name = "GitHubPackages"
        url = uri("https://maven.pkg.github.com/YOUR_ORG_NAME/YOUR_REPOSITORY_NAME")
        credentials {
          username = YOUR_USER_NAME
          password = YOUR_PASSWORD
        }
    }
...

以上までの設定が正しく完了すると、ライブラリを利用する準備が整ったことになります。

例えばライブラリが以下の情報で公開されている場合は、

<groupId>jp.co.hogehoge.fugafuga</groupId>
<artifactId>library</artifactId>
<version>0.1.0</version>

以下のように指定することで利用することが可能になるはず:

implementation "jp.co.hogehoge.fugafuga:library:0.1.0"

Library Module読み込みのセットアップ注意点

GitHubユーザーの権限

上でも記述しましたが、ここで username に指定したユーザーがRepositoryへのアクセス権限(もしかしたら不要かも?)と、GitHub PackagesへのWrite権限を持っていることを確認してください。自分はこれにハマりました。

ライブラリ利用の際のユーザー名とトークンのセットアップについて(追記)

GitHub Packagesで公開されているライブラリを利用する際、GitHubのトークンが必要となりますが、念の為バージョン管理せずに動的に値を設定する方針をとりました。

NAME=xxx
TOKEN=xxx

という文字列だけ保持するgithub-packages.propertiesというようなファイルを作成し、ローカルではgitignoreした状態でこちらを利用するようにしています。

CIの場合は、現状GitHub ActionsとBitrise両方を利用していますので、

  • GitHub Actions: Secretsにユーザー名とトークンの値をそれぞれ保存し、propertiesファイルに記述
  • Bitrise: 事前にこのpropertiesファイルをアップロードしておき、Bitriseのworkflow内でDLして利用

という形を現状はとっています。

まとめ

  • maven-publish plugin
  • GitHub Actions
  • GitHub Packages

でどのように自分がライブラリ公開を行ったかをざっと書きました。

GitHub Actionsを利用することで、たとえば

  1. ライブラリモジュールで依存しているライブラリのバージョンの自動更新をdependabotで行う
  2. tagを切ってGitHub Packages公開モジュールのバージョンを上げる
  3. ライブラリモジュールを利用しているリポジトリにバージョン更新PRを投げる

ということも自動で行えるように設定できると思います。(まだできていない)便利ですね。

以上です。間違っている点、不要な記述などあれば教えていただけたら嬉しいです🙏

参考にした記事やドキュメントなど