Generar automáticamente notas de lanzamiento
Este es unDevOpsflujo de automatización del dominio deautomatización que contiene 10 nodos.Utiliza principalmente nodos como Set, Code, FormTrigger, HttpRequest. Generar automáticamente notas de lanzamiento de GitHub y notificar por Slack
- •Pueden requerirse credenciales de autenticación para la API de destino
Nodos utilizados (10)
Categoría
{
"id": "CK1X6HPPuntaDwNl",
"meta": {
"instanceId": "14e4c77104722ab186539dfea5182e419aecc83d85963fe13f6de862c875ebfa",
"templateCredsSetupCompleted": true
},
"name": "Auto‑Generate Release Notes",
"tags": [],
"nodes": [
{
"id": "74c1115a-e28b-478e-b4d5-d3c7e890b39c",
"name": "Config",
"type": "n8n-nodes-base.set",
"position": [
200,
40
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "8b87d9c7-3a18-42a9-9ec1-8568fea2908a",
"name": "repoOwner",
"type": "string",
"value": "={{ $json['Repository Owner'] }}"
},
{
"id": "5cac0fee-0aa9-4a4f-a610-8fc3b8682039",
"name": "repoName",
"type": "string",
"value": "={{ $json['Repository Name'] }}"
},
{
"id": "ce2d2b21-55c8-4913-863f-c686e0a51610",
"name": "defaultBranch",
"type": "string",
"value": "={{ $json['Branch Name'] }}"
},
{
"id": "3445fa18-848c-4df5-b5d0-458f978d7cf1",
"name": "=labelMap",
"type": "string",
"value": "{ \"Feature\": \"🚀 Features\", \"bug\": \"🐞 Bug Fixes\", \"performance\": \"⚡ Performance\", \"sdk\": \"📦 SDK / Dependency\" }"
},
{
"id": "29753009-bf1f-40d0-adb9-2ae8135c2eed",
"name": "=qaChecklist",
"type": "string",
"value": "[ \"[ ] App boots successfully\", \"[ ] No crash on startup\", \"[ ] All features tested\", \"[ ] No broken UI on devices\" ]"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "dc575c60-f1ad-439f-8176-0729c109f631",
"name": "Obtener Última Etiqueta Git",
"type": "n8n-nodes-base.httpRequest",
"position": [
420,
40
],
"parameters": {
"url": "=https://api.github.com/repos/{{$json[\"repoOwner\"]}}/{{$json[\"repoName\"]}}/tags",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"id": "sWK5QVSgNgKCkpaF",
"name": "GitHub account"
},
"httpHeaderAuth": {
"id": "Q6oCLdEppyzR0Uga",
"name": "Header Auth account 3"
}
},
"typeVersion": 4.2
},
{
"id": "a45ac6c8-8f50-49c8-97cd-24e57d3b9c24",
"name": "Obtener Fecha de Commit de la Última Etiqueta",
"type": "n8n-nodes-base.httpRequest",
"position": [
640,
40
],
"parameters": {
"url": "={{$json[\"commit\"][\"url\"]}}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "51399899-3a7b-44d3-9067-64e474d0a00a",
"name": "Obtener Todos los PRs Fusionados Desde la Última Etiqueta",
"type": "n8n-nodes-base.httpRequest",
"position": [
860,
40
],
"parameters": {
"url": "=https://api.github.com/search/issues?q=is:pr+is:merged+repo:{{ $('Config').first().json.repoOwner }}/{{ $('Config').first().json.repoName }}+base:{{ $('Config').first().json.defaultBranch }}+merged:>={{ $json.commit.author.date }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "ed1609f1-f1c0-4c15-adb5-b116af6e0a44",
"name": "Ajustado: Agrupar PRs y Generar Notas de Lanzamiento",
"type": "n8n-nodes-base.code",
"position": [
1080,
40
],
"parameters": {
"jsCode": "// SAFELY access config node data\nconst configNode = $('Config').first();\nif (!configNode) {\n throw new Error(\"Missing 'Config' node or it's not accessible.\");\n}\n\nconst labelMap = configNode.labelMap|| {};\nconst qaChecklist = configNode.qaChecklist || [];\n\nconsole.log(\"Your message\", labelMap);\nconsole.log(\"Your message\", qaChecklist);\n\n// Access PR list from previous node\nconst prNode = $('Fetch All Merged PRs Since Last Tag').first(); // <-- Replace with your actual PR-fetch node name\nif (!prNode || !prNode.json || !Array.isArray(prNode.json.items)) {\n throw new Error(\"Pull request data not found or improperly formatted.\");\n}\n\nconst prItems = prNode.json.items;\n\n/** @type {Record<string, string[]>} */\nconst grouped = {};\n\n// Loop through each PR\nfor (const pr of prItems) {\n const labels = pr.labels?.map(l => l.name) || [];\n const matchedKey = labels.find(l => labelMap[l]);\n const groupTitle = matchedKey ? labelMap[matchedKey] : \"📋 Others\";\n\n if (!grouped[groupTitle]) {\n grouped[groupTitle] = [];\n }\n\n grouped[groupTitle].push(`- ${pr.title} (#${pr.number})`);\n}\n\n// Build Markdown content\nlet markdown = `## 📝 Release Notes\\n`;\n\nfor (const group in grouped) {\n markdown += `\\n### ${group}\\n`;\n markdown += grouped[group].join(\"\\n\") + \"\\n\";\n}\n\nmarkdown += `\\n## ✅ QA Checklist\\n`;\nmarkdown += qaChecklist.map(item => `[ ] ${item}`).join(\"\\n\");\n\nreturn [\n {\n json: {\n release_notes: markdown,\n },\n },\n];"
},
"typeVersion": 2
},
{
"id": "589e2cf2-e5f5-4411-a0ba-a4f705d242f9",
"name": "Github Pre Release",
"type": "n8n-nodes-base.httpRequest",
"position": [
1300,
40
],
"parameters": {
"url": "=https://api.github.com/repos/{{ $('Config').first().json.repoOwner }}/{{ $('Config').first().json.repoName }}/releases",
"method": "POST",
"options": {},
"sendBody": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "tag_name",
"value": "={{ $('Get Latest Git Tag').first().json.name }}"
},
{
"name": "name",
"value": "={{ $('Get Latest Git Tag').first().json.name }}"
},
{
"name": "body",
"value": "={{ $json.release_notes }}"
},
{
"name": "draft",
"value": "={{ true }}"
},
{
"name": "prerelease",
"value": "={{ false }}"
}
]
},
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "Q6oCLdEppyzR0Uga",
"name": "Header Auth account 3"
}
},
"typeVersion": 4.2
},
{
"id": "2190c525-95c9-49e8-84de-e13df0d826e5",
"name": "Enviar mensaje a slack",
"type": "n8n-nodes-base.httpRequest",
"position": [
1520,
40
],
"parameters": {
"url": "",
"method": "POST",
"options": {},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "text",
"value": "={{ $('Adjusted: Group PRs & Generate Release Notes').item.json.release_notes }} {{ $json.html_url }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "6c385b76-cc8e-4cbd-b086-0e2c7e9f42bc",
"name": "GitHub Release Input Form",
"type": "n8n-nodes-base.formTrigger",
"position": [
-20,
40
],
"webhookId": "80253212-d5c6-4542-9dba-b9ec3f7cc48d",
"parameters": {
"options": {},
"formTitle": "GitHub Release Input Form",
"formFields": {
"values": [
{
"fieldLabel": "Repository Name",
"placeholder": "Enter name of the repository",
"requiredField": true
},
{
"fieldLabel": "Repository Owner",
"placeholder": "Enter username of github",
"requiredField": true
},
{
"fieldLabel": "Branch Name",
"placeholder": "Enter branch name ",
"requiredField": true
}
]
}
},
"typeVersion": 2.2
},
{
"id": "bd0ad833-757e-4619-b31a-7abfef910fe7",
"name": "Nota Adhesiva",
"type": "n8n-nodes-base.stickyNote",
"position": [
-100,
-60
],
"parameters": {
"width": 1860,
"height": 360,
"content": "## Auto‑Generate Release Notes for Any GitHub Repo → Slack"
},
"typeVersion": 1
},
{
"id": "fa9609ed-9ef4-43b7-b1e5-1b2245cdc657",
"name": "Nota Adhesiva1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-100,
320
],
"parameters": {
"width": 1880,
"height": 1260,
"content": "#🚀 GitHub Automated Release Workflow (n8n)\n\nThis workflow auto-generates release notes from merged pull requests and creates a draft GitHub release, notifying via Slack. Below are the descriptions for each node involved:\n\n⸻\n\n🧩 1. GitHub Release Input Form\n\t•\tPurpose: Collects user input for:\n\t•\towner: GitHub username/org\n\t•\trepo: Repository name\n\t•\tbranch: Target base branch\n\n⸻\n\n⚙️ 2. Config\n\t•\tPurpose:\n\t•\tExtracts user input from the form node.\n\t•\tDefines the label grouping map to classify PRs under sections like feature, bug, performance, etc.\n\n⸻\n\n🔖 3. Get Latest Git Tag\n\t•\tPurpose: Fetches the most recent semantic Git tag from the selected repository.\n\t•\tWhy: Used to determine what PRs were merged after the last release.\n\n⸻\n\n🕒 4. Get Commit Date of Latest Tag\n\t•\tPurpose: Retrieves the commit timestamp for the latest tag.\n\t•\tWhy: This timestamp is used to filter only the PRs merged after the last release.\n\n⸻\n\n📥 5. Fetch All Merged PRs Since Last Tag\n\t•\tPurpose: Queries GitHub’s Search API for pull requests:\n\t•\tThat are merged.\n\t•\tMerged after the latest tag’s commit date.\n\t•\tOn the selected base branch.\n\t•\tWhy: Ensures only new, relevant PRs are included in the release.\n\n⸻\n\n🧠 6. Adjusted: Group PRs & Generate Release Note\n\t•\tPurpose:\n\t•\tGroups the filtered PRs by label (using Config map).\n\t•\tFormats them into a clean Markdown release note.\n\t•\tAdds a ✅ QA Checklist section at the end.\n\n⸻\n\n🪄 7. GitHub Pre Release\n\t•\tPurpose:\n\t•\tCreates a draft GitHub release.\n\t•\tUses the latest tag and generated notes.\n\t•\tSets:\n\t•\t\"draft\": true\n\t•\t\"prerelease\": false\n\n⸻\n\n💬 8. Send Message to Slack\n\t•\tPurpose: Posts the release summary to a designated Slack channel.\n\t•\tIncludes: Tag name, categorized release notes, and optionally a link to the GitHub release."
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "e0e3b36d-59a8-4ec1-a1e5-5a19fb5063ed",
"connections": {
"74c1115a-e28b-478e-b4d5-d3c7e890b39c": {
"main": [
[
{
"node": "dc575c60-f1ad-439f-8176-0729c109f631",
"type": "main",
"index": 0
}
]
]
},
"dc575c60-f1ad-439f-8176-0729c109f631": {
"main": [
[
{
"node": "a45ac6c8-8f50-49c8-97cd-24e57d3b9c24",
"type": "main",
"index": 0
}
]
]
},
"589e2cf2-e5f5-4411-a0ba-a4f705d242f9": {
"main": [
[
{
"node": "2190c525-95c9-49e8-84de-e13df0d826e5",
"type": "main",
"index": 0
}
]
]
},
"6c385b76-cc8e-4cbd-b086-0e2c7e9f42bc": {
"main": [
[
{
"node": "74c1115a-e28b-478e-b4d5-d3c7e890b39c",
"type": "main",
"index": 0
}
]
]
},
"a45ac6c8-8f50-49c8-97cd-24e57d3b9c24": {
"main": [
[
{
"node": "51399899-3a7b-44d3-9067-64e474d0a00a",
"type": "main",
"index": 0
}
]
]
},
"51399899-3a7b-44d3-9067-64e474d0a00a": {
"main": [
[
{
"node": "ed1609f1-f1c0-4c15-adb5-b116af6e0a44",
"type": "main",
"index": 0
}
]
]
},
"ed1609f1-f1c0-4c15-adb5-b116af6e0a44": {
"main": [
[
{
"node": "589e2cf2-e5f5-4411-a0ba-a4f705d242f9",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Intermedio - DevOps
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
WeblineIndia
@weblineindiaA Leading Software Engineering, Consulting & Outsourcing Services Company in USA & India serving Clients Globally since 1999.
Compartir este flujo de trabajo