주요 콘텐츠로 건너뛰기
문서워크플로우 구축모듈화 및 재사용

모듈화 및 재사용

sub_workflow, 로직 일부를 모듈로 캡슐화하고 원클릭 재구성 승격/강등 - 더 이상 워크플로우를 하나씩 복사하여 붙여넣을 필요가 없습니다.

두 번째 및 세 번째 워크플로에 도달하면 ASA 데이터 가져오기, 텔레그램 메시지 보내기, Excel 보고서 생성 등 특정 로직이 반복적으로 나타나는 것을 확인할 수 있습니다. 계속해서 복사해서 붙여넣으면 한 곳을 바꾸려면 세 곳을 바꿔야 하고, 테스트가 반복되어 버전이 통제 불능 상태가 됩니다. 이때는 모듈화를 해야 할 때이다.

템플릿 대 모듈 다시

템플릿 = 복제 후 독립적으로 발전하는 시작 문서의 스냅샷입니다. 모듈 = 참조할 수 있는 하위 프로세스이며 호출자는 업그레이드 후 자동으로 이점을 얻습니다. 둘은 대체가 아니라 보완적이다. 이 페이지에서는 모듈에 대해 설명합니다.

"모듈"이란 무엇입니까?

"모듈"은 기본적으로 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: 모듈 계약의 입력과 일대일로 대응합니다.
  • 통화가 완료된 후 통과하시면 됩니다 {{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는 자신을 간접적으로 참조할 수 없습니다. 플랫폼은 두 가지 수준에서 탐지를 수행합니다.

  1. 릴리스 시 정적 감지 — 모듈을 저장할 때 DFS는 참조하는 다른 모든 모듈의 종속성 그래프를 검색하고 루프가 있으면 저장을 거부합니다.
  2. 런타임 동적 감지 — 실행 중에 런타임에 의해 해결된 주기가 발생하는 경우(예: 조건 분기 이후에 참조되는 경우) 즉시 오류가 발생합니다.

기본 최대 재귀 깊이는 8레벨입니다. 이것은 팬아웃을 부르는 단 한 번의 부름이 아닌 '아버지의 아들의 아들'의 깊이입니다.

가변 격리

모듈은 상위 컨텍스트와 완전히 격리된 "하위 WorkflowExecutionContext"로 실행됩니다.

  • 부모의 변수/단계 출력/에이전트는 기본적으로 자식에게 상속되지 않습니다.
  • 자식의 내부 단계 출력은 부모로 오버플로되지 않습니다. 부모는 계약에 선언된 출력만 볼 수 있습니다.
  • 상위와 하위 간에 데이터를 전달하는 유일한 방법은 입력/출력(명시적 계약)입니다.

이러한 격리는 모듈식 신뢰성의 초석입니다. "블랙박스"는 비유가 아니라 문자 그대로입니다.

모듈에서 수준 내리기: 모듈을 인라인 단계로 복원합니다.

이를 수정하고 특정 로직이 실제로 한 곳에서만 사용되는 것을 발견하고 이를 모듈로 만들면 이해 비용이 증가하는 경우 Demote를 되돌릴 수 있습니다.

  1. 상위 워크플로에서 sub_workflow 노드를 선택합니다.
  2. 마우스 오른쪽 버튼 클릭 → "인라인 수준 내리기";
  3. 플랫폼은 모듈의 단계를 다시 상위 워크플로로 확장하고 sub_workflow 노드는 사라집니다.

원본 모듈 자체는 삭제되지 않습니다. 이를 참조하는 다른 워크플로가 있는 경우 해당 모듈은 여전히 유효합니다.

모든 모듈을 관리하는 위치

왼쪽의 기본 탐색 "모듈 라이브러리"는 개요 보기입니다. 여기에서 다음을 수행할 수 있습니다.

  • 모든 모듈 목록 보기(12개 포함 + 팀에서 생성한 모듈)
  • "나를 참조하는 사람"을 기반으로 한 역 쿼리 - 모듈을 변경하기 전에 영향을 받을 사람을 확인하세요.
  • 모듈 버전 기록/차이점 보기
  • 게시/보관/소유권 이전

모듈을 만들 때

  • ✓ 동일한 로직이 2개 이상의 워크플로에 나타납니다.
  • ✓ 논리적으로 안정적이고 명확한 외부 계약(일반적으로 "메시지 보내기/보고서 확인/마크다운 생성")
  • ✓ 단일 워크플로우가 15단계를 초과하여 가독성이 떨어졌습니다.
  • ✗ 로직은 한 번만 사용되며 나중에 재사용되지 않습니다. 직접 인라인됩니다.
  • ✗ 2~3줄의 작은 유틸리티 기능 - 코드 단계를 사용한 코드 재사용이 모듈보다 더 자연스럽습니다.

다음 단계

  • 내장 모듈 라이브러리 — 12개의 플랫폼에는 모듈이 내장되어 있습니다. 먼저 이를 사용하여 sub_workflow 호출 루틴에 익숙해지십시오.
  • 8단계 유형 — sub_workflow에 대한 전체 필드 참조
  • 모범 사례 — "해체 시기와 방법"