理系学生日記

おまえはいつまで学生気分なのか

GraphQL SchemaのLintと、GitHub ActionsでのLint実装

GraphQLに本格的に触れ出しました。新しい技術に触れるとき、やはり優先して取り組むのがLintや静的解析回りです。 GraphQLのスキーマにもLintをかけたい、GitHub Actionsでチェックしたいなと考え始めました。 graphql-schema-linterがそのものズバリのライブラリだったので、これをGitHub Actionsと組み合わせます。

Lintのルール

graphql-schema-linterには組み込みのルールが存在しており、v3.0.1時点での一覧は以下から参照できます。

いずれも有用なルールなのですが、このうちAppSync回りでハマったのが、いわゆるコメントを必須とするルールでした。 arguments-have-descriptionsenum-values-have-descriptionsなどです。

AppSyncとBlockComment

まず前提として、GraphQLのコメント(正確にはDescription)は仕様上StringValueとして定義されています。 そして、StringValueとしてBlockStringが許可されており、October2021の仕様を見ても以下のように記載できます。

"""
A simple GraphQL schema which is well described.
"""
schema {
  query: Query
}

一方で、このBlockString形式のDescriptionがAppSyncでは許可されません。これは以下のようにissue化されていますが、未クローズです。

このため、AppSyncを使う場合、スキーマにはBlockCommentは利用できません。 以下のような形式とする必要があるでしょう。

"A simple GraphQL schema which is well described."
schema {
  query: Query
}

graphql-schema-linterの設定ファイル

graphql-schema-linterの設定ファイルはgraphql-schema-linter.config.jsとして記述します。 なにが記述できるのか、というのはドキュメントされていないのですが、ソースコード側でそれなりに記述されているため、そちらをみると良いでしょう。

設定ファイルにおいて特徴的なのが、適用するルールの設定が「ホワイトリスト」形式であることです。 つまり、適用するルールをデフォルトから変更する場合は、すべて羅列する必要があります。

module.exports = {
  rules: [
    "defined-types-are-used",
    "deprecations-have-a-reason",
    "enum-values-all-caps",
    (snip)
  ],
  schemaPaths: ["./*.graphql"],
};

GitHub Actionsでの実装

GitHub ActionsでGraphQL SchemaをLintする設定は以下のようになりました。

graphql-schema-linterの出力フォーマットは--formatで変更が可能です。 これをcompactに設定してやると、Reviewdogとの組み合わせが容易になるでしょう。

name: graphql-schema-linter
on:
  pull_request:
    paths:
      - "**/*.graphql"

jobs:
  tsc:
    runs-on: ubuntu-latest
    name: runner / graphql-schema-linter
    steps:
      - uses: actions/checkout@v2
        name: Checkout source code
      - uses: actions/setup-node@v2
        with:
          node-version: "16"
      - uses: actions/cache@v2
        name: Cache graphql dependencies
        with:
          path: node_modules
          key: ${{ hashFiles('./package-lock.json') }}
      - name: Install dependencies
        run: npm install
      - uses: reviewdog/action-setup@v1
        with:
          reviewdog_version: latest
      - name: Lint graphQL schema
        run: >-
          npx graphql-schema-linter --format compact
          | sed "s|^${BASEPATH}||g"
          | reviewdog -efm="%f:%l:%c %m" -name="graphql-schema-linter" -reporter=github-pr-review -level=warning -fail-on-error=true
        env:
          REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.github_token }}
          BASEPATH: ${{ github.workspace }}