メインコンテンツへ移動
ドキュメントワークフローの構築モジュール化と再利用

モジュール化と再利用

sub_workflow、ロジックの一部をモジュールにカプセル化、プロモート/デモートのワンクリック再構築 - これにより、ワークフローを 1 つずつコピーして貼り付ける必要がなくなります。

2 番目と 3 番目のワークフローに到達すると、ASA データの取得、Telegram メッセージの送信、Excel レポートの生成など、特定のロジックが繰り返し表示されることがわかります。コピペを続けると、1箇所変更するのに3箇所も変更しなければならず、テストが繰り返され、バージョンが管理できなくなります。現時点ではモジュール化を行う時期です。

再びテンプレートとモジュール

テンプレート = 開始ドキュメントのスナップショット。クローン作成後に独自に進化します。 module = 参照可能なサブプロセス。アップグレード後、呼び出し側が自動的に恩恵を受けます。この 2 つは代替品ではなく、補完的なものです。このページではモジュールについて説明します。

「モジュール」とは何ですか

「モジュール」は本質的に、WorkflowModuleContract の最上位フィールドを宣言するワークフローです。さらに以下を公開します。

  • inputs — 呼び出し元が渡す必要があるパラメータ (名前、タイプ、必須、デフォルト値、説明付き)
  • outputs — 実行後に生成される構造化された結果 (呼び出し元が直接参照可能)
  • version — 呼び出し元のロックを容易にするセマンティック バージョン番号
yaml
name: my-team-slack-notifier
version: "1.0.0"

module:
  enabled: true
  inputs:
    webhook_url:
      type: string
      required: true
      description: Slack incoming webhook URL
    channel:
      type: string
      required: false
      default: "#general"
    message:
      type: string
      required: true
    mentions:
      type: array
      items: { type: string }
      required: false
  outputs:
    message_ts:
      type: string
      description: Slack 返回的 message timestamp,可用于后续更新消息
    status:
      type: string
      enum: [sent, failed]

# 模块自己的步骤(内部细节,对调用方黑盒)
steps:
  - id: format_text
    type: code
    language: node
    code: |
      const msg = process.env.WF_VAR_MESSAGE;
      const mentions = JSON.parse(process.env.WF_VAR_MENTIONS || '[]');
      return { text: mentions.map(u => `<@${u}>`).join(' ') + ' ' + msg };

  - id: post
    type: code
    depends_on: [format_text]
    credentials: [slack_oauth]
    code: |
      //  Slack API,返回 message_ts / status 

契約を結んだ後、呼び出し元 (親ワークフロー) の sub_workflow ステップは次のようになります。

  • 保存時の静的検証 - 必要な入力が不足している場合は保存されません。
  • 実行時の検証 - 型が一致しない場合、または列挙型がリストにない場合は、エラーが直接報告されます。
  • エディターでの自動補完 - 入力を記述するとき: 下にスクロールして、モジュールが公開するフィールドを確認できます。

親ワークフローがモジュールを呼び出す方法

yaml
steps:
  - id: build_report
    type: code
    # ...

  - id: notify
    type: sub_workflow
    module: my-team-slack-notifier    # 引用我们上面定义的模块
    version: "^1.0.0"                  # 锁主版本
    inputs:
      webhook_url: "{{credentials.slack_webhook}}"
      channel: "#ops-alerts"
      message: "日报已生成:{{steps.build_report.data.summary}}"
      mentions: ["U1234", "U5678"]

  - id: record
    type: code
    depends_on: [notify]
    code: |
      const ts = process.env.STEP_OUTPUT_NOTIFY_MESSAGE_TS;
      // 把 ts 存到你自己的数据库,方便后续更新那条消息 ...

重要なポイント:

  • module: dingyue-module-slack-deliver これはモジュール ID であり、プラットフォームは名前とバージョンに基づいて解決します。
  • inputs: モジュール コントラクトの入力と 1 対 1 に対応します。
  • 通話が完了したらそのまま通れます {{steps.deliver.outputs.message_id}} モジュール出力を読み取ります。

既存のワークフローをモジュールに変換する: モジュールにプロモートする

ほとんどの場合、モジュールを最初から作成するのではなく、既存のワークフローから取得します。プロセス:

  1. 「このロジックは再利用する価値がある」と思われるワークフローを開きます。
  2. マウス フレーム選択を使用するか、Shift キーを押しながらクリックして、キャンバス内の複数の連続するステップを選択します。
  3. 右クリックメニュー→「モジュールに昇格」、または上部ツールバーの同名のボタン。
  4. ポップアップウィンドウで:
    • 意味のあるモジュール名を付けます (グローバルに一意なので、先頭にチーム名を付けることをお勧めします (例: my-team-slack-notifier))。
    • プラットフォームは、選択したフラグメントに基づいて入力/出力の最初のドラフトを自動的に推測します。これは編集可能です。
    • 確認後、「モジュールの作成」をクリックします。
  5. 元のワークフローのこれらのステップは sub_workflow ノードに置き換えられます。パラメーターと接続は自動的に調整されます。
プロモートのメンタルモデル

IDE の「抽出関数」リファクタリングと同様です。コードの一部を選択すると、IDE がパラメーターと戻り値を含む関数を抽出し、元の位置を呼び出しに置き換えるのに役立ちます。 Braidrun もまったく同じことを行いますが、ワークフローのステップが異なります。

モジュールのアップグレードとバージョンの互換性

モジュールを保存するたびに、新しいバージョンが作成されます。親ワークフローは、sub_workflow ステップで選択できます。

  • version: latest — 最新バージョンを自動的に使用します (自分で保守するモジュールに適しています)
  • version: "1.2.0" — 特定のバージョンにロックされています (他の人のモジュールを参照するのに適していますが、アップグレードや互換性の低下が懸念されます)
  • version: "^1.2.0" — マイナーバージョンのアップグレードを許可し、クロスバージョンのメジャーバージョンを禁止します

「互換性のある変更」とは何ですか?

  • ✓ オプションの入力を追加します (必須/デフォルト値は壊れているとはみなされません)
  • ✓ 出力フィールドを追加する
  • ✗ 入力の削除/名前変更
  • ✗ 出力の削除/名前変更
  • ✗ 入力タイプの変更

互換性を損なう変更を行う場合は、セマンティック バージョンを次の MAJOR にアップグレードする必要があります。プラットフォームは強制しませんが、呼び出し元が ^X.Y.Z をロックすると保護されます。

ループ検知

モジュール A はそれ自体を間接的に参照できません。プラットフォームは、次の 2 つのレベルで検出を実行します。

  1. リリース時の静電気検出 — When saving a module, DFS scans the dependency graphs of all other modules it references and refuses to save if there are loops.
  2. 実行時の動的検出 — ランタイムによって解決されたサイクルが実行中に発生した場合 (たとえば、条件付き分岐の後に参照された場合)、すぐにエラーがスローされます。

デフォルトの最大再帰深さは 8 レベルです。これが「父の息子の息子」の深さであり、ファンアウトへの呼びかけは一度もありません。

変数の分離

このモジュールは、親コンテキストから完全に分離された「子 WorkflowExecutionContext」として実行されます。

  • 親の変数/ステップ出力/エージェントは、デフォルトでは子に継承されません。
  • 子の内部ステップ出力は親にオーバーフローしません。親はコントラクトで宣言された出力のみを参照できます。
  • 親と子の間でデータを渡す唯一の方法は、入力/出力 (明示的な契約) です。

この分離はモジュールの信頼性の基礎です。「ブラック ボックス」は比喩ではなく、文字通りの意味です。

モジュールから降格: モジュールをインライン ステップに復元します。

これを変更して、特定のロジック部分が実際には 1 か所でのみ使用されており、それをモジュールにすると理解するコストが増加することが判明した場合は、降格を元に戻すことができます。

  1. 親ワークフローで sub_workflow ノードを選択します。
  2. 右クリック → 「インラインを降格」;
  3. プラットフォームはモジュールのステップを親ワークフローに展開し、sub_workflow ノードが消えます。

元のモジュール自体は削除されません。それを参照する他のワークフローがある場合、それらは引き続き有効です。

すべてのモジュールを管理する場所

左側のメインナビゲーション「モジュールライブラリ」が概要ビューです。ここで次のことができます。

  • すべてのモジュールのリストを表示します (含まれる 12 個 + チームによって作成されたモジュール)
  • 「誰が私を参照しているか」に基づいた逆クエリ - モジュールを変更する前に誰が影響を受けるかを確認してください
  • モジュールのバージョン履歴/差分の表示
  • 所有権の公開/アーカイブ/譲渡

モジュールをいつ作成するか

  • ✓ 同じロジック部分が 3 つ以上のワークフローに表示されます
  • ✓ 論理的に安定した明確な外部契約 (通常は「メッセージの送信/レポートの確認/マークダウンの生成」)
  • ✓ 1 つのワークフローが 15 ステップを超え、可読性が低下しました。
  • ✗ ロジックの一部は一度だけ使用され、将来は再利用されません - 直接インライン化されます
  • ✗ 2 ~ 3 行の小さなユーティリティ関数 - コードステップを使用したコードの再利用はモジュールよりも自然です

次のステップ