textlintのルールに文章中のリンク先URLがアクセスできなくなってないかをチェックするtextlint-rule-no-dead-linkというルールがあります。

textlint-rule-no-dead-linkは実際にURLにリクエストを送ることでアクセスできるかをチェックするため、URLの数が多くなるとものすごく時間がかかります。 また、GitHubのように同一IPからのアクセスが連続すると429 too many requestsなどのエラーを返すサイトもあります。 textlint-rule-no-dead-linkRetry-Afterヘッダを見てリトライにも対応していますが、このリトライの間隔が長いサイトもあるため、リンク切れのチェックはコミット時にやるのには向いてない作業と言えます。

GitHubでは、GitHub Actionsを使ってschedule実行に対応しています。 一方で、scheduleで毎日特定の時間に実行しても、その結果の保存先をどうするかという問題がありました。

最近のGitHubではcode scanningという機能があります。 code scanningDependabotなどのセキュリティアラートとほぼ同じ仕組みとなっていて、アラートをServerityやコミットに紐付けて管理できます。 Dependabotと異なるのは、SARIF形式でLintなどのチェック結果をアップロードすれば、任意のチェック結果をcode scanningに表示できるようになっています。

Code Scanning

この仕組みを利用して、textlintのチェック結果をcode scanningに表示することもできます。

リンク切れの結果をcode scanningにアップロード

具体的には、次のようにtextlinttextlint-rule-no-dead-linkを利用するように設定します。

{
  "rules": {
    "no-dead-link": true
  }
}

この設定をして、GitHub Actionsでtextlintのチェック結果をSARIF形式にして、code scanningにアップロードするだけです。

name: Link Check
on:
  workflow_dispatch:
  schedule:
    - cron: '45 15 * * *'

permissions:
  contents: read
  security-events: write

jobs:
  test:
    runs-on: ubuntu-latest
    name: Link Check
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm ci
      - run: npx textlint -f @microsoft/eslint-formatter-sarif -o textlint.sarif || exit 0 # workaround https://github.com/textlint/textlint/issues/103
      - name: Upload SARIF file
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: textlint.sarif
          category: textlint

ESLintのformatterは大体textlintでも動くので、@microsoft/eslint-formatter-sarifをそのまま利用しています。

こうするとリポジトリのSecurityタブで、リンク切れの結果を確認できるようになります。

code scanningのメリット

code scanningは、重複チェックをしてくれるため、同じ結果を何度アップロードしてもできる項目は一つです。 GitHub Issuesを作るような仕組みだとこのチェックは自前で書く必要があります。

また、Dependabotと同じく結果からIssueを作成できたり、誤検知なので無視することも可能です。 code scanningの結果はコミットと紐づけることもできる(scheduleではなく、pushやpull_requestで回す)ので、どのコミットから起き始めた問題なのかも紐付けできます。

Details

code scanningは、リンク切れなどの不確実性があるチェックをCIで回すときに相性がいい仕組みです。 確実に落ちる落ちないがはっきりしているものは、PRを出すときにCIを回すのが良いですが、不安定なものはPR時に回すとノイズとなります。 そのため、時間がかかりすぎたり確実性が低い処理を毎日定時で回して、その結果をcode scanningに載せるだけでもカバーできる範囲が広がります。

このようにcode scanningは、セキュリティ以外の用途でも結構便利です。 code scanningはPublicリポジトリなら無料で利用できますが、PrivateリポジトリだとGitHub Advanced Securityがないと利用できないのが残念なポイントです。