Posts for: #Github

デプロイ改善の成果まとめ

23時に寝て5時過ぎに起きた。何度か途中で起きたけど、久しぶりによく寝た。前日あまり寝てなかったから19時過ぎには帰ってきてだらだらしてた。

もてなしだけではもう食えない

業界研究を兼ねて もてなしだけではもう食えない -ホテル経営学の本質と実践- を読み始めた。同じ出版社の週刊ホテルレストランという雑誌の連載を書籍化したものらしい。著者は立教大学で社会人向けビジネススクールでホテルマネジメントとホテルインベストメントを教えているらしい。ビジネスの堅い話しを小説調にすれば読みやすいんじゃないかみたいな取り組みなのかな?よくわかてないけど、小説仕立てで業界研究ができるような書籍になっているらしい。第1章プロローグと第2章腐りやすい在庫を読んだ。実際の現場でこんな仕事できない人が改革チームのリーダーなんかになったりしないなと思いながら読んでた。そこは本題じゃない!コンサルティングでありそうな経営の話しが出てくるのでうちの会社の経営の勉強にもなるかもしれない。少しずつ読んでいく。

デプロイ改善の成果

水曜日がすくらむのふりかえりイベントがあるのでそれに間に合わせて簡単にまとめの資料を作った。3スプリント (3週間) もかけて抜本的に開発のワークフローからビルド/デプロイの ci/cd を見直したので開発全般に影響を与えた。

  • 本番環境デプロイ: 実行時間を約72%の短縮
  • テスト環境デプロイ: 実行時間を約51%の短縮
  • hotfix デプロイ: 実行時間を約64%の短縮
    • そもそも従来のやり方では hotfix を出していないので机上の時間ではあるが

単純に github actions の実行時間だけ比較しても速くなっているのだけど、それ以上にブランチ戦略を大きく変えた。従来は3つのブランチで運用していた。

  • develop
  • test
  • main

これを1つのブランチのみで運用できるように開発のワークフローを刷新した。ブランチが1つしかないので ci/cd の戦略もシンプルになって、変則的な運用 (hotfix を出したいとか) をしても、開発全体に影響を与えない。「誰か勝手にブランチを作ってデプロイして」で終わる。従来のやり方は3つのブランチが開発ワークフローと ci/cd に密接であったために本番環境のリリースするときは開発すべてが止まってしまう状態だった。週1回のリリースだったので本番リリース前の1-2日は PR のレビューやマージを止めているという運用になっていた。それは開発速度に大きな影響を与えていた。ブランチ戦略を見直したことでいつでも本番環境にデプロイできるようになって、継続的デリバリーっぽいことがやりたかったらできるよという話しをした。

ワークフローの移行説明

3時に寝て6時半に起きた。朝起きたら github actions のリソース上限に達しているという連絡が slack に書き込まれていて週末に移行作業して1500分ぐらいは浪費しましたと事後報告した。

ワークフロー移行後の説明

週末に移行した新しい ci/cd の仕組みを開発者に説明した。開発のワークフローも大きく変わる。いくつか要望をもらいつつ、とくに混乱も誤解もなく受け入れられた。github actions の管理画面からボタンでデプロイ実行できるため、本番環境にデプロイできるユーザーは制限したいと言われて次のようなステップを追加した。

- name: デプロイユーザーを確認
  if: ${{ env.DEPLOYMENT_ENV == 'prod' }}
  run: |
    [[ "${{ contains(fromJSON(env.DEPLOYABLE_USERS), github.actor) }}" == "true" ]] && exit 0
    echo "デプロイ権限のあるユーザーではありません"
    exit 1    
  env:
    DEPLOYABLE_USERS: '["user1", "user2", "app-bot"]'

expressions の Functions に組み込みの関数がいくつか紹介されている。それらを組み合わせるとうまくいきそうと思って書いてみた。たしかにちょっと楽に実装はできるけど、github actions の expression とシェルの文字列との境界が、yaml のコード上では曖昧なため、真偽値などはとくにわかりにくい。例えば、次のコード。

[[ "${{ contains(fromJSON(env.DEPLOYABLE_USERS), github.actor) }}" == "true" ]]

${{ ... }} で囲まれたところは github の expression なので boolean として評価できるが、それをシェルにもってくると文字列になってしまうので文字列で比較しないといけない。普通にコードを書いていて気づきにくいので実行して振る舞いを検証しないと間違うみたいな話し。

もっとさいきょうのでぷろい

ぼくのかんがえたもっとさいきょうのでぷろい

昨日 ぼくのかんがえたさいきょうのでぷろい を実装したんだけど、その後、残っていた残課題に対応しているうちにもっと最強のデプロイ方法があることに気付いた。結論から言って GitHub Deployments を使う必要がなかった。GitHub Deployments で過去のリビジョンを指定したときは次のような 409 エラーが発生する。

gh: Conflict merging main into f0cff65c94c4a242efebc79c8fb1e31d58d2f592. (HTTP 409)

これを回避するためにどんな手段があるかなと workflow dispatch event をみていて inputs というパラメーターがあることに気付いた。あれ?workflow dispatch ってパラメーターを受け取ることができたんだっけ?と調べたら2020年7月ぐらいからできるようになってた。

github actions の web ui とも連動していて画面からもパラメーターを渡せるようになっていた。jenkins で言うところのパラメーター付きビルドと呼ばれる機能。カスタムアクションの inputs と同じような使い勝手で利用できる。workflow dispatch がパラメーターを受け取れるなら GitHub Deployments を使うメリットって何があるっけ?と思ったら何もなかった。GitHub Deployments を使うことで無駄にリソースを浪費してパイプライン処理を複雑化させるデメリットしかなかった。inputs に渡す型に environment を指定すると、環境の制限や権限、protected branch などにも応用できるらしい。但し、この environment は public リポジトリか、github enterprise でしか高度な設定はできないみたい。GitHub Deployments 経由でリソースの作成自体はできる。

週末は休出

2時に寝て8時頃に起きた。前日に深夜まで開発してたせいか、朝起きたら頭痛かった。

ストレッチ

お仕事に集中していて今週は1回しかストレッチができなかった。今日の開脚幅は開始前164cmで、ストレッチ後165cmだった。先週と同じぐらいかな。それでも毎週予定が入っているので必ず週に1回はちゃんとしたストレッチを受けられる。もう1年以上続けているのだけど、以前より体調のよい状態をずっと継続できている。私はなにかに集中すると他のことをしばらく放置してそればっかりやってしまう傾向があるから毎週の予約があることが継続的な体調管理に大きく役立っている。太ももの後ろの筋肉と腰のストレッチの2つを楽しみにしている。デスクワークをする人は基本的にこの2つに疲労が蓄積するので疲労が溜まるのは自然と言える。その度合いがどのぐらいかでその週の疲労感や調子がよくわかる。今日は先週よりもその2つはましになっていた。

ぼくのかんがえたさいきょうのでぷろい

ここ2週間ほど、ビルドとデプロイの分離のための作業をしている。具体的には GitHub DeploymentsGitHub Actions を組み合わせて、新たな開発のワークフローを作るといったもの。main, test, develop と3つのブランチで開発/運用しているのを main ブランチ1つに統合し、ビルドもデプロイも最小限に留めて継続的デリバリーを目指すというもの。移行時は開発を止めてしまうのでこの土日で作業する予定だった。準備は十分にやっていたので問題なく移行を完了させた。今日は単体リポジトリのテスト環境へのデプロイができるところまでできた。あとはデプロイツールや github actions の処理を洗練させていくだけ。テンションが上がっているのでこのまま明日も休出してできるだけ品質をあげていく。

github apps を調べた

23時に寝て5時半に起きた。何度か夜中にも起きた。起きてからドラクエタクトやってた。

oauth apps と github apps

いまお仕事で ci/cd の改善をやっていて、その一環としてリポジトリをまたがったパイプライン処理を検討している。 ci/cd で使うような認可の仕組みとして github には oauth apps と github apps の2種類がある。

私はどちらも全く関わったことがなかったので、仕組みがイメージできる oauth apps を使えばよいのだろうと調べ始めた。しかし、一通り調べてみて会社の開発における ci/cd に使うなら github apps の方が適していることがわかった。両者がどう違うのかもドキュメントに記載されている。最初にこのドキュメントを読めば oauth apps を調査する必要はなかった。

具体的には、oauth apps は user の権限を認可する仕組みで、github apps は organization の権限を認可する仕組みと言える。github apps も oauth によるユーザー認証もできる上にアプリ自身の認証もできる。さらにアクセスできるリポジトリも制限できることから github actions などで、特定のリポジトリに対してのみアクセス可能なトークンを取得するには github apps の方が向くというわけだ。oauth でユーザーが認可するときに scope を指定するが、その scope を organization が設定できるといったところが github apps と oauth との違いにみえる。取得できる token の有効期限にもその考え方の違いが出ている。

  • oauth apps
    • ユーザー/デバイス認証
      • 認可コード: 15分
      • アクセストークン: 無期限
  • github apps
    • installation 認証
      • 認可jwt: 10分
      • installation トークン: 1時間
    • ユーザー/デバイス認証
      • 認可コード: 15分
      • アクセストークン: 8時間

github deployments の調査

22時に寝て23時半に起きて1時に寝て6時に起きた。

ストレッチ

先週に引き続き、右太もも後ろの張り感が強い。もしかしたらここ2-3週間、長時間机に向かっていることが増えて負担がかかっているのかもしれない。2月は寒いから帰って散歩やジョギングすることもなくて余計に筋肉をほぐすこともできていない。今日の開脚幅は開始前164cmで、ストレッチ後160cmで先週と変わらないぐらいだった。調子がよくなかったのか、ストレッチ後にあまり開脚できなかった。たまにこういうときもある。

github deployments の調査

github actions を実行するにはなんらかのトリガーが必要なことから、デプロイのためのトリガーに使えそうなものはないかを Events that trigger workflows で調べていたら deploymentdeployment_status というイベントがあることに気付いた。

わりと最近できた仕組みで github deployments という api 群が提供されている。一度ベーダとして出したものの、アルファレベルだったせいか、gh cli でも専用コマンドとして機能追加されていないし、github の slack インテグレーションでも一度提供した deploy サブコマンドを削除するみたいなことが発生している。まだ設計やインタフェースが使いやすいものではないから作り直すみたいな状況にみえる。とはいえ、rest api は提供されているので現状の機能のまま github actions のトリガーとして使う分には問題なさそう。

ビルドとデプロイを分離するにあたって、デプロイのためのトリガーが github 上のサービスとしてみつかったのはよかったと言える。github deployments は現状では中途半端なサービスという位置づけにみえる。

docker の勉強

0時に寝て6時に起きた。

ストレッチ

ここ1ヶ月ほどお仕事に集中しているのもあるけど、あまりストレッチに意識を割いていない。やるときは集中して注力するのだけど、飽きてくると怠ける性格的なところがある。とはいえ、やめずに続けているといいことがあると経験則からわかっているのでなるべく継続していきたい。今週も特別なことはなにもしていないのだけど、右足の股関節周りに張りがあってあまり調子がよくなかった。今日の開脚幅は開始前163cmで、ストレッチ後167cmで先週よりも数値が悪化している。良くなるときもあれば悪くなるときもある。毎週ストレッチを受けて計測しているとそういう気付きがあること自体、この機会は健康のために役立っているように考えている。

github packages で docker イメージを公開する

docker が流行りだした頃に勤めていた会社の貸与端末が docker 禁止だったので私は docker に乗り遅れて、これまでも誰かが用意してくれたコンテナを使うだけでよかったため、最低限の docker コマンドや docker-compose の使い方しか知らなかった。ちょうどインフラの運用を見直す過程で docker コンテナの作成方法から見直すお仕事ができたのでこの機にいろいろ勉強する。いまどき当たり前なんだろうけど、docker の マルチステージビルド をやってみる。

最初に go のバイナリを選択したのは間違いだったのかもしれない。go のビルド環境を作るベースイメージの選択が難しくて、ビルドはできるけど、作成したバイナリが動かないという状況にはまった。ECSのタスク起動時に「standard_init_linux.go」関連のエラーが出た場合の対処方法 であるように、いろんな不具合がある。ベースイメージの選択やビルドに必要なライブラリがないとそういうエラーになるんだと気付くまでに時間がかかった。

最終的に次のような Dockerfile でマルチステージビルドができた。builder としてのベースイメージの選択によってやり方はいろいろ変わってくるように思える。

FROM golang:alpine as builder
RUN apk add --no-cache git make gcc musl-dev
WORKDIR /work
COPY . .
RUN go mod download
RUN make build

FROM alpine:latest
WORKDIR /
COPY --from=builder /work/bin/sql-executor .
CMD [ "/sql-executor" ]

Dockerfile ができたら Publishing Docker images を読みながら github actions で自動的に docker イメージを github packages に公開する設定をやってみた。リリースを作成したときに docker イメージをビルドして公開する workflow yml を作成した。ほとんどドキュメントのまま。

github actions の実行結果。

github packages 上で公開された docker イメージ。

リリースのタイミングじゃなくてコミットのタイミングでも docker イメージを生成できると思うけど、docker イメージのタグに相当するものをどう付けるかというところは工夫する必要がありそう。

github actions のワークフローカスタマイズ

0時に寝て6時半に起きた。

github actions の並行ビルド

1-2日でできると思ったら想定したよりややこしくて3日かかった。既存処理でかかっている時間を40-50%ほど短縮できた。1つの job で複数モジュールのビルドや docker イメージの生成、aws ecr への登録、eks の pod 更新などをしている処理を複数の job に分割する。job を分割すると、ビルド成果物を共有できなかったり、env のスコープも変わってくる。独立した job 環境で効率よく処理できるよう、ビルドキャッシュを導入したり、カスタムの composite アクションで処理を共通化したりと、あれやこれやを変更する量が増えていった。変更すること自体は問題ないけど、動作検証は github actions 上で動かさないと分からないところがあって、その検証に時間がかかる。複雑なワークフローを実装していると、github actions のかゆいところに手が届かないのにも気付けた。まだまだ circleci は企業向けに使われるのかもしれないなと思えた。

github actions のビルドキャッシュ運用

23時に寝て5時に起きてちょっと作業してまた寝て7時に起きた。お仕事も働き始めて1ヶ月が経過して、だいぶチームの雰囲気や業務に慣れてきたところ。稼働日の18日間で作成した pr が16件。入ったときに割当てられた3つの課題から10数件の issue を派生させてちょうどすべて fix した。来週から新しい課題に取り組む。

ストレッチ

今週もお仕事に注力してたらストレッチは2日/週とあまりできなかった。ウォーキングもやってない。今日の開脚幅は開始前165cmで、ストレッチ後167cmだった。さぼってたせいか、数値が悪くなってしまった。右股関節の関節の可動域がよくないところは少しずつまがるようになってきてよくなってきている実感がある。一方で右太ももの後ろの筋が張りが大きいことに気付いた。トレーナーさんに聞くと、この筋は椅子に座っていると張りやすいという話しなので、最近はお仕事に注力して椅子に座っている時間が以前より伸びているせいだと思う。あと会議に出席している時間も増えているため、その時間は椅子に座っておかないといけないという制約も増えている。

actions/cache の exclude 設定

github actions でビルドキャッシュを扱う方法は Caching dependencies to speed up workflows に書いてあって、それは actions/cache という github actions がキャッシュ機能を提供している。ここでドキュメントにはキャッシュの除外設定については何も書かれていないが、リポジトリに含まれる examples.md には次のような説明と設定例が出てくる。

Depending on the environment, huge packages might be pre-installed in the global cache folder. With actions/cache@v2 you can now exclude unwanted packages with exclude pattern

https://github.com/actions/cache/blob/main/examples.md#c---nuget

- uses: actions/cache@v2
  with:
    path: |
      ~/.nuget/packages
      !~/.nuget/packages/unwanted      
    key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
    restore-keys: |
      ${{ runner.os }}-nuget-      

! を入れるだけかと思って検証してみたらどうも意図した振る舞いにならない。実はこの設定はバグっていて実際には動かない。なぜ動かないかを追いかけてないけど、issue にも登録されている。path の記述方法によって動いたり動かなかったりするというのが現状の振る舞いになるらしい。

ちなみに正しい動く設定は次になる。ワイルドカードを使わないといけないらしい。ドキュメントに除外設定について書いていないのはバグってて中途半端な振る舞いをしているからかもしれない。

- uses: actions/cache@v2
  with:
    path: |
      ~/.nuget/packages/*
      !~/.nuget/packages/unwanted      
    key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
    restore-keys: |
      ${{ runner.os }}-nuget-      

あとビルドキャッシュのキーにパッケージ管理のファイルのハッシュ値を取るようになっている。この背景も github actions がキャッシュをクリアする機能を提供していないからであろう。Clear cache #2 でも議論されているが、キャッシュをクリアできないため、同じキーにパッケージが溜まり続けるような運用は開発者にとっても github 社にとってもリソースを浪費するので好ましくない。いまは7日以上アクセスされていないキャッシュを削除する運用になっているため、なるべくフレッシュなキャッシュが生成されるような運用となるよう、ハッシュ値を取得するようなキーの運用が行われているように推測される。

朝から晩まで多忙な一日

0時に寝て5時に起きた。昨日 slack で質問していた内容に5時頃に返信があるのをたまたまみかけた。この時間に起きているんだと思って返信にコメントしてたら別のメンバーからもコメントが書き込まれて、早起きは三文の得みたいな感じで朝5時から slack でやり取りしてた。いま私はだいたい8時から始業している。開発チームの半分ぐらいのメンバーはそのぐらいから始業しているのが課題管理システムや git のコミットログからわかる。このチームは朝早い人たちが多いなと感心した。

朝活: アジャイル開発とスクラム 第2版

2021-11-26 AM 6 金曜朝6時開催のもくもく会 で第6章と第7章を読んだ。第2部は企業において実際にスクラムを導入していったときの四方山話が出てくる。私はあまり他社の事例に興味はないが、対談の過程で本質的に大事なことや難しいことなどがあぶり出されることもあるので、実務を通しての話題も参考になる場合があることは理解できる。大半の事例は実業務で使われているという結論がわかるだけでも十分だと思う。とくに大企業は様々な厳しい制約や要件の中で採用していると推測されるので、それだけで大きなメッセージをもつ。斜め読みでざっと読み進めながら興味のある話題があれば精読するといった程度で読んでた。

大企業あるあるな話しでスクラムイベントを通してお互いの距離感が縮まってうまくいったといった内容があった。開発者からすると距離感の遠近に関係なく、必要なら適切な相手を探し出してコミュニケーションを取るのが普通だけど、みんながみんなそうではないだろうし、(同じ会社の社員でも)よく知らない人とは話さないといった考え方をもつ人もいるだろう。ある人はこれを単純接触効果で説明していたけど、業務ではなく人間の側面からみてスクラムイベントが多いことにも意義があるのかもしれない。

顧問さんと雑談

隔週で打ち合わせをしている。最近はお手伝いのお仕事が忙しいので今回は雑談になってしまったが、近況としてリーンキャンバス、スクラム実践の話題などを話していた。わりと盛り上がって1時間で切り上げるつもりが1時間半に伸びてしまって、別のお仕事の時間を圧迫したけど、それはそれで意義のある雑談になったので収穫はあった。

ある組織で新規事業を行う上で AARRR (あー) モデル をすごく重視しているといった話題が出た。バケツみたいなイメージがあって、そこに現実の数字を当てはめていってプロジェクト/プロダクトの改善やふりかえりなどに活かしているという。サービスのグロースに責任をもつ人には重要な概念だという。うちのプロダクトはグロースしなくてもよいけど、なんらかのフレームワークに当てはめて抜け・漏れがないかをチェックすることにも使えるかもしれない。世の中でよく使われているフレームワークを調査しておいて損はないと思う。私はビジネスに全く疎いのでリーンキャンバスを通じて、AARRR モデルの話題になって、それがどういった用途で使われているかというお話しは興味深かった。

具体的には AARRR モデルの他に、スクラムの話題からは野中郁次郎氏のオリジナルの論文、大規模アジャイルの方法論などが盛り上がっていくつかキーワードが出た。そういった雑談の中で感性に従って気になったことを深堀りしていくとおもしろい調査や知見になったりすることを経験的に実感しつつある。今後もそういう機会や内容を大事にしていきたい。

カスタム GitHub Actions の開発

先日 調査していたものをベースに、普通にやる方法と カスタム GitHub Actions の compoiste action で実装する場合の検討資料などを作って、カスタム GitHub Actions を実装してよいといった許可をもらった。企業における唯一の懸念は (原則) public リポジトリで運用するところで、CI のような処理に社外秘は含まれないが、public そのものに審査や承認を必要とするような組織では腰が重くなるようなこともあるかもしれない。ロードマップにも private リポジトリでカスタム GitHub Actoins を動かせるようにしようという課題は作成されている。

カスタム GitHub Actions のサンプルを作ってみた

23時半に寝て5時半に起きた。昨夜は夜にウォーキングに出掛けようと思いつつ、22時頃に1時間ほど寝てしまった。それで出掛けるのが面倒になってそのまま寝てた。早く寝た分、早く起きた。せっかく早起きしたのでドラクエタクトのデイリーミッションやって、それから起きて7時ぐらいにはオフィスに着いてたと思う。

カスタム GitHub Actions 作成

GitHub Docs の アクションの作成 をみながらサンプルを作ってみた。カスタムアクションは3つの作成方法がある。

  • docker コンテナを使ったアクション
  • javascript を使ったアクション
  • シェルスクリプトなどを使ったアクション (composite アクション)

たぶんランタイムに何を使うかでアクションの作り方が異なるようにみえる。最後の composite アクションは呼び出される環境で動くことを想定しているのかな?サンプルには bash 上で動くものを紹介していた。ほとんどチュートリアルの内容そのままんだけど、動かして雰囲気を掴むために自分で composite アクションを作ってみた。単一のリポジトリに閉じたものなら通常のワークフローの設定に書けばいいけど、複数のリポジトリで同じ処理をしたい場合は composite アクションとして再利用できるようにするとよさそう。