Posts for: #Github

テンパった開発状況

今日の運動は腹筋ローラー,スクワットをした。統計を 運動の記録 にまとめる。

開発がなかなか進まない

本当は次の開発課題に着手しないといけないところだが、先週からずっと新機能のための、既存コードのリファクタリングに時間を費やしている。データ構造を変えたり、主キーを変えたりしているので影響範囲が大きくて、テストコードもあちこち修正しないといけなくて時間がかかる。結合テストの実行そのものにも時間がかかるし。

なかなか開発がテンパっているものの、今日でようやく一通りのリファクタリングを完了して、意図していた新機能のための web api が動くところまで確認できた。なんというか、新機能を作るために既存コードの改善に8割の時間を費やした感じ。おかげで新機能はなにも開発していないのに勝手に動いた (違) ような気持ちになった。今後、同様に個別データの拡張や新たなデータ追加のときは既存データに影響を与えず、独立して追加しやすい設計となっている。将来的に私がいなくなった後に拡張するときにこの設計は役に立つだろうと思う。

awesome-go へ道

昨日の続き 。contribution guidelines を読んでいて最低限やれと書いてあることの1つに Go Report Card report を作れと書いてあった。これは静的解析したスコアのようなものが表示される。すべて100%が表示されるようにした。

カバレッジも測れとあったので github actions の workflow ファイル を設定して計測してみた。63.9 % といまいちだった。コアなところしかテスト書いてないからかな。ユーティリティや cli のテストもちゃんと書いたら 80-90% ぐらいはいくのかな?また後日、時間のあるときにやってみる。余談だけど、久しぶりに github actions を触ったらもうワークフローファイルの文法とか覚えてなくてずっと触ってないとすぐ忘れるとか思ったりもした。

if the library/program is testable, then coverage should be >= 80% for non-data-related packages and >=90% for data-related packages. (Note: the tests will be reviewed too. We will check your coverage manually if your package’s coverage is just a benchmark result);

Quality standards

出張帰りにオフィスに寄って開発する

18時19分の新幹線に乗って21時前に新神戸駅に着く。この時間帯で帰ってくるのが楽な気がする。新神戸駅についたらいつもそこからタクシーで帰りたいと思う。いまうちの会社は全然儲かってないのでそんなことできないけれど、いつか余裕ができたら出張帰りの電車乗り継ぎをやめてタクシーで直帰してよいルールにしたい。

go 1.21 への移行

昨日 Go 1.21 is released! されたことを知った。自分の作業を中断して早めに移行して問題があれば検出できるしておきたかったので 1.20 から 1.21 への移行をしていた。もっとも大きな移行としてログ出力をすべて log/slog へ移行した。もともと cybozu-go/log という標準の log パッケージに近いものを使っていたので移行そのものは大きな課題にはならなかった。一方で変更することによって運用にどういった影響が出るかは実際に動かさないと気付かないこともあるだろうという視点で早く移行したかった。昨日の夕方に 1.21 で一通りは動くようにして、今朝から細かいところの修正は他のライブラリとして slices/maps といった新規に追加された標準ライブラリを使うように変更していった。リポジトリが数個あるので単純に労力だけの問題。ついでに go-ldap の ci 環境の設定も変えておいた。

github-api-tools 再び

帰りの新幹線の中でてらださんとやり取りしていた。issue 検索に llm の技術を使ってサンプルアプリケーションを作るというアイディアが進んでいて、公けの github issues のデータを使えばいいという話しをした。実際に学習データにするには、一定の前処理したテキストとメタデータが必要になる。github issues からあるプロジェクトの情報を一括で取得する方法はないか?という相談を受けて、github の rest api などを使って取得するのがよいのではないか?と提案した。

私も過去に github での作業時間の検証のために github-api-tools というツールを作っていた。21時半頃にオフィスに戻ってきて、せっかくなので試しにやってみるかと翌1時過ぎぐらいまでコードを書いていた。過去にも issues の機能も作った方がよいよねという課題は残してあった。

python のコードを滅多に触る機会がなくなってしまったので勘所を思い出したりするのにやや手間取った。それでも自分が過去に作ったものなのですぐにできた。

コワーキングから学ぶコミュニティ

0時に寝て2時に起きて5時前ぐらいまで本を読んでまた寝て8時に起きた。昨日の続きでちょっとした画面の改修をやって、小さいタスクを2つほど片付けて、それでもやることなくて暇だなぁ。

backlog-github-integration-action のアップデート

backlog のライブラリのバージョンが上がっていたのを少し前にみかけていたので更新してリリースした。

コワーキングのオンラインイベント

先日のカフーツさんのトークイベント 同様、9月のイベントに参加した。前回は急遽スケジュール調整をしたせいか私1人だったけど、今日は6人の参加者がいた。私以外はコワーキングスペースを運営している人みたい。コワーキングと街づくりといった内容が今日のテーマだったみたい。その事例の1つとして オトナリ[島根県雲南市] を教えてもらった。成功事例の話しを聞いていると共通点の1つとして主催者が地元の人ではなくても、その地域に移住して運営しているという。オトナリも東京のコンサル会社が受注してコワーキングのビジネスを始めたものの、その会社の社員が東京から移住してまでその地域の街づくりに参画しているという。その熱意の違いが正否をわける要因の1つであろうと私は感じた。以前、神戸市さんとコミュニティについて雑談した ときも、あえて言わなかったけど、職員自らではなく業者に委託して運営しているようなコミュニティではまったく運営の取り組みは異なるだろうと思う。他にも コミュニティ財団 という財団法人を作って運営している 愛媛県 西条市 の事例なども教えていただいた。

その後、参加者個々のコワーキングスペースの運営者のお悩み相談みたいなやり取りをしていた。私だけ運営者じゃないのでちょっと浮いてた。お前何ものやねん的なw あと箇条書きで書いたものをマインドマップに変換する Transno というエディターがあるらしい。私は手書きでマインドマップを描くのでこういったツールは使わないけれど、ツールでマインドマップを書くのが好きな人には向くのかもしれない。

ドキュメントを書きながら思うこと

3時に寝て7時に起きた。眠れない。

github リポジトリとシステム間連携

社員さんが運用対応に忙しくてスプリントタスクがなくなって暇なのでドキュメントを書いてた。github に新規リポジトリを作成したときに行う初期設定の作業が増えてきた。大半は私が導入した仕組みや機能のための初期設定になるが、私はリポジトリの管理権限をもっていないので、社員さんにお願いして、この設定して、あの設定してとお願いして対応してきた。もうすぐ辞めるので引き継ぎできるようにやっていることのドキュメントを整理した。

  • slack 連携
  • backlog 連携
  • github
    • pull requests テンプレート
    • github actions
      • github apps
      • github environments

リポジトリと他システムとの連携を効率化しようとすればするほど設定や背景が煩雑になる。とくに認証や権限周りのセキュリティを考慮した仕組みはサービスとのトレードオフになるので設定が面倒になりがちではある。とくに github actions のワークフローは 【登壇報告】JJUG CCC 2022 Spring で語りきれなかった技術的なお話 にあるように、世の中のプラクティスに依らず、私が設計して整備したものなので他メンバーにとって身近ではない。

backlog の wiki にプロジェクトのドキュメントを書いている。開発メンバーでドキュメントを定期的に書くのはほぼ私だけで、他メンバーはほとんど書かない。なぜそうなるのかな?と考えたときに思いつくことの1つとして、開発全般の業務としてやることを、誰でもできる汎用的な仕組みに落とし込むことを考慮して設計していないからではないかと思う。あるアプリケーションが内製/外部システム/外部ライブラリに関わらず、こういう機能や仕組みを使って、こんな課題を解決して、こんな機能を実現していますという構成にはなっていない。発生している問題に対して動けばいいといったレベルでしか開発していないから、本来どう在るべきなのか、どういった設計思想なのか、今後はどうやって保守していけばいいのかの指針を提供できない。これは私の言葉だと設計ができないということと同義だと思う。他に思いつくこととしては、既存アプリケーションにない新規の仕組みを定期的に設計しているのは私しかいないのかもしれない。言い換えれば、言われたことしかやらない人しかいない。

久しぶりにブログを書いた

2時過ぎに寝て7時に起きて9時まで寝てた。

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

読み進めておもしろかったし学びにもなったので書評を書いた。

backlog-github-integration-action v1.0.1 リリース

backlog-github-integration-action のバグ修正 した変更を v1.0.1 としてリリースした。2週間ほど検証環境でリグレッションがないかをみていた。問題なさそうなので v1 ブランチにマージして docker イメージを push して v1.0.1 タグを付けてリリース成果物を作成した。久しぶりにやると手順を忘れていてドキュメントを書かないといけないなとか思ったりした。

意図がわかる設計とリファクタリング

1時に寝て7時に起きた。久しぶりに HELLSING をみてた。アレクサンド・アンデルセンの狂信者ノリが好き。

煩雑な保守

昨日から着手した s3 とやり取りするアプリケーションの保守をしている。一通り機能は実装できたが、このアプリケーションの保守を今後どうやっていけばいいのかが私からはみえない。要件が変わる度に継ぎ接ぎで拡張してきて、意図をもった設計があるわけではないようにみえる。このまま保守することはできるかもしれないが、このロジックの説明もテストも検証もすべてが難しい。私がみても難しいのだから、経験の浅い開発者がみるともっと難しいのではないかと思う。

これを直すにはまず単体テストを直さないといけない。単体テストの大半がモックベースなので実際の振る舞いと異なる可能性がある。とくに s3 とやり取りするところの検証ができない。testcontainers の localstack があるので単体テストはモックからこのモジュールを使うように代替できそう。まずはそこからやるべきだが、2-3日はかかると見込まれるのでチームで承認を得られるかどうか、ちょっと聞いてみてから考える。

Job Summary を使ってみた

ちょっと前に github actions のワークフローの実行画面にサマリを出力できるようになったという記事をみた。

自動でよさげなサマリを出力してくれるわけではなく、自分でサマリを作らないといけないので面倒だなと思ってそのまま放置していた。先週末に モジュール別のビルド・デプロイのワークフロー改善 を行った。ふとワークフローの実行結果をみていて、選択したモジュール名が表示されているとわかりやすくていいなと思えた。それを出力する手段としてサマリがちょうどいいやということに気付いた。inputs などで動的に変更するパラメーターをワークフローの実行画面で確認できるといちいちログ確認する手間が省けてよいという場面が他の用途でもある気がしてきた。もっと積極的にサマリを使っていこうと思えた瞬間だった。

放置していたバグを直した

1時に寝て7時に起きた。寝ていて夜中に吐き気して眠れなくて上体を起こすしかなかった。たまにある 胃食道逆流症 のひどいやつ。

参議院選挙

普段は期日前投票で済ませるのだけど、今週は他のことに注意を取られていたせいか、当日行ってきた。場所が期日前と違ったので勝手がわからなかったけど、とくに混雑もしてなかったのですぐに完了できた。タイムラインを眺めると、私のタイムライン上では投票したと発言する人が増えてきたように思う。投票率が50%程度で半分ぐらいの人が投票していない状況に懸念をもつ人たちの可視化がされている。

ふと父の選挙はどうなるんだろう?と思って検索してみた。意思表示できない状態だと選挙はできないみたい。

選挙人本人が投票所に行き自らの意思で投票することが原則であることから、意思表示が困難である場合には投票することはできません。これは投票所の係員が選挙人の投票を補助する代理投票においても同様です。したがって、家族の方が本人に代わって投票することはできません。

神戸市 FAQ > 市政情報 > 選挙

70歳以上は傷病で選挙権を行使できない人たちもいるだろうから減るのかな?と、総務省の 年代別投票率 のグラフを確認してみた。直近だと、70歳以上が61.96, 60歳代が71.43、50歳代が62.96だった。60歳代と比べて減ってはいるけど、50歳代とそう変わらないのをみると、元気な人たちに選挙へ行こうと呼びかけるのは正しい気がした。

backlog-github-integration-action のバグ修正

運用してすぐにコミットメッセージ中にシングルクォートやダブルクォートが含まれると引数を正しくパースできなくてエラーになることがわかっていた。いま運用している環境の用途だと、それほど重要ではないので後回しにしているうちに面倒になって放置していた。晩ご飯を食べてからデバッグしていたら7時間ぐらいやってた。

bash 上の文字列の扱いと action.yml の inputs の args に引数渡しするときの振る舞いの勘違いもあって、issue の見た目以上に複雑な振る舞いをしていることがわかった。github actions 上のコンテキストに依存したくなかったため、github.event.commits の json をそのまま cli パラメーターとして渡している。bash 上の json 文字列と cli パラメーターとしての扱いが煩雑になるのでこのやり方は失敗だったかもしれない。ローカルでのテストもやりにくい。私はそのことをよく理解していたはずなのに github actoins 上のアンチパターンにはまってしまった。カスタムアクションのユーザーが簡単に使えるように cli パラメーターの設定を簡単にする意図で json 渡しにしたんだけど、エスケープの振る舞いが想像以上にややこしくなって、エスケープしたいユーザーには簡単ではなくなってしまった。それでもデバッグをがんばったおかげでシングルクォートは完全に使えるように実装できた。ダブルクォートは制限付きでエラーにならなくできるが、事実上は使わないでくださいといった仕様制限にしてしまおうと思う。引用するときはダブルクォートじゃなくてシングルクォートを使ってくださいと啓蒙することに決めた。

github actions の push イベントワークフロー改善

23時に寝て6時に起きた。今週はサービスインで凸凹していて疲れた。

ストレッチ

今日の開脚幅は開始前161cmで、ストレッチ後164cmだった。ちょっと数値がよくなった。一昨日の日本酒イベントで4時間ほど立ち呑みをしていた疲労で腰に張りが少しあった。それ以外はとくに問題はなくて調子がよかった。右股関節の詰まりも2-3週間前よりもよくなっている気がする。これはトレーナーさんも注意を払って詰まりを取り除くようにストレッチのメニューを組んでくれているのでその成果が徐々に出始めている気がする。以前よりも可動領域が広がってきている気がして安心感を得た。

github actions の push イベントワークフロー改善

午後からビルド・デプロイの最適化のために github actions のワークフローを改善作業をしていた。

今週はサービスインにより、本番環境への緊急リリースを何回もやっているのを傍からみていて、ビルド・デプロイが速くなればなるほど、その回数を増やせるし、修正後の検証に時間を多く割ける。あるリポジトリが7つのモジュールをまとめてビルド・デプロイしている。これはあるモジュールの微修正の反映には向かないので改善することにした。結果として最大で50%ぐらいのビルド時間の削減、モジュールに依っては、具体的には10分かかっていたものを4分台でビルドできるようにした。

ワークフロー改善のためのデバッグしている間はビルド・デプロイが出来なくなることから開発者が使っていない時間帯が望ましい。必然的にサービス休日出勤して github actions のワークフローを改善していた。デバッグと動作の検証も兼ねて午後から半日以上やっていたので休日にやったのは正解だと言えるだろう。

push イベントの github コンテキストの github.event.commits にコミット情報が入っていて、そこにコミットのリビジョンがある。例えば、次のようなオブジェクトで id がコミットのリビジョンに相当する。

[
  {
    "author": {
      "email": "...",
      "name": "...",
      "username": "t2y"
    },
    "committer": {
      "email": "...",
      "name": "...",
      "username": "t2y"
    },
    "distinct": true,
    "id": "f8df1f77ffec9ef234e7321b2e237b663256b01c",
    "message": "コミットログのメッセージ",
    "timestamp": "2022-07-08T12:32:33+09:00",
    "tree_id": "37b066734e58779c5d2c687d40b4cc43af177cb2",
    "url": "https://github.com/OWNER/REPO/commit/f8df1f77ffec9ef234e7321b2e237b663256b01c"
  },
  ...
]

このリビジョンを使って github rest api からファイル情報を取得できる。

$ gh api -H "Accept: application/vnd.github+json" /repos/OWNER/REPO/commits/f8df1f77ffec9ef234e7321b2e237b663256b01c

いろんなデータが返ってくるけど、ここでは変更したファイルのパスを知りたい。

{
  "sha": "...",
  "node_id": "...",
  "commit": {
    ...
  },
  ...
  "files": [
    {
      "sha": "...",
      "filename": "module1/path/to/src",
      ...
    },
    {
      "sha": "...",
      "filename": "module2/path/to/src",
      ...
    }
  ]
}

この filename のトップディレクトリがモジュール名と同じなのでここだけ取り出して、管理対象のモジュールかどうかを比較する。bash でも =~ をサブ文字列のマッチングができる。

$ targets=(mymodule1 mymodule2)
$ echo " ${targets[@]} "
 mymodule1 mymodule2 
$ [[ " ${targets[@]} " =~ " mymodule1 " ]] && echo "match"
match
$ [[ " ${targets[@]} " =~ " mymodule2 " ]] && echo "match"
match

さらにマッチしたモジュールを github actions の expressions で制御しやすいように json の array に変換する。

$ jq --compact-output --null-input '$ARGS.positional' --args -- ${targets[@]}
["mymodule1","mymodule2"]

これを step の outputs として格納する。

echo "::set-output name=modules::${json_array}"

例えば、後続の job で実行条件としてモジュールの有無を調べたいときは expressions を使って次のように記述できる。if 文は ${{ ... }} のブラケットを省略できるようだけど、ここだけ省略すると返って混乱するかなと思って私は記述するようにしている。その方が統合性があってコードが読みやすいように私は考えている。

  mymodule1-job:
    if: ${{ contains(fromJSON(needs.build.outputs.mymodule_target.modules), 'mymodule1') }}
    needs:
      - build

ちなみに workflow レベルの env は job の if 文には使えない。outputs を使って動的な値を扱うようにしている。どうも workflow レベルの env はいろいろ問題があるみたいでなかなか issue がクローズされないのをみると取り扱い注意なのかもしれない。

最終的なモジュールを判別するための step は次のようなものになった。

  build:
    outputs:
      mymodule_target: ${{ steps.mymodule-target.outputs.modules }}
    steps:
    - name: コミットログからビルド対象のモジュールを設定
      id: mymodule-target
      run: |
        declare -A modules
        target_modules=${{ env.TARGET_MODULES }}
        revisions=$(jq --raw-output '.[].id' <<< '${{ env.COMMITS }}')
        for revision in ${revisions}
        do
          names=$(gh api -H "${{ env.ACCEPT_HEADER }}" ${{ env.COMMITS_PATH }}/${revision} | jq --raw-output '.files[].filename' | cut -d"/" -f1 | sort -u)
          for name in $names
          do
            if [[ " ${target_modules[@]} " =~ " ${name} " ]]; then
              modules[${name}]=true
            fi
          done
        done
        targets=$(jq --compact-output --null-input '$ARGS.positional' --args -- "${!modules[@]}")
        echo "::set-output name=modules::${targets}"        
      env:
        TARGET_MODULES: |
          (
            'mymodule1'
            'mymodule2'
          )          
        ACCEPT_HEADER: "Accept: application/vnd.github+json"
        COMMITS_PATH: /repos/${{ github.repository }}/commits
        COMMITS: ${{ toJSON(github.event.commits) }}

処理も理屈も簡単なんだけど、実際の運用コードはもう少しだけ複雑なものの、デバッグは github actions を実行しないといけない。ちょっとした typo のために実は2時間ほどはまっていたのは内緒。シェルの配列や連想配列を使うと、記号が多くてわかりにくい。配列の閉じブラケットを忘れていたがために EOF のエラーが発生していた。閉じブラケットのミスだけにエラーが発生しているところと実際のコードがズレていて、それに気付くのに少しずつコードを足したり消したりしてデバッグするみたいな原始的なやり方で些細な typo を気付くのに時間がかかった。

xxx.sh: line 47: unexpected EOF while looking for matching `"'

資料作りと抜け・漏れ防止

marketplace への公開

pull request と push イベントに対応して基本機能は実装できたとみなし、v1 のタグ/ブランチを作成して marketplace に公開した。backlog と連携するカスタム action はすでにいくつかあるのだけど、pull request か push イベントのどちらかしか対応していなかったり、説明が日本語で書かれていて日本人向けしか対象としていないものしかない。グローバル向けの今後も要件次第で拡張可能なカスタム action はこれしかないと、ポジショントークも含めて言っておこう。ちょうどこみやさんも関心をもっているのでまた機会があれば使い方の説明とかやりますよと伝えた。まずは会社のメンバーに紹介してくれるらしい。使ってくれる人が増えると嬉しいなぁ。

リリース作業をしていてその内容について mermaid 記法を使って簡単なフローチャート図やシーケンス図も書いてみた。感覚的には plantuml で書くのと大差ないので github がサポートしているネットワーク効果を考えると、今後は mermaid を積極的に活用していくのもよいかもしれない。

打ち合わせ資料の作成

先日 第3期のふりかえり は行ったが、第4期の展望はできなかったので次回の打ち合わせのための資料を作った。今期も普通に業務委託をするだけではあるものの、今後のキャリアのために grpc の開発/運用経験を積む必要があることに気付いた。他人に話す機会があって、そのための資料を作ってみて、当たり前の抜け・漏れに自分自身で気付けるというのが思考の外在化のよいところと言える。誰かに指摘されればすぐ気付くことを自分自身で気付くのは意外と難しかったりする。特定技術を狙って案件を探すのはあまりうまくいかない。本来はビジネスがあって、それを実現するために技術を選ぶのであって、その逆ではないから。周りの友だちや知人に聞いてみるかなぁ。

個人開発楽しい

0時に寝て7時に起きた。朝から雨降りだったのでだらだらしながら家を出たけど、オフィスに着いたのは9時頃だったと思う。午前中にコードを書いてテストして、それからお昼ご飯食べて、家に戻って、ちょっとゆっくりしてからオフィスに戻ろうと思ってたら3時間ほど寝てた。

backlog のコミット連携の反応

たまたまツィートしていたらこみやさんが関心をもってくれた。fix, close などでチケットのステータスを変えたいという要望をもらったので作ることにした。

3時間ほどとわりとすぐに実装できた。いまのプロジェクトでは使わない機能なので当初は乗り気ではなかったけど、やっぱり使いたいという人がいると開発のモチベーションになる。

機能拡張して、テストしたり、ドキュメント書いたりしてた。github discussions も積極的に使ってみようと思っていてちょっとした faq も書いてみた。

1-2週間ほど試験運用して問題なさそうだったら v1 のタグをつけて marketplace などに公開してもよいかもしれない。ブログにも書かないとな。まだまだタスクは残っている。

カスタム action の開発再開

22時に寝て0時に起きて3時に起きて5時半に起きた。

ワーケーションのリトライ

オミクロン株の流行で延期していた開発合宿を行う。レンタカーと きのいえ の予約を6月3-5日で確定させた。3回目のワクチンを接種したばかりだし、世の中の雰囲気も with コロナへの取り組みになってきている気がする。行き先は同じなので前回作った旅のしおりをコピーしていくつか修正しながら再計画していく。Go To トラベル 再開が6月ではないかという噂もある。

backlog-github-integration-action の機能拡張

先日作った backlog-github-integration-action に push という新たなサブコマンドを追加した。コミットをリポジトリに push したときのイベントをフックしてカスタム action を実行する。インプットが github から取得できるデータになるため、GitHub Events 単位にサブコマンドを作ればトリガーと扱えるインプットデータが一致してわかりやすい機能分割になるんじゃないかと思えた。ひとまずそれでやってみる。今日のところはローカルで動かしてコミット連携ができることを確認して、いくつかテストを書いていた。また明日、結合レベルのテストをやってみる。