tech.guitarrapc.cóm

Technical updates

はてなブログワークフロー利用の課題と暫定対応

以前、GitHubとはてなブログを連動させているを書きました。はてなブログ提供のボイラーテンプレートを今も使っていますが、はてなワークフローは運用していく中で直接使わないケースも出てきたのでメモです。

はてなブログのワークフロー想定と使い勝手

はてなブログのボイラーテンプレートは、はてなが提供しているReusable Workflow hatena/hatenablog-workflowsを使っています。はてな管理のワークフローが実処理を担っているため、利用者はボイラーテンプレートを使うだけで済むという方針ですね。

実際割とよく機能するのですが、私はいくつかのワークフローはコピー&ペーストしてきて自前管理で運用しています。

はてなワークフローを使い続ける課題

はてなワークフローを使ってみると、いくつかの課題が見えてきました。以下に挙げるものは、私が実際に運用していて感じたことです。

ワークフローがタグ指定

hatena/Hatena-Blog-Workflows-Boilerplateとhatena/hatenablog-workflowsは、共にReusable Workflowやアクションをタグ指定しています。昨今のSHA指定が推奨される流れを考えると、タグ指定はセキュリティやメンテナンスの観点で課題があります。ボイラーテンプレートのREADMEを見るとworkflowの変更は原則 Reusable workflows を変更するため基本的には更新は不要ですと書いてあり、v1タグを指定している意図が分かります。

はてなブログのバージョン

タグ指定は、例えば次の利用シーンで課題があります。

  1. Reusable Workflowが使っているアクションで脆弱性があった時にユーザーは気づけず回避が難しい
  2. はてなブログワークフロー自身がSHA固定するプラクティスから外れている

先日のtj-actions/changed-filesの脆弱性CVE-2025-30066が発表されたとき、はてなブログのボイラーテンプレートはこれをタグで指定したため影響を受ける状況でした。脆弱性発生が土曜、SHAに切り替える修正は月曜に入ったのですが、はてなが管理しているため土日は修正されないままでした。Issueで脆弱性共有はあげたものの、PRをあげても週末にマージされないのは分かっていたためこのタイミングで私は自前ワークフローへの変更に切り替えました。

サードパーティアクションはSHA指定されたものの、はてなブログのボイラーテンプレートからワークフロー参照はv1タグを使っておりSHA指定されていません。このため、はてなブログのワークフロー自身が同様のCVE書き換えされた場合、ボイラーテンプレートを使っているユーザーは影響を受けることになります。

ワークフローやアクションの修正

hatena/hatenablog-workflowsの処理に手を入れたいとき、はてな側の方針とやりたいことが一致なければ変更が受け入れられないでしょう。例えば私はtj-actionsを使わないポリシーに変えましたが、はてなブログのボイラーテンプレートはtj-action/changed-filesをそのまま使う方針です。こういった方針の違いは当然ありますし、その場合はフォークするか自前でワークフローを持つしかないでしょう。それはそういうものです。

ボイラーテンプレートでの利用以上の利用想定がなさそう

これはAPI設計の話ですが、はてなブログのワークフローはボイラーテンプレートの利用しか想定されてなさそうです。

これは、ボイラーテンプレートにないワークフローの再利用は試されていなさそうな空気を修正PRから感じています。 この修正PRは、create-draftワークフローがcreate-draft-pull-requestアクションを呼び出す際の修正に関するものです。create-draft-pull-requestアクションはinputtitleを受け取りますが、ボイラーテンプレートではgithub.event.inputs.titleを指定していました。このため、アクションのtitleは使われず、呼び出し元のcreate-draftワークフロー呼び出し時のtitleが使用される仕様になっていました。これは、設計上の意図と異なる挙動である可能性が高いと考えられます。他のワークフローも呼び出しやinputsが柔軟ではないことから、ボイラーテンプレートの利用しか想定されていないと推測されます。

uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7
env:
  OWNER_NAME: ${{ steps.set-owner.outputs.OWNER_NAME }}
  ENTRY_ID: ${{ steps.set-entry-variables.outputs.ENTRY_ID }}
  PREVIEW_URL: ${{ steps.set-entry-variables.outputs.PREVIEW_URL }}
with:
  title: ${{ github.event.inputs.title }}
  branch: draft-entry-${{ env.ENTRY_ID }}
  body: |
    ## ${{ github.event.inputs.title }}

    省略

アクションに渡したtitleを使うには次のようにinputs.titleを指定する必要があります。

    - name: create draft pull request
      uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7
      env:
        OWNER_NAME: ${{ steps.set-owner.outputs.OWNER_NAME }}
        ENTRY_ID: ${{ steps.set-entry-variables.outputs.ENTRY_ID }}
        PREVIEW_URL: ${{ steps.set-entry-variables.outputs.PREVIEW_URL }}
      with:
        title: ${{ inputs.title }}
        branch: draft-entry-${{ env.ENTRY_ID }}
        body: |
          ## ${{ inputs.title }}

          省略

暫定対応

私の運用では、ボイラーテンプレートをフォークして運用するのではなく、コピー&ペーストしてファイル名の先頭に_をつけて運用しています。自分のポリシーと合わないものだけをコピーして修正、あとはボイラーテンプレートのものを使うという運用です。ポリシーは次の通りです。

  • 自分が使いたくないアクションを差し替える
  • できないことをできるようにする
  • hatenablog-workflowsもSHA指定しつつ自動更新する

自分が使いたくないアクションを差し替える例

例えば、hatenablog-workflowsから.github/workflows/push-published-entries.yamlワークフローをもってきて.github/workflows/_push-published-entries.yamlとして保持しています。中で他のワークフローを参照していたらそれももって来る感じです。もともと参照していたワークフローはコメントアウトして、いつでも戻せるようにしておきます。

# BEFORE: hatena/hatenablog-workflows | .github/workflows/push-published-entries.yaml
name: "[Reusable workflows] push published entries"

on:
  workflow_call:
    secrets:
      OWNER_API_KEY:
        required: true

jobs:
  upload-images:
    if: github.event.pull_request.merged == false
    uses: hatena/hatenablog-workflows/.github/workflows/upload-images.yaml@4cb2032c9665ad3b0eba9835182e2d23a1d49a81 # v1
    secrets:
      OWNER_API_KEY: ${{ secrets.OWNER_API_KEY }}



# AFTER: guitarrapc/blog | _push-published-entries.yaml
name: "[Reusable workflows] push published entries"

on:
  workflow_call:
    secrets:
      OWNER_API_KEY:
        required: true

jobs:
  upload-images:
    if: github.event.pull_request.merged == false
    # uses: hatena/hatenablog-workflows/.github/workflows/upload-images.yaml@v1
    uses: ./.github/workflows/_upload-images.yaml
    secrets:
      OWNER_API_KEY: ${{ secrets.OWNER_API_KEY }}

これはupload-images.yamlがtj-actions/changed-filesを使っているため、私のポリシーに合わないからです。変更した際は、外部アクションをすべてSHAに変更しつつ、tj-actions/changed-filesからdorny/paths-filterにしていました。以下は、現在(左)とhatenablog-workflows(右)の差分です。

upload-images.yaml

できないことをできるようにする

例えば、.github/actions/create-draft-pull-request/action.yamlはPRボディが固定文字になっています。PULL_REQUEST_TEMPLATE.mdを指定して持ってくるか、文章を変更するかで悩みましたが、後者にしました。本家の1.3.8でPULL_REQUEST_TEMPLATE.mdがあれば指定できるようになるPRが取り込まれているので、1.3.8が出たら戻す予定です。

hatenablog-workflowsもSHA指定しつつ自動更新する

ユーザーがhatenablog-workflowsワークフローを固定するときも、v1タグで運用する想定なのはちょっと微妙です。初めからSHA指定にしておいてDependabotで自動更新するようにテンプレート展開すれば、ユーザーは自分で更新する手間を最小にしつつワークフローを更新するか選択できます。

私は次のようにして、npmとGitHub Actionsの両方をDependabotで更新するようにしています。これにより、SHA指定しつつも自動更新が可能になります。ボイラーテンプレートでもGitHub Actionsの更新をする.github/dependabot.yamlが追加されればタグ指定からSHA指定に変更できそうですが、現状はSHA指定のままです。

# ref: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly" # Check for updates to GitHub Actions every week
    ignore:
      # I just want update action when major/minor version is updated. patch updates are too noisy.
      - dependency-name: "*"
        update-types:
          - version-update:semver-patch
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly" # Check for updates to GitHub Actions every week
    ignore:
      # I just want update action when major/minor version is updated. patch updates are too noisy.
      - dependency-name: "*"
        update-types:
          - version-update:semver-patch

まとめ

hatena/hatenablog-workflowsは多くの人が使っていて、ワークフローとして想定があるのでなかなか修正を出しにくいものもあります。API的に問題ない場合はこれからも提示していきますが、合わない割り切って手元管理でいい気持ちもあります。徐々に良くなってきているので、今後も貢献できるものはしたいです。

参考