Modularisation et réutilisation
sub_workflow, encapsulez un élément de logique dans un module, favorisez/rétrogradez la reconstruction en un clic - afin que le flux de travail n'ait plus besoin d'être copié et collé un par un.
Lorsque vous atteignez les deuxième et troisième flux de travail, vous constaterez qu'un certain élément de logique apparaît à plusieurs reprises : extraire des données ASA, envoyer des messages Telegram et générer des rapports Excel. Si vous continuez à copier et coller, vous devrez changer de trois endroits pour changer d'endroit, le test sera répété et la version sera hors de contrôle. Il est temps de faire de la modularisation en ce moment.
Template = un instantané du document de départ, qui évolue indépendamment après le clonage ; module = un sous-processus qui peut être référencé, et l'appelant en bénéficiera automatiquement après la mise à niveau. Les deux ne se substituent pas, mais se complètent. Cette page parle de modules.
Qu'est-ce qu'un "module"
Un « module » est essentiellement un workflow qui déclare les champs de niveau supérieur de WorkflowModuleContract. Il expose en outre :
- inputs — Paramètres que l'appelant doit transmettre (avec nom, type, obligatoire, valeur par défaut, description)
- outputs — Le résultat structuré généré après exécution (peut être directement référencé par l'appelant)
- version — Numéro de version sémantique pour faciliter le verrouillage de l'appelant
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 …Après avoir obtenu le contrat, l'étape sub_workflow de l'appelant (workflow parent) va :
- Vérification statique lors de la sauvegarde - les entrées requises ne seront pas enregistrées s'il en manque une ;
- Vérification au moment de l'exécution - si le type ne correspond pas/l'énumération n'est pas dans la liste, une erreur sera signalée directement ;
- Remplissage automatique dans l'éditeur - lorsque vous écrivez des entrées : vous pouvez faire défiler vers le bas pour voir quels champs le module expose.
Comment le workflow parent appelle le module
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 存到你自己的数据库,方便后续更新那条消息 ...Points clés :
module: dingyue-module-slack-deliverIl s'agit de l'identifiant du module et la plateforme le résoudra en fonction du nom + de la version.inputs:Correspond un à un aux entrées du contrat du module.- Une fois l'appel terminé, vous pouvez passer
{{steps.deliver.outputs.message_id}}Lire la sortie du module.
Transformez les flux de travail existants en modules : passez au module
La plupart du temps, vous n'écrirez pas un module à partir de zéro, mais vous le retirerez plutôt d'un flux de travail existant. Processus :
- Ouvrez un workflow dans lequel vous pensez que « cette logique mérite d'être réutilisée ».
- Utilisez la sélection du cadre de la souris ou Maj+clic pour sélectionner plusieurs étapes consécutives dans le canevas.
- Menu contextuel → "Promouvoir vers le module" ou le bouton du même nom dans la barre d'outils supérieure.
- Dans la fenêtre pop-up :
- Donnez un nom de module significatif (globalement unique, il est recommandé de le préfixer avec le nom de votre équipe, par exemple : my-team-slack-notifier) ;
- La plateforme déduira automatiquement la première ébauche d'entrées/sorties en fonction du fragment sélectionné, que vous pourrez éditer ;
- Après confirmation, cliquez sur "Créer un module".
- Ces étapes du workflow d'origine seront remplacées par un nœud sub_workflow - les paramètres et les connexions sont automatiquement alignés.
Comme la refactorisation de la "fonction d'extraction" dans l'EDI. Vous sélectionnez un morceau de code et l'IDE vous aidera à extraire une fonction avec des paramètres et des valeurs de retour, et à remplacer la position d'origine par l'appel. Braidrun fait exactement la même chose, mais pour les étapes du flux de travail.
Mise à niveau du module et compatibilité des versions
Chaque fois que vous enregistrez un module, une nouvelle version est créée. Le workflow parent peut être sélectionné à l'étape sub_workflow :
version: latest— Utilisez automatiquement la dernière version (adaptée aux modules que vous maintenez vous-même)version: "1.2.0"— Verrouillé sur une version spécifique (adapté au référencement de modules d'autres personnes, peur d'une mise à niveau et d'une compatibilité dommageable)version: "^1.2.0"— Autoriser les mises à niveau de versions mineures, interdire les versions majeures multi-versions
Qu'est-ce qu'un « changement compatible » ?
- ✓ Ajoutez une entrée facultative (les valeurs obligatoires/par défaut ne sont pas considérées comme cassées)
- ✓ Ajouter un champ de sortie
- ✗ Supprimer/renommer l'entrée
- ✗ Supprimer/renommer la sortie
- ✗ Changer le type d'entrée
Lorsque vous apportez des modifications qui rompent la compatibilité, la version sémantique doit être mise à niveau vers la version MAJEURE suivante. La plateforme n'applique pas, mais est protégée lorsque l'appelant verrouille ^X.Y.Z.
Détection de boucle
Le module A ne peut pas se référencer indirectement. La plateforme effectue une détection à deux niveaux :
- Détection statique au moment du relâchement — Lors de la sauvegarde d'un module, DFS analyse les graphiques de dépendances de tous les autres modules auxquels il fait référence et refuse de sauvegarder s'il y a des boucles.
- Détection dynamique d'exécution — Si un cycle résolu par le runtime se produit pendant l'exécution (par exemple, il est référencé après une branche conditionnelle), une erreur sera immédiatement générée.
La profondeur de récursion maximale par défaut est de 8 niveaux. C'est la profondeur du "fils du fils du père", pas un seul appel à l'épanouissement.
Isolement variable
Le module s'exécute en tant que "WorkflowExecutionContext enfant", complètement isolé du contexte parent :
- Les variables/étapes, sorties/agents du parent ne sont pas héritées de l'enfant par défaut ;
- Le résultat de l'étape interne de l'enfant ne débordera pas sur le parent - le parent ne peut voir que les résultats déclarés dans le contrat ;
- La seule façon de transmettre des données entre le parent et l'enfant est les entrées/sorties (contrat explicite).
Cette isolation est la pierre angulaire de la fiabilité modulaire : la « boîte noire » n'est pas une métaphore, c'est une métaphore littérale.
Rétrograder du module : restaurer le module à une étape en ligne
Si vous le modifiez et constatez qu'un certain élément de logique est réellement utilisé à un seul endroit, et que le transformer en module augmente le coût de compréhension, vous pouvez inverser la rétrogradation :
- Sélectionnez le nœud sub_workflow dans le workflow parent ;
- Clic droit → « Rétrograder en ligne » ;
- La plateforme étend le retour du module au workflow parent et le nœud sub_workflow disparaît.
Le module d'origine lui-même n'est pas supprimé : s'il existe d'autres workflows qui y font référence, ceux-ci sont toujours valides.
Où Gérer tous les modules
La navigation principale "Bibliothèque de modules" sur la gauche est votre vue d'ensemble. Ici, vous pouvez :
- Voir une liste de tous les modules (12 inclus + ceux créés par votre équipe)
- Requête inversée basée sur "Qui me référence" - vérifiez qui sera concerné avant de changer de module
- Afficher l'historique des versions du module / les différences
- Publier/Archiver/Transférer la propriété
Quand créer des modules
- ✓ La même logique apparaît dans plus de 2 workflows
- ✓ Un contrat externe logiquement stable et clair (généralement « envoyer des messages/vérifier des rapports/générer du Markdown »)
- ✓ Un seul workflow a dépassé 15 étapes et sa lisibilité a diminué.
- ✗ Un élément de logique n'est utilisé qu'une seule fois et ne sera pas réutilisé à l'avenir - directement intégré
- ✗ Une petite fonction utilitaire de 2 à 3 lignes - la réutilisation du code en utilisant les étapes de code est plus naturelle que les modules
Étape suivante
- Bibliothèque de modules intégrée — 12 plates-formes sont livrées avec des modules intégrés. Utilisez-les d'abord pour vous familiariser avec la routine d'appel sub_workflow.
- 8 Types d'étapes — Référence de champ complète pour sub_workflow dans
- Meilleures pratiques — "Quand et comment démonter"