GitHub Actionsでの処理の再利用(Reusable Workflows, Custom Actions)について整理

処理を再利用したいときには、以下の方法があり、それぞれで呼び出しのレベルが異なっています。

  • Reusable Workflows
  • Custom Actions (Composite Action)
    • Stepの一つとして呼び出す
    • jobs.<job_id>.steps[*].uses シンタックスで呼び出す

なので、どういうレベルで呼び出したいかや処理の粒度で、workflowにするかactionにするかを選ぶと良いと思います。

ログの出力も少し違っていて、Reusable Workflowsの方が見やすいですが、どちらも見ることはできるのでそれほど困らないはずです。

checkoutの振る舞いの違い

GitHub Actionsのご紹介と弊社での利用について - Stanby Tech Blog に書いてくれていますが、以下のように違います。

  • Composite Action
    • Composite Actionを定義している側のリポジトリのリソースをcheckout
  • Reusable Workflow
    • Reusable Workflowを利用している側のリポジトリのリソースをcheckout

Composite Actionはステップの一つなのでそうなるのも理解しやすいですし、大元のワークフローの方でcheckoutするはずなので、この点はとくに問題にはならないと思います。Composite Actionでチェックアウトしたくなったら、Reusable Workflowへの変更を考えるのが良いでしょう。

Workflowなどをプライベートリポジトリーに配置したら再利用できない

現状ではできません。認証が通らないので、パブリックリポジトリーに置かないといけないです。それが憚られる場合は、暫定措置として、ファイルをコピーして別プロジェクトに展開するのが今のところの妥協案かなと思っています。

-   Both workflows are in the same repository.
-   The called workflow is stored in a public repository, and your organization allows you to use public reusable workflows.

Reusing workflows - GitHub Docs

Private Access Tokenを使ってチェックアウトすれば当然リポジトリーを参照できますが、権限が大きすぎるし個人に依存するし、詐称してなんでもできてしまうのでこれは使うべきではないでしょう。

- name: Checkout private tools
  uses: actions/checkout@v3
  with:
    repository: my-org/my-private-tools
    token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT
    path: my-tools

GitHub - actions/checkout: Action for checking out a repo

一応、イシューにはなっており、 Actions: Reusable workflows work with private repositories · Issue #51 · github/roadmap · GitHub ロードマップ上では 2022Q4が目標になっているので、注視したいところです。どうやって権限を移譲するのかがイメージついていません。 GitHub public roadmap

Reusable Workflows

Reusing workflows - GitHub Docs

基本的にドキュメントの通りですが、いくつかポイントがあるので記します。

呼び出しの記述

以下のようにファイルパスまで指定します。

jobs:
  call-workflow-1-in-local-repo:
    uses: octo-org/this-repo/.github/workflows/workflow-1.yml@172239021f7ba04fe7327647b213799853a9eb89 # local repo
  call-workflow-2-in-local-repo:
    uses: ./.github/workflows/workflow-2.yml # local file path
  call-workflow-in-another-repo:
    uses: octo-org/another-repo/.github/workflows/workflow.yml@v1 # another public repo

ファイルパスまで指定するので .github/workflows ディレクトリーじゃなくてもいいかと思ったんですが、以下のエラーになって実行できません。

invalid value workflow reference: references to workflows must be rooted in '.github/workflows'

Custom Actions (Composite Action)

カスタムアクション自体は以下の3つの選択肢があります。

  • Docker container Action
    • コンテナー内で実行できるのでミドルウェアを利用するような処理を書ける
  • JavaScript Action
    • Node.jsで実行できるので複雑なロジックを書くことができる
  • Composite Action

それぞれ使い道があるので使い分ければいいですが、Composite Actionが実行が速くて手軽なので基本的にこれを使うのが良いはずです。

Creating a composite action - GitHub Docs

ディレクトリ構成

規定されていませんが、以下が推奨されています。

.github/actions/action_name

Composite Actionのシンタックス

通常のworkflowと少しだけ違うので以下を参照してください。

Metadata syntax for GitHub Actions - GitHub Docs

呼び出しの記述

以下のようにフォルダー名までを指定します。action.ymlは暗黙で補完されます。

    steps:
      - uses: actions/checkout@v3
      - uses: ./.github/actions/first_action # local folder path
      - uses: octo-org/this-repo/.github/actions/first_action@main # local repo        

ローカルフォルダーパスで実行する場合は事前にチェックアウトが必須ですが、ローカルリポジトリー形式だとチェックアウトは不要です。 チェックアウトをしない関係なのか、ローカルリポジトリー形式の方が実行完了が速いです。

ワークフローとアクションは相互運用できない

Reusable Workflowをstes.usesシンタックスで呼ぼうとすると以下のエラーになります。

reusable workflows should be referenced at the top-level `jobs.*.uses' key, not within steps

Custom Actionをjobs.usesシンタックスで呼ぼうとすると以下のエラーになります。そもそもCustom Actionはworkflow_callトリガーを実装しないので無理がありますね。もし、実装したとしても多分実行できないはず。

invalid value workflow reference: references to workflows must be rooted in '.github/workflows'

アトミックな操作をしたいときのロック状態の作り方

Crontabで実行しているバッチで重複した実行をしてほしくないときにロック状態を作ったりしますが、どうやるのがいいのかの選択肢を整理。

令和の時代と思えない話だけど今も必要な話だった。

おおむね、サイボウズのsatさんの書いていることを確認した感じになります。 https://zenn.dev/satoru_takeuchi/articles/e0636407a0040c

選択肢は以下。

おすすめは一番最後のファイルロック。

汎用性のある話なので、Linuxのコマンドで例を書いています。高等言語でもたいていラッパーがあるし。

ロックファイルを作る

if test -e /var/lock/foobar
then
  exit
fi
touch /var/lock/foobar

# do something

rm /var/lock/foobar

最初でファイルの有無を確認し、なければ作成して続行。処理の最後で削除する。プリミティブ。

単純だけどあんまりおすすめはしない。

  • Pros
    • 単純
  • Cons
    • 確認と作成に時間差があるので、その隙間で重複実行されることがあるかもしれない。crontabからの実行とかなら問題となりにくいけど
    • プロセスが途中で死ぬとロックファイルが残ってしまう
    • ロックファイル名が衝突する可能性がある

シンボリックリンクを作る

ln -s $0 /var/lock/foobaz

# do something

unlink /var/lock/foobaz

ln -s は既に存在していたらexitcode 1を返す。なので、存在確認と作成を同時にできるので、時間差がない。

  • Pros
    • 時間差がないので、隙間で重複実行のリスクがない(はず)
  • Cons
    • プロセスが途中で死ぬとロックファイルが残ってしまう
    • ロックファイル名が衝突する可能性がある

pidofコマンドでプロセスがあるかを調べる

/usr/sbin/pidof -x cron_job.sh >/dev/null || /path/to/your/cron_job.sh

一番簡単かもcron起動プロセスの多重起動防止ワンライナー - Qiita

ワンライナーでやるならこれがいいかも。だけど、プロセスを探すときのクエリーを間違えそう。引数が多い時とか特に。

  • Pros
    • 解除処理が不要
    • プロセスが途中で死んでも問題ない
    • ファイルに頼らないので、ファイル名の衝突などのリスクがない
  • Cons
    • プロセスを探すときのクエリーを間違えそう

実行スクリプト自身をファイルロックする

flock -xn foobar.rb vi foobar.rb

Exclusive, non-blockingのオプションをつければ、実行プロセスは一つにして、他のプロセスは待たせないですぐ完了にできる。これが一番いいと思う。

  • Pros
    • 解除処理が不要
    • プロセスが途中で死んでも問題ない
    • ファイルに頼らないので、ファイル名の衝突などのリスクがない
    • スクリプト自身をロックすれば依存するものを減らせる
  • Cons
    • ないと思う

Rubyでの実装例

以下、Rubyでの実装例

def main
  puts "Start #{Time.now}"
  locked = lock_myself
  if locked
    puts "Grab lock, Stay running"
  else
    puts "Quit due to process duplicated"
    return
  end

  sleep_sec = 65 
  puts "sleep #{sleep_sec} sec"
  sleep sleep_sec
  puts "Completed"
end

def lock_myself
  f = File.open(__FILE__, "a")
  # ロックが取れない場合、falseを返す
  f.flock(File::LOCK_EX | File::LOCK_NB)
end

main

こんなスクリプトが以下のようにcrontabに登録されていると、

ubuntu@ip-172-31-10-98:~$ crontab -l
* * * * * ruby /home/ubuntu/flock_test.rb  >> /var/log/cron_log

以下のように出力される。

出力の順番がずれているのは、スクリプトの完了時に標準出力がフラッシュされるため。ロックが取れないケースの方が先に完了するので先に出る。

ubuntu@ip-172-31-10-98:~$ tail -f  /var/log/cron_log 
Start 2022-10-17 04:09:01 +0000
Quit due to process duplicated
Start 2022-10-17 04:08:01 +0000
Grab lock, Stay running
sleep 65 sec
Completed
Start 2022-10-17 04:11:01 +0000
Quit due to process duplicated
Start 2022-10-17 04:10:01 +0000
Grab lock, Stay running
sleep 65 sec
Completed
Start 2022-10-17 04:13:01 +0000
Quit due to process duplicated
Start 2022-10-17 04:12:01 +0000
Grab lock, Stay running
sleep 65 sec
Completed
Start 2022-10-17 04:15:01 +0000
Quit due to process duplicated
Start 2022-10-17 04:14:01 +0000
Grab lock, Stay running
sleep 65 sec
Completed

プランが変わったSlackの代替を探したけどDiscordもTeamsもフィットしなかった

やりたいこと

  • 用途ごとにチャンネルを分ける
  • RSSフィードの購読
  • Trelloの更新通知の受付
  • webhookの利用
  • チャットログのエクスポート
  • (optional) チャットログのインポート

Discord

インポートができないのはいいけど、エクスポートもできないのに驚いた。 RSSフィードの購読も機能としてない。IFTTTやMonitoRSSを使うことになるけど、

  • IFTTTは一つのアプレットで一つのフィードを登録する。フィードを登録しまくるというのができない
  • MonitoRSSは無料だとフィードは5つまで
    • Patreonで$1のサポートをすれば200まで登録できるのでサポートするのも全然アリ

という感じ。Zapierを使うのがいいんだろうか。 次を調べる。

Microsoft Teams

2021年5月の更新で個人向けが追加され、職場向けのものと別物になってしまった。

Microsoft、無料の個人向け「Teams」機能を正式リリース ~仕事用の「Teams」と併用可能 - 窓の杜 家庭向け Teams を友達や家族と一緒に | Microsoft Teams

画像 Microsoft、無料の個人向け「Teams」機能を正式リリース ~仕事用の「Teams」と併用可能(1/5) - 窓の杜

個人向けではできないことが多い。チャンネルを分けることもできないし、インテグレーションを追加することもできない。

暫定の結論

Slackを使い続けて、定期的にバックアップをとる、みたいな。

Slackの家庭内日記をはてなブログに同期していく - すぎゃーんメモ を真似したい。

Rails6, 7でのdb系rakeタスクの確認

この辺いつも忘れるのでメモ。 あと、paperclipを削除するときにmigrationファイルの add_attachment が残ってしまう問題があったので、どう影響するかの確認のためでもある。

db:migrate

migrateファイルを日付け順に実行する。なので、削除された外部依存(e.g. paperclipの add_attachment )があればそこでundefinedのエラーになる。

db:schema:load

schema.rbから実行する。migrateファイルは実行しない。速いのでいいのだけど、

execute (“ALTER TABLE apples AUTO_INCREMENT = 9999”)

みたいなのはschemaに載らないので実行されないのに注意。

db:prepare

6以降のbin/setupからはこれが呼ばれる。以下の挙動の通りなので、普段はこれ呼ぶだけでもいい。

DBがなければ以下を実行。

  • db:create
  • db:schema:load
  • db:seed

DBがあれば以下を実行。

  • db:migrate

db:setup

DBがなければ作り、あってもスキーマロードを実行する。なので、普段からこれを使うことはない。

  • db:create
  • db:schema:load
  • db:seed

db:truncate_all

テーブルを全部truncateしてくれる。 Rails6の時点でヘルプに出てこなかったけど存在している。 rails/databases.rake at d5fc7da4c39470a8f5b0055eddc2d1bca2d034e3 · rails/rails · GitHub

paperclipを削除して困らない?

困らないので削除していい。

削除して困るのは一から db:migrate を実行するケース。

本番環境では、最初からmigrateすることはない。

開発環境では、 db:prepareスキーマロードするのでいい。ALTER TABLE が走らないけど開発環境なら支障はない。

ステージング環境を増やすみたいなときは、既存の環境のデータを持ってきて、 db:truncate_all すればいい。そしたらデータがなくてAUTO_INCREMENTが進んだ状態を作れる。

ということで、マイグレーションを一から実行することはないので、squasher gemみたいなのは使う意味がないと思う。

こども向けのSDGsの本をいくつか読んでみた

こどもが海洋環境汚染について興味を持っているので、説明の材料になるかなと思って読んでみた。

4・5・6さいの なぜなにSDGs せいかつから まなぶ!

あっさりした説明なので幼稚園児向けにはちょうどいい。あっさりしていて踏み込んだ話はないので、大人には物足りない。 幼稚園児に話すきっかけにはちょうどいい。

きみにもできる! よりよい世界のつくりかた SDGsにつながる小さな一歩

中1くらいから向けかな。

自分、コミュニティー、人類、世界という身近なところから広がっていく構成で、非常に良かった。世界を守るにはまず自分を守る方法を知らねばならないという、大切なのに蔑ろにされがちな話をしっかり伝えてくれている。

あと、世界の状況を伝えるだけじゃなくて、そのあとに具体的にどう活動するべきか、例えば、デモ行進の参加の方法とか、アクティビストになる方法まで踏み込んでてそこも最高。

日本だと環境問題について煽りまくりながら情報提供はするのに、具体的な話になると「水を大切に」みたいなしょぼい話で終わりがちだけど、この本はちゃんと行動の選択肢を書いている。

数字でわかる! こどもSDGs 地球がいまどんな状態かわかる本

小学校中学年くらいから向けかな。

全体通して煽り気味の書き方ではあるけど、数字とその出典(曖昧ではあるけど)も書いているのでわかりやすい。

世界の難民出身国の上位が、シリア、ベネズエラアフガニスタン南スーダンミャンマーというのも知らなかった。シリア、ウクライナに注目が集まりがちだけど、ベネズエラアフガニスタン南スーダンミャンマーの方が支援が届きにくくてある意味深刻なのかもしれない。そんな話を数字を交えて説明してくれるので、深掘りしたくなる。小学生の自由研究のネタ探しにもちょうど良さそう。

こどもSDGs(エスディージーズ) なぜSDGsが必要なのかがわかる本

煽り気味の書き方だけど、具体的な活動については記述が少ない。あんまり良くない。

iDeCo, 企業型確定拠出年金(企業型DC)での手数料などのもろもろの話

会社で企業型DCが始まるので、自分の理解を兼ねて書いたことをブログにも書いておく。

商品数は最大で35件

上限の35件というのは法律で決まっている。 確定拠出年金制度の概要|厚生労働省

同じSBIベネフィットでもiDeCoだと84件あるので、個人型と企業型でけっこう商品構成は違う。 iDeCo(個人型確定拠出年金)|SBI証券

とはいえ、うちの会社でのプランは「SBI みらい年金プラン」だけど、SBIアセットマネジメントが扱う、信託報酬が低めの「SBI・V・S&P500 インデックス・ファンド」とかが選べるので、それほど困るわけではない。たとえば、「三菱UFJ国際-三菱UFJ 純金ファンド」とかは企業型の方にはない、けど、これは信託報酬が1%近いので選ぶのに難易度が高い商品なのでなくても僕はそんなに困らない。

確定拠出年金の加入者側の手数料いろいろ

以下は個人型の場合の費用を書いています。

企業型になると口座管理手数料が会社負担になって掛け金の固定減衰が減るので、そういう面でも企業型のメリットは大きいです。

  • 加入時・移換時手数料
    • iDeCoから企業型DCに移管する場合、SBIだと4400円かかる
  • 口座管理手数料
    • 企業型になると、ここの費用が会社負担になり、加入者手数料や資産管理手数料で賄われる
    • 国民年金基金連合会に支払う「事務手数料」
      • 月額 105円(年間 1260円)
      • 拠出を止めるとこれは掛からなくなる
    • 信託銀行に支払う「運営管理機関手数料」
      • 月額 66円(年間 792円)
      • 拠出を止めても毎月かかる。なので、手数料負けの恐れもある
    • SBI証券は手数料無料!とか言ってるけど、大体どこの証券会社も無料でやっている
  • 給付事務手数料
    • 給付一回につき440円(税込)かかる
    • 分割受取だと毎回これが引かれて損するので、非課税枠内で受け取り回数を少なくする方がいい
  • 還付事務手数料
    • 間違えて拠出したときの還付を受ける際の手数料。1500円くらいが還付金から控除されてしまう
  • 信託報酬/信託財産留保額
    • 商品ごとに異なる
    • 信託財産留保額がかかる商品は基本選ばない方がいいと思う

会社側の手数料も結構かかる。

運営管理手数料について|企業型確定拠出年金|SBI証券

「手数料負け」とは

利益よりも口座管理手数料や信託報酬が上回るケースのこと。実際は節税効果のメリットもあるので計算が難しいけど、認識はしておいた方がいい。

たとえば、元本確保タイプの「ろうきん確定拠出年金定期預金(スーパー型)」を選ぶと保証利率が0.1%なので、55000円拠出すると、55円が利息としてつく。だけど、個人型だと毎月171円かかってしまうので、差し引きで116円毎月減っていくことになる。企業型なら口座管理手数料を会社が負担してくれるので手数料負けはしにくいけど、元本確保タイプを選ぶのもそれはそれで難しさはあることは理解できると思う。

iDeCoとの併用について

2022年10月から併用が基本的に可能になった。なので、iDeCoで23000円拠出を続けて、企業型DCで32000円拠出というのは可能。 だけど、口座管理手数料がiDeCoの方でもかかり続けてしまうので、せっかく会社が負担してくれているのにもったいない。

iDeCoの方が商品の種類が多いのでそちらを選ぶというのもあるけど、企業型DCでも手数料の安いインデックス連動投信はあるので、あんまりそこにこだわらない方がいいとは思う。種類にこだわっても口座管理手数料で負けてしまう。

曲面ディスプレイについて調べてみたら欲しくなってきた

最近4Kディスプレイを縦にして縦長で使っているけど、やっぱ上下が見づらい。ターミナルを下辺に置いたら入力ラインが一番下にくるからまあ見づらい。

そういえば社内で曲面ディスプレイにした人がいたのでちょっと調べてみたらなんか欲しくなってきた。

基礎知識

  • 大きさ
    • 24インチくらいからあるけど、解像度に対応して、UWQHD(3440×1440)だと34インチ、4K(3840x2160)だと31.5インチになるみたい
  • 解像度
    • 横長なので色々だけど、UWQHD(3440×1440), 4K(3840x2160)あたりが多い
  • パネル
    • ほとんどVA。VAの方が湾曲しやすいから湾曲率も高くできる
    • IPSが常に上位互換だと思い込んでいたけどそんなことはなかった。VAの方がコントラスト比が優れている。視野角で有利な湾曲モニターならVAで良い
  • 湾曲率
  • VESA規格対応
    • 重くなりがちだけどVESA対応のもある

良さそうなディスプレイ

HP M34d WQHDカーブド ディスプレイ

HP M34d WQHDカーブド ディスプレイ 価格.com 限定モデル 製品詳細 - モニター | 日本HP

PD65Wもあるし、これ最強では?

  • 34インチ
  • 湾曲率 1,500R
  • UWQHD(3440×1440)
  • ノングレア
  • DisplayPort 1.2 ×1
  • USB Type-C(DP Alt Mode, PD 65W)×1
  • デュアルスピーカー内蔵
  • VESAマウント (100)対応
  • 7.3kg

49500円。安い。

MSI Optix MAG321CURVJP

MSI ゲーミングモニター Optix MAG321CURVJP

PDが15Wなのが残念。でもそれ以外は十分。

  • 31.5インチ
  • 湾曲率 1,500R
  • 4K UHD(3,840 × 2,160)
  • ノングレア
  • DisplayPort 1.2a ×1
  • USB Type-C(DP Alt Mode, PD 15W)×1
  • VESAマウント (100)対応
  • 7.3kg

Joshinで55000円で売ってる。思ったよりだいぶ安い。 Joshin webショップ 通販| MSI | OPTIX-MAG321CURVJ

Dell S3221QS 31.5インチワイドモニター

USB Type-C接続がないのが残念。でも結構良い。

  • 31.5インチ
  • 湾曲率 1,800R
  • 4K UHD(3,840 × 2,160)
  • ノングレア
  • DisplayPort 1.2 ×1
  • USB Type-Cなし
  • VESAマウント (100)対応
  • 7.4kg

クーポン適用で52000円