ラベル GitHub Actions の投稿を表示しています。 すべての投稿を表示
ラベル GitHub Actions の投稿を表示しています。 すべての投稿を表示

2026年8月31日月曜日

【GitHub Actions】シークレットを別のリポジトリに migrate するツールを作った

みなさん、GitHub Actions のシークレットの管理ってどうしてますか?
設定された内容をどこか別の管理場所で保存している場合もあると思いますが、設定するだけで何もしてない場合も多いのではないでしょうか。

登録されたシークレットの中身は基本的に閲覧することはできません。シークレットの操作は gh secret コマンドから行なうことも可能ですが、当然これらも delete / list / set サブコマンドしかなく、get はできません。
GitHub Actions に詳しい人なら、中身を確認する方法はわかるのではないかと思いますが、面倒ではあります。

ただ、シークレットの中身を閲覧できなくても、困ることはほとんどないでしょう。

https://github.com/srz-zumix/gh-secret-kit
今回「シークレットを別のリポジトリに migrate するツール」の紹介をするわけですが、なぜこれが必要になったのか、から説明します。

なぜこれが必要か

きっかけはとあるリポジトリのホスト移動が必要になったことです。
このようなケースは GitHub の公式ツールでサポートされており、 gh-gei を使うことで migrate することができます。
About migrations between GitHub products with GitHub Enterprise Importer - GitHub Docs

しかしながら、サポートされている移行対象のデータは限定的です。
プルリクエストなどは移行できますが、Rulesets や Teams など結構よく使う機能も移行対象外になっています。
当然、シークレットも移行できません。

Rulesets や Teams などは設定を閲覧することができますし、API で取得・設定することも可能なため、それらを移行するのは(手動でも自動でも)難しくはないでしょう。AI に依頼すれば直接やったり、スクリプトを書いたりしてくれる気がします。
しかし、シークレットは簡単には閲覧することができず、リポジトリや Organization に設定されたシークレットを1つ1つ手動で再設定するのは、とても面倒です。
Organization の移動が大量にある場合は考えたくないですね。

でも、シークレットの中身を知る方法がないわけではありません。GitHub Actions のジョブの中では中身を使っているわけですから。
シークレットの移行が自動でできる可能性は 0 ではない。ということで作成をしました。

使い方

使い方はドキュメントにまとめてあるので、そちらを参照してください。
また、Skills も用意してあります。
gh-secret-kit をインストールしたのち、gh secret-kit skills install することでインストールできます。

仕組み
さて、仕組みですが基本は単純です。
移行元で実行されたジョブの中から移行先にシークレットを設定します。
ジョブからはシークレットの内容を知ることができるわけですから、これは実現可能ですよね。

しかし、対象のシークレットはワークフローに静的に記載されている必要があります。
なので、シークレットをリストアップしてワークフローを生成し、その生成したワークフローを push してそれを実行します。

ワークフローを実行する方法はいくつかありますが、デフォルトブランチにワークフローが必要なものと、トピックブランチにあれば良いものので大きく分けられます。
今回 GitHub のリポジトリ移行という目的があるので、デフォルトブランチを書き換えるのは避けたいです。CLI からワークフローを実行するのであれば workflow_dispatch が都合が良いのですが、これはデフォルトブランチにワークフローが必要なため、今回は pull_request イベントの labeled アクティビティで発火させるようにしています。
なぜ labeled なのかというと、任意のタイミングでコミットに紐づかずに再実行可能にしたかったからです。
(ちなみに、デフォルトブランチを変更することなく、workflow_dispatch を実行する方法はあるのですが、実装当時に知らなかったのでこのやり方になっています)

これで CLI からシークレット移行ワークフローを実行させることができるようになります。

ここで問題になるのがアクセス権限です。
移行元のアクセス権限は問題ないと思いますが、移行元に「移行先のシークレット設定が可能なシークレット」が存在しているとは考えにくいです。
このために設定するという手段もあると思います。gh-secret-kit では、どのシークレットを使うか指定できるようになっているので、そのケースにも対応はしています。
しかし、そのシークレットも移行対象となり移行先で消す必要が出てきます。(まぁ、そのための除外オプションもあるのですが)

そうではなく、移行担当者は移行元・移行先どちらの admin 権限を持っているはずなので、担当者の環境でジョブを実行し、担当者の gh auth token を使えば、移行に必要な権限を確実に得ることができるわけです。

GitHub Actions は Self-hoted runner として、好きな環境でランナーを起動することが可能です。ScaleSet API を使って CLI 実行者のローカルマシンでランナーを立ち上げ、専用のランナーラベルを指定してワークフローを実行します。
これにより、既存のランナーを使うことなく移行が可能になるため、開発に影響を与えずに移行が可能になりました。

さいごに
gh-secret-kit は Organization / Repository / Environments のシークレットを移行することが可能ですが、Agents / Codespaces / Dependabot のシークレットには対応していません。
Agents と Codespaces は対応できなくもないかも?しれないですが、Dependabot は無理なような気がしています。もしアイディアあれば教えてください。

あと、このブログを書いてて実はもっと簡単な手順で対応も可能な気がしてきたので、試してみようかなと思います。

これを使う機会はそうそうない気がしますが、誰かの役に立てば幸いです。




2025年9月10日水曜日

【GitHub Actions】export-ignore でアクションのサイズを小さくする小技

こんにちは。皆さん GitHub Actions のアクション作ってますか?
では、${{ github.action_path }} はご存知でしょうか? 
github.action_path は composite action の実行中に有効なプロパティで、アクションのリポジトリに含まれているファイルにアクセスするときに便利なやつです。

例えば、私が先日リリースした srz-zumix/labeler-action ではリポジトリにおいてある aqua の設定を使ってツールのインストールを行っています。
ブログズミ: 【GitHub Actions】actions/labeler 互換で on.pull_request 以外でも使えるアクション srz-zumix/labeler-action を作りました
ソースコード的にはこのあたりです。
https://github.com/srz-zumix/labeler-action/blob/main/action.yml#L43

実はこのアクションを作ったときに github.action_path に .git ディレクトリがないことに気づきました。てっきり checkout されていると思っていたのですが、実際には git archive されているようでした。

あまり使う機会はないかもしれませんが、git archive はリポジトリの内容だけを保存できる機能で、GitHub 上だと「Download ZIP」にあたります。


ところで、.gitattributes の export-ignore はご存知でしょうか? Git - Git の属性 (export-ignore)
これは archive に特定のパスを含めないようにできる属性です。例えば、成果物を提出する時なんかに便利な機能です。



さて、ここまで来たら想像がつきますよね?
そうです。アクションのリポジトリでも export-ignore を設定することで、アクションを使うときにダウンロードしてくるサイズをちょっと節約できます。


ちなみに、composite action 以外の action でも archive が展開されるのは同じです。
TypeScript でアクションを作ってる方は多いと思いますが、アクションが実際に使うのはコンパイル後の .js ファイルです。ソースである .ts ファイルやテストコードなどアクションの実行には不要なファイルがそこそこあります。
このようなアクション実行時に不要なファイルを export-ignore してみるのはどうでしょうか。試しに自作アクションで導入してみました。
srz-zumix/post-run-action


御覧頂いているように、不要なファイルを除外しつつ、問題なくアクション実行できています。

今回試した post-run-action はもともと小さなリポジトリなので、export-ignore の恩恵はほとんどないとは思います。ただ、ソースが大きかったり、テストデータが大きかったりする場合は多少変わってくるかもしれません。



今回はちょっとした小技の紹介でした。
(ちなみに export-ignore を確認したときに知ったのですが、export-subst でなんか面白い使い方できないかなぁと思った)

ではでは。

2025年9月1日月曜日

【GitHub Actions】actions/labeler 互換で on.pull_request 以外でも使えるアクション srz-zumix/labeler-action を作りました

actions/labeler 便利ですよね。
でもちょっと困ったことがありました。
過去の PR に対してルール適用をしようと思ったところ、ブランチ名ルールが pull_request イベント前提のコードになっていて、workflow_dispatch で PR 番号指定して実行したときに設定どおりにラベル付けできませんでした。

この問題の修正 PR を出してはいるんですが反応がないので、自分で作りました。

srz-zumix/labeler-action
使い方は actions/labeler とほぼ同じです。
labeler の設定ファイルと同じ設定ファイルが使えます。
labeler-action は `dot: false` には対応していないのですが、ラベルの色設定に対応しています。labeler はラベルがない場合にラベルを作成してくれはしますが、色がグレーになってしまうのでちょっと不便でした。

色指定は以下のようにします。
ci:
- any:
  - changed-files:
    - any-glob-to-any-file: '.github/*'
- color: '#7c0bb2'

aqua:
- changed-files:
  - any-glob-to-any-file: 'aqua.*.yaml'
- color: '#1E90FF'

documentation:
- changed-files:
  - any-glob-to-any-file:
    - 'docs/*'
    - README.md
都合が良いことに color の設定があっても actions/labeler では無視されてエラーにはなりません。

ちなみに labeler-action はツールを呼び出しているだけで処理の実体は srz-zumix/gh-label-kit にあります。こちらも私が作っているもので、GitHub のラベル関係の操作を行える gh-extension となっています。
この拡張機能の1機能として labeler コマンドを実装しています。
したがって、gh-label-kit を使っていただければ GitHub Actions を使わず、ローカル環境からでもラベル設定が可能になります。
その他にも gh 標準には(今のところまだ)ない機能が揃っているので是非使ってみてください。

また、今回は gh-extension を gh extension install するのではなく、aqua を使用してインストールしています。これは self-hosted runner のことをちょっと意識しています。
aqua はまだ使い始めて間もないので、もっと便利な使い方を実践していきたいです。


以上です。ではでは



2025年7月10日木曜日

【GitHub Actions】任意のスクリプトを Post 実行するアクションを作った


srz-zumix/post-run-action

リポジトリはこちちです。
機能としては run step と同等のことが Post タイミングで実行できるアクションです。

アクションには後片付けをするタイミングとして Post 処理が書けます。
よく使う actions/checkout も Post 処理で git config などを元に戻す処理がされています。
実行ログを見ていただくと、下図のように Post 処理が並んでいると思います。



このようにワークフローで手軽に Post 処理を記述ができようになる便利なアクションが post-run-action です。
もちろん post-run-action を使わずとも if: always() なステップを最後に追加すれば、後片付けをすることは可能です。

後片付けしたい処理と、後片付け処理を近くに書いておけるのがメリットでしょうか。
例えば、長いワークフローだと Post step が遠くて分かりづらいかもしれません。

      steps:
      - name: Checkout
        id: checkout
        uses: actions/checkout@v4
      - name: Do
        run: |
          echo "TODO"
      - name: Post Action
        uses: srz-zumix/post-run-action@v2
        with:
          post-run: |
            echo "Post run step"

      # ...

      - name: Post
        if: always()
        run: |
          echo "Post run step"

そのような場合には、アクション化してしまうことも1つ手段かと思います。
しかし、残念なことに現状 composite action で Post 処理が書けません!
JavaScript action なら Post 処理を書けますが、複数のステップをまとめてアクション化する場合、composite が書きやすくそれを選択しがちです。

そこで post-run-action を使います!
実は composite で Post 処理が書けないことをなんとかしたくて作ったのがこのアクションなのです。

post-run-action を使うことで好きなタイミングで後片付け処理をセットできるようになります。私が作成したアクションの中でも業務でよく使っているアクションの1つになります。
ぜひ使ってみてください。

では。


2023年5月28日日曜日

【GitHub Actions】Organization/Owner 配下にあるすべてのリポジトリをマトリックスにする

https://github.com/srz-zumix/github-actions-sample/blob/main/.github/workflows/owner_all_repo_matrix.yaml

name: Organization/Owner repo matrix
on:
  pull_request:

permissions:
  contents: read

env:
  GH_TOKEN: ${{ github.token }}

jobs:
  prepare:
    runs-on: ubuntu-latest
    outputs:
      repos: ${{ steps.get-repos.outputs.repos }}
    env:
      TARGET_OWNER: srz-zumix
    steps:
      - id: get-repos
        run: |
            # shellcheck disable=SC2016
            REPOS=$(gh repo list "${TARGET_OWNER}" --json nameWithOwner --template '[ {{ range $i, $e := .}}{{ if ne $i 0 }}, {{ end }}"{{ $e.nameWithOwner }}"{{ end }} ]')
            echo "repos=${REPOS}" >> "${GITHUB_OUTPUT}"
      - run: echo "${{ steps.get-repos.outputs.repos }}"

  main:
    runs-on: ubuntu-latest
    needs: prepare
    strategy:
      matrix:
        repo: "${{ fromJSON(needs.prepare.outputs.repos) }}"
    steps:
      - run: echo ${{ matrix.repo }} 

gh repo list でリポジトリをリストアップして、その結果を --template で json の配列に整形。
fromJSON で matrix にセットします。

gh 使うとこういったことが楽に実現できるので便利です。

今回は以上です。

2023年4月19日水曜日

【GitHub Actions】【reusable workflow / composite action】Enable Debug logging したときだけコンテキストをダンプする step を仕込む

 GitHub Actions の共通アクションやワークフローを書いていると、たまに失敗したときの状態をより詳しく知りたいことがあります。
今回はその一例として github コンテキストなど、GitHub Actions から提供されるコンテキストのデバッグログを仕込みたいと思います。

ところで GitHub Actions の VSCode 拡張が公式からリリースされました。
実はこれを使うとコンテキストやワークフローの候補が出るようになるので、大変便利になりました。
これによって、いちいちこのコンテキストからは何が参照できるんだっけな?と調べる必要が減りました。
※ event の詳細は 2023/4 時点では候補にでなかったので、まだまだ event の詳細は公式ドキュメント(webhook のドキュメントですが同じものが入ります)や実挙動を見て確認する必要がありそうです

ワークフローを書いてる最中はどういう変数があるかはわかりますが、実際にどのような値が入ってくるのかはドキュメントなどから想像するしかありません。
ローカル環境でワークフローを実行する nektos/act のようなツールもありますが、これらは非公式かつ挙動が完全一致するものではないので、実際にワークフローを動かして確認するのが現時点では一番確実です。

私は act の gh 拡張機能(gh-act)を開発しており、その動作確認をこめてコンテキストをダンプしてるので参考にしてみてください。


さて、ワークフローを開発している最中や、リポジトリ専用のワークフローであれば、なにか失敗したときの調査に役立ちますし、常にコンテキストをダンプする step を置いておけば良いかなと思ってます。(実際にそうしてることが多いです)

こんな感じです

    steps:
    - name: $github
      env:
        GITHUB_CONTEXT: ${{ toJson(github) }}
      run: |
        echo "${GITHUB_CONTEXT}"
  

一方、reusable workflow など共通化して多数のリポジトリから使用されるものの場合、機能とは関係のないダンプはいれづらいです。(気にしなくていいとも思ったりもしますが、なんか個人的には避けたかった)


GitHub Actions はワークフローが失敗したときにデバッグログを有効にして re-run できます。理想としてはデバッグログとしてダンプできたらいいなと思っておりました。


reusable workflow 側でデバッグログを有効にされていることをなんらかの方法で判別できればよかったのですが、環境変数やコンテキストでは判別できなさそうでした。
ただ、デバッグログを有効にした場合、最初に紹介した $github ステップの env の設定がダンプされていることに気づきました。

こんな感じ

そしてこの env の評価ですが、 if: false のように常に実行しないステップにしても評価はされました。


先程と同じ用に見えますが、前者は ✔ マークアイコンですが、後者は / マークでスキップされていることがわかります。

ここでようやく結論、タイトル回収です。
「if: false で常に実行しないステップを用意し、知りたい情報を env にセットしておく」
こうすることでデバッグログを有効にしたときだけ github コンテキストの内容を確認できました。この方法は github コンテキストに限らず使えます。


今回は以上です。


2023年2月22日水曜日

GitHub Actions で停止してしまったスケジュールワークフローをリストアップする

メインブランチに更新がない状態が続くとスケジュールで動くワークフローは無効化されます。
無効化される前に通知が来てリンクからワークフローのページを開いて「Enable workflow」を押す必要があるのですが、わりと忘れがちでいつの間にかワークフローが止まっていることがありました。
そして無効になってしまったあとは特に通知も来ないので、たまたま見に行ったときに気づくことがほとんど。
無効になってしまったワークフローを一覧できたらなーと思っていたのですが、gh でできそうだったのでやってみました。

一覧
gh repo list --json nameWithOwner --jq .[].nameWithOwner | xargs -I {} sh -c "echo {}; gh workflow list -a -R {} | grep disabled"

無効になっているワークフローは disabled_inactivity ステータスになっているのでリポジトリリストからワークフローリストを取得して grep しています。

Web で開く
gh repo list --json nameWithOwner --jq .[].nameWithOwner | xargs -I {} sh -c "echo {}; gh workflow list -a -R {} | grep disabled | grep -oe [0-9]*$ | xargs -I WID gh workflow view -R {} WID --web"

「名前 ステータス ワークフローID」が出力されるので末尾の ワークフローID を取得してブラウザで開くコマンドを呼び出します。

無効になっているワークフローのページが開くのでそこで「Enable workflow」ボタンを押せば有効に戻せます。

Enable にする
gh repo list --json nameWithOwner --jq .[].nameWithOwner | xargs -I {} sh -c "echo {}; gh workflow list -a -R {} | grep disabled | grep -oe [0-9]*$ | xargs -I WID gh workflow enable -R {} WID"

gh workflow enable でワークフローをコマンドラインから有効にすることもできるので、Web で開く部分を少し変えればワンライナーで全リポジトリのワークフローを有効に戻せます。

今回は以上です。では。

2022年12月27日火曜日

GitHub Actions の Composite Action で post 処理を実現する方法の訂正

GitHub Actions の Composite Action で post 処理を実現する方法

こちらの記事で「./」でパス指定すれば OK って書いたのですが、これは自分自身をチェックアウトしてたのでできたことでした。
このアクションを使う場合はアクションの実体は GITHUB_ACTION_PATH 環境変数の指す場所にあり、uses をパス指定する場合は workspace からの相対パスになるのでこの方法ではダメというわけです。

uses で env は使えないので(静的に解決される必要があるかな?使えれば env. GITHUB_ACTION_PATH で良かったのですが)、workspace の .github/ 配下に post-action のシンボリックリンクを貼って、そのパスを指定するようにしました。

https://github.com/srz-zumix/setup-service-jenkins/pull/27

ちょっと微妙な感じもしますが、他に回避方法思いつかなかったのでこうしました。
composite action でも早く post 処理できるようになるといいなー。
(post action 用の repo or branch 用意するのも考えたけど、コードが分離するのが嫌だったのでやめました。でも、指定したパスの shell script を post 処理で実行するだけの action はあってもいいかなーと思いました。)

以上。

2022年10月18日火曜日

【GitHub Actions】コンテキストダンプのススメ

GitHub Actions では github や job などのコンテキストから git の状態や PR の内容、ジョブの情報などが取得できます。
これらを利用してステップの条件をつけたり、処理を変えたりなどができます。
さて、このコンテキストですがどういったものがあるのかは、ドキュメントで確認できます。

コンテキスト - GitHub Docs

ただ、実際にどういった値が入っているかまではわからないですし、ランナーやジョブによって当然値は変化します。
なので、コンテキストをダンプするための repository を用意しておくととても便利です。
私は ci-spec repository でいろいろなイベントトリガーでダンプできるようにしてあります。
https://github.com/srz-zumix/ci-specs/blob/master/.github/workflows/events.yml
この情報って取れるのかな?って探すことが結構あるので重宝してます。


また、github context の json は nektos/act の入力イベントとしても使えるので、常にダンプしておくと便利かもしれません。。かも。。

今回は以上。
act のことは「ブログズミ: nektos/act で GitHub Actions のワークフローをローカル実行」と「GitHub Actions のローカル実行ツール(nektos/act)を便利にする gh extension を作った」で書いたのでよければ見て下さい。

2022年8月31日水曜日

nektos/act で GitHub Actions のワークフローをローカル実行

GitHub Actions で困る、というか面倒なのがワークフローのデバッグをするために都度 push してトライアンドエラーなところじゃないでしょうか?
単純に直列に step 並べるだけならそんなに困らないですが、steps.*.if 使ったり output 使って後続 step で利用しているような場合など、ちょっとしたミスで動かなかったりするのでできれば push するまえに確認できると嬉しいですよね。

あとはイベントによっては PR のときに確認できないことがあるので、マージしてからミスに気づくこともあります。
Release してみたらワークフロー失敗したってのは私も何回もやってます。そういう系は workflow_dispatch に対応しておくのがオススメ。

また、CI と同じことをローカルで実行したいということはよくあると思います。
CI サービスによってはローカル実行サポートしてることもありますが、GitHub Actions 公式には今の所ないので act を使います。

https://github.com/nektos/act

act pull_request とすると、 pull_request で trigger されるジョブが実行されます。
細かい使い方はドキュメント見ていただくとして、ここでは使ってみてわかった注意点などを書いておこうと思います。

最初に結論

最初にもっとも重要な注意点を書いておこうと思います。

act オススメしません!

補足すると「GitHub Actions と同じことをローカルでやりたい」のであれば act 使わずに Dagger とか Makefile とか shellscript とかなんでもいいので GitHub Actions のワークフローと処理を分離しておくことをおすすめします。
Jenkins のときと同じですね。

というわけでそのような目的がある場合は、この記事を読んでいないで処理の分離を始めましょう。

そうではなく、GitHub Actions のワークフローの方をローカルで検証したいときは act を使ってみるのはアリかもしれません。
記事の最後で私なりの利用ケースを考えてみたので興味のある方は最後までお付き合いいただけると幸いです。

ポイント
act の runner は hosted runner と同一ではない

act の runner は hosted runner よりも最小の環境で作られています。
なので hosted runner にはあるけど act の runner にはないものがあったりします。

より hosted runner に近いイメージも用意されていますが、とても大きいイメージなので注意してね、とのことです。
https://github.com/nektos/act#runners

↑にも書かれていますが、 -P ubuntu-18.04=nektos/act-environments-ubuntu:18.04 のように runs-on 指定の名前を置換してあげることができます。
このオプションを利用すると self-hosted runner 使っている場合の対応が簡単です。

act のときは〜をする・〜をしない

https://github.com/nektos/act#skipping-steps

やはりどうしても環境が異なっていたり、act でできないこともあり、act でそのまんまワークフローを実行するのは無理だったりします。
なので、そういう場合は if: ${{ !env.ACT }} のように ACT 環境変数で分岐させると良いです。

コンテキストの内容がすべて定義されない

act pull_request としても github context にはほとんどの情報が設定されません。
特に event は空っぽなので、 github.event.pull_request.head.sha とかを workflow 中に参照していると失敗します。
イベント情報などある状態で act 実行したい場合は、以下に書かれてるようにイベントの json ファイルをオプションで指定してください。

https://github.com/nektos/act#events

GITHUB_TOKEN は自動発行されない

https://github.com/nektos/act#github_token

はい。当たり前ですが自動では発行されないです。必要な場合は -s オプション使ってシークレットをセットしてください。

サービスコンテナは未対応

services の内容は無視されます。

設定ファイル

act で実行するにはそれなりにオプションで動くようにカスタマイズが必要だと思います。
お試し程度なら良いかもしれませんが、開発ワークフローで act を常用するようであれば、それらの設定をファイル(.actrc)に書き出しておくと良いと思います。
こうしておけば誰でも実行できるようになるはず。

https://github.com/nektos/act#configuration

ドキュメントに書かれてないこと
本家とは微妙に挙動が異なることがある

これはほんの一例ですが、公式ツールではないのでどうしても本家と違う挙動をすることがあります。
※下記の例は旧バージョンの話なのですでに修正されてます。

setup-ruby が ImageOS が想定外のために失敗する

act の提供してる image の ImageOS 環境変数が small ってなってて ruby/setup-ruby が失敗しました。どうやら setup-ruby は ImageOS 環境変数で実行環境を判断してるっぽいです。
step.*.env で ImageOS 環境変数を与えて上げること回避することはできますが、act 向けの変数になってしまうので微妙ではあります。

こんなときに便利かも
シークレットを設定する権限をもっていないとき

そういうケースってあんまりない気もしますが、なくもないのかなと思います。
シークレットが必要なワークフローの PR をしたけど、そのリポジトリのシークレットを設定する権限がない。 fork したとか、リーダーにしか権限ないとか?

シークレット追加してもらって検証というのもしづらいかなと思いますので、act -s で想定シークレットを渡してデバッグしておくといいかもしれません。

レアなイベントをトリガーにしている場合

pull_request イベントなら PR 出せば済む話ですが、workflow_dispatch とか release とか branch_protection_rule とかのイベントトリガーのワークフローをデバッグするのってめんどくさいです。
というのもイベントによってはデフォルトブランチにワークフローがあることが条件のものがあるからです。
ワークフローをトリガーするイベント - GitHub Docs

こういうやつ。

ですが、act 使えばこれらのイベントでトリガーされたときのデバッグが簡単になると思います。(env.ACT をみて dryrun な状態にしておくこと!)
最後に

act どうなんでしょうね?
本当に必要なケースってあんまりないような気もしてしまいます。

GitHub Actions のワークフローで書くことって大概が pull_request イベントだと思うし、それなら実際に動かしたらいいってなるし。

時間かかるからローカルがいい、処理をデバッグしたいって話だとワークフローとは別の話な気がするので act でなくても解決できるはず。

デフォルトブランチに入れなきゃ動作確認できないイベントはたしかに act があると便利そうではありますが・・果たして本当に楽になるのだろうか?


「デフォルトブランチに入れなきゃ確認できない」って部分は GitHub 公式でなんらか解決策を出してくれると嬉しいですね。

以上。

2022年8月9日火曜日

GitHub Actions の Composite Action で post 処理を実現する方法

GitHub Actions での処理の共有方法として action がありますが、現在この action は javascript と docker そして composite の  3  つの方法で作成することができます。
筆者は今から action 作るなら composite をおすすめします。
composite action は登場した当初は runs.steps[*].if や runs.steps[*].uses が使えなかったので、ちょっと力不足でしたが最新のバージョンであればこれらが使えるようになっており、action を作る上で困ることはほとんどなくなったと思います。

じゃあ、タイトルはなんなんだということになりますが、ちょっと凝ったことしようと思うと(他ではできるけど) composite ではできないこともあります。

それがタイトルに書いた post 処理です。
右のスクリーンショットは action に書ける Metadata syntax なのですが、composite だけ post に対応してません。(詳細はリンク先へ)


でも、大丈夫です。というのがこの記事。
いずれ公式で composite action にも post が対応されると思いますが、今の状態でも post 処理できます。


その前に。
post 処理とはどんなものかと言うと、ジョブのステップが全部終わった後に行う処理のことです。みなさんがよく使うであろう actions/checkout でも post 処理が行われています。

こんな感じ。
基本的には action で設定したものをもとに戻したり、docker コンテナを停止したりするのに利用されています。


では本題です。
composite action で post 処理を行うには・・・
post 処理ができる action を uses で呼び出す」ことで可能です!

つまり、「composite action は uses で他の action を呼び出せるので、javascript/docker action を呼べば良い」のです。

リポジトリが別になっちゃう?
いえ、大丈夫。 uses は相対パスで action を呼び出せます。

つまりこういうことです。

composite action の repository のサブディレクトリに javascript/docker action を配置して、それを composite action から呼び出し、呼び出した action の post 処理を composite action の post 処理の代わりにします。
「uses: "./resources/post-action"」 がその部分で、この action のメイン処理は空で、post 処理で起動したコンテナの終了をしています。

実際にこの書き方をした action のリポジトリはこちら。
https://github.com/srz-zumix/setup-service-jenkins


composite ではない action を使うことになるので、それはそれで問題があったりしますがネストされた action なので実はそのへんもなんとかなっちゃうかもしれないなと思ってます。(javascript action の default node version 問題とか)
(docker action は実行できない os があるので、この目的ではあまりオススメしません)


ざつにざーっと書きましたが、今回は以上となります。では。


2022年6月7日火曜日

Jenkinsfile の sh ブロックの shellcheck をする GitHub Action をリリースしました

https://github.com/srz-zumix/jenkinsfile-shellcheck

actionlint が run の内容に対して shellcheck してくれるのをみて、Jenkinsfile の sh にもしてほしいなと思って作ってみました。

一応それっぽくできたのですが、何点か既知の問題があります。

sh ブロックの検出は AstBuilder 使ってるので問題ないのですが、行継続のエスケープが展開されて一行になるので、行番号がズレてしまうのが問題です。

ちなみに上は Groovy の文字列の記述がどう展開されるかテストしたものです。
Groovy の文字列記述には複数種類があります。ダブルクオーテーション・シングルクォーテーション、それを3つつなげて複数行記述。「$/」と「/$」で囲うことでも複数行記述できます。このうちシングルクォーテーション以外は GString にあたります。($/~/$はエスケープがそのまんま展開されるのがダブルクオーテーションと異なります)

GString は「${HOGE}」のような変数を展開します。
Jenkinsfile で GString の場合に環境変数を参照する場合に ${env.HOGE} のように書くこともあるのではないでしょうか。
(GString は知らないと結構ハマりやすいところだと思います)

AstNode から getText すると GString は展開されて取得できるのですが、そのとき「${env.HOGE}」は「env.HOGE」として展開されます。
この挙動はそんなには問題ないですが、Jenkinsfile が実行されるときのそれとは異なるので注意。


実行時と異なるという点での問題はまだあります。
sh の引数には単一の文字列ではなく、文字列連結して渡すことも当然できるため以下のようなケースで正しく解析できません。

頑張ればできないことはないかもしれませんが、今は非対応です。

ちなみに GString でシークレット環境変数を使うと展開されてから評価されるので shell 実行時に環境変数展開されるようにすべきなのですが、その警告は Jenkins がしてくれるので jenkinsfile-shellcheck ではノータッチです。
(ジョブ実行時もしくは validate で検出可能)

issue や pull request お気軽にどうぞ。
では、今回は以上です。

2022年5月18日水曜日

GitHub Actions で export-ignore 指定したパスがワークスペースになくて composite action が実行できなかった話

なにが起きたか

workflow の中で composite action として .github フォルダに置いた action を実行しようとしたところで、パスが存在しなくて失敗してました。


こんな感じのステップ
      - name: report
        uses: ./.github/actions/composite/test-report
        with:
          report_paths: test/*.xml
        if: always()

この composite action はいろいろなジョブで使っていたのですが、なぜか一部のジョブだけ失敗してました。
失敗していたジョブの共通点としては container 指定していて、 runner 上ではなく in コンテナなジョブであることでした。

なぜ .github フォルダがないのか?

確認してみるとパス指定ミスでもなく本当に .github フォルダがありませんでした。
ないフォルダはそれだけではなく、いくつか存在しないパスがありました。

これ見て即座に git export の除外指定だなとわかりました。
大分昔に Release 時に不要なパスが含まれないようにしていたのでした。
(git export の使い方としてあっているのかは知らない)

git export の設定を修正して、リリースワークフローを変えれば解決はするのですが、本質的ではないので export 設定はこのままにし、調査を続行。

なぜアーカイブダウンロードになったか?

export-ignore は clone/checkout には影響がないはずですし、
checkout 後にこれらのパスを削除するようなことはないです。
そこで actions@checkout ステップのログを確認してみると

なせかアーカイブダウンロードしてました。(なぜ?)
よくよく見ると・・・

The repository will be downloaded using the GitHub REST API
To create a local Git repository instead, add Git 2.18 or higher to the PATH
って書いてありました。つまり、コンテナにインストールされている git のバージョンが古いということですね!
これでコンテナ使ってるジョブだけ失敗するのも腑に落ちました。
どうしたか

使用してたコンテナイメージを更新して、インストールされている git のバージョンを更新しました。
git がインストールすらされていないコンテナイメージもありましたが、それでもなんとかしてくれる actions@checkout 偉いなと思いました。

コンテナの git が古い・ない、かつ export-ignore してるというなかなか踏むことなさそうな条件ですが、誰かの参考になれば幸いです。
では。

2022年3月24日木曜日

GitHub Actions だけで Jenkinsfile の lint をする

 皆さん、 Jenkins 使ってますか?
私は仕事で使ってます。最近は GitHub Actions が使えるようになったので、脱 Jenkins を進めているのですが、まだまだ Jenkins とのお付き合いは続きそうな感じです。

ところで近年の Jenkins に久しぶりに触れているのですが、昔と大分変わってきた印象があります。
そのなかでも私は as Code に注力をしていっています。
Jenkinsfile を使ったジョブの定義は当然のことですが、JCasC (Jenkins Configuration as Code) を使った Jenkins そのものの as Code をしています。あとは JobDSL も使ってます。(もう GUI でぽちぽちしてジョブ作るのがしんどいなと思うようになってしまった)JCasC も JobDSL も便利なんでぜひ使ってほしいところですが、今回は Jenkinsfile の話です。

パイプラインの Validate

as Code をすると PR 出してレビューしてもらって、履歴も管理しやすいしとっても便利です。
さて、PR を出したとき Jenkinsfile の動作確認はどのようにしていますか?
もちろん「PR ブランチを指定してジョブを実行する」これでもいいです。
しかし、カッコの閉じ忘れだったり、しょうもない typo で時間を無駄にしてしまうことはないでしょうか?

そういうときは jflint が便利です。
Jenkins 2.0 (5): Jenkinsfileをコマンドラインからlintする - 生産性向上ブログ
Jenkins にはパイプラインの Validate してくれる API が備わっていますが、jflint はその呼出を簡単にできるようにしてくれたものです。(できれば公式の jenkins-cli.jar が対応してほしい)
jflint 自体は Jenkins の API を実行しているだけなので、Jenkins のインスタンスが必要になります。
通常は使っている Jenkins のインスタンスを挿せば問題ないです。
というか、そうでないと利用しているプラグインがインストールされていなくて Validate が失敗したりしてしまいます。

さて、ここで表題に戻ります。
GitHub Actions だけで Jenkinsfile の lint をする」
jflint を使った方法は Jenkins のインスタンスが必要ですが、ここでは利用している Jenkins には到達できない、もしくは汎用的・テンプレート的なリポジトリで対になる Jenkins インスタンスが存在しないと過程して GitHub Actions のみで lint します。
(※Jenkins インスタンスがあって到達可能ならそれ使ったほうがいいです)

GitHub Actions に Jenkins を起動する

GtiHub Actions ではサービスコンテナの機能があります。
テストするために DB など他のサービスがほしい場合に便利な機能です。

これを利用して Jenkins を起動し、サービスコンテナの Jenkins に Validate してもらいます。(Jenkins は使いますが GitHub Actions だけで完結します。Jenkins 使わずに Validate するのは相当しんどい。プラグインがあるしカバーしきれない…)

サービスコンテナは↓な感じで起動できます。
セットアップウィザードを無効にしないと入力待ちで止まってしまうので、このオプションは必須です。
起動したコンテナのIDは「job.services.サービス名.id」で取れるのでこれを使って steps などで操作することもできます。

    services:
      jenkins:
        image: jenkins/jenkins:lts-jdk11
        credentials:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
        env:
          # セットアップウィザードを無効
          # disable setup wizard
          JAVA_OPTS: -Djenkins.install.runSetupWizard=false
        ports:
          - 8080:8080
          - 50000:50000
  

上記例では起動したコンテナに localhost:8080 でアクセスできるので、この URL で jflint を実行すると Jenkinsfile の lint が GitHub Actions だけでできるようになります。(※これだけじゃならない)

プラグインをインストールする

さて、ここで1つ問題が発生します。起動した Jenkins はプラグインが空っぽで Validate すらできない状態になってしまっています。

デフォルトプラグイン、推奨プラグインをインストールする必要があります。
さらに、Validate する Jenkinsfile によっては追加でプラグインのインストールが必要です。
プラグインのインストールは jenkins-cli.jar の install-plugin で可能なので、これをサービスコンテナの Jenkins に対して実行すればインストールできます。

java -jar jenkins-cli.jar install-plugin -s http://localhost:8080 ws-cleanup

こんな感じですね。サービスコンテナから jenkins-cli.jar をダウンロードして実行するか、コンテナに対して exec すればできると思います。

setup-service-jenkins アクション

さて、GitHub Actions で Jenkins を起動して jflint することができそうなことはわかりました。しかし、プラグインのインストールが必要でちょっとめんどくさいです。
なので、アクションにしてみました。

https://github.com/srz-zumix/setup-service-jenkins

サービスコンテナの記述はそれぞれ必要になりますが、コンテナ ID を指定してこのアクションを実行すると必要なプラグインを Jenkins にインストールするのと、 jenkins-cli のラッパースクリプトを agent にインストールします。

      - uses: srz-zumix/setup-service-jenkins@main
        with:
          id: "${{ job.services.jenkins.id }}" # サービスコンテナの ID (job.services.サービス名.id)
          port: 8080 # ポート番号(サービスコンテナのポート設定と合わせる)
          install_suggested_plugins: true # Suggested Plugins をインストールするかどうか
          plugins_file: JenkinsPlugins.txt # 追加でインストールしたいプラグインのリストファイル
  
公式イメージからのセットアップ

例えば公式のイメージを起動した場合はプラグインが空っぽなので、install_suggested_plugins オプションを true にしてデフォルト推奨プラグインをインストールするか、プラグインが列挙されたファイルを plugins_file に指定してインストールしてください。
デフォルト推奨プラグインはこちらのファイルに列挙したものになっています。
(Suggested Plugins をインストールした状態から cli でダンプ、加工したもの)
https://github.com/srz-zumix/setup-service-jenkins/blob/main/resources/DefaultJenkinsPlugins.txt

公式イメージを使う場合はセットアップウィザードを無効にすることを忘れないでください。
現状アクション側で対応してないので、冒頭に書いたようにサービスコンテナを起動するときのオプションが必須です。

カスタムイメージからのセットアップ

例えば、実際に使用している Jenkins のベースイメージがあり、プラグインなどセットアップ済みであれば特にプラグインのインストールは不要になると思います。
おそらく公式イメージよりも都合がよいと思うのでこちらのほうがおすすめですが、クリーンな状態からテストしたい場合などは公式イメージを使うほうがおすすめです。
適宜選択してください。

jenkins-cli.jar のラッパースクリプト

このアクションを使用すると agent マシンにラッパースクリプトの jenkins-cli をインストールします。こちらはサービスコンテナの Jenkins を挿すようにしただけのラッパーです。
CLI でそこそこ自由に Jenkins を操作できるのでワークフローを作る際に使ってみてください。

GitHub Actions だけで Jenkinsfile の lint をする

最終的にできあがったワークフローはこちらです。
https://github.com/srz-zumix/github-actions-sample/blob/main/.github/workflows/reviewdog-jflint.yml

公式イメージ + suggested plugins だと ansiColor プラグインがインストールされないので、jflint で指摘されているのがわかりますね。

今後の展望

サービスコンテナで Jenkins が起動し、プラグインインストールや CLI での操作が可能になりました。今後は JCasC をロードさせて Jenkins の設定を読み込ませた状態でジョブやスクリプトを実行してみたいです。
また、Shared Library のテストが書け、実行できると思っているのでそのへんも手を付けたいです。

以上。


2022年1月20日木曜日

GitHub Actions の action 開発者にお願いしたいメジャーバージョンアップするタイミング

 GitHub Actions とっても便利ですね!
個人開発ではもちろんのこと、会社でも便利に使っています。
使うだけではなく action を作ったりもしてます。

さて、本題に入りますが、
会社の GitHub が Enterprise のため github.com の方にはあるが Enterprise にはまだない機能や環境を使われると action が動かないことがあります。
幸い使用する action のバージョンを固定することで回避できるのですが、できることならそのような変更時にはメジャーバージョンアップしてほしいなと思ってます。
(SemVer 採用してる前提ですが)メジャーバージョンでバージョン固定しているケースが多いため、マイナーバージョンアップだと管理下の全リポジトリに対してバージョン固定をして回らないといけなくてすごく面倒くさいのです。。
メジャーバージョンアップならこのような破壊的変更を自然に避けられるので、何卒。
(まぁ Enterprise 使ってないとそういった事情はわからないので仕方がないとは思ってますけど)

実際にあった例としては、

  • 「using: "composite"」
    Composite Action が Enterprise でまだ使えなくて動かなくなった。
  • 「using: "node16"」
    Enterprise はまだ「docker」か「node12」しか使えない状態だったので動かなくなった。(こっちは Enterprise のアップグレード以外に方法があるなら知りたい)
がありました。
とりあえず using 変えると Breaking Change になるようにするのが良さそうですね。

この辺を自動で対応するなら using の差分があったらラベルつけるとかできればなんとかなりそう。(actions/labeler だとファイル単位なので別のやり方が必要)
なんかいい方法見つけたらブログで書きたいと思います。

以上。

2021年12月23日木曜日

GitHub で草生やさないようにする

 GitHub で「草を生やす」方法はすぐ出てくるのですが、「草を生やさない」方法がすぐに見つからなくて困っていたので備忘録。

というのも、GitHub Actions で定期的に commit をするワークフローがあるのですが、そのコミットが contribution に含まれてしまってました。 
問題の workflow => https://github.com/srz-zumix/wandbox-status/actions(今は修正済み)
このワークフローでは、修正前は自分の GitHub アカウントの noreply メールアドレスを使ってました。

git config --local user.name ${{ github.actor }}
git config --local user.email ${{ github.actor }}@users.noreply.github.com
筆者は noreply ではなく個人のメールアドレスを登録してるのでカウントされないと思ってたのですが、そうではなかったみたいです。
コントリビューションがプロフィールに表示されないのはなぜですか? - GitHub Docs
※「草が生えない」で困ってる人は↑の公式ドキュメントを読むのをおすすめします。

というわけで、user.email をなんかテキトーなメールアドレスにしたら良いのですが、ちょうど良さげな記事があったのでこれにしました。

GitHub Actionsのボットがコミットしたようにアイコンをつけるにはメールに「github-actions[bot]@users.noreply.github.com」を指定すれば良い - nwtgck / Ryo Ota

git config --local user.name github-actions[bot]
git config --local user.email github-actions[bot]@users.noreply.github.com
これで無事、定期ジョブの自動コミットで草を生やさないようにできました。
(濃い草が自動コミットも含まれていた時期)


めでたしめでたし。

2021年12月9日木曜日

Facebook 改め Meta 社の静的解析ツール Infer を GitHub Actions でかける

この記事は「C++のカレンダー | Advent Calendar 2021 - Qiita」の9日目です。

Infer とは

Infer は Facebook 社改め Meta 社が作った静的解析ツールです。
今回は C++ Advent Calendar ということで C++ の静的解析ツールとして紹介しますが、Infer 自体は OCaml で書かれています。
また、C++ の他に Java/C/Objective-C の解析も可能です。

C++ の静的解析ツールというと Cppcheck や Coverity 、コンパイラ付属のものがあったりします。筆者はこれまでこれらのツールを使ってきました。
Infer は 2015 年にOSS化して公開されたのですが、ずっと使ってみたいと思いつつ機会がありませんでした。

今回こうして記事にしているのは、仕事で必要になったからとか趣味でやる気になったからではなく、社名が変わったからネタとして触ることにしました。
理由はともあれ、以下で紹介していきます!

ローカル環境で使う場合

本記事は表題どおり「GitHub Actions」で Infer を使う手順を紹介しますが、ローカル環境で実行する場合も軽く触れておきます。
まず大事なこととして、Windows 非対応です!
Mac の場合は brew install infer でインストールできます。Linux の場合はビルド済みバイナリをダウンロードするか、ソースコードビルドで使うことができます。Docker という手もあります。
詳しいことは公式の「Getting Started with Infer」を見てください。

セットアップできたら「infer run -- ビルドコマンド」のようにコマンド実行すると以下のように結果が出ます。

ビルドコマンドは対象によって変わると思いますが、コンパイラー以外にも cmake や make 、mvn などのビルドツールにも対応しています。

ビルドコマンドが bash script になっているような場合はキャプチャーするコマンドを認識できないので、--force-integration オプションで教えてあげてください。
対応している integration は --force-integration オプションのヘルプで確認できます。
e.g. infer run --force-integration clang -- build.sh

GitHub Actions で使う

では、ここから本題です。
GitHub Actions で Infer を使うために、Setup Infer action (srz-zumix/setup-infer) と Infer reviewdog action (srz-zumix/reviewdog-action-infer) を作成しました。

setup-infer

Infer を現在の環境にセットアップするアクションです。
当然ですが Windows は非対応です。また Mac の場合はバージョン指定はできず、 brew install で取得できるバージョンがインストールされます。
(要望あれば対応しようかと思いますので、issues へどうぞ)

reviewdog-action-infer

Infer の結果を reviewdog を使って PR にコメントするアクションです。
Infer の実行結果が入っている infer-out から result.txt を参照し、reviewdog を使って PR に問題をコメントします。


なぜ action を分けたのか

最初は Infer インストールや解析込みの action を書こうと思ったのですが、ビルドツールや環境はユーザーによってバラバラで、action 側ですべてに対応するのは難しいと考えてこのようになりました。

Infer の実行

上記2つの action は infer での解析処理をしませんので、ワークフローで適宜呼び出してください。
個人開発してるテストフレームワーク(iutest)の例を記載しておきます。

  infer:
    runs-on: ubuntu-latest
    needs: prepare
    steps:
      - uses: actions/checkout@v2
      - uses: srz-zumix/setup-infer@v1
      - name: infer
        run: |
          infer -- make -C test IUTEST_USE_PYTHON=0
      - name: Check Infer report
        uses: srz-zumix/reviewdog-action-infer@v1
        with:
          reporter: github-pr-review
   
結果

iutest のワークフローの結果はこちらです。
静的解析なしだと 10 分くらいのテストが、Infer ありだと 25 分弱と少し時間がかかってますが、まぁ趣味開発なので許容範囲です。

速度向上

Recommended flow for CI | Infer」こちらで CI 向けのおすすめ実行方法が書いてあります。うまくキャッシュできるのであれば --reactive オプションでキャプチャーした情報を再利用すれば早くなると思います。
reportdiff は reviewdog で同等のことができるのでどちらでも。

また --changed-files-index オプションで差分ファイルのリストを指定すれば、そのファイルの解析だけが行われるため、速度向上可能です。
ただし、C++ の場合はヘッダーファイルを指定しても解析されません。.cpp ファイルを指定しないとダメです。(※ --changed-files-index は analyze 時に有効なので capture 時間の短縮にはならない)

Infer capture/analyze TIPS
capture/analyze 中にクラッシュする場合

--skip-analysis-in-path で除外指定できるのでそれをおすすめします。
-g オプションでデバッグモードになるので原因調査ができるかもしれませんが、ストレージを圧迫するかもしれません。
(3,000 弱のソースコードファイル数からなるプロジェクトでやったら 600GB 越えたあたりでディスクフルになって PC 自体が落ちました。。)

解析途中でエラーが出る場合

--keep-going オプションを付けると続行可能です。

compile_commands.json の場合 --clang-blacklisted-flags/--clang-blacklisted-flags-with-arg は効かない

そのまんまです。特に xcodebuild の場合 infer が使う clang が知らないオプションを使ってることがあり、「error: unknown argument: '-index-store-path'」のように失敗していまいます。 infer はデフォルトで  --clang-blacklisted-flags-with-arg に -index-store-path が入ってますが、 compile_commands.json から capture をする場合は --clang-blacklisted-flags(-with-arg) オプションは考慮されないので、json ファイルの command から削除してください。

--continue-analyz

仕事のプロジェクトに Infer 掛けてみたら analyze でクラッシュするわ、エラー起こるわ、なんか応答なくなるわ、そもそも解析時間がクソ長いわ、で辛かったんですが、--continue-analyz オプションつけると続きから解析してくれるので作業が無駄になりません。
(最初に知りたかった)

.inferconfig にオプションを書ける

infer のコマンドラインオプションは .inferconfig ファイルに書いておくことができます。
ファイルの中身は JSON 形式でオプションから -- を除いた名前をキーに設定をします。

例えば、上記で紹介した --skip-analysis-in-path や、 infer の clang にインクルードパスを追加する場合は以下のように書けます。

{
    "skip-analysis-in-path": [
        "path/to/lib/xxx/src",
    ],
    "Xclang": [
        "-I /path/to/dir/include",
    ]
}
まとめ

静的解析ツールは1つかければ十分というものではないので、ぜひ試してみてください。

以上。

2021年11月24日水曜日

master/main 混在している git submodule すべてをデフォルトブランチ最新にする

Git - サブモジュール

git submodule update --remote

以上!


下書き終えて、清書したら公開できる状態にしてあったのですが、git コマンド一発で解決することがわかったのでこの記事の↓↓の方の内容は読まなくて OK です。
でも、この過程ももったいないので残しつつ公開することにしました。
こういうときに Zenn のスクラップが便利なんだろうなーと思いました。



 GitHub のデフォルトブランチが master から main に変わって大分経ちました。
筆者も切り替わってから設定を master に戻すことはせず使ってきましたが、たまーに GitHub Actions の branches 指定を master/main で間違うくらいで特に困ってはいませんでした。

筆者の場合は、既存のリポジトリは今までのまま master としており、新規は main がメインブランチ(デフォルトブランチ)という感じになっています。
この状態の方も結構多いのではないでしょうか。

今までは特に困ってなかったのですが、ついに面倒くさい状態になったので備忘録を残しておきます。

なにが起きた

master がデフォルトブランチのリポジトリに複数のサブモジュールがぶら下がっているリポジトリがありました。
サブモジュールも含めてすべてデフォルトブランチが master でした。
ところが、ここに新規作成した新しいリポジトリをサブモジュールに追加したことで、main がデフォルトブランチのサブモジュールが増え、master/main 混在状態になりました。

でも、これだけであれば、まぁ git 操作時にうち間違えて面倒くさいってくらいだと思います。

サブモジュールの自動更新ジョブが止まった・・

問題が起きたのはサブモジュールの自動更新ジョブでした。
このジョブは毎日サブモジュールをデフォルトブランチ最新にし、commit/push するというものでした。
このジョブを作成した当時はデフォルトブランチは master だけだったので、特に気にせず master から pull してきてました。
はい。そうです。
main がデフォルトブランチのサブモジュールができたことで失敗するようになってしまいました。。

どうしたか

まず main → master を考えましたが、時代に逆行するのでやめました。(サブモジュール増えるたびに踏み抜きそうだったし)
次に master → main を考えましたが、これも面倒くさいのでやめました。

デフォルトブランチは検出することが可能なので、検出する action を書いたりもしましたがサブモジュールだと使いづらいというか、無理な感じだったので最終的にはデフォルトブランチを git submodule foreach 時に検出するようにしました。

コマンドはこんな感じです。

git submodule foreach "git remote show origin | grep 'HEAD branch' | awk '{print \$NF}' | xargs -I{} git pull origin {}"

デフォルトブランチを知る方法は他にもあるので調べてみてください。

では、今回は以上。



2021年10月22日金曜日

npm-groovy-lint + reviewdog で Jenkins Shared Library の PR チェック

 reviewdog は様々なツールの出力から PR に対してレビューをつけてくれるとても便利なツールです。私も GitHub Actions で reviewdog 使って shellcheck とか lint とかをよくかけています。

今回は Jenkins Shared Library の groovy スクリプトの lint をしたいと思い、npm-groovy-lint + reviewdog の GitHub Actions を用意したので紹介します。

reviewdog とツールがセットになったアクションがたくさんありますが、
npm-groovy-lint のアクションはなかったので作るか、アクション側で書くかのどちらかになります。
今回はアクション側で対応したいと思います。

.reviewdog.yml

reviewdog は .reviewdog.yml に runner 情報(実行コマンドや出力フォーマット)を書いておくと、-runners オプション指定で簡単に実行できるようになるので、その方法を使います。

作成した .reviewdog.yml がこちらです。

runner:
  npm-groovy-lint:
    # cmd: npm-groovy-lint # (required)
    cmd: npm-groovy-lint -o log.txt && cat log.txt
    errorformat: # (optional if you use `format`)
      - '%-P%f'
      - '%*\s%l%*\s%tnfo%*\s%m'
      - '%*\s%l%*\s%tarning%*\s%m'
      - '%*\s%l%*\s%trror%*\s%m'
      - '%-Q'

コマンド指定のところで一度ログファイルに出力しているのは、色付き出力されたものを reviewdog に認識させるのが面倒だったためです。

github/workflows/reviewdog.yml

続いて、GitHub Actions のワークフローです。
こちらは npm-groovy-lint を実行する環境を整えつつ、reviewdog を実行するワークフローになっています。

name: GitHub Actions - reviewdog
on:
  pull_request:

jobs:
  groovylint:
    runs-on: ubuntu-latest
    container:
      image: docker://nvuillam/npm-groovy-lint
      credentials:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    steps:
      - run: apk add curl git
      - uses: reviewdog/action-setup@v1
      - uses: actions/checkout@v2
      - name: Run reviewdog
        env:
          REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          reviewdog -reporter=github-pr-review -runners=npm-groovy-lint

npm-groovy-lint を実行するのに、公式のコンテナ上で実行するのが楽だったのでそのようになっています。このコンテナには reviewdog が実行するために必要になる curl と git が入ってなかったので、はじめに追加をしてます。

結果

これでセットアップ完了です。
以下のように npm-groovy-lint の結果をレビューコメントしてくれるようになりました。



2021年10月8日金曜日