📌

GitHub Actions でちょっと凝ったことしたいとき、シェルスクリプトじゃなくてもいいよ

2024/12/29に公開

シェルスクリプトや *nix コマンドでもいいけど...

GitHub Actions で、ほんのちょっとだけ凝ったこと、というか、小さな編集処理をしたいときがあります。ありがちなのは、GitHub Actions で GitHub Pages へのデプロイを行なう際に、index.html 内の <base href="/" /> の値を書き換える、などです。

そうしたときによく見かけるコードは sed や awk などを用いたシェルスクリプトで、そういうささやかなテキスト編集などの加工を行なうことです。

自分もシェルスクリプトは決して嫌いではないですし、今時代、ChatGPT とかに聞けば、さくっとそのようなシェルスクリプトを生成してくれることでしょう。また、シェルスクリプトでワンライナーで書いた方がすっきりすることも多いです。

でもある程度の手順を必要とする処理となると、シェルスクリプト以外で書いたほうが、いいような気がしませんか?

とくに自分は C# が得意なのと、もっぱら C# プログラムを GitHub にあげて GitHub Actions で CI/CD したりするので、C# で書いた方がいいように感じます。では GitHub Actions の Workflow 内で、C# による、そのような小さな編集処理を実装・実行できるのでしょうか?

C# で書いてもいいよね

答えは「YES」で、よくよく考えれば当たり前ではあります。GitHub Actions 上で、CI/CD プロセスとして、C# プログラムのビルドや単体テスト実行ができるのですから、それ以外の任意の処理も C# で実装・実行できるわけです。

具体的には以下のようになるでしょう。

まずは、そういう、GitHub Actions の Workflow 内で実行したい C# プログラムのためのプロジェクトを、リポジトリに追加しておきます。素のコンソールアプリでいいので、以下のような感じでプロジェクト作るといいでしょう。

$ mkdir ./for-actions/Command1
$ cd ./for-actions/Command1
$ dotnet new console
$ _

すると、作業フォルダに Program.cs が生成されていますので、その中に臨む動作を実装します。

for-actions/Command1/Program.cs
// index.html をテキストとして読み取り...
var indexHtml = File.ReadAllText("./public/index.html");
// <base href="/"> を <base href="/my-repo/" /> に置換して..
indexHtml = indexHtml.Replace("<base href=\"/\" />", "<base href=\"/my-repo/\" />");
// index.html に書き戻し
Fille.WriteAllText("./public/index.html", indexHtml);

これならば、GitHub に Push する前に Visual Studio 上でデバッグ実行もできます。また、上記はあくまで例としたのでとてもシンプルにしましたが、変更後の静的アセットの Integrity や Fingerprint を再計算して JSON ファイルを更新する必要がある場合など、凝った処理が必要になると、シェルスクリプトよりも保守しやすいのではないか、と考えています。

あとは GitHub Actions の Workdlow 内から、この C# プログラムを「dotnet run」コマンドで実行するだけです。

.github/workflows/workflow.yml
name: deploy

on:
  push:
    branches: 
      - main

jobs:
  Deply to GitHub Pages:
    runs-on: ubuntu-latest
    steps:
      # Checkout the code
      - uses: actions/checkout@v4

      # Install .NET SDK
      - name: Setup .NET SDK
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: 9.0.x

      # 👇 ここで、上記で実装した C# プログラムを実行! (index.html をプチ編集)
      # Perform pre-process
      - name: Perform pre process
        run: dotnet run --project ./for-actions/Command1
      (以下略)

今回は自分は C# が得意なので C# で記述しましたが、皆さん自分の得意な言語で GitHub Actions の Workflow 内の処理を書いてもいいよね? っていう話でした。

Discussion