Saltar para o conteúdo principal
DocsCompilar o workflowModularização e reutilização

Modularização e reutilização

Use sub workflow, a lógica do pacote em módulos e refator com Promote / Demote para que os workflows não tenham mais que ser copiados e colados um por um.

Ao chegar ao segundo e terceiro workflows, você descobrirá que uma determinada parte da lógica aparece repetidamente - extraindo dados ASA, enviando mensagens do Telegram e gerando relatórios do Excel.

Modelos versus módulos novamente

Template = um instantâneo do documento inicial, que evolui de forma independente após a clonagem;

O que é um "módulo"

Um “módulo” é essencialmente um workflow que declara os campos de nível superior de WorkflowModuleContract.

  • inputs — Parâmetros que o chamador deve passar (com nome, tipo, obrigatório, valor padrão, descrição)
  • outputs — O resultado estruturado gerado após a execução (pode ser referenciado diretamente pelo chamador)
  • version — Número de versão semântico para facilitar o bloqueio de chamadas
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 

Depois de ter o contrato, a etapa sub_workflow do chamador (workflow pai) irá:

  • Verificação estática ao salvar - as entradas necessárias não serão salvas se alguma estiver faltando;
  • Verificação em tempo de execução - se o tipo não corresponder/a enumeração não estiver na lista, um erro será reportado diretamente;
  • Preenchimento automático no editor - quando você escreve entradas: você pode rolar para baixo para ver quais campos o módulo expõe.

Como o workflow pai chama o módulo

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 存到你自己的数据库,方便后续更新那条消息 ...

Pontos principais:

  • module: dingyue-module-slack-deliver É o id do módulo e a plataforma irá resolvê-lo com base no nome + versão.
  • inputs: Corresponde individualmente às entradas do contrato do módulo.
  • Depois que a chamada for concluída, você poderá passar {{steps.deliver.outputs.message_id}} Leia a saída do módulo.

Transforme workflows existentes em módulos: Promova para módulo

Na maioria das vezes você não escreverá um módulo do zero, mas sim extraí-lo de um workflow existente.

  1. Abra um workflow onde você pensa que "vale a pena reutilizar essa lógica".
  2. Use a seleção de quadro do mouse ou Shift+clique para selecionar diversas etapas consecutivas na tela.
  3. Menu do botão direito – “Promover para módulo” ou o botão com o mesmo nome na barra de ferramentas superior.
  4. Na janela pop-up:
    • Forneça um nome de módulo significativo (globalmente exclusivo, é recomendado prefixá-lo com o nome da sua equipe, por exemplo: my-team-slack-notifier);
    • A plataforma inferirá automaticamente o primeiro rascunho de entradas/saídas com base no fragmento selecionado, que você pode editar;
    • Após a confirmação, clique em “Criar Módulo”.
  5. Essas etapas no workflow original serão substituídas por um nó sub_workflow - parâmetros e conexões são alinhados automaticamente.
Modelo mental da Promova

Como a refatoração da "função de extração" no IDE.

Atualização de módulo e compatibilidade de versão

Cada vez que você salva um módulo, uma nova versão é criada.

  • version: latest — Use automaticamente a versão mais recente (adequada para módulos que você mesmo mantém)
  • version: "1.2.0" — Bloqueado em uma versão específica (adequado para fazer referência a módulos de outras pessoas, medo de atualizar e prejudicar a compatibilidade)
  • version: "^1.2.0" — Permitir atualizações de versões secundárias, proibir versões principais entre versões

O que é uma “mudança compatível”?

  • ✓ Adicione uma entrada opcional (valores obrigatórios/padrão não são considerados quebrados)
  • ✓ Adicione um campo de saída
  • ✗ Excluir/renomear entrada
  • ✗ Excluir/renomear saída
  • ✗ Alterar tipo de entrada

Ao fazer alterações que quebrem a compatibilidade, a versão semântica deve ser atualizada para a próxima MAJOR.

Detecção de loop

O Módulo A não pode fazer referência indireta a si mesmo.

  1. Detecção estática no momento da liberação — Ao salvar um módulo, o DFS verifica os gráficos de dependência de todos os outros módulos aos quais faz referência e se recusa a salvar se houver loops.
  2. Detecção dinâmica em tempo de execução — Se um ciclo resolvido pelo tempo de execução ocorrer durante a execução (por exemplo, for referenciado após uma ramificação condicional), um erro será gerado imediatamente.

A profundidade máxima de recursão padrão é de 8 níveis.

Isolamento variável

O módulo é executado como um "WorkflowExecutionContext filho", completamente isolado do contexto pai:

  • As variáveis/etapas, saídas/agentes do pai não são herdadas para o filho por padrão;
  • A saída da etapa interna do filho não irá transbordar para o pai - o pai só pode ver as saídas declaradas no contrato;
  • A única maneira de passar dados entre pai e filho são entradas/saídas (contrato explícito).

Esse isolamento é a base da confiabilidade modular – “caixa preta” não é uma metáfora, é literal.

Rebaixar do módulo: restaure o módulo para uma etapa inline

Se você modificá-lo e descobrir que uma determinada parte da lógica é realmente usada em apenas um lugar, e transformá-la em um módulo aumenta o custo de compreensão, você pode reverter o rebaixamento:

  1. Selecione o nó sub_workflow no workflow pai;
  2. Clique com o botão direito em "Rebaixar inline";
  3. A plataforma expande a etapa do módulo de volta ao workflow pai e o nó sub_workflow desaparece.

O módulo original em si não é excluído – se houver outros workflows que façam referência a ele, eles ainda serão válidos.

Onde gerenciar todos os módulos

A navegação principal "Biblioteca de Módulos" à esquerda é sua visão geral.

  • Veja uma lista de todos os módulos (12 incluídos + aqueles criados pela sua equipe)
  • Consulta reversa baseada em "Quem está me referenciando" - verifique quem será afetado antes de alterar o módulo
  • Ver histórico/diferença da versão do módulo
  • Publicar/Arquivar/Transferir Propriedade

Quando fazer módulos

  • ✓ A mesma lógica aparece em mais de 2 workflows
  • â Um contrato externo logicamente estável e claro (normalmente "envio de mensagens/verificação de relatórios/geração de Markdown")
  • ✓ Um único workflow excedeu 15 etapas e sua legibilidade diminuiu.
  • ✗ Uma parte da lógica é usada apenas uma vez e não será reutilizada no futuro - diretamente incorporada
  • ✗ Uma pequena função utilitária de 2 a 3 linhas - a reutilização de código usando etapas de código é mais natural do que módulos

Próximo passo