{ "kind": "open-flow-workflow", "version": 1, "name": "Assign GitHub Issues from Requests", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_17b49db370d949d9": { "name": "Receive issue events", "kind": "integration", "config": { "owner": { "kind": "value", "value": "your-github-owner" }, "repo": { "kind": "value", "value": "your-github-repo" }, "events": { "kind": "value", "value": [ "issues", "issue_comment" ] }, "insecureSsl": { "kind": "value", "value": false } }, "definition": { "configInputs": [ { "jsonSchema": { "type": "array", "items": { "type": "string", "enum": [ "*", "branch_protection_configuration", "branch_protection_rule", "check_run", "check_suite", "code_scanning_alert", "commit_comment", "create", "custom_property_values", "delete", "dependabot_alert", "deploy_key", "deployment", "deployment_status", "discussion", "discussion_comment", "fork", "gollum", "issue_comment", "issue_dependencies", "issues", "label", "member", "meta", "milestone", "package", "page_build", "project", "project_card", "project_column", "public", "pull_request", "pull_request_review", "pull_request_review_comment", "pull_request_review_thread", "push", "registry_package", "release", "repository", "repository_advisory", "repository_import", "repository_ruleset", "repository_vulnerability_alert", "secret_scanning_alert", "secret_scanning_alert_location", "secret_scanning_scan", "security_and_analysis", "star", "status", "sub_issues", "team_add", "watch", "workflow_job", "workflow_run" ] }, "minItems": 1, "uniqueItems": true }, "nullable": false, "handle": "events" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "insecureSsl", "value": false }, { "jsonSchema": { "type": "string", "pattern": "^[a-zA-Z0-9](?:[a-zA-Z0-9]|-(?=[a-zA-Z0-9])){0,38}$" }, "nullable": false, "handle": "owner" }, { "jsonSchema": { "type": "string", "pattern": "^(?!\\.{1,2}$)[a-zA-Z0-9._-]{1,100}$" }, "nullable": false, "handle": "repo" } ], "definitionVersion": 2, "description": "Triggers when selected GitHub webhook events occur in a repository.", "displayName": "Repository Event", "key": "github.on_repo_event", "name": "on_repo_event", "outputs": [ { "jsonSchema": { "type": "object" }, "nullable": false, "handle": "body" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "deliveryId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "event" } ], "provider": "github", "type": "integration", "endpoint": { "body": { "allowArray": false, "allowEmpty": false, "formats": [ "json" ] }, "methods": [ "POST" ], "successStatus": 202 } } }, "n_2dfe07ac565184b3": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_17b49db370d949d9", "output": "body" } ] } }, "name": "Inspect the assignment request", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object" }, "nullable": false, "handle": "body" } ], "outputs": [ { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "action" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "owner" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "repo" }, { "jsonSchema": { "type": "integer", "minimum": 1 }, "nullable": false, "handle": "issueNumber" }, { "jsonSchema": { "type": "array", "items": { "type": "string" }, "minItems": 1 }, "nullable": false, "handle": "assignees" }, { "jsonSchema": { "type": "array", "items": { "type": "string" }, "minItems": 1 }, "nullable": false, "handle": "labels" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "comment" } ], "name": "Inspect the assignment request", "moduleId": "n_7c692c3deeb29cee", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_d48702e6214ce73c": { "inputs": {}, "name": "Assign the requester", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "action" } }, "operator": "==", "right": { "kind": "value", "value": "assign" } } ] } ] } ] }, "n_05bedbc515be17f7": { "inputs": { "owner": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "owner" } ] }, "repo": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "repo" } ] }, "issueNumber": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "issueNumber" } ] }, "assignees": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "assignees" } ] }, "labels": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "labels" } ] } }, "name": "Assign the issue", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "owner" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "repo" }, { "jsonSchema": { "type": "integer", "minimum": 1 }, "nullable": false, "handle": "issueNumber" }, { "jsonSchema": { "type": "array", "items": { "type": "string" }, "minItems": 1 }, "nullable": false, "handle": "assignees" }, { "jsonSchema": { "type": "array", "items": { "type": "string" }, "minItems": 1 }, "nullable": false, "handle": "labels" } ], "outputs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "description": "The issue ID." }, "number": { "type": "integer", "description": "The issue number." }, "title": { "type": "string", "description": "The issue title." }, "state": { "type": "string", "description": "The issue state." }, "html_url": { "type": "string", "description": "The issue URL." }, "body": { "type": [ "string", "null" ], "description": "The issue body." }, "comments": { "type": "integer", "description": "The number of comments." }, "user": { "type": "object", "properties": { "id": { "type": "integer", "description": "The user ID." }, "login": { "type": "string", "description": "The username." }, "avatar_url": { "type": "string", "description": "The avatar URL." }, "html_url": { "type": "string", "description": "The profile URL." }, "type": { "type": "string", "description": "The account type." } }, "required": [ "id", "login" ], "additionalProperties": true, "description": "The issue author." }, "assignees": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "description": "The user ID." }, "login": { "type": "string", "description": "The username." }, "avatar_url": { "type": "string", "description": "The avatar URL." }, "html_url": { "type": "string", "description": "The profile URL." }, "type": { "type": "string", "description": "The account type." } }, "required": [ "id", "login" ], "additionalProperties": true, "description": "A GitHub user summary." }, "description": "The assigned users." }, "labels": { "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "id": { "type": "integer", "description": "The label ID." }, "name": { "type": "string", "description": "The label name." }, "color": { "type": "string", "description": "The label color hex code." }, "description": { "type": [ "string", "null" ], "description": "The label description." } }, "required": [ "name" ], "additionalProperties": true, "description": "A GitHub label record." }, { "type": "string", "description": "A union variant." } ], "description": "An array item." }, "description": "The issue labels." }, "pull_request": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The linked pull request metadata." } }, "required": [ "id", "number", "title", "state", "html_url" ], "additionalProperties": true, "description": "A GitHub issue record." }, "nullable": false, "handle": "output" } ], "name": "Assign the issue", "moduleId": "n_3a7e00b6b32267c0", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [ { "action": "github.update_issue" } ] } ] } }, "n_46238f48b197c180": { "inputs": {}, "name": "Already assigned", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "action" } }, "operator": "==", "right": { "kind": "value", "value": "comment" } } ] } ] } ] }, "n_9398bb2f70f585e8": { "inputs": { "owner": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "owner" } ] }, "repo": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "repo" } ] }, "issueNumber": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "issueNumber" } ] }, "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2dfe07ac565184b3", "output": "comment" } ] } }, "name": "Reply to the commenter", "kind": "task", "task": { "inputs": [ { "description": "The repository owner.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The repository owner." }, "nullable": false, "handle": "owner" }, { "description": "The repository name.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The repository name." }, "nullable": false, "handle": "repo" }, { "description": "The issue number.", "jsonSchema": { "type": "integer", "exclusiveMinimum": 0, "description": "The issue number." }, "nullable": false, "handle": "issueNumber" }, { "description": "The comment body.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The comment body." }, "nullable": false, "handle": "body" } ], "outputs": [ { "description": "A GitHub issue comment record.", "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "description": "The comment ID." }, "html_url": { "type": "string", "description": "The comment URL." }, "body": { "type": "string", "description": "The comment body." }, "user": { "type": [ "object", "null" ], "properties": { "id": { "type": "integer", "description": "The user ID." }, "login": { "type": "string", "description": "The username." }, "avatar_url": { "type": "string", "description": "The avatar URL." }, "html_url": { "type": "string", "description": "The profile URL." }, "type": { "type": "string", "description": "The account type." } }, "required": [ "id", "login" ], "additionalProperties": true, "description": "The comment author." }, "created_at": { "type": "string", "description": "The creation timestamp." }, "updated_at": { "type": "string", "description": "The last update timestamp." } }, "required": [ "id", "html_url", "body" ], "additionalProperties": true, "description": "A GitHub issue comment record." }, "nullable": false, "handle": "output" } ], "name": "Reply to the commenter", "executor": { "kind": "connector", "action": "github.create_issue_comment", "outputMode": "value" } } } }, "edges": [ { "source": "n_17b49db370d949d9", "target": "n_2dfe07ac565184b3" }, { "source": "n_2dfe07ac565184b3", "target": "n_d48702e6214ce73c" }, { "source": "n_d48702e6214ce73c", "target": "n_05bedbc515be17f7", "sourceHandle": "yes" }, { "source": "n_d48702e6214ce73c", "target": "n_46238f48b197c180", "sourceHandle": "otherwise" }, { "source": "n_46238f48b197c180", "target": "n_9398bb2f70f585e8", "sourceHandle": "yes" } ] } }, "modules": { "n_7c692c3deeb29cee": { "name": "Inspect the assignment request", "imports": [], "source": "export default function decide({body}) {\n const ignore={action:'ignore',owner:'unused',repo:'unused',issueNumber:1,assignees:['unused'],labels:['assigned'],comment:'unused'};\n if(!body||typeof body!=='object'||Array.isArray(body))throw Error('Invalid GitHub event');\n if(body.action!=='opened'&&body.action!=='created')return ignore;\n const issue=body.issue,repo=body.repository;if(!issue||!repo||typeof repo.name!=='string'||!repo.name||typeof repo.owner?.login!=='string'||!repo.owner.login||!Number.isSafeInteger(issue.number)||issue.number<1||!Array.isArray(issue.assignees))throw Error('Invalid GitHub issue event');\n const isComment=body.action==='created',text=isComment?body.comment?.body:issue.body;\n if(text==null)return ignore;if(typeof text!=='string')throw Error('Invalid issue or comment text');\n if(!/[a,A]ssign[\\w*\\s*]*me/gm.test(text))return ignore;\n const requester=isComment?body.comment?.user?.login:issue.user?.login;\n if(typeof requester!=='string'||!/^[A-Za-z0-9](?:[A-Za-z0-9]|-(?=[A-Za-z0-9])){0,38}$/.test(requester))throw Error('Invalid requester login');\n const base={...ignore,owner:repo.owner.login,repo:repo.name,issueNumber:issue.number};\n if(issue.assignees.length===0)return {...base,action:'assign',assignees:[requester]};\n if(!isComment)return ignore;\n const assigned=issue.assignee?.login;if(typeof assigned!=='string'||!/^[A-Za-z0-9](?:[A-Za-z0-9]|-(?=[A-Za-z0-9])){0,38}$/.test(assigned))throw Error('Missing assigned user');\n return {...base,action:'comment',comment:'Hey @'+requester+',\\n\\nThis issue is already assigned to '+assigned+' 🙂'};\n}\n" }, "n_3a7e00b6b32267c0": { "name": "Assign the issue", "imports": [], "source": "export default async function assignIssue({owner,repo,issueNumber,assignees,labels},context){const issue=await context.actions.call('github.update_issue',{owner,repo,issueNumber,assignees,labels});return {output:issue};}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }