Automatically resolve tickets with Port
Send this guide to your coding agent.
Prerequisite: Install Port MCP
Open plan mode. Implement this Port guide in my org via MCP: https://docs.port.io/guides/all/automatically-resolve-tickets/ Goal: get the guide's core flow working end-to-end in my org; adapting it to fit my existing setup takes priority over matching the guide 1:1. Plan: 1. Confirm MCP is connected, in the right org, with sufficient permissions. 2. Diff the guide's data model (blueprints, properties, relations, actions, agents, automations, integrations, secrets) against mine. 3. Propose adaptations for gaps, reusing existing blueprints/relations over guide-named duplicates. 4. Flag what needs a UI click, credential, or secret from me, testing MCP capability empirically before ruling anything out. 5. Stop on any blocker and give me options. Approving this plan authorizes the writes it lists; pause only for writes beyond what's listed. Build: - Extend blueprint schema additively when upserting; don't remove or overwrite existing properties, and treat type conflicts as a blocker, not an auto-fix. - List any mock data in the plan, minimal and labeled mock; once approved, seed it without re-asking, and tell me what you seeded. - For anything the guide writes downstream (e.g. a webhook target), use a real entity, not a mock. - For pages/widgets, use the real page identifier from the app URL, not a guessed slug. - When you hit a UI step confirmed (not assumed) unsupported via MCP, pause, give exact clicks, then resume via MCP. - Validate and give links after each meaningful step (only a tool-returned URL, no guessed paths); don't proceed if the last run wasn't a success. Done: - Confirm the guide's expected output exists and runs in Port. - Summarize adaptations, seeded data, what was mocked or skipped, remaining UI steps, and how to verify.
This guide demonstrates how to automatically resolve Jira tickets using coding agents orchestrated by Port or an n8n workflow enriched with Port context.
Both approaches preserve service ownership, repository, dependency, and documentation context when work moves from Jira to GitHub. They also maintain traceability by linking generated issues and pull requests back to the original ticket.
Common use casesβ
- Create pull requests for bug fixes automatically to reduce repetitive work.
- Generate GitHub issues from Jira tickets with Port context before assigning them to coding agents.
- Assign enriched GitHub issues to coding agents such as GitHub Copilot or Claude Code.
- Preserve organizational context from services, repositories, teams, dependencies, and documentation.
- Link Jira tickets to GitHub issues and pull requests for end-to-end traceability.
- Choose Port-native or external orchestration based on your automation environment.
Choose your approachβ
Choose coding agents when you want Port to orchestrate ticket resolution directly. Choose n8n when your team already operates n8n or prefers external orchestration.
- Coding agents
- n8n workflow
Use this approach to run ticket resolution with a Port workflow or with Port actions, automations, and an AI agent.
You can implement the Port-native flow in one of two ways:
-
Workflow - A single Port workflow runs when a Jira ticket moves to In Progress. It enriches the ticket with Port context, creates a GitHub issue, triggers the coding agent, and comments on Jira with the issue link.
-
Actions & Automations - An AI agent creates GitHub issues from Jira tickets with Port context. Automations invoke the agent and add the pull request link to Jira when the coding agent opens a pull request.
Both options use the same data model and external-tool setup. Only their orchestration differs.

Prerequisites
This guide assumes the following:
- You have a Port account and have completed the onboarding process.
- You have access to a Slack developer account with permissions to create apps.
- Port's Jira integration is installed in your account.
- GitHub Ocean integration is installed in your account.
- You have completed the setup in the Trigger GitHub Copilot from Port guide, so that Copilot is automatically assigned to GitHub issues created through this guide.
- For the Workflow option: you have access to workflows in Port. Workflows are currently in open beta and available to all users.
While this guide uses GitHub and Jira, you can adapt it for other Git providers (e.g. GitLab, Azure DevOps) and project management tools (e.g. Linear). You can also use other coding agents (e.g. Claude Code, Devin) instead of GitHub Copilot for similar automation.
Set up data model
We will configure the necessary blueprints to support our AI-enhanced coding workflow. This involves updating the Jira issue blueprint with necessary relations.
Update Jira issue blueprint
When you install Port's Jira integration, the Jira project and issue blueprints are created by default. However, we need to update the Jira issue blueprint to add the pull request relation and create a mirror property for the PR link.
-
Go to the builder page in Port.
-
Find and select your existing Jira issue blueprint (e.g.
jiraIssue). -
Click on
{...} Edit JSON. -
Add the following relation to the
relationssection:Pull request relation (Click to expand)
"pull_request": {"target": "githubPullRequest","required": false,"many": false} -
Add the following mirror property to the
mirrorPropertiessection:Pull request link mirror property (Click to expand)
"pull_request_link": {"title": "Pull Request Link","path": "pull_request.link"} -
Click
Saveto update the blueprint.
Update GitHub integration mapping
To track pull requests opened by Copilot that are meant to fix Jira issues, we need to update the GitHub integration mapping so that a pull request can be linked to the corresponding Jira issue using the Jira issue key in the PR title.
-
Go to the data sources page in Port.
-
Find and select your GitHub Ocean integration.
-
Go to the Mapping tab and click
{...} Edit JSON. -
Add the following mapping to the
mappingssection:Pull request mapping (Click to expand)
- kind: pull-requestselector:query: ((.title // "") | test("[A-Z]+-[0-9]+")) and (.user.login == "Copilot")port:entity:mappings:identifier: (.title // "") | match("[A-Z]+-[0-9]+").stringblueprint: '"jiraIssue"'properties: {}relations:pull_request: .id|tostring -
Click
Saveto update the integration configuration.
Set up external tools
We need Jira API access so that the workflow or automations can add comments to Jira issues.
Set up Jira API access
-
Log in to your Jira instance.
-
Generate an API token:
- Go to Atlassian Account Settings.
- Click Create API token. Ensure the token has permission to update issues and add comments.
- Copy the generated token (you will need it for the Port secret).
Set up Slack app
-
Create a Slack app and install it on a workspace.
-
Add the following permissions to the Slack app:
- Send messages (required).
chat:write.chat:write.public.
- Send messages (required).
-
Navigate back to the OAuth & Permissions page. You will see an access token under OAuth Tokens for Your Workspace that you will use in the
SLACK_BOT_TOKENPort secret.

Add Port secrets
To add secrets to Port:
-
Click ... in the top right corner of your Port application.
-
Click Credentials.
-
Click the Secrets tab.
-
Click + Secret and add the following secrets:
GITHUB_TOKENβ A GitHub fine-grained personal access token with read and write permissions for Issues, Metadata, and Pull requests, and Actions (write) for workflow dispatch. Required for the Workflow option; the Actions & Automations option may need it if you use an action that creates GitHub issues via the API.GITHUB_ORGβ Your GitHub organization or username. Required for the Actions & Automations option when using thecreate_github_issueaction.SLACK_BOT_TOKEN- Your Slack bot token from the OAuth & Permissions page.
Choose a Port-native implementation
Choose one implementation. The data model and external setup above are the same for both.
- Workflow β One workflow runs when a Jira issue moves to In Progress with the required label. It calls Port AI for context, creates a GitHub issue, triggers the Copilot assignment workflow, and comments on the Jira issue with the GitHub link. No separate AI agent; the flow is deterministic and visible in the workflow editor.
- Actions & Automations β You create an AI agent that generates GitHub issues from Jira tickets, and two automations: one that invokes the agent when a Jira ticket moves to In Progress with the copilot label, and one that adds the PR link to the Jira ticket when a related pull request is created.
- Workflow
- Actions & Automations
Build the workflow
Use Port's workflow to run the full sequence: trigger on Jira update β enrich with AI context β create GitHub issue β trigger Copilot β comment on Jira. You can build it with the AI assistant or paste the JSON template.
-
Go to the workflows page in Port.
-
Click on the + Workflow button in the top-right corner.
-
In the dialog, click Skip to editor to open the workflow editor.
-
Copy and paste this JSON template directly into the editor.
Automatically resolve ticket workflow template (Click to expand)
{"title": "Autonomous Ticket Resolution With AI","icon": "Jira","description": "Automatically generate GitHub issues from Jira tickets with rich organizational context when tickets move to In Progress, assign to GitHub Copilot, and link PRs back to Jira","allowAnyoneToViewRuns": true,"nodes": [{"identifier": "trigger","title": "On Jira Ticket Updated","icon": "Jira","description": "Listens for Jira issue updates and triggers the workflow when a ticket transitions from 'To Do' to 'In Progress', is product-approved, and has an assignee.","config": {"type": "EVENT_TRIGGER","event": {"type": "ENTITY_UPDATED","blueprintIdentifier": "jiraIssue"},"condition": {"type": "JQ","expressions": [".diff.before.properties.status == \"To Do\"",".diff.after.properties.status == \"In Progress\"","(.diff.after.properties.labels | index(\"product_approved\")) != null",".diff.after.relations.assignee != null"],"combinator": "and"},"published": true},"variables": {},"links": [],"verbose": true},{"identifier": "extract_context_with_ai","title": "Extract Context with Port AI","icon": "AI","description": "Invokes Port AI to enrich the Jira issue with contextual data from the Port catalog","config": {"type": "AI","userPrompt": "A Jira issue has moved to In Progress.\n\nIssue Details:\n- Key: {{ .outputs.trigger.diff.after.identifier }} \n- Title: {{ .outputs.trigger.diff.after.title }}\n- Type: {{ .outputs.trigger.diff.after.properties.issueType }}\n- Description: {{ .outputs.trigger.diff.after.properties.description }}\n\nRelated Jira Project:\n- Key: {{ .outputs.trigger.diff.after.relations.project }}\n\nYour task:\nQuery the Port catalog using MCP tools to find any related services or repositories connected to this Jira issue.\n\n- Always fetch ALL available properties for each entity\n- Do not limit properties unless explicitly required\n\nExtract ONLY context that actually exists and is directly related via Port relationships.\n\n### Core service context (if available)\n- Service description and tier based on the README\n- Owning team(s)\n- Deployment environments (e.g. prod)\n- Key dependencies (upstream/downstream services)\n\n### Relationship-heavy context (AGGREGATE, DO NOT LIST)\nFor the related service/repository, summarize:\n- PagerDuty incidents:\n - Total number of open incidents\n- Deployments:\n - Number of deployments\n - Environments deployed to\n - Most recent deployment timestamp (if available)\n- Security vulnerabilities:\n - Number of open vulnerabilities\n - Breakdown by severity (e.g. critical / high / medium)\n\nDo NOT include:\n- Raw logs\n- \"None found\" bullet lists\n\nOnly mention a category if at least one related entity exists.\n\nThen prepare:\n1. A GitHub issue title that starts with the Jira key in this exact format: {{ .outputs.trigger.diff.after.identifier }} - <what needs to be done>\n2. A GitHub issue body that:\n- Clearly summarizes the Jira issue in developer-friendly language\n- Adds concise business-relevant Port context (ownership, risk, stability, deploy state)\n- Uses aggregated facts, not exhaustive lists\n- Avoids assumptions or inferred data\n- Is fully self-contained\n\nReturn your response as a JSON object with this exact structure:\n{\n \"title\": \"<GitHub issue title starting with Jira key>\",\n \"body\": \"<GitHub issue body with context>\",\n \"labels\": [\"<Jira key as label>\", \"auto_assign\", \"<additional relevant labels>\"]\n\n\nIMPORTANT OUTPUT CONSTRAINT (HIGHEST PRIORITY)\n- If no relevant Port context exists, use empty strings (\"\") for fields where applicable.\n- You must return ONLY a valid JSON object and nothing else.\n\nOutput format:\nThe response must be parseable by JSON.parse() with no cleanup.\nReturn EXACTLY:\n{\"title\":\"\",\"body\":\"\",\"labels\":[\"\"]}","systemPrompt": "You are a helpful assistant that extracts contextual information from the Port catalogue. You must return ONLY a valid JSON object and nothing else. If you violate this output format, downstream systems will fail.","tools": ["^(list|get|search|load|track|describe)_.*"],"outputSchema": {"type": "object","properties": {"body": {"type": "string"},"title": {"type": "string"},"labels": {"type": "array","items": {"type": "string"}}}}},"variables": {},"links": [],"verbose": false},{"identifier": "has_ai_context","title": "Has AI Response","icon": null,"description": "Checks whether the AI context extraction completed successfully and returned a non-empty response. Prevents downstream actions when AI invocation fails or returns no usable output.","config": {"type": "CONDITION","outlets": [{"identifier": "yes","title": "AI context available","expression": "(.outputs.extract_context_with_ai.response != null)"},{"identifier": "no","title": "AI failed or returned no context","expression": ".outputs.extract_context_with_ai.response == null"}]},"variables": {},"links": [],"verbose": false},{"identifier": "create_github_issue","title": "Create GitHub Issue","icon": "Github","description": "Creates a new GitHub issue using the Jira issue details and AI-generated context","config": {"type": "WEBHOOK","url": "https://api.github.com/repos/<GITHUB_ORG>/<GITHUB_REPO>/issues","agent": false,"synchronized": true,"method": "POST","headers": {"Accept": "application/vnd.github+json","Authorization": "Bearer {{ .secrets.GITHUB_TOKEN }}","X-GitHub-Api-Version": "2022-11-28"},"body": {"body": "{{ .outputs.extract_context_with_ai.response | fromjson | .body }}","title": "{{ .outputs.extract_context_with_ai.response | fromjson | .title }}","labels": "{{ .outputs.extract_context_with_ai.response | fromjson | .labels }}"},"onTimeout": "fail","onFailure": "terminate"},"variables": {},"links": [],"verbose": false},{"identifier": "comment_on_jira_ai_failure","title": "Comment on Jira β AI Context Failed","icon": "Jira","description": "Adds a comment to the Jira issue explaining that automated GitHub issue creation was skipped because AI context extraction failed, and suggests next steps.","config": {"type": "WEBHOOK","url": "https://<YOUR_JIRA_ORGANIZATION_URL>/rest/api/3/issue/{{ .outputs.trigger.jira_key }}/comment","agent": false,"synchronized": true,"method": "POST","headers": {"Accept": "application/json","Content-Type": "application/json","Authorization": "Basic {{ .secrets._JIRA_ATLASSIAN_USER_EMAIL + \":\" + .secrets._JIRA_ATLASSIAN_USER_TOKEN | @base64 }}"},"body": {"body": {"type": "doc","content": [{"type": "paragraph","content": [{"text": "β οΈ Automated GitHub issue creation was skipped because context enrichment failed.","type": "text"}]},{"type": "paragraph","content": [{"text": "What this means:\nβ’ The Jira ticket was detected correctly\nβ’ The AI step did not return usable context\nβ’ No GitHub issue was created to avoid low-quality or incomplete data","type": "text"}]},{"type": "paragraph","content": [{"text": "Next steps:\nβ’ You can retry the automation\nβ’ Or manually create a GitHub issue if work should proceed immediately","type": "text"}]}],"version": 1}},"onTimeout": "fail","onFailure": "terminate"},"variables": {},"links": [],"verbose": false},{"identifier": "trigger_copilot_assignment","title": "Trigger Copilot Assignment Workflow","icon": "Github","description": "Triggers a GitHub Actions workflow that assigns the newly created GitHub issue to GitHub Copilot, enabling AI-assisted implementation.","config": {"type": "WEBHOOK","url": "https://api.github.com/repos/<GITHUB_ORG>/<GITHUB_REPO>/actions/workflows/assign_to_copilot.yml/dispatches","agent": false,"synchronized": true,"method": "POST","headers": {"Accept": "application/vnd.github+json","Authorization": "Bearer {{ .secrets.GITHUB_TOKEN }}","X-GitHub-Api-Version": "2022-11-28"},"body": {"ref": "main","inputs": {"issue_number": "{{.outputs.create_github_issue.response.data.number | tostring}}","repository_name": "<GITHUB_REPO>","repository_owner": "<GITHUB_ORG>"}},"onTimeout": "fail","onFailure": "terminate"},"variables": {},"links": [],"verbose": false},{"identifier": "send_to_slack","title": "Send to Slack","icon": "Slack","description": "Sends a rich, informative Slack notification with workflow summary, automation steps, and quick action buttons","config": {"type": "WEBHOOK","url": "https://slack.com/api/chat.postMessage","agent": false,"synchronized": true,"method": "POST","headers": {"Content-Type": "application/json","Authorization": "Bearer {{ .secrets.SLACK_BOT_TOKEN }}"},"body": {"text": "β Autonomous Ticket Resolution Complete - {{ .outputs.trigger.diff.after.identifier }}","blocks": [{"text": {"text": "β Autonomous Ticket Resolution Complete","type": "plain_text","emoji": true},"type": "header"},{"text": {"text": "*{{ .outputs.trigger.diff.after.title }}*","type": "mrkdwn"},"type": "section"},{"type": "divider"},{"text": {"text": "π *Workflow Summary*","type": "mrkdwn"},"type": "section"},{"type": "section","fields": [{"text": "*Status:*\nπ’ In Progress","type": "mrkdwn"},{"text": "*Issue Type:*\n{{ .outputs.trigger.diff.after.properties.issueType }}","type": "mrkdwn"},{"text": "*Project:*\n<https://app.port.io/jiraProjectEntity?identifier={{ .outputs.trigger.diff.after.relations.project }}|{{ .outputs.trigger.diff.after.relations.project }}>","type": "mrkdwn"},{"text": "*Assignee:*\n{{ .outputs.trigger.diff.after.relations.assignee }}","type": "mrkdwn"}]},{"type": "divider"},{"text": {"text": "π *AI-Powered Automation Steps*\nπ Context Enrichment from Port Catalog\nπ GitHub Issue Created (#{{.outputs.create_github_issue.response.data.number}})\nπ€ Assigned to GitHub Copilot\nπ Linked to Jira Ticket","type": "mrkdwn"},"type": "section"},{"type": "divider"},{"type": "actions","elements": [{"url": "https://app.port.io/jiraIssueEntity?identifier={{ .outputs.trigger.diff.after.identifier }}","text": {"text": "View Jira Ticket","type": "plain_text","emoji": true},"type": "button","style": "primary"},{"url": "{{ .outputs.create_github_issue.response.data.html_url }}","text": {"text": "View GitHub Issue","type": "plain_text","emoji": true},"type": "button"},{"url": "https://app.port.io/jiraIssueEntity?identifier={{ .outputs.trigger.diff.after.identifier }}&activeTab=2","text": {"text": "View PRD","type": "plain_text","emoji": true},"type": "button"}]},{"type": "context","elements": [{"text": "Powered by Port AIβ¨","type": "mrkdwn"}]}],"channel": "<SLACK_CHANNEL>"},"onTimeout": "fail","onFailure": "terminate"},"variables": {},"links": [],"verbose": false},{"identifier": "update_jira_with_github_link","title": "Add Comment to Jira Issue","icon": "Jira","description": "Adds a comment to the original Jira ticket containing a direct link to the created GitHub issue, ensuring traceability between Jira and GitHub.","config": {"type": "WEBHOOK","url": "https://<YOUR_JIRA_ORGANIZATION_URL>/rest/api/3/issue/{{.outputs.trigger.jira_key}}/comment","agent": false,"synchronized": true,"method": "POST","headers": {"Accept": "application/json","Content-Type": "application/json","Authorization": "Basic {{ .secrets._JIRA_ATLASSIAN_USER_EMAIL + \":\" + .secrets._JIRA_ATLASSIAN_USER_TOKEN | @base64 }}"},"body": {"body": {"type": "doc","content": [{"type": "paragraph","content": [{"text": "β GitHub issue created and assigned to Copilot: ","type": "text"},{"text": "{{ .outputs.create_github_issue.response.data.html_url }}","type": "text","marks": [{"type": "link","attrs": {"href": "{{ .outputs.create_github_issue.response.data.html_url }"}}]}]}],"version": 1}},"onTimeout": "fail","onFailure": "terminate"},"variables": {},"links": [],"verbose": false}],"connections": [{"description": "Triggered when a Jira issue meets the workflow criteria and begins AI-based context enrichment.","sourceIdentifier": "trigger","targetIdentifier": "extract_context_with_ai"},{"description": "Routes the AI invocation result into a conditional gate to determine whether downstream actions should proceed.","sourceIdentifier": "extract_context_with_ai","targetIdentifier": "has_ai_context"},{"description": "Continues workflow execution only when AI context extraction succeeds","sourceIdentifier": "has_ai_context","targetIdentifier": "create_github_issue","sourceOutletIdentifier": "yes"},{"description": "Uses the newly created GitHub issue to trigger Copilot assignment.","sourceIdentifier": "create_github_issue","targetIdentifier": "trigger_copilot_assignment"},{"description": "Finalizes the workflow by linking the GitHub issue back to the originating Jira ticket.","sourceIdentifier": "trigger_copilot_assignment","targetIdentifier": "update_jira_with_github_link"},{"description": "Notifies Jira that AI context extraction failed and GitHub issue creation was intentionally skipped.","sourceIdentifier": "has_ai_context","targetIdentifier": "comment_on_jira_ai_failure","sourceOutletIdentifier": "no"},{"description": "Send Slack notification","sourceIdentifier": "update_jira_with_github_link","targetIdentifier": "send_to_slack"}]} -
Click Publish in the top right corner of the editor. If you encounter validation errors, refer to the workflows troubleshooting page.
Configure the workflow
After publishing, replace placeholder values in the workflow nodes.
Specify Jira URL and auth
- Update the Comment on Jira - AI Context Failed (
comment_on_jira_ai_failure) and Add Comment to Jira Issue (update_jira_with_github_link) nodes.- Replace
<YOUR_JIRA_ORGANIZATION_URL>in the webhook URL with your Jira organization URL (e.g.example.atlassian.net).
- Replace
Specify Slack channel
- Update the Send to Slack (
send_to_slack) node.- Replace
<SLACK_CHANNEL>in the request body with your preferred Slack channel to receive notification about the automation run.
- Replace
Configure the GitHub integration
-
Update the Create GitHub Issue (
create_github_issue) node.- Replace
<GITHUB_ORG>with your GitHub organization or username. - Replace
<GITHUB_REPO>with your repository name.
- Replace
-
Update the Trigger Copilot Assignment Workflow (
trigger_copilot_assignment) node.- Replace
<GITHUB_ORG>and<GITHUB_REPO>in the webhook URL with the same values. - Update the
repository_nameandrepository_ownerinputs to match.
- Replace
Create the GitHub issue action
The AI agent uses the create_github_issue action to create GitHub issues from Jira tickets. Create this action first so the agent can invoke it.
-
Go to the Self-service page in Port.
-
Click on the + New Action button.
-
Click on the
{...} Edit JSONbutton. -
Copy and paste the following JSON configuration into the editor:
Create GitHub issue action (Click to expand)
Replace the variables<GITHUB-ORG>- your GitHub organization or user name.<GITHUB-REPO-NAME>- the repository where the workflow file is stored.<YOUR_GITHUB_OCEAN_INTEGRATION_ID>- your GitHub Ocean integration installation ID.
{"identifier": "create_github_issue","title": "Create GitHub Issue","icon": "Github","description": "A self-service action to open a GitHub repository issue with labels","trigger": {"type": "self-service","operation": "DAY-2","userInputs": {"properties": {"title": {"icon": "DefaultProperty","type": "string","title": "Issue Title"},"labels": {"type": "array","title": "Label","description": "Issue label","default": ["bug"],"items": {"enum": ["bug","enhancement","documentation","dependencies","question","invalid","duplicate"],"enumColors": {"bug": "red","enhancement": "turquoise","documentation": "blue","dependencies": "purple","question": "lime","invalid": "yellow","duplicate": "orange"},"type": "string"}},"content": {"type": "string","title": "Content","format": "markdown"}},"required": ["title"],"order": ["title", "content", "labels"]},"blueprintIdentifier": "githubRepository"},"invocationMethod": {"type": "INTEGRATION_ACTION","installationId": "<YOUR_GITHUB_OCEAN_INTEGRATION_ID>","integrationActionType": "dispatch_workflow","integrationActionExecutionProperties": {"org": "<GITHUB-ORG>","repo": "<GITHUB-REPO-NAME>","workflow": "create-github-issue.yml","workflowInputs": {"title": "{{ .inputs.title }}","content": "{{ .inputs.content }}","labels": "{{ .inputs.labels }}","target_org": "{{ .secrets.GITHUB_ORG }}","target_repo": "{{ .entity.identifier }}","port_context": {"blueprint": "{{ .action.blueprint }}","entity": "{{ .entity }}","runId": "{{ .run.id }}","trigger": "{{ .trigger }}"}},"reportWorkflowStatus": true}},"requiredApproval": false} -
Click Save to create the action.
Add the GitHub workflow
The self-service action dispatches a GitHub workflow that creates the enriched issue. Follow these steps in the repository that stores your Port workflows.
-
Add the following GitHub repository secrets:
PORT_CLIENT_IDβ your Port client ID.PORT_CLIENT_SECRETβ your Port client secret.GH_TOKENβ a GitHub token with permission to create issues in the target repositories.
-
Create the workflow file
.github/workflows/create-github-issue.ymlin the same repository:Create GitHub issue workflow (Click to expand)
create-github-issue.ymlname: Create GitHub issueon:workflow_dispatch:inputs:title:required: truetype: stringcontent:required: falsetype: stringlabels:required: falsetype: stringtarget_org:required: truetype: stringtarget_repo:required: truetype: stringport_context:required: truetype: stringjobs:create-issue:runs-on: ubuntu-lateststeps:- name: Inform starting of issue creationuses: port-labs/port-github-action@v1with:clientId: ${{ secrets.PORT_CLIENT_ID }}clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}operation: PATCH_RUNrunId: ${{ fromJson(inputs.port_context).runId }}logMessage: |Creating a GitHub issue...- name: Create GitHub issueenv:GH_TOKEN: ${{ secrets.GH_TOKEN }}run: |LABELS_INPUT='${{ inputs.labels }}'LABELS_JSON=$(echo "$LABELS_INPUT" | jq -c 'if type == "string" then fromjson | (if type == "array" then . else [.] end) else (if type == "array" then . else [.] end) end' 2>/dev/null || echo "[\"bug\"]")PAYLOAD=$(jq -n \--arg title "${{ inputs.title }}" \--arg body "${{ inputs.content }}" \--argjson labels "$LABELS_JSON" \'{title: $title, body: $body, labels: $labels}')RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \-H "Accept: application/vnd.github+json" \-H "Authorization: Bearer $GH_TOKEN" \-H "Content-Type: application/json" \-d "$PAYLOAD" \"https://api.github.com/repos/${{ inputs.target_org }}/${{ inputs.target_repo }}/issues")HTTP_STATUS=$(echo "$RESPONSE" | tail -n1)BODY=$(echo "$RESPONSE" | sed '$d')echo "HTTP Status: $HTTP_STATUS"if [ "$HTTP_STATUS" -ge 200 ] && [ "$HTTP_STATUS" -lt 300 ]; thenecho "Issue created successfully."echo "$BODY" | jq -r '.html_url' >> $GITHUB_STEP_SUMMARYelseecho "Failed to create issue. Response: $BODY"exit 1fi- name: Inform completionuses: port-labs/port-github-action@v1with:clientId: ${{ secrets.PORT_CLIENT_ID }}clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}operation: PATCH_RUNrunId: ${{ fromJson(inputs.port_context).runId }}logMessage: |GitHub issue created.
Create an AI agent
We will create an AI agent that generates GitHub issues from Jira tickets with appropriate context and labels.
Configure the GitHub issue creation AI agent
-
Go to the AI Agents page in Port.
-
Click on
+ AI Agent. -
Toggle
Json modeon. -
Copy and paste the following JSON schema:
GitHub issue creation AI agent configuration (Click to expand)
{"identifier": "work_item_synchronizer","title": "Work Item Synchronizer","icon": "Details","team": [],"properties": {"description": "Ensures seamless workflow continuity across development tools","status": "active","prompt": "Create a GitHub issue that builds on the context of a linked Jira ticket.\n\nThe GitHub issue should:\n1.\tSummarize and clearly explain the task, using the Jira description as a base.\n2.\tAugment the description with relevant insights from the repository β such as the README, setup or contribution instructions, existing issues, or implementation notes β to make the issue fully self-contained.\n3.\tThe **issue title MUST start with the Jira ticket key**, using the format: `<Jira-Ticket-ID> - <what needs to be done>` (e.g., `JIRA-1234 - Add missing lint configuration`). This ensures PRs created by Copilot are linkable back to Jira.\n4.\tAdd GitHub labels, including one with the Jira ticket key (e.g., `JIRA-1234`), and any additional relevant labels (e.g., bug, enhancement, infra).\n5.\tAlso include a label named `auto_assign` in all creations.\n6. The GitHub issue body should end with the following directive:\nπ¨ **IMPORTANT NOTE FOR COPILOT**: When creating the pull request to resolve this issue:\n 1. You **must ALWAYS include the Jira ticket ID** (e.g., `JIRA-1234`) in the **PR title**.\n 2. Do **not** rename the PR title or remove the Jira ticket reference.\n 3. Add GitHub labels with the Jira ticket key (e.g., `JIRA-1234`) to the PR.\n\nIf no direct match can be confidently made (e.g., across multiple repos), make a best guess, and clearly state any assumptions in the issue body.","execution_mode": "Automatic","conversation_starters": [],"tools": ["^(list|search|track|describe)_.*","^run_create_github_issue$"]},"relations": {}}MCP enhanced capabilitiesThe AI agent uses MCP (Model Context Protocol) enhanced capabilities to discover relevant blueprint entities via its tools. The
^(list|search|track|describe)_.*pattern lets the agent access and analyze related entities in your context lake. We also add^run_create_github_issue$so the agent can create GitHub issues from Jira tickets. -
Click
Createto save the agent.
Set up automations
We will create two automations:
-
Trigger the AI agent when Jira tickets move to In Progress with the copilot label.
-
Comment on the Jira ticket with the related pull request link when a PR is linked.
Create an automation to trigger the AI agent
This automation can be configured to trigger on different criteria (e.g. label, properties, or ownership), such as: automatically fix small bugs, fix security issues with critical SLA, or only tasks in repositories that are onboarded to the AI agents and are considered low-risk.
-
Go to the automations page in Port.
-
Click on
+ Automation. -
Copy and paste the following JSON schema:
Create GitHub issue from Jira automation (Click to expand)
{"identifier": "create_github_issue_from_jira","title": "Create a GitHub issue from Jira ticket","description": "When Jira issue moves to In Progress with Copilot label, create a GitHub issue","icon": "Github","trigger": {"type": "automation","event": {"type": "ENTITY_UPDATED","blueprintIdentifier": "jiraIssue"},"condition": {"type": "JQ","expressions": [".diff.after.properties.status == \"In Progress\"",".diff.before.properties.status == \"To Do\"","(.diff.after.properties.labels | index(\"copilot\")) != null"],"combinator": "and"}},"invocationMethod": {"type": "WEBHOOK","url": "https://api.port.io/v1/agent/work_item_synchronizer/invoke","agent": false,"synchronized": true,"method": "POST","headers": {"RUN_ID": "{{ .run.id }}","Content-Type": "application/json"},"body": {"prompt": "Jira Task title: \"{{.event.diff.after.title}}\"\n. Jira Task identifier: \"{{.event.diff.after.identifier}}\"\n Jira Task description: \"{{.event.diff.after.properties.description}}\"\nRepository:{{.event.diff.after.relations.repository}}.","labels": {"source": "create_github_issue_automation","jira_issue_id": "{{ .event.diff.after.identifier }}"}}},"publish": true} -
Click
Createto save the automation.
Create an automation to add the pull request link to Jira
This automation adds a comment to the Jira ticket when a new pull request is linked (e.g. by the GitHub integration), so the ticket shows the PR link.
-
Go back to the automations page in Port.
-
Click on
+ Automation. -
Copy and paste the following JSON schema:
Add PR link to Jira issue automation (Click to expand)
Atlassian domain replacementReplace
<YOUR_ATLASSIAN_DOMAIN>with your actual Atlassian domain in the webhook URL.{"identifier": "add_pr_link_to_jira_issue","title": "Add PR Link to Jira Issue","description": "An automation that adds the PR link to the Jira issue as a comment","icon": "GitPullRequest","trigger": {"type": "automation","event": {"type": "ENTITY_UPDATED","blueprintIdentifier": "jiraIssue"},"condition": {"type": "JQ","expressions": [".diff.after.relations.pull_request != .diff.before.relations.pull_request"],"combinator": "and"}},"invocationMethod": {"type": "WEBHOOK","url": "https://<YOUR_ATLASSIAN_DOMAIN>.atlassian.net/rest/api/3/issue/{{ .event.diff.before.identifier }}/comment","agent": false,"synchronized": true,"method": "POST","headers": {"RUN_ID": "{{ .run.id }}","Authorization": "Basic {{ .secrets._JIRA_ATLASSIAN_USER_EMAIL + \":\" + .secrets._JIRA_ATLASSIAN_USER_TOKEN | @base64 }}","Content-Type": "application/json"},"body": {"body": {"type": "doc","version": 1,"content": [{"type": "paragraph","content": [{"type": "text","text": "A new pull request identified for this ticket. Find the link below:"}]},{"type": "paragraph","content": [{"type": "text","text": "View Pull Request","marks": [{"type": "link","attrs": {"href": "{{ .event.diff.after.properties.pull_request_link }}"}},{"type": "strong"}]}]}]}}},"publish": true} -
Click
Createto save the automation.
Test the implementation
After you complete either the Workflow or the Actions & Automations setup, use the steps below to verify that ticket resolution runs correctly.
Trigger a test Jira ticket update
-
Go to your Jira instance and find a test ticket.
-
Add the required label:
- Workflow: add the product_approved label and ensure the ticket has an assignee.
- Actions & Automations: add the copilot label.
-
Move the ticket status from To Do to In Progress.
Verify GitHub issue creation
-
Go to your GitHub repository.
-
Verify that a new issue was created with the appropriate title (starting with the Jira key), description, and labels.
-
Check that the issue has the
auto_assignlabel.
Test pull request linking
-
Verify that the GitHub issue is automatically assigned to Copilot.
-
Confirm that a pull request is created (with the Jira ticket key in the title for the Actions & Automations flow).
-
Check the Jira ticket for a comment: Workflow adds the GitHub issue link; Actions & Automations adds the PR link when the PR is linked to the Jira issue.

- Check the Slack channel for the sent notification.
More relevant guides
Use this approach when your team already operates n8n or prefers to orchestrate ticket resolution outside Port. The workflow uses Port as its context lake before assigning an enriched GitHub issue to a coding agent.
The coding-agents tab requires no n8n infrastructure and keeps orchestration in Port. The n8n option is best suited to teams with an existing n8n environment.

Prerequisites
This guide assumes the following:
-
You have a Port account and have completed the onboarding process.
-
GitHub Ocean integration is installed in your account.
-
Port's Jira integration is installed in your account.
-
You have a working n8n instance (Cloud or self-hosted) with Port's n8n custom node installed.
-
Your GitHub organization has GitHub Copilot enabled, so Copilot can be automatically assigned to any issues created through this guide.
While this guide uses GitHub and Jira, you can adapt it for other Git providers like GitLab or Azure DevOps, and other project management tools like Linear. Additionally, although this guide demonstrates using GitHub Copilot, you can also use other coding agents like Claude Code, or Gemini, etc., to achieve similar automation and integration.
Create n8n workflow
We will create an n8n workflow that uses Port as a context lake to enrich GitHub issues with organizational context from your context lake. The workflow will trigger when a Jira issue moves to "In Progress" with a specific label, query Port for relevant context, and create a GitHub issue with that context.
Import the workflow template
-
Go to your n8n instance.
-
Click on Workflows in the left sidebar.
-
Click on Import from File or Import from URL.
-
Copy and paste the following workflow JSON:
n8n workflow template (Click to expand)
{"name": "Auto-resolve Jira tickets with GitHub Copilot using Port Context","nodes": [{"parameters": {"conditions": {"options": {"version": 2,"leftValue": "","caseSensitive": true,"typeValidation": "strict"},"combinator": "and","conditions": [{"id": "ded3f45f-fd63-493a-a5fc-225004d5d292","operator": {"type": "number","operation": "notEmpty","singleValue": true},"leftValue": "={{ $json.number }}","rightValue": ""}]},"options": {}},"id": "dc5b0535-793f-4ba7-b748-2798a3c4e22e","name": "Is issue creation successful?","type": "n8n-nodes-base.if","position": [2080,544],"typeVersion": 2.2},{"parameters": {"conditions": {"options": {"version": 2,"leftValue": "","caseSensitive": true,"typeValidation": "strict"},"combinator": "and","conditions": [{"id": "8800068e-ddaa-4979-a589-6442f424bb09","operator": {"type": "boolean","operation": "true","singleValue": true},"leftValue": "={{ $json.webhookEvent == \"jira:issue_updated\" && $json.issue.fields.status.name == \"In Progress\" && $json.issue.fields.labels.includes(\"product_approved\") && !$json.issue.fields.labels.includes(\"copilot_assigned\") }}","rightValue": ""}]},"options": {}},"id": "222058f6-cc6c-450a-8fbb-be3ed01c1f4a","name": "Is ready for assignment?","type": "n8n-nodes-base.if","position": [1184,560],"typeVersion": 2.2},{"parameters": {"owner": {"__rl": true,"value": "https://github.com/ORG","mode": "url"},"repository": {"__rl": true,"value": "aws-codeploy-demo","mode": "list"},"title": "={{ $json.result.message.parseJson().github_issue_title }}","body": "={{ $json.result.message.parseJson().github_issue_body }}","labels": [{"label": "n8n"},{"label": "ai-workflow"}],"assignees": []},"id": "03c29fb9-c747-4602-941e-a8f279cda515","name": "Create a GitHub issue","type": "n8n-nodes-base.github","position": [1872,544],"webhookId": "d7f1c627-82f6-4f61-a220-bbe24c943a51","typeVersion": 1.1,"credentials": {"githubApi": {"id": "3LaRYp1opDmuB6HX","name": "GitHub account"}}},{"parameters": {"operation": "createComment","owner": {"__rl": true,"value": "https://github.com/ORG","mode": "url"},"repository": {"__rl": true,"value": "aws-codeploy-demo","mode": "list"},"issueNumber": "={{ $('Create a GitHub issue').item.json.number }}","body": "@copilot please take ownership of this issue and begin working on a solution.\n\nUse the information in the issue body and title to propose and implement the necessary code changes.\n"},"id": "bd136228-82c3-4342-9a39-1461bf59b170","name": "Assign issue to Copilot","type": "n8n-nodes-base.github","position": [2288,544],"webhookId": "e4ba9b66-a68a-40d4-9c69-2dabb05d337b","typeVersion": 1.1,"credentials": {"githubApi": {"id": "3LaRYp1opDmuB6HX","name": "GitHub account"}}},{"parameters": {"resource": "issueComment","issueKey": "={{ $('On Jira ticket updated').item.json.issue.key }}","comment": "=We've created an issue at {{ $('Create a GitHub issue').item.json.html_url }} and assigned it to Copilot.","options": {}},"id": "ee576573-0a96-4713-b71e-cf6b48d1aabe","name": "Add issue link to Jira ticket","type": "n8n-nodes-base.jira","position": [2592,416],"typeVersion": 1,"credentials": {"jiraSoftwareCloudApi": {"id": "kFxflLsLkRHNY8gr","name": "Jira SW Cloud account"}}},{"parameters": {"operation": "update","issueKey": "={{ $('On Jira ticket updated').item.json.issue.key }}","updateFields": {"labels": "={{ $('On Jira ticket updated').item.json.issue.fields.labels.concat('copilot_assigned') }}"}},"id": "46c0c5c2-4670-4a68-8338-5ded401e7242","name": "Mark ticket as assigned","type": "n8n-nodes-base.jira","position": [2592,656],"typeVersion": 1,"credentials": {"jiraSoftwareCloudApi": {"id": "kFxflLsLkRHNY8gr","name": "Jira SW Cloud account"}}},{"parameters": {"events": ["jira:issue_updated"],"additionalFields": {}},"id": "155cb785-4a98-4d57-a8ed-fb45cd8a800e","name": "On Jira ticket updated","type": "n8n-nodes-base.jiraTrigger","position": [960,560],"webhookId": "559a3f87-cf37-4a25-b04a-13fc2dd72cf5","typeVersion": 1.1,"credentials": {"jiraSoftwareCloudApi": {"id": "kFxflLsLkRHNY8gr","name": "Jira SW Cloud account"}}},{"parameters": {"content": "## Auto-resolve Jira tickets with coding agents\n\nImprove issue resolution by assigning Jira tickets to coding agents with full operational context from Port, ensuring faster, accurate, and context-aware development\n\n### How it works\n1. Listen for Jira ticket updates and detect when an issue moves to \\\"In Progress\\\" with the label product_approved and without copilot_assigned.\n2. Query the Port catalog to extract only contextual information relevant to the Jira issue (services, repos, docs, resources, dependencies).\n3. Generate a concise GitHub issue title and a self-contained issue body that summarizes the Jira description and includes any found Port context.\n4. Create the GitHub issue in the target repository and post a comment that requests Copilot to take ownership.\n5. Write the GitHub link back to the Jira ticket and add the copilot_assigned label so the ticket is marked as handled.\n\n### Setup\n- [ ] Connect your Jira Cloud account and enable issue_updated events\n- [ ] Register for free on [Port.io](https://www.port.io)\n- [ ] Connect your Port.io account and add the API key\n- [ ] Connect your GitHub account and select the target repository\n- [ ] Ensure a Copilot bot or @copilot user has access to the repository\n- [ ] Confirm the workflow webhook or Jira trigger URL is active\n- [ ] Test by moving a product_approved ticket to In Progress","height": 672,"width": 512},"id": "4193fee9-a6b8-4fa3-a0cd-17397c54d64e","name": "Sticky Note","type": "n8n-nodes-base.stickyNote","position": [368,240],"typeVersion": 1},{"parameters": {"content": "## Port Context Lake\n\nTo extract contextual information relevant to the Jira issue (services, repos, docs, resources, dependencies).","height": 560,"width": 400,"color": 6},"id": "ff5792b7-5bcf-4837-9cc8-232f7dc69f7b","name": "Sticky Note1","type": "n8n-nodes-base.stickyNote","position": [1408,256],"typeVersion": 1},{"parameters": {"content": "## Github Copilot Assignment\n\nTo assign a ticket to Copilot, we first create a GitHub issue and then add a @copilot comment to the GitHub issue instructing Copilot to take ownership.","height": 560,"width": 592,"color": 4},"id": "c4d094bd-342f-4625-a881-484ea9b2ad45","name": "Sticky Note2","type": "n8n-nodes-base.stickyNote","position": [1840,256],"typeVersion": 1},{"parameters": {"content": "## Jira Ticket Linkage\n\nTo ensure that any new Github issue related to a Jira ticket is promptly linked back to the ticket in a comment, providing clear traceability and context for development progress.","height": 560,"width": 464,"color": 5},"id": "c0593d1b-48f9-4bfe-88db-6b2e2a0dbbf4","name": "Sticky Note3","type": "n8n-nodes-base.stickyNote","position": [2464,256],"typeVersion": 1},{"parameters": {"operation": "getInvocation","invocation_identifier": "={{ $json.invocationIdentifier }}"},"type": "@port-labs/n8n-nodes-portio-experimental.portApiAi","typeVersion": 1,"position": [1664,544],"id": "da319617-4f73-4988-8558-370cea868d60","name": "Parse Port AI response","credentials": {"portApi": {"id": "tRAwIiwSncqQh00a","name": "Port account"}}},{"parameters": {"operation": "generalInvoke","userPrompt": "=A Jira issue has moved to In Progress.\n\nIssue Details:\n- Key: {{ $('On Jira ticket updated').item.json.issue.key }}\n- Title: {{ $('On Jira ticket updated').item.json.issue.fields.summary }}\n- Type: {{ $('On Jira ticket updated').item.json.issue.fields.issuetype.name }}\n- Description: {{ $('On Jira ticket updated').item.json.issue.fields.description }}\n\nRelated Jira Project:\n- Key: {{ $('On Jira ticket updated').item.json.issue.fields.project.key }}\n- Name: {{ $('On Jira ticket updated').item.json.issue.fields.project.name }}\n\nRelated Service or Github Repo entity ID:\n{{ $('On Jira ticket updated').item.json.issue.fields.customfield_10308.value }}\n\nYour task:\nUse the Related Service/Repo ID and Issue ID to query the Port catalog.\n\nWhen querying Port entities via MCP (e.g. list_entities):\n- Always fetch ALL available properties for each entity\n- Do not limit properties unless explicitly required\n\nExtract ONLY context that actually exists and is directly related via Port relationships.\n\n### Core service context (if available)\n- Service description and tier based on the README\n- Owning team(s)\n- Deployment environments (e.g. prod, staging, dev)\n- Key dependencies (upstream/downstream services)\n\n### Relationship-heavy context (AGGREGATE, DO NOT LIST)\nFor the related service/repository, summarize:\n- PagerDuty incidents:\n - Total number of open incidents\n- Deployments:\n - Total number of deployments\n - Environments deployed to\n - Most recent deployment timestamp (if available)\n- Security vulnerabilities:\n - Total number of open vulnerabilities\n - Breakdown by severity (e.g. critical / high / medium)\n\nDo NOT include:\n- Raw logs\n- βNone foundβ bullet lists\n\nOnly mention a category if at least one related entity exists.\n\nThen prepare:\n1. A GitHub issue title that starts with the Jira key.\n2. A GitHub issue body that:\n- Clearly summarizes the Jira issue in developer-friendly language\n- Adds concise business-relevant Port context (ownership, risk, stability, deploy state)\n- Uses aggregated facts, not exhaustive lists\n- Avoids assumptions or inferred data\n- Is fully self-contained\n- Ends exactly with: @github-copilot please begin working on this issue.\n\nIMPORTANT OUTPUT CONSTRAINT (HIGHEST PRIORITY)\n- If no relevant Port context exists, use empty strings (\"\") for fields where applicable.\n- You must return ONLY a valid JSON object and nothing else.\n\nOutput format:\nThe response must be parseable by JSON.parse() with no cleanup.\nReturn EXACTLY:\n{\"github_issue_title\":\"\",\"github_issue_body\":\"\"}\n","generalProvider": "port","generalModel": "gpt-5","systemPrompt": "You are a helpful assistant that extracts contextual information from the Port catalogue. You must return ONLY a valid JSON object and nothing else. If you violate this output format, downstream systems will fail.","executionMode": "Automatic"},"type": "@port-labs/n8n-nodes-portio-experimental.portApiAi","typeVersion": 1,"position": [1472,544],"id": "9f3068e9-cbbe-47a6-a617-35914ba2c366","name": "Extract context from Port","credentials": {"portApi": {"id": "tRAwIiwSncqQh00a","name": "Port account"}}}],"pinData": {},"connections": {"Create a GitHub issue": {"main": [[{"node": "Is issue creation successful?","type": "main","index": 0}]]},"On Jira ticket updated": {"main": [[{"node": "Is ready for assignment?","type": "main","index": 0}]]},"Assign issue to Copilot": {"main": [[{"node": "Add issue link to Jira ticket","type": "main","index": 0},{"node": "Mark ticket as assigned","type": "main","index": 0}]]},"Is ready for assignment?": {"main": [[{"node": "Extract context from Port","type": "main","index": 0}]]},"Is issue creation successful?": {"main": [[{"node": "Assign issue to Copilot","type": "main","index": 0}]]},"Parse Port AI response": {"main": [[{"node": "Create a GitHub issue","type": "main","index": 0}]]},"Extract context from Port": {"main": [[{"node": "Parse Port AI response","type": "main","index": 0}]]}},"active": false,"settings": {"executionOrder": "v1","availableInMCP": false},"versionId": "de493068-851e-422d-96f5-9891b3e6868e","meta": {"templateId": "11728","templateCredsSetupCompleted": true,"instanceId": "ece285d5f6d021267c1bf415cc6f43f61f89e93c51704a3846513e293fe52759"},"id": "DhwPhvyAJzzDoAiq","tags": []} -
Click Import to load the workflow into n8n.
Configure workflow credentials
Before the workflow can run, you need to configure credentials for Jira, GitHub, and Port.
Configure Jira credentials
-
In the On Jira issue updated node, click on the credentials dropdown.
-
Select Create New Credential or use an existing Jira credential.
-
Enter your Jira credentials:
- Jira URL - Your Jira instance URL (e.g.,
https://your-domain.atlassian.net). - Email - Your Jira account email.
- API Token - Your Jira API token (create an Atlassian API token).
- Jira URL - Your Jira instance URL (e.g.,
-
Click Save to store the credential.
Configure GitHub credentials
-
In the Create an issue node, click on the credentials dropdown.
-
Select Create New Credential or use an existing GitHub credential.
-
Enter your GitHub credentials:
- GitHub personal access token - A token with
reposcope (create a GitHub personal access token).
- GitHub personal access token - A token with
-
Click Save to store the credential.
Configure workflow parameters
After importing the workflow, you need to update several parameters to match your environment:
-
Update GitHub repository settings:
- In the Create an issue node, update the
ownerfield with your GitHub organization or username. - Update the
repositoryfield with your target repository name.
- In the Create an issue node, update the
-
Update Jira trigger conditions (optional):
- In the Is Ready for Assignment? node, you can modify the condition to match your workflow requirements. The default condition checks for the following.
- The issue status is In Progress.
- The issue has the
product_approvedlabel.
- You can change the label name or add additional conditions as needed.
- In the Is Ready for Assignment? node, you can modify the condition to match your workflow requirements. The default condition checks for the following.
-
Update Port AI prompt (optional):
- In the Extract issue context node, you can customize the
userPromptto adjust how Port queries your catalog and formats the GitHub issue. - The prompt uses Port's MCP tools (
^(list|search|track|describe)_.*) to query your context lake for relevant context.
- In the Extract issue context node, you can customize the
You can customize the workflow to match your specific needs:
- Change the Jira label trigger condition to use different labels or status transitions.
- Modify the Port query prompt to focus on specific blueprint types or properties.
- Add additional nodes to enrich the workflow with notifications, logging, or other integrations.
- Adjust the GitHub issue labels to match your repository's labeling conventions.
Set up Jira webhook trigger
The workflow uses a Jira webhook trigger to listen for issue updates. After importing the workflow, you need to configure the webhook in Jira.
-
Open the On Jira issue updated node in your n8n workflow and copy its webhook URL.
-
In Jira, go to Settings > System > Webhooks and click Create a webhook.
-
Enter a name, paste the URL, enable it, select Issue updated, and optionally add a JQL filter.
-
Click Create to save.
Understand how the workflow works
The n8n workflow orchestrates the following steps:
-
Jira trigger β The workflow listens for Jira issue updates via webhook.
-
Condition check β Verifies that the issue status is "In Progress" and has the required label (e.g., "product_approved") without the "copilot_assigned" label.
-
Port context extraction β Uses Port's n8n node to query your context lake for relevant context about services, repositories, teams, dependencies, and documentation related to the Jira issue.
-
Parse response β Retrieves the AI-generated GitHub issue title and body from Port.
-
Create GitHub issue β Creates a new GitHub issue with the enriched context from Port.
-
Assign to Copilot β Adds a comment to the GitHub issue instructing Copilot to take ownership.
-
Add issue link to Jira ticket β Adds a comment to the Jira ticket with the GitHub issue URL, providing clear traceability.
-
Mark ticket as assigned β Updates the Jira ticket to add the "copilot_assigned" label, preventing duplicate processing.
Test the workflow
-
Trigger a test Jira update: Add the configured label (e.g.,
product_approved) to a test ticket and move it from To Do to In Progress. -
Verify workflow execution: In n8n, check the workflowβs execution history. Ensure each node outputs as expected (webhook payload, condition pass, Port context, parsed JSON, GitHub issue creation).
-
Verify GitHub issue: Confirm a new issue was created with the Jira key in the title, context in the description, correct labels, and a comment for Copilot.
More relevant guides
- Set up Port's n8n custom node β Learn how to install and configure Port's n8n node.
- Remediate vulnerability with n8n and Port β Another example of using Port as a context lake in n8n workflows.