10 ポイント 投稿者 GN⁺ 2026-01-15 | 3件のコメント | WhatsAppで共有
  • GitHub Actions の遅いフィードバックループと複雑なデバッグ過程に対する開発者の苛立ちを共有
  • tmplr プロジェクトで build.rs を通じて CUE でドキュメントを生成していたが、CI ビルドが失敗したことで問題が始まる
  • 4つのプラットフォームのうち Linux ARM だけがビルド失敗。その原因は、cross build 時に x86_64 バイナリが arm64 ランナー上で隠される GitHub Actions の動作方式にあった
  • 単一の変更をテストするのに 2〜3分 かかる非効率なフィードバックループを繰り返す
  • 解決策として build.rs を削除し、GNU Makefile に移行。CI ロジックを直接制御する方式で問題を解決

問題発生の背景

  • tmplr は、人が読み書きできるテンプレートファイルを使うファイル/プロジェクト用スキャフォールディングツール
  • build.rsCUE を使って README.mdCHANGELOG.md、バージョン/ヘルプファイルを生成し、一貫性を保証
  • 作業自体は約1.5時間で完了し、関連する記事も書き終えていた
  • ローカルでは正常に動作したが、GitHub Actions の CI 環境では CUE バイナリが未インストールのためビルド失敗

ビルド失敗の原因

  • 4つのプラットフォーム(Linux ARM、macOS ARM、Linux x86_64、macOS x86_64)のうち Linux ARM だけで「command not found」エラー が発生
  • 原因: matrix cross build が強く分離されており、CUE は x86_64 Linux ホストmacOS ARM ホスト にしかインストールされていなかった
    • macOS は x86_64 バイナリの実行に問題なし
    • Linux x86_64 も x86_64 バイナリの実行に問題なし
    • しかし GitHub Actions は arm64 ランナーで x86_64 バイナリを隠し、実行不能な状態にしていた

非効率なフィードバックループ

  • 問題解決のために繰り返した手順:
    1. 可能な修正方法を調べる
    2. ci.yml を変更する
    3. コミットしてプッシュする (jj squash --ignore-immutable && jj git push)
    4. 「Actions」タブを開く
    5. 最新の実行を開く
    6. Linux ARM の実行を開く
    7. 数秒待つ
    8. うんざりする
    9. 繰り返す
  • 変更1回ごとに 2〜3分 かかる
  • 理想を言えば、GitHub が 完全な機能を備えたローカルランナー を提供するか、あるいはプッシュ後に進行状況を素早く確認できる機能を提供できればよい
    • 「scratch commit」 のような機能: Git 履歴や Action の実行履歴を汚さずに、さまざまな実行を試せる方法
  • しかし現時点では、そのような機能は存在しない

解決方法

  • 30分間このループを繰り返した後で中断
  • インターネットで知られている方法を適用: 「GitHub Actions にロジックを管理させず、自分でスクリプトを制御し、Actions にはそのスクリプトを呼び出させるだけにすること
  • build.rs を削除(惜しさはあったが、犠牲は必要だった)
  • すべての生成作業を GNU Makefile に移行
  • 生成されたファイルをリポジトリにコミットし、CI の変更を元に戻す
  • 問題解決完了

結論

  • GitHub Actions は、ある種の良いものを持てなくしてしまう原因になっている
  • ランナーのデバッグやビルドプロセス最適化に多くの時間を失う
  • しかし一方で、他の方法では得がたい macOS ビルド のような利点もある
  • もちろん、GitHub Actions より設定が簡単な別システムも知られていない

We are all doomed to GitHub Actions. …but at least I dodged the bullet early.

3件のコメント

 
iolothebard 2026-01-15

GitHub Actionsは環境セットアップ(OS、ビルドツールチェーン、…)とスクリプト(シェル、Python、bat、ps1…)の実行だけを担うべき。GitHubが落ちても、環境さえ整っていればどこでもビルドできるべきだ。最近のGitHub Actionsのワークフローを見ていると、ここまでしてわざわざ使う必要があるのかと思う。はるか昔(?)にAnsibleもそうなって廃れた。

 
GN⁺ 2026-01-15
Hacker Newsの意見
  • GitHub Actionsの核心的な問題は、フィードバックループが遅すぎること 単純な失敗を確認するだけでも、pushして待たなければならないのは本当にもどかしい CIジョブはローカルで実行できるスクリプトとして分離し、Actionsの機能は段階的な拡張としてだけ使うのがよいと思う workflow_dispatchgh workflow runの組み合わせも悪くないが、後者が実行したワークフローのURLをすぐ返さないのは不便

    • nektos/actを使えば、ローカルでActionsを実行できる 迅速なフィードバックを得るのにかなり成功した
    • 自分はActionsがDockerイメージをビルドしてテストするよう標準化した 問題が起きたとき、GitHub Actions環境とほぼ同じ状態でデバッグできる
    • CIステップをローカルで実行できないのはおかしいと思う すべてのCIシステムの基本要件であるべきだ
    • ローカル実行可能なCIツールを自作しようかと考えたことがある 結局重要なのは、キューイング、出力解析、そしてビルド履歴テレメトリのような機能だ
    • gh workflow runでURLを得るには、GitHub APIでワークフロー実行一覧を再取得する必要があった 同時に複数の実行があると混線する可能性はあるが、今のところそれなりにうまく動いている
  • CI設計のコツをまとめてみた

    1. bashの代わりにpwshのようなCI向きのスクリプト言語を使う
    2. ワークフローにはロジックを入れず、シンプルに保つ
    3. 独立したスクリプトにして、ローカルでテスト可能にする
    4. デバッグしやすいように、状態出力とバージョン情報を残す
    5. デバッグ機能が充実したサードパーティ製ランナーを検討する
    • (1)には同意しない。ビルドやテストの工程が複雑になるのは悪い兆候だと思う 単純なシェルで十分であるべきだ
    • (1)には同意しないが、(2)はその通りだと思う MakefileにCIターゲットを定義し、make ci-testのように簡単に呼び出せるのがよい
    • 昔、Jenkinsプラグイン地獄を経験したことがある それ以来、すべてのCIはmake buildのような単純なラッパーで管理している
    • 単一スクリプトで全ビルドを包むと、CIシステムが詳細ステップの可視性を失う BeginStep("Step Name")のようなマーカーで区切れたらよいのにと思う
    • 結局こういう構造なら、スクリプトを直接実行する新しいCIツールが必要なのではないかと思う
  • 問題はGitHub Actionsそのものより、その上に雑に積み上げられた自動化にある ロジックはPythonのような言語でスクリプト化し、ローカルでも実行可能にすべきだ

    • 多くの人が不満に思っているのは、失敗したVMにSSHで直接入ってデバッグできないことだ 毎回ワークフローを修正してpushして待たなければならない
    • 「そういうスクリプト化作業は、お金をもらってやる数週間単位の仕事だ」と冗談を言う人もいた
    • デプロイ、リリース、キャッシュのようなCI専用機能は、ローカルで完全再現するのが難しい
    • このアプローチは、まるでsystemdがinit.dスクリプトを呼び出していた時代のようだが、悪くはない
    • ある人は「これは100% GitHub Actionsのせいだ」と言い切っていた
  • 自分はすべてのCIをコンテナ内で処理している CIプラットフォームはそのコンテナを実行するだけなので、ローカルでも同じように回せる プラットフォーム側はこうしたやり方を嫌う。ベンダーロックインが崩れるからだ

    • SourceHut CIが気に入っている 失敗時にSSHですぐ接続してデバッグでき、ブランチをpushしなくてもマニフェストを編集して再実行できる ただしセルフホスティングが必要だ
    • GitLab CIでも同様に専用Dockerイメージを作って使っていた 標準化はしやすくなるが、イメージ保守というトレードオフが生じる
    • 欠点は、macOSビルドをコンテナ化しにくいことだ
    • GitHubのWebhookは非常に詳細だ 実際にはほとんどロックインはないのに、人々はCI/CDカーゴカルトにはまっている
    • 「この内容をニュースレターで送ってほしい」という反応もあった
  • 自分はGitHub Actionsが好きだ 以前使っていたTravisより良いし、OSSプロジェクトにとっては無料リソースとして非常に有用だ Nixを導入して以降、環境再現性が高まり、Actionsとの相性がずっと良くなった

  • GitHub Actionsは単にbashやpythonスクリプトを呼び出す構造であるべきだと思う bashには限界が多く、Pythonの方が柔軟でローカル実行もしやすい この記事のように、uvを自動インストールして依存関係を管理する方式が理想的だ bashより複雑ではあるが、Actions環境では性能上の問題は大きくない

    • 実際、YAMLはランタイム環境定義用であり、実行ロジックは外部スクリプトに置くのが正しい
  • Actionsの最大の問題は、「ワークフローを組み合わせろ」という宣伝のされ方にある デバッグはほとんど不可能で、キャッシュ設定も厄介なためビルドが遅くなる こうした理由から、常駐VMで直接実行する方式が魅力的に感じられる

  • 自分はDepotの創業者だ GitHub Actionsランナーをより高速かつ安価に提供するサービスを運営している 多くの人が感じている不満は、実際に大多数の意見だ Actionsシステムは構造的に非効率で、毎週新しいボトルネックが見つかる より良い方法があると確信しており、それを実験している 詳しくはdepot.devで確認できる

  • 先週末にgg watch actionというツールを作った 現在のブランチの最新または実行中のアクションを見つけてくれるツールだ GitHubリンク

    • 「これはgh CLIに入っているべき機能だ」と好評だった ただし、gg tuiコマンドでリポジトリが見えないバグがあった
  • actのようなツールが役に立つのか気になった nektos/act アーキテクチャの違いにより、ローカル実行とオンライン実行が異なる可能性はあるが、それでも有用そうだ

    • 以前見たときは完全な代替ではなかった 約80%程度の互換性だった
    • 完全に同一ではないが、高速なフィードバックループを作るのに非常に役立つ
    • 実際に最も必要なのは、失敗後にSSHで入ってデバッグできる機能だ SourceHutはこれをサポートしていて、本当に便利だ
 
anyflow 2026-01-18

YAMLの中にロジックを入れなければならない構造なので、避けられない問題のように見えます。

上の記事がその答えをおおむね下のように出しているようですが、スクリプト部分をDaggerに置き換えれば、これが正解なのではないかとも思います。

"GitHub Actionsにロジックを管理させるのではなく、スクリプトを直接制御し、Actionsはそのスクリプトを呼び出すだけにすること"