Shogo's Blog

Oct 1, 2023 - 1 minute read - github github-actions slack

Slack Incoming Webhook を GitHub Actions Secrets へ突っ込むのに疲れた俺達は

GitHub ActionsからSlackへ通知したいとき、一番お手軽なのはSlack Incoming Webhookです。 直接curlで叩いてもいいですし、マーケットプレイスにも通知用のアクションがたくさんあります。 しかし、Incoming Webhookは一般公開してはいけないシークレットです。 迂闊にレポジトリにコミットしてはいけません。 GitHub Actions Secrets へ突っ込む等して、適切に管理する必要があります。 一個や二個ならまだしも、いくつもレポジトリがあると管理が大変です。 そういうわけで、OIDCを使ってSlackへの通知を行うアクションを書きました。 actions-notify-slack 使い方 gha-notify.shogo82148.com へアクセスします。 「Add to Slack」をクリックして、アプリをSlackにインストールします。 @actions-notify-slack というボットが追加されるので、こいつを通知を流したいチャンネルに招待します。 投稿先のチャンネルで /gha-notify allow ORG/REPO スラッシュコマンドを実行します。これにより ORG/REPO からの投稿が許可されます。 ワークフローにアクションを追加して完成! - uses: shogo82148/actions-notify-slack@v0 with: team-id: T3G1HAY66 # 自分のチームIDに置き換え channel-id: C3GMGG162 # 自分のチャンネルIDに置き換え payload: '{"text": "hello world"}' 仕組み 早い話が、過去 GitHub や AWS 向けに作ったアクションを Slack 向けに焼き直したものです。 actions-github-app-tokenの紹介 AWS_SECRET_ACCESS_KEY を GitHub Actions secrets へ突っ込むのに疲れた俺達は GitHub Actions は直接 Slack とやり取りするかわりに、中継サーバーにリクエストを投げます。 中継サーバーは、OIDC ID Tokenを検証し、Slackへの投稿権限をチェックします。 権限を確認できたら、ボットユーザーとして投稿する、という流れです。

Sep 26, 2023 - 1 minute read - github github-actions

actions-github-app-tokenの紹介

GitHub App Tokenを発行するための actions-github-app-token という GitHub アクションを書きました。 実験的なアクションだったので、マーケットには公開していませんでした。 最近になって「安定して動作しているし、マーケットに公開するか!」という気持ちになったので、 改めてご紹介です。 背景 GitHub Actionsのワークフローから、GitHub APIを叩きたいこと、よくありますよね? GITHUB_TOKEN そんなとき第一候補に挙がるのは secrets.GITHUB_TOKEN です。 Automatic token authentication 特段複雑な設定をせずとも使えるのでお手軽です。 しかし、 secrets.GITHUB_TOKEN には大きな制限があります。 それは「他のGitHub Actions Workflowを起動できない」ということ。 これは無限ループで大量のジョブが投入されるのを防ぐための制限です。 理由もはっきりしていて妥当な制限だとは思うのですが、 必要なワークフローが起動しなくて困ることがときどきあります。 PAT (Personal Access Token) (Classic) 「他のGitHub Actions Workflowを起動できない」制限を回避する簡単な方法は、 Personal Access Token を使うことです。 このトークンにはこの制限はありません。 ただし、トークンを発行したユーザーの権限でAPIを叩くので、権限の範囲が広すぎる、という問題があります。 実行できるアクションは制限できるのですが、レポジトリの範囲までは調整できません。 また、トークンは「ユーザー」に紐づきます。 個人のレポジトリならまだいいんですが、Organization管理のレポジトリ困ることがあります。 一番のあるあるは「トークンを発行したユーザーがOrganizationを抜けるとワークフローが止まる」ですかね。 属人化が進み、健全とは言い難い状態です。 fine-grained personal access tokens 「権限の範囲が広すぎる」問題を解決するのが fine-grained personal access tokens です。 レポジトリ単位でアクセス権を設定できます。 しかし、権限の広さは解決しますが、「トークンがユーザーに紐づいていることの弊害」は解消しません。 また、fine-grained personal access tokensは有効期限の設定が必須です。 管理するレポジトリの数が多いと、トークン更新行脚をする必要があります。 GitHub Apps ここで本命、 GitHub Apps の出番です。

Sep 21, 2023 - 1 minute read - go golang

ぼくのかんがえたさいきょうのGo HTTPサーバー起動方法

これまで何度か HTTP Server の Graceful Shutdown について記事を書きました。 Go 言語で Graceful Restart をする Go 言語で Graceful Restart をするときに取りこぼしを少なくする Go1.8 の Graceful Shutdown と go-gracedown の対応 最終的に Go 1.8 で Server.Shutdown が導入され、この件は解決を見ました。 しかし、最近「あれ?本当に正しく Server.Shutdown 使えている?」と疑問に思い、少し考えてみました。 というか ↑ の記事もまだ考慮が足りない気がする。 ぼくのかんがえたさいきょうの Go HTTP サーバー起動方法 とりあえず完成形のコード。 package main import ( "context" "log" "net/http" "os" "os/signal" "syscall" "time" ) func main() { // シグナルを待ち受ける chSignal := make(chan os.Signal, 1) signal.Notify(chSignal, syscall.SIGINT, syscall.SIGTERM) defer signal.Stop(chSignal) // 起動したいサーバーを準備 mux := http.

Sep 18, 2023 - 1 minute read - go golang

Goのコメント全部消す

深遠な理由で、ソースコードからコメントをすべて抹消したくなったことはありませんか? そんなときに使えるツールを作りました。 shogo82148/go-comment-eraser Go製コマンドなので、 go install でインストール。 go install github.com/shogo82148/go-comment-eraser@latest ソースコードのおいてあるディレクトリを指定すると、 そのディレクトリ以下の *.go からすべてコメントを削除します。 go-comment-eraser ソースコードのあるディレクトリ 実際に shogo82148/go-comment-eraser 自身のソースコードで試した結果がこちら。 diff --git a/main.go b/main.go index 5087d08..913debc 100644 --- a/main.go +++ b/main.go @@ -65,22 +65,18 @@ func eraseComment(src string) error { return nil } -// parseFile parses the Go source code file and returns the Go source -// that is modified to erase all comments. func parseFile(src string) ([]byte, error) { - // Parse the Go source code file + fset := token.

Sep 16, 2023 - 1 minute read - github

ChooseALicense.com の日本語訳を公開しました

ChooseALicense.com の日本語訳を公開しました。 choosealicense.shogo82148.com 背景 いつの間にか「オープンソースライセンスを適切に管理する係」になってしまい、 最近はライセンス文章とにらめっこする毎日のいっちーです。 そんな中お世話になったのがChooseALicense.comの付録です。 ライセンスの概要が大まかにわかります。 まあ、最終的には原文を読まないといけないわけですが、読む手がかりにはなります。 母国語が日本語の僕にとって、毎回英語読むのはきつい・・・日本語版欲しいな・・・ってことで作りました。 ツール 今回お世話になったツールたちです。 GitHub Pages BudouX GitHub Pages ChooseALicense.com は GitHub Pages でホストされています。 自然とchoosealicense.shogo82148.comのホスト先もGitHub Pagesになりました。 GitHub Pages自体はこのブログでもお世話になっている機能です。 今回個人的に初挑戦だったのは、独自ドメインの割り当てでした。 ChooseALicense.comのコードがカスタムドメインでの提供前提で組まれており、サブディレクトリでの提供では表示が崩れてしまうからです。 とは言ってもドキュメントにしたがい、GitHub側の設定を済ませたあと、自分のドメインにCNAMEレコードを挿入するだけでした。 Managing a custom domain for your GitHub Pages site お手軽なので、今後なにかに使えるかもしれないですね。 BudouX タイトルの「Choose an open source license」は「オープンソースライセンスを選ぼう」と翻訳しました。 が、これをそのまま表示すると、こうなります。 オープンソースライセンスを選ぼ う 「う」の位置がなんか気に食わない・・・。 この問題の解決のため、BudouXを利用しました。 自動でいい感じの改行位置を決めてくれます。 オープンソースライセンスを 選ぼう まとめ ChooseALicense.com の日本語訳を公開しました。 choosealicense.shogo82148.com 参考 ChooseALicense.com choosealicense.shogo82148.com オープンソースライセンスの日本語参考訳 Managing a custom domain for your GitHub Pages site GitHub Pages BudouX

Sep 14, 2023 - 1 minute read - aws cloudformation

CloudFormationでECDSA形式のTLS証明書が取れた

2022 年 11 月から ECDSA(楕円曲線デジタル署名アルゴリズム)に対応しています。 AWS Certificate Manager が楕円曲線デジタル署名アルゴリズム TLS 証明書のサポートを開始 しかし、 CloudFormation のサポートは近日中に提供が開始されます。 と書いてあるように、CloudFormation からの利用はできませんでした。 今日試してみたら、行けたっぽい(?)ので、設定方法のメモです。 設定方法 KeyAlgorithm に EC_prime256v1 もしくは EC_secp384r1 を指定します。 AWSTemplateFormatVersion: "2010-09-09" Resources: Certificate: Type: AWS::CertificateManager::Certificate Properties: DomainName: shogo82148.com ValidationMethod: DNS DomainValidationOptions: - DomainName: shogo82148.com HostedZoneId: Z1TR8BQNS8S1I7 KeyAlgorithm: EC_prime256v1 注意 ふと、AWS::CertificateManager::Certificate リソースのドキュメントを読んでいたら KeyAlgorithm という属性を見つけたので試してみました。 しかし、2023-09-14 現在説明文は Property description not available. の一文のみ。 リリースの案内も見つけられなかったので、心配な人は正式リリースの案内を待ちましょう。 基本的に CloudFormation のプロパティーはサービスの API と同じ名前です。 今回試してみた EC_prime256v1 という値も、ACM の API リファレンスの KeyAlgorithm を参照しました。 ACM API Reference: RequestCertificate KeyAlgorithm 参考 AWS Certificate Manager が楕円曲線デジタル署名アルゴリズム TLS 証明書のサポートを開始 ACM API Reference: RequestCertificate KeyAlgorithm AWS::CertificateManager::Certificate: KeyAlgorithm

Sep 10, 2023 - 1 minute read - go golang

log/slogにログを転送する logrus hook を書いた

長らく構造化ログの仕組みが標準ライブラリになかったGoですが、 Go 1.21がリリースされて晴れて log/slog が使えるようになりました。 弊社ではlogrusを使っているので、log/slogを連携するためのフックを書きました。 背景 弊社ではlogrusをメインに使っています。 特段困ったこともなく 素晴らしいライブラリだと思います!!!(大事) 強いて問題点を上げるとすれば、メンテナンスモードに入ってしまってあまり開発が活発でない、ということでしょうか。 重大なバグがあれば別ですが、新規機能の追加等は行わない方針のようです。 一方 log/slog は公式ライブラリなので、log/slogの仕様を前提としたエコシステムが、今後発展してくでしょう。 logrusを使いながらlog/slogのいいとこ取りとする方法はないか?と考えた結果作ったのが shogo82148/logrus-slog-hook です。 SYNOPSIS sloghook.New で作成したフックを差し込むだけです。 logrusに流したログがlog/slogの設定で流れてきます。 package main import ( "io" "log/slog" "os" sloghook "github.com/shogo82148/logrus-slog-hook" "github.com/sirupsen/logrus" ) func main() { h := slog.NewTextHandler(os.Stderr, nil) logrus.AddHook(sloghook.New(h)) // logrus も logrus-slog-hook もSTDERRに書き込むので、同じログが二回表示されてしまう。 // logrus側を止めて防止。 logrus.SetFormatter(sloghook.NewFormatter()) logrus.SetOutput(io.Discard) logrus.WithFields(logrus.Fields{ "name": "joe", "age": 42, }).Error("Hello world!") // Output: // time=2023-09-10T23:32:41.229+09:00 level=ERROR msg="Hello world!" age=42 name=joe } 注意点 logrusはエラーレベルが Trace, Debug, Info, Warn, Error, Panic, Fatal と7段階ありますが、 log/slogには Debug, Info, Warn, Error しかありません。 しかし実は整数をレベルを設定できるので、適当に割り当てました。

Sep 8, 2023 - 2 minute read - github github-actions

actions/checkout@v4の襲撃を受けた件

先日 actions/checkout@v4 がリリースされましたね。 actions/checkout@v4 まあ、何が言いたいかというと、「メジャーバージョンアップ多すぎじゃない???」という話。 actions/checkout@v4の襲撃 新規に作成したレポジトリには基本的にdependabotをセットアップしています。 まあそんな状況下で actions/checkout@v4 なんてリリースされたら、こうなるわけですよ。 actions/checkout のアップデートつらい pic.twitter.com/4bNeCFsE4Y — f96fd3a0-bdb9-4f10-b69f-8f765c1d341c ICHINOSEShogo (@shogo82148) September 5, 2023 よほど単純なワークフローでない限り、 actions/checkout は必須のアクションです。 GitHub Actions でCIを組んでいるレポジトリはもれなく使っています。 @shogo82148以下にあるレポジトリだけで、76個のプルリクエストが来ました。 心を無にしてマージボタンを押しまくりました。 他のorgにも参加しているので、実際に対応したプルリクエストはもっと多いです。 Node.js 16 のEOLが近い 背景には Node.js 16 が9月11日にEOLになるという話があります。 actions/checkout@v3 は Node.js 16 で動くので、当然サポート対象外になります。 そこで新しいバージョンが必要なわけです。 actions/checkout@v4 は Node.js 20 で動くようになりました。 GitHub Actions はセフルホストできるので、まだ Node.js 20 が動かない環境も残っています。 そのような環境でオプトインできるよう、メジャーバージョンアップにしたのだと思います。 Node.js 18 がスキップされた話 ちなみに Node.js 16 と Node.js 20 の間には Node.js 18 が存在するわけですが、 Node.js 18 はスキップされました。 (Node.

Sep 4, 2023 - 4 minute read - go golang

ぼくのかんがえたさいきょうの[0.0, 1.0)の乱数を得るための方法

Twitterもとい𝕏でこんなスライドが流れてきました。 $[0.0, 1.0)$ の範囲を保証しつつ、浮動小数点数が表現可能なすべての値をとるのは難しい、というお話です。 なるほど・・・確かに改めて考えてみると「浮動小数点数が表現可能なすべての値」という条件は難しいですね。 でも、スライド中で紹介されていたアルゴリズムには、もうちょっと最適化の余地があるのでは?と考えてみました。 Goの標準ライブラリでの実装 もとのスライドはC++の話っぽいけど、C++はよくわからないので、Go言語での実装を考えます。 除算法 Goの標準ライブラリはスライド中で「除算法」と呼ばれている方法で乱数を生成します。 Go 1.21.0 の実装: https://github.com/golang/go/blob/33d4a5105cf2b2d549922e909e9239a48b8cefcc/src/math/rand/rand.go#L188-L212 // Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0). func (r *Rand) Float64() float64 { // コメント略 again: f := float64(r.Int63()) / (1 << 63) if f == 1 { goto again // resample; this branch is taken O(never) } return f } 除算法は大変シンプルですが、丸め誤差の影響で誤って 1.0 を返すことがあります。 Goは乱数を再生成することで、この問題を回避しています。 過去の実装 実際 Go 1.2 までは 1.

Sep 3, 2023 - 1 minute read - memo

ウェブ魚拓の創業者のインタビュー記事のウェブ魚拓

年に一度くらいこういうことありませんか? ウェブ魚拓の創業者のインタビュー記事読みたいな、と思って探したら、メディアが終了していてもう読めない。ウェブ魚拓を取っておけば・・・https://t.co/qpC5EdFQIJhttps://t.co/9JITbnj5ZM — f96fd3a0-bdb9-4f10-b69f-8f765c1d341c ICHINOSEShogo (@shogo82148) June 12, 2023 (はっ・・・?今年2回目・・・?) https://t.co/xzuix067a0 魚拓にあるって教えて貰ったので引っ張り出してきた。 — V (@voluntas) June 13, 2023 【魚拓】炎上の歴史とともに10周年、あの「ウェブ魚拓」創業者に会ってきた | HRナビ by リクルート https://t.co/RHWwoQwfVn 【魚拓】“握力の強さ”で日本一に 「ウェブ魚拓」創業者はいかにして肉体派プログラマーになったか | HRナビ by リクルート https://t.co/63arUxyU7Y… — V (@voluntas) June 13, 2023 Twitterもとい𝕏は最近雲行きが怪しいので、ぱっと見られるようにリンクを貼っておきます。 【魚拓】炎上の歴史とともに10周年、あの「ウェブ魚拓」創業者に会ってきた | HRナビ by リクルート 【魚拓】“握力の強さ”で日本一に 「ウェブ魚拓」創業者はいかにして肉体派プログラマーになったか | HRナビ by リクルート 新沼大樹さんも伏黒パパの役イケそう。 「呪術廻戦」伏黒パパがリアルに顕現!? 漫画みたいにTシャツへ浮き出る腹筋が「フィジカルギフテッド」と話題 魚拓