おそらくはそれさえも平凡な日々

tagpr を機能強化してv1.0.0をリリースしました

前回のtagprの紹介エントリの反響が思ったより大きくて喜んでいます。ということで、積み残し及び、要望やヒントから着想を得て幾つかの機能を追加実装しv1.0.0をリリースしました。

https://github.com/Songmu/tagpr/releases/tag/v1.0.0

ありがたいことに、public repoだけでも十数名の方に既にご利用いただいているようで、フィードバックから細かいエッジケースの修正も幾つかおこなって敲かれたため、だいぶ使い物になるソフトウェアになったと言って良いでしょう。

ということで、追加された機能等について解説していきます。

uses: Songmu/tagpr@v1

これまではワークフロー上で uses: Songmu/tagpr@main とブランチ直指定してもらっていましたが、uses: Songmu/tagpr@v1 と指定できるようになりました。こっちのほうが、tagpr自体のリリースタイミング的にも若干安全なので、既にお使いの方にはお手数ですが切り替えを推奨します。

併せてMarketplaceへの公開もしました。GitHub ActionsのカスタムワークフローのMarketplace公開は初めてなので嬉しいですね。

https://github.com/marketplace/actions/automate-pull-request-generation-and-tagging-for-releases-using-tagpr

CHANGELOG.md を自動変更しないオプション

CHANGELOG.mdを自動更新しない設定を .tagpr 設定ファイルに書けるようになりました。

[tagpr]
    changelog = false

前回の紹介エントリを書いたらすぐにsiketyanさんからpull requestいただきました。ありがとうございます!

https://github.com/Songmu/tagpr/pull/86

Conventional Labelsの強化

リリース対象のpull request一覧を拾い、それらのラベルに"major"か"minor"が含まれていた場合、それを考慮して次バージョン番号候補をtagprが生成するpull request上に出力するようにしました。

これは便利だと思います。

GitHub Releases作成挙動の変更オプション

tagprはデフォルトでtagを打つと同時に、GitHub Releasesも作成しますが、この挙動を設定可能にしました。tagpr.release設定キーに、true, false, draftの何れかを指定できます。

[tagpr]
    release = false # [true/false/draft]

GitHub Actions用出力により後続のタスクとの連携が容易に

tagprがtagを打った後、別途ジョブを動かしたいケースは多いでしょう。実行ファイルやコンテナをビルドしてパッケージングし、それらを何らかのリポジトリにアップロードしたり、deployフローを動かしたりなど。

これは、tagをトリガーにして別ワークフローを動かすのが良いと思いますが、前のエントリで説明したように、GitHub tokenの権限周りの仕様の関係でトークン発行処理を組む必要が出てくるなど少し複雑になります。

ですので、tagpr実行後に直接後続のタスクを動かせれば一つのワークフローの責務は多めになりますが、お手軽です。

それを実現しやすくするために、GitHub Actions用の出力を出すようにしました。具体的にはtagpull_requestというoutputsを出力します。このtagが空か否かを見ることで後続のフローを動かすかどうかの判定を簡単におこなえます。具体的には以下のような具合です。

- uses: actions/checkout@v3
- id: tagpr
  uses: Songmu/tagpr@v1
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: ./.github/actions/release
  with:
    tag: ${{ steps.tagpr.outputs.tag }}
  if: "steps.tagpr.outputs.tag != ''"

このサンプルでは、後続のリリースフローをリポジトリローカルのカスタムアクションにまとめています。.github/actions/release/action.yml に処理を記述することになるでしょう。

このようにしておくと便利な点としては、上記のtagprのワークフローが途中で意図せず失敗してしまった場合に、リリースフローをリカバリするために手動でタグを打つワークフローを別途用意しやすくなることです。

name: release
on:
  push:
    tags:
    - "v[0-9]+.[0-9]+.[0-9]+"
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: ./.github/actions/release
      with:
        tag: ${{ github.ref }} # Note that github.ref is formatted like refs/tag/v1.2.3

tagprがタグを打った時、secrets.GITHUB_TOKEN を使っている限りはこのワークフローがトリガーされることはありませんが、手動でタグを打った場合にはこのワークフローが動くという具合です。

FUNDING.yml

FUNDING.ymlを配置してGitHub Sponsorsへの導線をつけました。ワンショットスポンサーのメニューもあるので、是非スポンサーをご検討下さい。

https://github.com/sponsors/Songmu?frequency=one-time

スポンサーのみならず、引き続きpull requestや感想や要望等お待ちしております!

Shodo校正APIの結果をpull requestのレビューコメントに自動反映する

Shodo AI校正APIのベータ版に申し込み、利用させていただいています。Shodo、日本語校正のSaaSということで注目していて、今回のAPIベータ版の話がTLに流れてきたので申し込み、当選することができました。

日本語校正サービス・ソフトウェアは商用のものの質はやはり高く、例えば老舗ジャストシステムのJust Right!などは友人のライターが利用していて、評判の良さも聞いています。

ただ、それらはいかんせん良いお値段します。もちろん、良質なサービスに対価を払うことはやぶさかではありませんが、私のようなホビーライターからするとちょっと厳しいお値段です。

ただ、私もブログは細々と継続していて、不定期で有償の記事や執筆をお受けすることもあるため、何らかの校正サービスを使いたいと思っては常々思っていました。

その点、スポットで従量課金的に利用できるSaaSモデルであるShodoは魅力的です。また、APIがあればCI/CDに組み込むのも容易です。私はGitHubで文書を管理することが多いため、そこも嬉しいポイントです。インストールライセンス型のパッケージでは実現しづらい部分でしょう。

action-shodo-lint

ということで、ShodoのAPIを利用して、pull rquestにレビューコメント及び変更提案をしてくれるGitHub Acitonsのカスタムアクションを作りました。

https://github.com/Songmu/action-shodo-lint

ブランチを切ってpull requestを作ると、デフォルトブランチとの差分があるマークダウン(.md)ファイルを校正APIにかけ、以下のような変更提案をしてくれます。

ワークフローも以下のように簡単に書けます。

name: action-shodo-lint
on: [pull_request]
jobs:
  shodo:
    name: runner / shodo
    runs-on: ubuntu-latest
    steps:
    - uses: Songmu/action-shodo-lint@main
      with:
        github_token: ${{ secrets.github_token }}
        api_token: ${{ secrets.SHODO_API_TOKEN }}
        api_root: 'https://api.shodo.ink/@{your_organization}/{your_project}/'

Shodo 校正API自体がベータであるため、このアクションも割と実験的なものにはなりますが、現在のベータ利用者はすぐにご利用いただけます。

スクリーンショットからわかる通り、内部的にはreviewdogを使っています。また、今回別で作った、Go版のShodo API CLIツールであるgoshodoも活用しています。

goshodo

https://github.com/Songmu/goshodo

公式のPython CLIがありますが、個人的にはGoのほうが早く書けるのと、とりあえずやりたいことを実現するためにGoで別のCLIを作りました。

この goshodo は公式の shodo コマンドの lint サブコマンド相当の機能のみ備え、かつ、それを拡張しています。

具体的には、複数ファイルを引数に持てるようにしたことと、-f checkstyle オプションを指定することでCheckstyle形式のXMLを標準出力に出せるようにしたところが拡張点です。

なにがしかの規格に準拠したフォーマットで出力を出せれば、他のツールと連携しやすくなります。実際、reviewdogもcheckstyle入力フォーマットを受け付けているため、とりあえずそれで出せるようにしました。

action.shを見てもらうとわかりますが、やっていることは以下の一行がほぼ全てです。

echo "$files" | xargs goshodo lint -f checkstyle | \
  reviewdog -f="checkstyle" \
    -name="shodo" \
    -reporter=github-pr-review \
...

checkstyle を選んだのは action-textlinttextlintとreviewdogの連携で使われていたため、それに倣った形です。

ただ、checkstyleフォーマットにも不満があって、具体的には指摘の開始位置を指定できるのですが、仕様上終端を指定できない点が困ります。

なので、現状action-shodo-lintでは無理やりsuggestionsを出力しているのですが、それは校正範囲とその提案が一行に収まる場合のみに限っています。

このあたりの課題感については、reviewdog repository内の以下のドキュメントにまとまっており、読み応えがあるのでおすすめです。

Reviewdog Diagnostic Format (RDFormat)

これを読んだ結論として変更提案をより良く出したい場合には、以下のフォーマットへの対応を検討すると良さそうです。

Shodo APIやCLIへのフィードバック

ベータ版を使わせて頂いている身として、この場でフィードバックを何点か書いてこの記事を終了しようと思います。

校正結果APIのレスポンスの"after"

https://github.com/zenproducts/developers.shodo.ink/blob/master/docs/api.md

レスポンスには必要な情報が網羅されていて良かったです。

一点だけ対応してほしい点として、推奨される置き換えテキストが格納されているafterフィールドに「トル」という校正指示が入るケースがあるのが気になりました。校正後の置き換えテキストは空文字列にしつつ、校正指示文言は別のフィールドに格納されている方がプログラムから扱うには嬉しいです。

また、カラム位置やインデックス番号がすべてUTF-8文字数になっているのはプロダクトの思想の問題だと思うので構わないと思います。ただ、合字などの扱いがどのようになるのかは調べていませんが、気になりました。

校正ルールのAPI管理

校正ルールを設定ファイルやAPIで管理できると、GitHubを用いたような執筆フローにより組み込みやすいと思いました。

公式CLIのlint出力

公式のCLIの出力は、デフォルトでは人間が読みやすい出力になっていて、それは問題ないと思います。

それに加えて、私がgoshodoで拡張したように、複数ファイルを受け取れるようにして、-f オプションで各種出力フォーマットを選択できるようになると嬉しいと思いました。textlintが多くの出力フォーマットに対応していて参考になります。

公式CLIのXDG_CONFIG_HOME対応

これは本当に些細な指摘で好みの話ですが、公式CLIは現状 ~/.shodo/credentials に秘匿情報を書き込みますが、近年はホームディレクトリが汚れないように、 $XDG_CONFIG_HOME/shodo, ~/.config/shodoにこういった情報を書き込むのがセオリーになってきています。特にこだわりがなければそのように変更してみるのはいかがでしょうか。

ref. https://wiki.archlinux.jp/index.php/XDG_Base_Directory

何にせよShodoのことは応援しています!

GitHubのリリースノート自動生成機能からCHANGELOG.mdを生成する

tl;dr

本題

GitHubには、リリースノートを自動生成する機能がある。これは、リリース間でマージされたpull requestのタイトルを一覧し、リリース項目としてGitHub Releases上に出力してくれるものです。リポジトリ上に.github/release.yml設定ファイルを配置すれば、pull requestの作者やラベルを元にグルーピングしたり非表示にするといった出力内容のカスタマイズもできる。

このあたりの実際の運用方法については以下のBlog記事を参考にすると良いと思うし、僕も参考にさせてもらいました。

また、r7kamuraさんの記事にも書かれていますが、このリリースノートはAPIからMarkdownを得ることもできます。そして、このAPI出力を、keep a changelog形式に近いMarkdownに変換し、CHANGELOG.mdを出力するgh2changelogというツールを作った。これはtagpr を作る中の副産物で、別ツールとして切り出したものでもあります。

https://github.com/Songmu/gh2changelog

ちなみに、keep a changelog形式は、これもまたr7kamuraさんの記事に書かれていますが、Changelogのガイドラインとして2015年頃に提案され、受け入れられてポピュラーなフォーマットになったものです。参考リンクを載せておきます。

pull requestのタイトルをChangelogに転記するコンセプト

個人的にもともと、Changelogは作りたいが、書く手間をあまり取られたくない、しかしcommit messageを一覧してChangelogするのは粒度がマチマチで見づらくなるし、後から書き換えるのも煩雑になるで避けたい。なのでpull requestのタイトルを一覧してChangelogとするのは良い落とし所だと考えていました。

実際、そのコンセプトを実現するためにghch というツールを以前作り、今でも活用しています。ありがたいことに200 starsを超え、僕のOSSの中では代表的なものになっています。

そして、冒頭に書いたGitHub公式のリリースノート生成機能は去年追加されたのですが、これも既に書いたとおり、まさにpull requestのタイトルベースでChangelogを生成するものでした。

公式がそういう機能を出してきたのであれば乗るのが正道であり、そこで作ったのがgh2changelogです。なのでghchの一部機能の後継ツールでもあります。

.github/release.ymlでのカスタマイズも嬉しい点で、keep a changelog形式で提案されているAdd, Changed, Deprecatedといったタイプ別に、ラベルを用いたカテゴリ設定を記述すれば、理想的なCHANGELOG.mdを出力できます。

ちなみに、gh2changelogは敢えてのkeep a changelog形式決め打ちの出力であり、ghchはJSON出力もできて自由度が高いツールです。コンセプトが異なるため、完全にgh2changelogghchを置き換える訳ではありません。

CHANGELOG.md欲しい?

GitHub Releasesが熟れてきたし、そっちのリリースノートに更新内容が書いてあれば、もはやCHANGELOG.mdを配置する必要は無いし、むしろ二重管理になるのも困るという意見は正しいと思います。

なので、CHANGELOG.mdを配置するというのは僕個人のちょっとしたこだわりでしかないとも思います。ただ、以下のような利点から配置するようにしています。自動生成する分には二重管理の問題も解消されているので。

ということで、私同様にChangelogが好きな方は、一度gh2changelogをご利用いただけると嬉しいです。

リリース用のpull requestを自動作成し、マージされたら自動でタグを打つtagpr

常々GitHubにtag requestが欲しいと言ってきましたが、それを実現するツールを作りました。OSSなど、バージョニングとリリースが伴うソフトウェア開発のリリースエンジニアリングをとにかく楽にしたいという動機です。既に自分が管理している幾つかのOSSでは導入して便利に利用しています。

https://github.com/Songmu/tagpr

アイデア

基本の発想は以下のようにシンプルです。

リリース用のpull requestを自動で作りマージボタンを以てリリースと為す、というのは、みんな(僕が)大好き git-pr-release と同じ発想です。git-pr-releaseではブランチをdevelopとmainに分けることでマージをリリースとしていましたが、tagpr ではmainブランチ一本で、マージコミットにタグを打つ点が異なります。

タグが打たれるので、それをトリガーにして成果物の生成などを別途行うと良いでしょう。

CHANGELOG.mdについては、GitHubのリリースノート生成機能を利用しているため、.github/release.ymlで表示が調整できます。

ref. https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes

導入

リリース時にsemver形式のtagを打つフローのリポジトリであれば、今すぐ導入できます。GitHub Actionsでの実行を前提としており、以下のワークフローを配置するだけで導入完了です。

# .github/workflows/tagpr.yml
name: tagpr
on:
  push:
    branches: ["main"]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: Songmu/tagpr@main
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

tagが打たれた後に、更に別のAcitonを動かしたいときには GITHUB_TOKEN の扱いについて気をつけるべき点があり、それは後で説明します。

実際のフロー

tagpr の実際のフローをもう少し詳細に説明すると以下のようになります。

  1. (自動) mainブランチが進むとリリース用のpull requestが作られる
    • mainブランチの先頭からブランチングされる
    • mainブランチが更に進むと自動で追随する
  2. 1で出来たブランチに必要なら更新を加える
  3. pull requestを好きなタイミングでマージする
  4. (自動) タグが打たれ、GitHub Releasesも作られる

作られるpull requestは以下のようなものです。

pull requestの内容 https://github.com/Songmu/tagpr/pull/69

作った動機

個人のOSS開発上の課題意識から。OSS開発のリリース作業は、定形作業ではあるのですが、細々した作業が発生し、案外漏れが出たり、属人的にもなりやすい。例えば以下のような作業です。

特に、リリースに必要なファイル変更は、機能開発とは関係ないちょっとした変更なのでリリース担当者がサッと済ませてしまうことも多く、案外暗黙知となります。それで、他の人が見様見真似でやると必要なファイル更新が漏れる事故などが起こりがち。

これは、ちゃんと引き継げばいいと言うよりかは、引き継がなくても恙無くリリースできる状況を作るのが理想です。

なので、これもpull requestにしてレビュー可能な状況を作るとともに、pull request及びその変更も可能な限り自動で作られ、それがマージされたらリリースされるようにしたい。それを実現したのがこのtagprというわけです。

リポジトリに訪れた人も、そのpull requestを見れば、未リリース項目が把握でき、マージすれば新バージョンがリリースされることがわかるという、見える化・透明性の向上効果もあります。

リリース作業時にリポジトリ上で追加で変更したいファイルがある点や、tagを以てリリース完了としたいという点で git-pr-release とユースケースが異なります。

pull requestのタイトルと本文

上記のスクショを見てもらうとわかるように、pull requestの本文に、"What's Changed"で始まるリリース項目が自動で一覧されるのがお役立ちです。これはGitHub標準のリリースノート生成機能を利用しています。

このタイトルと本文は、設定ファイル.tagprtagpr.template キーにGo形式のテンプレートを指定することでカスタマイズ可能です。

pull requestのcommit内容

tagprはpull request生成時に標準で以下のファイル更新を行います。

また、初回実行時に以下のファイルが存在しない場合、最小限設定済の雛形を生成します。

リリース作業時に他にも自動更新させたいプロジェクト固有の項目がある場合、tagpr.command 設定にコマンドを指定し、commit前に任意のコマンド実行ができます。

また、リリース前の変更作業を手動でおこないたい場合、pull requestのブランチを直接編集し、commitを重ねてしまって構いません。

後はこのpull requestをマージすれば、マージコミットに自動でtagが打たれます。merge commitを作る形式でもsquash mergeでも構いません。

tagと同時にGitHub Releaseも作るのですが、これをオフにするオプションも設けるかもしれません。

次バージョン指定方法

tagprのバージョンインクリメント挙動はデフォルトではpull request上で単にpatchバージョンをインクリメントするだけです。しかし、major, minorバージョンを上げたいことも当然あるでしょう。これには二つの対応方法があります。

後者は、versionfileを利用しない運用の際に採用すると良いでしょう。また、リリース対象項目のpull requestに付与されたラベル等を見て、major,minor,patchのどれをインクリメントするかを推測する機能を将来的に追加したい。

secrets.GITHUB_TOKEN が次のActionsをキックしない問題

tagprは自動でgit tagを打つところまでやってくれるため、そこから別のGitHub Actionsのワークフローをトリガーしたいこともあるでしょう。成果物の生成やアップロード等。

しかし、tagprの動作にGitHub Actionsが自動で提供してくれる secrets.GITHUB_TOKEN を利用すると、後続のワークフローは動きません。これは、ワークフローの意図しない再帰的な連続実行を防ぐための仕様です。

ref. https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow

このため、後続のワークフローをトリガーしたい場合、tagprを別の権限で実行する必要があります。以下は、secrets.GH_PAT にpersonal access tokenを指定した例です。git push --tags も別権限で行いたいので、actions/checkoutにもこのtokenを指定しています。secretsはリポジトリ設定から別途指定してください。

name: tagpr
on:
  push:
    branches:
    - main
jobs:
  tagpr:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
      with:
        token: ${{ secrets.GH_PAT }}
    - uses: Songmu/tagpr@main
      env:
        GITHUB_TOKEN: ${{ secrets.GH_PAT }}

簡単のためにpersonal access tokenの例を書きましたが、GitHub Apps等を用いてtokenを都度生成するような手法を使ったほうが安全でしょう。

まとめ

他の細かい設定等についてはドキュメントをご確認ください。長々と書きましたが導入は簡単で便利です。実際個人的に便利に使っていますし、結構頑張って作ったので使ってもらえると大変喜びます。

とはいえ主張が強いツールなので、色々適用しづらい場合もあるかとは思います。そのあたりはフィードバックがあると大変嬉しいです。

ちなみに、今回のtagprを含め、これまでOSSのリリースエンジニアリングに関わるOSSを幾つか自作したり開発に携わったりしてきたので、どうやら私はこの分野が好きなようです。

そのあたりの話を来月のGo Conference mini 2022 Autumn IN SENDAIでお話する予定です。「OSSの最適なリリースエンジニアリングを求める旅路」というタイトルです。

私は仙台に行く予定ですが、現地枠もオンライン参加枠もまだあるようなので是非お申し込みください。仙台で交流できることも楽しみにしています。

https://sendaigo.connpass.com/event/256463/

git-pr-releaseとGitHub Actionsでワンクリックデプロイを実現する

突然ですが、git-pr-releaseのなんちゃってコラボレーターである私が僭越ながら、その王道の使い方を皆様に伝授していきます。何番煎じかの記事ではありますが、現代の、特にGitHub Actions出現以降の使い方をまとめたいというのが動機です。

git-pr-releaseはGitHubを業務開発で利用している場合に便利なツールで、デフォルトブランチにマージされたpull requestをリリース項目として一覧し、それをpull request化してくれるものです。これにより以下のことが実現できます。

導入

git-pr-releaseはCIで自動実行するのが基本です。今はGitHub Actionsがあるので、なんと、以下の1枚のYAMLをGitHub上のリポジトリに配置するだけです。

# .github/workflows/git-pr-release.yaml
name: git-pr-release
on:
  push:
    branches:
    - develop
jobs:
  git-pr-release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # git-pr-release needs the git histories
      - uses: actions/setup-ruby@v1
        with:
          ruby-version: 3.1
      - run: gem install --no-document git-pr-release
      - run: git-pr-release --squashed
        env:
          GIT_PR_RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GIT_PR_RELEASE_BRANCH_PRODUCTION: main
          GIT_PR_RELEASE_BRANCH_STAGING: develop
          GIT_PR_RELEASE_LABELS: pr-release
          # GIT_PR_RELEASE_TEMPLATE: .github/git-pr-release.erb
          # TZ: Asia/Tokyo

もちろん環境によって多少は調整が必要です。GIT_PR_RELEASE_BRANCH_STAGING にデフォルト開発ブランチを、GIT_PR_RELEASE_BRANCH_PRODUCTION に本番ブランチ名を指定してください。このブランチについては少し後に説明します。

成功イメージ

トピックブランチがマージされるなどしてデフォルト開発ブランチのコミットが進むと、GitHub Actionsにより以下のようにデフォルトブランチから本番ブランチへのpull requestが自動で作られます。マージされたpull reqeustの一覧がリリース項目として表示されており、開発ブランチのコミットが進む度にリストは自動で更新されます。

折を見てこのpull requestをマージすれば、mainブランチのコミットが進み、それによりdeployされるという寸法です。deployフローは各自のものをお使いください。

前提とするブランチングモデル

git-pr-releaseは以下のようなブランチングモデルを前提としています。ここではmainとdevelopという名前にしていますが、名前は先に述べたように設定可能です。

メインで開発を進めるdevelopブランチと並走するmainブランチがあります。developからmainへのマージによりmainブランチのコミットが進むことがdeploymentのトリガーとなり、deployフローが走り始めることを想定しています。

mainは基本的にはdevelopからのマージでしかコミットは進みませんし、マージされた時点ではdevelopとmainの内容は等しくなります。

このブランチングモデルは、物議を醸しがちなgit flowの簡易版とも言えるもので、割とポピュラーなのではないでしょうか。developが進んだ時点でステージングやQA環境を自動デプロイしている組織も多いでしょう。

他のブランチングモデルとしては、本番ブランチ(ここではmain)を分けて作らずに、デフォルトブランチにマージされた時点で本番deployを走らせるようなフローや、トピックブランチのレビューが通った時点でそのトピックブランチを本番deployし、それが成功したらデフォルトブランチにマージするようなフローもあるでしょう。

そういったスタイルに比べて、このモデルのデリバリー速度は少し落ちるかもしれませんが、ステージング環境が用意できること、リリースのタイミングを制御できること、複数のフィーチャーブランチが近いタイミングでマージされた時にdeployが混雑せずリリースフローを直列化できるところなどにメリットがあるでしょう。

GitHub Actions用のYAMLの解説

冒頭のYAML上のいくつかのポイントについて解説していきます。

shallow cloneとgitの履歴

git-pr-releaseはリリース項目の抽出のためにgit logを使います。なのでshallow cloneで履歴が少ないケースでは上手く動きません。ですので、clone時にshallow cloneを防ぐ設定が必要です。

- uses: actions/checkout@v3
  with:
    fetch-depth: 0 # git-pr-release needs the git histories

実は、shallow clone時に自動でunshallowする挙動 が近々リリースされるので、この設定せずとも動くようになりますが、余計なfetchが減らせるので、この設定を入れるメリットはまだほんの少しだけあります。

squash mergeのための--squashed オプション指定

pull requestのmergeにsquash mergeを使っている場合、--squashed オプションを指定してください。

squashしないプロジェクトではこのオプションを付ける必要はありませんが、付けても多少APIリクエストが増える可能性があるだけなので、常につけて大きな損はないでしょう。

ちなみに、開発ブランチへのコミットがすべてマージコミットである場合には--squashed オプションによる追加のAPIリクエストは一切発生しません。なので、このオプションを標準挙動にしてしまっても良いのではないかとも思っていますが、そのあたりはメンテナ陣と議論が必要ですね。

pull requestへのラベル自動付与

GIT_PR_RELEASE_LABALS 環境変数にpull requestに自動付与するラベルを設定できます。カンマ区切りで複数指定も可能です。これは後でリリースを抽出して振り返りたい場合等に便利です。あまり言及されていることは少ないのですが、設定することをおすすめします。

TZ環境変数によるタイムゾーン設定

標準ではpull requestのタイトルに時刻が表示されますが、GitHub Actions上で実行する場合UTC表示になります。開発チームにわかりやすいタイムゾーンで時刻表示したい場合、TZ環境変数を設定すればお手軽に表示を変更できます。

JSTで表示したい場合GitHub ActionsのYAMLの適切な箇所に以下のようなenv設定書くことになるでしょう。

TZ: Asia/Tokyo

独自テンプレートの活用

pull requestのタイトル及び本文はテンプレートでカスタマイズできます。GIT_PR_RELEASE_TEMPLATE 環境変数でファイルパスを指定します。erb形式のテンプレートで、デフォルトの内容は以下です。一行目がpull requestのタイトルになり二行目以降が本文になります。

Release <%= Time.now %>
<% pull_requests.each do |pr| -%>
<%=  pr.to_checklist_item %>
<% end -%>

最近の自分のユースケースだと、リリース方法、手順、ロールバック方法等を冒頭に載せているのと、mergeされたpull requestをそれぞれチェックリストとして表示する必要性は感じなくなったので、以下のようにしています。

## How to deploy
...

## Items to be Released
<% pull_requests.each do |pr| -%>
- #<%=  pr.number %> <%= pr.mention %>
<% end -%>

テンプレートが意図通り出力されるかどうかの確認には、手元で git-pr-release --dry-run を実行すると良いでしょう。

落ち穂拾い

マージボタンに対するワークフロー

個人的にはあまり厳密にやらないのですが、git-pr-releaseが作成したpull requestのマージを、特定メンバーのレビューや何らかのチェックが通るまではブロックしたいこともあるでしょう。そういった場合はBranch ProtectionやCODEOWNERS機能を活用すると良いです。

リリース障害時の切り戻しはどうするの?

リリースしたコードに不具合があり、手動で切り戻しが必要になった時にどうするか。

ロールバックが作り込まれていればそれを使えばよいですが、個人的には本番ブランチを変更してcommitを進めてリリースしてしまうのがお手軽だと思っています。具体的にはgit-pr-releaseのpull requestをrevertしたりhotfixを入れるなどする。

「本番ブランチのcommitが進めば新しいリリースが作られてdeployが始まる」というメンタルモデルに寄せてしまったほうが覚えることや混乱が少ないというのが理由。障害時に普段使わない不慣れなロールバック作業をすると余計なミスが生まれるリスクも高まります。

もちろん、直前に稼働していたコンテナイメージなどの成果物を再利用できたほうが切り戻しが早いというのはあります。そのためにロールバックを整えるのも手ですが、例えば、成果物を特定するためのidentityにコミットハッシュを使うのではなく、git rev-parse HEAD^{tree} でツリーオブジェクトのハッシュ値を使えば、revert commitでも直前の成果物をつかってくれる仕組みを組むことが可能でしょう。

参考: 同じソースツリーでテストが通っていたらテストをスキップする

さて、本番ブランチにrevertやhotfixを入れると、開発ブランチと本番ブランチの内容に食い違いが出てしまいます。そういった時にどうするか。

本番ブランチと開発ブランチの食い違い問題

結論を書くと、普段とは逆向きに、本番ブランチから開発ブランチに向けてmergeしてしまえば良いです。

git-pr-releaseは前述の通り、本番ブランチと開発ブランチの内容はマージ時点で同一になることを想定しています。そして、通常時は開発ブランチから本番ブランチへのマージでしか本番ブランチのコミットは進まないため、それがほぼ担保されます。

しかし、前項のような緊急オペレーションを行なったなどの理由で乖離が発生する可能性があります。こういったときは、気持ち悪く感じるかもしれませんが、本番ブランチから開発ブランチに、通常とは逆向きのマージをしてしまえば大体問題ないです。ここはちょっと手作業が必要になってしまいますが。

それで問題が起きたことは、これまで10年近く複数プロジェクトに渡って長らく使ってきましたが、特にありません。いざとなったら本番ブランチを消すなりリネームして新たに開発ブランチから作り直しても良いと思います。また、厳密には本番ブランチと開発ブランチに乖離が無いかのチェックを簡単なスクリプトでCIしても良いのかもしれませんが、やったことはなく、困ったこともありません。

設定ファイル .git-pr-release

git-pr-releaseには設定ファイルがあります。リポジトリルートに .git-pr-release というファイル名で配置して、git-config形式で設定を記述します。

ここに書ける設定はすべてここまでで解説した GIT_PR_RELEASE_* 環境変数で代用することができます。特にこの記事ではGitHub ActionsのYAML一枚でわかりやすく完結させるために、このファイルは使っていません。

ただ、手元で git-pr-release を動かす場合、具体的にはテンプレートの動作確認のために --dry-run をつけて動かしたいなどの場合、設定ファイルがあったほうが都合が良いこともあります。

また、リポジトリルートにこのファイルがあることで、git-pr-release を利用していることがわかりやすいという話もあります。ただ、近年はリポジトリルートにファイルが散乱しがちなので、逆に置きたくないという向きもあるでしょう。

カスタムアクション化しないの?

メンテナンス体制との兼ね合いで、メインメンテナ(@onk)的に提供する気は無いようです。

実際、冒頭のYAMLを見てもらえれば分かりますが、やってることは gem install git-pr-release && git-pr-release だけなので、いちいちカスタムアクションをかぶせるのも大袈裟とも言えます。

有志の方でカスタムアクションを作られてる方もいて、僕もそれを利用していたこともありましたが、最新機能を使いたくなったこともあり、最近はそれらを使わない素朴な形になりました。

都度インストールすると、オーバーヘッドやRubyGemsのダウンリスクなどが気になるかもしれませんが、gem install git-pr-release の所要時間は2秒程度ですし、そういった些細な事象を気にして複雑度を上げる必要もないと考えます。

Go化などは考えないのか?

git-pr-release はRuby製のツールですが、オリジナル作者の @motemen や私は最近はGo Hackerでもあります。なので、私も個人的にGoで作り直すことを考えたこともありましたが、必要ないと思うようになりました。

Rubyによる実行オーバーヘッドは些細なものです。それに、言語自体のパフォーマンスよりもリモートリポジトリやAPIへのアクセスが実行時間に対して支配的です。それに、git-pr-release 自体の実行時間は差分の量にもよりますが精々10秒程度です。そこが開発スピードの全体ボトルネックになることは考えづらいでしょう。

erbでテンプレートが書ける点もRuby製ならではの嬉しさと言えます。

git-pr-release は長年使われており、メンテナンスもされ、より安定して使いやすくなっていっています。例えば、squash merge関連の機能が整備されたこと等が、ここ一年の地味に嬉しい機能拡張として挙げられます。そのあたりも後発ツールに比べた強みがあるので、是非ご利用ください。(ポジショントーク)

--no-fetch オプションは現状全く意味がない

余談ですが、 --no-fetch というオプションがあるのですが、これは現状全く動いていません。このオプションを指定してもなんと何も動作が変わらないのです。

これについては、以下のissueで過去の経緯や、今後どうするかを議論しているので興味がある方は御覧ください。

https://github.com/x-motemen/git-pr-release/pull/33

Shokzの骨伝導イヤホンは会議でも運動でも入浴でもマルチに使えて快適

Amazonプライムデー開催中ですし、Shokzの宣伝エントリでも書きます。Shokzの骨伝導イヤホンはこれまで4本自分で購入していましたが、4月にありがたいことにShokz様からOpenRun Proを頂き、宣伝ツイートもさせていただいたので、この先を読みすすめる場合、そういう利害関係がありPR的な側面が出てしまうことをご承知おきください。

この後長々書きますが、まずは試してみたいという方は、エントリーモデルを一つ買うと良いでしょう。マイクが必要な会議でもこれで十分です。

ちなみに、Shokz製品との出会いは多くのWebエンジニアがそうであるように、例によってlestrratさんのエントリです。一度使ってみたら様々なシーンでメリットがあることが分かりました。まとめてみると以下のような点です。

在宅勤務で

一日中つけっぱなしでもストレスがないのは大きい。メガネと似たような感じ。耳も塞がないので圧迫感が不快になったり、周りの音が聞こえなくてふと不安になることもなく、実際家族の様子も分かります。

Web会議もブームマイクついてないモデルでもちゃんと通話できます。たまに自分の声を録音して聞くこともありますが問題を感じたことはありません。

ただ、モデルにもよりますが連続稼働時間が6~10時間なので、本当に一日中連続で利用していると電池切れすることはあります。ISUCON参加したときは電池切れしました。会議の多い人はこまめに充電が必要でしょう。ちなみにブームマイクがついたモデルのOpenCommは16時間もつようです。

音楽に関してはそれなりですが全然聞けるレベルです。耳栓をつければ音の響きなどもより感じられるようになります。ただ、没頭して作業したい場合にはノイズキャンセリングのオーバーイヤーヘッドフォンをつけています。

ちなみに、今はフルリモート勤務ですが、前職でオフィスによく行っていた頃も、周りの音が聞こえるので重宝していました。

ちなみに、macOSのMontereyをお使いの場合、Web会議中に突然ミュートになるという事象が発生することがあるようなので、その場合は以下のエントリを参考にしてください。

Montereyと(After)Shokzの相性問題とその解決方法

運動や散歩や家事で

Shokz製品には耳栓が付属しています。これがエポックメイキングで、耳栓をつけると周りの音が大きくても快適に音楽や音声メディアを聞けます。これはカナル型のようなメリットも享受できると言えますし、イヤーチップと違って耳栓は自分にあったものを安価に用意できる点も優位点です。

水仕事や部屋でローラーを漕ぐときに重宝していて、少し音がする場合であっても、耳栓をつければ快適にコンテンツを楽しめます。外出時も電車などでは助かります。歩いているや外で運動している時に両耳を塞いでいると危ないので、つけないか、片耳だけつけるなどしています。

風呂で

防水性能が高いので風呂で気にせず使っています。特に、現旧ハイエンドのOpenRun ProやAeropexはマグネット式の充電で水が入り込みそうな穴が空いていないのも安心感があります。入浴しながらpodcastやaudibleが聞けるのはかなり良い体験です。

ただ、カタログ上のスペックの防水性能は旧ハイエンドのAeropexが一番高く(IP67)、OpenRun Proは一段落ちて(IP55)、他の製品と横並びです。なので、OpenRun Proは石鹸等がついてしまったりするとちょっと良くないのかもしれないのですが、そこまで神経質にならずに使っていて、問題にもなっていません。

私の使い分け

マルチポイントに対応していて、一本で2台接続先を設定できますが、2台では足りないので以下のように使い分けています。

それとは別に妻も一本つかっています。

マルチポイントに関しては、Macbook ProとiPhoneを頻繁に切り替えて使う場合でも、新フラッグシップのOpenRun Proでは問題なく使えています。またOpenRun Proの場合アプリで簡単にマルチポイントの設定ができる点も良かったです。旧モデルではマルチポイントは少し不安定になることがありました。

充電ケーブル

Aeropex, OpenRun Proはマグネット式の独自の充電ケーブルで、OpenMoveはUSB Type-Cでの充電です。このあたりは好みがあるでしょう。ただ、マグネット式の充電のモデルの場合にケーブルが2本付属してくるのは抜かりない配慮だと感じました。私は1本はデスクに置き、1本持ち歩き用のケースに忍ばせています。

既に述べたとおりマグネット式の場合、防水性能が高そうなのが安心ポイントです。なので上位モデルは軒並みマグネット式です。

メガネやマスクとの干渉について

最近は外出時にマスクも必要なので、耳の上がどうしても混雑してしまうのは事実です。ただ、つけてる間はそれほどストレスは感じません。ただ、つけ外しする時に絡まってめんどくさかったりするので、最近たまに外出時にコンタクトレンズをつけるようになりました。

まとめ

ということで非常に快適に使っているのおすすめです。以下に私が使っているモデルのリンクを貼ります。

また、ブームマイク付きのOpenCommはどれくらい会議で違うのかは少し気になっています。長時間バッテリーがもつのも魅力です。また、既存モデルは仰向けに寝た時にツルが少し気になってしまうので、OpenRun Miniも少し気になっています。気が向いたら購入してまたエントリを書くかもしれません。

GitHub Actionsのmatrixを動的に生成してGoの最新安定バージョンでテストする

Goのライブラリを提供している場合、Goの最新の安定バージョンでテストしたくなることがあるでしょう。具体的にはマイナーバージョンの直近2バージョン、今だと1.18と1.17です。GitHub Actions定義への記述は以下のようになるでしょう。

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go-version: ['1.17', '1.18']
    steps:
    - uses: actions/setup-go@v3
      with:
        go-version: ${{ matrix.go-version }}
    - run: go test ./...

しかしこのようにベタに書いてしまうと、Goのバージョンが上がったときにチマチマ上げるのが地味にめんどくさい。なのでこれを動的に生成したい。

これは事前にGoの安定バージョン一覧を取得するjobを走らせ、その出力からmatrix用のリストを生成すれば実現できます。具体的には以下のようにした。

jobs:
  go-versions:
    runs-on: ubuntu-latest
    outputs:
      versions: ${{ steps.versions.outputs.value }}
    steps:
      - id: versions
        run: |
          versions=$(curl -s 'https://go.dev/dl/?mode=json' | jq -c 'map(.version[2:])')
          echo "::set-output name=value::${versions}"
  test:
    needs: go-versions
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        go-version: ${{fromJson(needs.go-versions.outputs.versions)}}
    steps:
    - uses: actions/setup-go@v3
      with:
        go-version: ${{ matrix.go-version }}
    - run: go test ./...

go-versions というジョブで https://go.dev/dl/?mode=json からGoの安定バージョン一覧を取得してそれをjqで加工し、GitHub Actionsのset-output で出力を作っている。

% curl -s 'https://go.dev/dl/?mode=json' | jq -c 'map(.version[2:])'
["1.18.2","1.17.10"]

その出力を test ジョブの中で使っているという具合。test.needsgo-versions を依存として記述している。

ref. https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter

実際に拙作の prompter というライブラリに 導入してみた がちゃんと動いている。

本当はカスタムアクションを提供できると嬉しいと思ったのだが、一旦このような形でささっとやってみた。

https://go.dev/dl/?mode=json は決め打ちで最新安定のマイナー2バージョンしか返さない。それで多くの場合は十分だろうが、例えば3バージョンテストしたいとか、次バージョンのRCが出たらそれも早めにテストしたいなどのニーズもあろうかと思う。

その場合は、 https://go.dev/dl/?mode=json&include=all から一覧を取得してテストしたいバージョンを抜き出せると嬉しそうである。

そういった機構も含めたカスタムアクションがあると良さそうなので、僕もそのうち気が向いたらやるかも知れないが、誰かチャレンジしてくれると嬉しい。

母校や育ててもらった場所に寄付をして未来に思いを馳せる

いかにも中年臭い話だが、最近自分の中で少し寄付ブームだという話。寄付を公言するのはかっこ悪いように昔の自分も感じていたが、結局寄付というのは世界にどうあって欲しいかという願いでもあるので、それを表明しておくのも悪くないと思った。

今年はトンガとウクライナへの寄付をしたのだが、ふと思い立ってそれに加えて以下にも寄付をしてみた。

いずれもお世話になったところで、今後も継続してほしいので寄付をした。

母校に寄付をする

母校に寄付をしようと思ったきっかけとして、毎年送られてくる活動報告の冊子に寄付金の総額が記載されており、それが「案外少ないな」と思ったというのがある。学年300人しかいないわけで、大学等と比べたら少なくなるのは仕方がないとは思ったが、それでも少しさびしい額に感じたのだ。

なので、これを読んだ同窓の人がいたら寄付を検討してくれると嬉しい。

母校は東京男子高校御三家に連ねられる超トップ校である。僕が中学受験をした頃は御三家は抜きん出ており、それに比肩できる中学は関東だと筑駒と栄光くらいしかなかった覚えがある。

しかし最近は新興勢力も頑張っており、新御三家と言われるような学校が難易度や進学実績で同ランクに連ねられたりしていると聞く。

競争があることは良いことで、勢いのある新興勢力の台頭は喜ばしいことである。しかし、古くからのトップ校としてのアドバンテージの一つにOBの力がある。それらを大人気なく活用して新興勢力の壁となることも古豪に求められている姿なのではないか。

それに純粋に母校が長く続いて欲しい。自分の小学校は無くなってしまった。そういう意味でも、歴史のある中学・高校に入ることができたのは良かったとも思っている。

子供が小学校に上がり教育について考える機会も増えた。うちの子供は小学校のうちは少なくとも公立に行ってもらうので、その間は母校に寄付をできれば良いかな、と思っている。

寄付の権力性

寄付をするときに留意していおきたいのはその権力性である。個人が寄付をする場合、その先は恣意的に選ばれることになるので、公平性の担保という点ではあまり合理的とは言えない。とはいえ、冒頭にも書いたとおり、寄付というのはその個人が世界にどのようにあって欲しいかという願いでもあるので、公平性とは実はそこまで関連しないのだとも思う。

id:anzenchan の以下のエントリが好きで、そこからの引用をもってこの文章を終わろうと思う。

そもそも、私は募金というシステムそのものに対して懐疑的なんです。気まぐれに施しをすることもできるし、取りやめることもできる。そういった決定権を握っている状態というのを権力とよぶのなら、募金もエゴイスティックな権力行使にすぎません。実際、援助を受ける側は感謝することや謙虚であることを強いられる現実もあります。私たちが安穏と暮らしている一方で、理不尽な不運や貧しさに苦しんでいる人たちがいる。このような格差を正当化する理由は全くないのだから、本来、再分配は税金を通じた強制力ある形でなされるべきではないでしょうか。ボランタリーな再分配というのは、選択肢の豊富さによって生じる権力構造の問題にメスを入れることのできない、欺瞞的なやり方ですよ……
-- https://anzenchan.hatenadiary.org/entry/20110412/1302607222

YAPC::Japan::Onlineのキーノートで「変化し続けるキャリアと変わらない原体験」という話をしました

少し前なのですが、光栄なことにYAPC::Japan::Onlineでキーノートを担当させてもらい「変化し続けるキャリアと変わらない原体験」というタイトルでお話をさせてもらってきました。資料は単体としては粗があるのですが公開してしまいます。

https://junkyard.song.mu/slides/yapc-japan-online-2022/#0

自分のキャリアや行動原理を見直す良い機会にもなり、良い機会をいただけてありがたく思っています。ブラッシュアップして少し別の角度から別のイベントでお話したり、文章に起こしたりできると良いな、とも思っています。

ちなみに、開催数日前にブースターショットを打っていたにも関わらず、その直後にコロナに罹って寝込んでしまい、その関係もあってずるずると公開が伸びてしまいました。

今回はオンライン開催で、Discordの使い方など工夫が見られてよかったです。逆に今後のハイブリッドな開催の可能性なども感じました。最近そういう動きも増えてきていますが、ハイブリッドな形で技術カンファレンスが開催され、オフラインでも多くの人とお話ができる機会が復活する事を願っています。

雌伏の時

カッコつけたタイトルを付けてしまった。中二っぽい。 強がりと言うか、自分に言い聞かせている部分もあるのだと思う。

有り体に言うと、新しい環境にまだ苦しんでいて、上手く動けていない。こんなことを書くと同僚に心配されてしまいそうだが、同僚には現状を伝えていて、その上で信頼してくれているとも感じている。会社に不満があるわけではなくて満足している。

少し精神的に参っていたので、今週前半は少し休ませてもらった。これは休んだほうが良いな、と思ってyoshioriさんに相談したところ、こちらから休みについては何も言わずとも「休んだほうが良いよ」と言ってくれた。話が早くてありがたかった。

現状意識していることや感じていることについて書き留めておく。

成果を完璧に出せてはいないが淡々とやる

現状、社内では成果目標を定めて、達成度を振り返るというのを毎月やっているが、1月に関しては100%をつけることができた。

しかし、自分としてはまだできることはあったな。ベストを尽くさなかったな。という忸怩たる思いがある。新規機能のサーバー側実装だったが、自分の実装が完了した後に、まだできることがあるはずなのにやらなかった。

具体的には全体の機能としての完成度を見るのをサボってしまった。ちゃんと画面を触ってみて、ユーザー体験としてどうかや、今後の機能拡張の方向性を考えておくことなどをやらなかった。

とは言え、それが現状の自分の能力、認知負荷の限界なのだろうなとも思うようにしている。だから、それができない自分を責めすぎずに、敢えて目の前のことを淡々とやる、ということに務めている。

そうしたら案の定、今月の機能拡張で考慮不足が露呈してしまって、苦しむ原因となってしまったのだが、まあそれも仕方がない。

オーナーシップを持てないジレンマ

個人的な想いとして、夢中で仕事をしたい。人生の多くの時間を割くものなのだから、そうありたいし、そうすれば結果も伴うことが多いとこれまでの経験上感じている。これはあくまで僕個人の成果の出し方の流儀でしかありません。

そして、自分はソフトウェアが絡んだモノづくりが好きなので、プロダクト・サービスへのオーナーシップが仕事をする上での大きな原動力となる。サービスは我が子、くらいの感覚を持ちたいし、実際自分の人生の某かの産物ではあるだろう。

ただ「このサービスは自分のものだ」という感覚に至るのは難しいし時間がかかる。特に、自分でゼロから作ったサービスではない場合においては。ゼロからサービスを立ち上げることがめったに無い自分としては、これはいつも抱えるジレンマであり、それをこれまで何度か乗り越えてきたとも思っている。

しかし、今回は予想していたよりモチベーションが湧いてくるのが遅くて困っている。Launchableは自分にピッタリのプロダクトなので、すぐにキャッチアップできるだろうと思っていたが、それよりも燃えてくるのが遅い。

こういう表現が適切なのかは分からないが、これは「連れ子を愛せるか」という話に近いかもしれないと感じている。本当はもっと愛したいのに愛せない、というところで苦しんでいる。

ただ、もちろん今のサービスは「嫌いではない」。そして、それを生み出してきた同僚も本当に好きだ。それが本当に大事なことで、焦らずコミットしていけば時間が解決するだろう、とも考えるようにしている。

情熱があって何かを始める人なんて少なくて、何気なく始めたことが無意識のうちにのめり込んで、そこから情熱が生まれる
-- 岡本太郎

ちなみに、今回モチベーションのキャッチアップが遅いことについて自分の中にも考察があるのだが、ここではそれには触れません。

ところで、サービスを生み出す側じゃないからこそ、モチベーションが湧きづらい困難について書いたが、逆にサービスを生み出した人が思いが強すぎて、それがサービス成長の足かせになったりするともある。そういったところにプロダクト開発・運営の面白さもありますね。

牙を磨くことにリソースを割く

閑話休題。やる気がそこまで湧いてこないからこそできることもあるな、と思うようにもなった。仕事に対するマインドシェアが少ないということは、他のことにそれを回せる余裕があるということでもある。特に自分は仕事にのめり込んでしまうと他のことをやる余裕を失ってしまいがちなので、逆に今がチャンスだとも捉えている。

具体的には、フィジカルトレーニングと英語学習に意識的に時間を割いている。トレーニングと言っても、ここ5年くらい本当に不健康だったので色々見直して減量をしている中で、ロードバイクのローラーを漕いだり軽い筋トレをやったりするくらい。その中でトレーニング自体が楽しくなってきているというのはある。英語もとりあえず軽くてもいいから毎日なにがしかの学習をする、というくらいだが、じわじわと英語力が上がってきているのは感じているので楽しい。

このあたりは、結果として今後の業務パフォーマンスにつながるとも。

あとは、ゲームを始めた。ゼルダBotW。去年子供にNintendo Switchをプレゼントしたのだがそれで遊んでいる。個人的には社会人になってから21世紀初のゲーム機である。セガサターンがその前。

自律駆動

チームメンバーは、開発チーム以外も含めて全員素晴らしい。お互いに敬意を払っているし、信頼してくれていることもわかる。他人のケツを叩くことは誰もしない。自律的に動くことが期待されているからだ。

これはある意味恐ろしい。自発的に動けない人は何もできなくなってしまうからだ。他人からケツを叩かれ慣れてしまって、自分で駆動する力を失ってしまうことが人間何より恐ろしいと個人的には思う。

だから、この時差のあるフルリモートの環境は、自分の自律を鍛える良いチャンスでもある。ソフトウェアもチームも、自律・分散した系が協調して継続的に動くことが美しい。それを実現していきたい。

社内ブログを書くことも推奨されているため、このエントリも社内向けに英語でリライトして読んでもらおうと思う。

宣伝

YAPC::Japan::Onlineでキーノートを務めることになっています。なんと一週間後です。

https://yapcjapan.org/2022online/

ソフトウェアエンジニアのキャリアやコミュニティについて話して欲しいと言われていますが、このように現在絶賛悩んでいる状況でお話させてもらうのはちょっと面白いな、と思っています。

ご興味あれば聞いてくださると嬉しいです。僕のトークに限らず、面白そうなトークがいっぱいあるので盛り上げていきましょう。