path-filteringのmappingからCHANGELOGが漏れて、docsがdeployされなかった

タグ:

monorepoのdocsサイトをCircleCIでdeployしていて、npmへのpublishは成功したのにChangelogページだけが更新されない問題に遭遇しました。原因はpath-filtering orbのmappingにCHANGELOGのパスがなかったことです。orbのソースで仕様を確認しながら直した記録です。

広告ここから
広告ここまで

目次

    monorepoのOSSで、docsサイトをCircleCIでdeployしています。あるとき、npmへのpublishは成功しているのに、ドキュメントサイトのChangelogページだけが古いままになっていました。CircleCIはgreenで、deploy workflowは実行されず、docs/にも変更はありません。

    path-filtering orbのmappingに原因があり、1行足せば直ります。ただ、AIに生成させた直しのYAMLに違和感を覚えました。

    mapping: |
      (\.circleci/docs-release\.yml|docs/.*|packages/[^/]+/CHANGELOG\.md) run-docs-deploy true

    3つの条件を(A|B|C)で1行に押し込んだ正規表現は、単純に読みにくく感じます。mappingは複数行で書けたはずという記憶もあったので、orbのソースを確認しました。

    mappingの仕様はorbのスクリプトで確認できる

    path-filtering orbのv1系では、mappingをcreate-parameters.pyが解釈します。このスクリプトを読むと、判断に必要な仕様がひと通りわかります。

    • mappingの文字列をsplitlines()で1行ずつに分け、各行を空白でsplit()する
    • 1行は3要素(パス、parameter、value)か、configファイルを加えた4要素にする。最初の行の要素数が3と4のどちらでもなければInvalid mapping length、行ごとに要素数がずれたらExpected N fields but found Mの例外になる
    • パスはre.compile(r'^' + path + r'$')で正規表現として扱われる(^と$は自動付与)
    • valueはjson.loadsで解釈される
    • 最後はdict(filtered_mapping)でまとめるので、同じparameter名の行は後ろの行の値で上書きされる

    公式のapi-preview-docsにも「Later matches override earlier ones.」とあり、標準の例も複数行で書かれています。つまり(A|B|C)は複数行で書けるものを正規表現のorに書き直しただけでした。

    なお、orbはv2.0.0でcreate-parameters.pyをやめ、bashのcreate-parameters.shに移りました。最新のv3.0.0でも、1行を空白で分割する点と、パスを^と$で囲んで正規表現にする点は同じです。

    複数行に分けて、抜けていたCHANGELOGを足す

    最終的なmappingは次のとおりです。

    mapping: |
      \.circleci/docs-release\.yml run-docs-deploy true
      docs/.* run-docs-deploy true
      packages/[^/]+/CHANGELOG\.md run-docs-deploy true

    3行ともrun-docs-deployをtrueにするので、後勝ちのルールがあっても結果は変わりません。後勝ちが結果を変えるのは、同じparameter名にtrueとfalseを混ぜたときだけです。

    docs/だけを見ていたので、deployがスキップされていた

    最初のmappingから抜けていたのは、3行目のpackages/[^/]+/CHANGELOG\.mdです。Changesetsのpnpm changeset versionが更新するのはpackages/*/CHANGELOG.mdとpackages/*/package.jsonです。docs/には触れません。一方、docsサイトのChangelogページは、packages/*/CHANGELOG.mdをloaderで読んで生成しています。deployのトリガーがdocs/**だけの場合、CHANGELOGが更新されてもパイプラインは「変更なし」と判定します。その結果、deployはスキップされます。CIはgreenなのにサイトだけが古い状態は、これが原因でした。

    mappingはフォルダではなく、ビルドの入力依存関係で書く

    monorepoでは、docsビルドの入力ソースがdocs/の外に散らばります。packages/*/CHANGELOG.mdのほか、TypeDoc用のpackages/*/src/**やルートのREADMEなどです。「docsはこのフォルダにある」という感覚でdocs/**だけを書くと、これらの変更を取りこぼします。設計の時点で、chore: version packages相当のコミットでrun-docs-deployがtrueになるかを確かめておけば、気づけたはずです。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark