Skip to main content

Check out Port for yourselfย 

Resource mapping examples

Map repositories and pull requestsโ€‹

The following example demonstrates how to ingest your GitHub repositories, their README.md file contents and open pull requests to Port.
You can use the following Port blueprint definitions and port-app-config.yml:

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Pull request blueprint (click to expand)
{
"identifier": "githubPullRequest",
"title": "Pull Request",
"icon": "Github",
"schema": {
"properties": {
"creator": {
"title": "Creator",
"type": "string"
},
"assignees": {
"title": "Assignees",
"type": "array"
},
"reviewers": {
"title": "Reviewers",
"type": "array"
},
"status": {
"title": "Status",
"type": "string",
"enum": ["merged", "open", "closed"],
"enumColors": {
"merged": "purple",
"open": "green",
"closed": "red"
}
},
"closedAt": {
"title": "Closed At",
"type": "string",
"format": "date-time"
},
"updatedAt": {
"title": "Updated At",
"type": "string",
"format": "date-time"
},
"mergedAt": {
"title": "Merged At",
"type": "string",
"format": "date-time"
},
"createdAt": {
"title": "Created At",
"type": "string",
"format": "date-time"
},
"link": {
"format": "url",
"type": "string"
},
"leadTimeHours": {
"title": "Lead Time in hours",
"type": "number"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {
"days_old": {
"title": "Days Old",
"icon": "DefaultProperty",
"calculation": "(now / 86400) - (.properties.createdAt | capture(\"(?<date>\\\\d{4}-\\\\d{2}-\\\\d{2})\") | .date | strptime(\"%Y-%m-%d\") | mktime / 86400) | floor",
"type": "number"
}
},
"relations": {
"repository": {
"title": "Repository",
"target": "githubRepository",
"required": false,
"many": false
}
}
}
Port port-app-config.yml (click to expand)
resources:
- kind: repository
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
port:
entity:
mappings:
identifier: ".name" # The Entity identifier will be the repository name.
title: ".name"
blueprint: '"githubRepository"'
properties:
readme: file://README.md # fetching the README.md file that is within the root folder of the repository and ingesting its contents as a markdown property
url: .html_url
defaultBranch: .default_branch
- kind: pull-request
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
states: ["open"] # List of Pull Request states to include: use ["open"], ["closed"], or ["open","closed"].
port:
entity:
mappings:
identifier: ".head.repo.name + (.id|tostring)" # The Entity identifier will be the repository name + the pull request ID.
title: ".title"
blueprint: '"githubPullRequest"'
properties:
creator: ".user.login"
assignees: "[.assignees[].login]"
reviewers: "[.requested_reviewers[].login]"
status: ".state" # merged, closed, opened
closedAt: ".closed_at"
updatedAt: ".updated_at"
mergedAt: ".merged_at"
createdAt: ".created_at"
prNumber: ".id"
link: ".html_url"
leadTimeHours: >-
(.created_at as $createdAt | .merged_at as $mergedAt |
($createdAt | sub("\\..*Z$"; "Z") | strptime("%Y-%m-%dT%H:%M:%SZ") | mktime) as $createdTimestamp |
($mergedAt | if . == null then null else sub("\\..*Z$"; "Z") |
strptime("%Y-%m-%dT%H:%M:%SZ") | mktime end) as $mergedTimestamp |
if $mergedTimestamp == null then null else
(((($mergedTimestamp - $createdTimestamp) / 3600) * 100 | floor) / 100) end)

relations:
repository: .__repository
learn more
  • Port leverages the JQ JSON processor to map and transform GitHub objects to Port Entities.
  • Click Here for the GitHub repository object structure.
  • Click Here for the GitHub pull request object structure.

After creating the blueprints and committing the port-app-config.yml file to your .github-private repository (for global configuration), or to any specific repositories (for per-repo configuration), you will see new entities in Port matching your repositories alongside their README.md file contents and pull requests. (Remember that the port-app-config.yml file has to be in the default branch of the repository to take effect).

Additionally, you can configure your selector to limit the number of closed pull requests to ingest using a combination of maxResults and since. By Default, we only fetch 100 cloosed pull requests within 60 days.

- kind: pull-request
selector:
query: "true"
states: ["closed"] # Specifically for closed PRs
maxResults: 50 # Limit closed PRs to 50 capped at 300
since: 60 # Fetch closed PRs within 60 days capped at 90 days

Map repositories and issuesโ€‹

The following example demonstrates how to ingest your GitHub repositories and their issues to Port, you may use the following Port blueprint definitions and port-app-config.yml:

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Issue blueprint (click to expand)
{
"identifier": "githubIssue",
"title": "Issue",
"icon": "Github",
"schema": {
"properties": {
"creator": {
"title": "Creator",
"type": "string"
},
"assignees": {
"title": "Assignees",
"type": "array"
},
"labels": {
"title": "Labels",
"type": "array"
},
"status": {
"title": "Status",
"type": "string",
"enum": ["open", "closed"],
"enumColors": {
"open": "green",
"closed": "purple"
}
},
"createdAt": {
"title": "Created At",
"type": "string",
"format": "date-time"
},
"closedAt": {
"title": "Closed At",
"type": "string",
"format": "date-time"
},
"updatedAt": {
"title": "Updated At",
"type": "string",
"format": "date-time"
},
"description": {
"title": "Description",
"type": "string",
"format": "markdown"
},
"issueNumber": {
"title": "Issue Number",
"type": "number"
},
"link": {
"title": "Link",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"repository": {
"target": "githubRepository",
"required": true,
"many": false
}
}
}
Port port-app-config.yml (click to expand)
resources:
- kind: repository
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
port:
entity:
mappings:
identifier: ".name" # The Entity identifier will be the repository name.
title: ".name"
blueprint: '"githubRepository"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: issue
selector:
query: ".pull_request == null" # JQ boolean query. If evaluated to false - skip syncing the object.
state: "closed"
port:
entity:
mappings:
identifier: ".__repository + (.id|tostring)"
title: ".title"
blueprint: '"githubIssue"'
properties:
creator: ".user.login"
assignees: "[.assignees[].login]"
labels: "[.labels[].name]"
status: ".state"
createdAt: ".created_at"
closedAt: ".closed_at"
updatedAt: ".updated_at"
description: ".body"
issueNumber: ".number"
link: ".html_url"
relations:
repository: ".__repository"
learn more
  • Refer to the setup section to learn more about the port-app-config.yml setup process.
  • We leverage JQ JSON processor to map and transform GitHub objects to Port Entities.
  • Click Here for the GitHub repository object structure.
  • Click Here for the GitHub issue object structure.

Map repositories and branchesโ€‹

The following example demonstrates how to ingest your GitHub repositories and their branches to Port, you may use the following Port blueprint definitions and port-app-config.yml:

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Branch blueprint (click to expand)
{
"identifier": "githubBranch",
"title": "Branch",
"icon": "Github",
"schema": {
"properties": {
"is_protected": {
"title": "Is branch protected",
"type": "boolean",
"icon": "DefaultProperty"
},
"commit_sha": {
"title": "Commit SHA",
"type": "string",
"icon": "DefaultProperty"
},
"commit_url": {
"title": "Commit URL",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "githubRepository",
"required": true,
"many": false
}
}
}
Port port-app-config.yml (click to expand)
resources:
- kind: repository
selector:
query: 'true'
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"githubRepository"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: branch
selector:
query: 'true'
port:
entity:
mappings:
identifier: .__repository + "_" + .name
title: .__repository + " " + .name
blueprint: '"githubBranch"'
properties:
is_protected: .protected
commit_sha: .commit.sha
commit_url: .commit.url
relations:
repository: .__repository

Map files and file contentsโ€‹

The following example demonstrates ingestion of dependencies from a package.json file in your repository into Port:

Package blueprint (click to expand)
{
"identifier": "package",
"title": "Package",
"icon": "Package",
"schema": {
"properties": {
"package": {
"icon": "DefaultProperty",
"type": "string",
"title": "Package"
},
"version": {
"icon": "DefaultProperty",
"type": "string",
"title": "Version"
}
},
"required": [
"package",
"version"
]
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Port config YAML (click to expand)
 - kind: file
selector:
query: 'true'
files:
- path: '**/package.json'
repos:
- name: vscode
branch: main
port:
itemsToParse: .content.dependencies | to_entries
entity:
mappings:
identifier: >-
.item.key + "_" + if (.item.value | startswith("^")) then
.item.value[1:] else .item.value end
title: .item.key + "@" + .item.value
blueprint: '"package"'
properties:
package: .item.key
version: .item.value

The example will parse the package.json file in your repository and extract the dependencies into Port entities.
For more information about ingesting files and file contents, click here.

Map files and repositoriesโ€‹

The following example demonstrates mapping files to repository.

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
File Blueprint (click to expand)
{
"identifier": "files",
"title": "Files",
"icon": "Github",
"schema": {
"properties": {
"name": {
"type": "string",
"title": "Name"
},
"path": {
"type": "string",
"title": "Path"
}
},
"required": [
"name",
"path"
]
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"repository": {
"title": "repository",
"target": "githubRepository",
"required": false,
"many": false
}
}
}
Port app config (click to expand)
deleteDependentEntities: true
resources:
- kind: repository
selector:
query: 'true'
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"githubRepository"'
properties:
description: if .description then .description else "" end
visibility: if .private then "private" else "public" end
defaultBranch: .default_branch
readme: file://README.md
url: .html_url
language: if .language then .language else "" end
- kind: file
selector:
query: 'true'
files:
- path: 'README.md'
repos:
- name: test-repo
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"files"'
properties:
name: .name
path: .path
relations:
repository: .repository.name

Map repositories and monoreposโ€‹

The following example demonstrates how to ingest your GitHub repositories and their folders to Port. By following this example you can map your different services, packages and libraries from your monorepo into separate entities in Port. You may use the following Port blueprint definitions and port-app-config.yml:

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Port port-app-config.yml (click to expand)
resources:
- kind: folder
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
folders: # Specify the repositories and folders to include under this relative path.
- path: apps/* # Relative path to the folders within the repositories.
repos: # List of repositories to include folders from.
- name: backend-service
branch: main
- name: frontend-service # if you don't specify a branch, we'll use the repository's default branch
port:
entity:
mappings:
identifier: .folder.path | split("/") | last
title: .folder.path | split("/") | last
blueprint: '"githubRepository"'
properties:
url: .__repository.html_url + "/tree/" + .__repository.default_branch + "/" + .folder.path
readme: file://README.md

To retrieve the root folders of your monorepo, use the following syntax in your port-app-config.yml:

- kind: folder
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
folders: # Specify the repositories and folders to include under this relative path.
- path: "*" # Relative path to the folders within the repositories.
repos: # List of repositories to include folders from.
- name: backend-service
- name: frontend-service
learn more
  • Refer to the setup section to learn more about the port-app-config.yml setup process.
  • We leverage JQ JSON processor to map and transform GitHub objects to Port Entities.
  • Click Here for the GitHub repository object structure.
  • Click Here for the GitHub folder object structure.

Map repositories, workflows and workflow runsโ€‹

The following example demonstrates how to ingest your GitHub repositories, their workflows and workflow runs to Port, you may use the following Port blueprint definitions and port-app-config.yml:

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Workflow blueprint (click to expand)
{
"identifier": "githubWorkflow",
"title": "Workflow",
"icon": "Github",
"schema": {
"properties": {
"path": {
"title": "Path",
"type": "string"
},
"status": {
"title": "Status",
"type": "string",
"enum": [
"active",
"deleted",
"disabled_fork",
"disabled_inactivity",
"disabled_manually"
],
"enumColors": {
"active": "green",
"deleted": "red"
}
},
"createdAt": {
"title": "Created At",
"type": "string",
"format": "date-time"
},
"updatedAt": {
"title": "Updated At",
"type": "string",
"format": "date-time"
},
"deletedAt": {
"title": "Deleted At",
"type": "string",
"format": "date-time"
},
"link": {
"title": "Link",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "githubRepository",
"required": false,
"many": false
}
}
}
Workflow run blueprint (click to expand)
{
"identifier": "githubWorkflowRun",
"title": "Workflow Run",
"icon": "Github",
"schema": {
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"triggeringActor": {
"title": "Triggering Actor",
"type": "string"
},
"status": {
"title": "Status",
"type": "string",
"enum": [
"completed",
"action_required",
"cancelled",
"startup_failure",
"failure",
"neutral",
"skipped",
"stale",
"success",
"timed_out",
"in_progress",
"queued",
"requested",
"waiting"
],
"enumColors": {
"queued": "yellow",
"in_progress": "yellow",
"success": "green",
"failure": "red"
}
},
"conclusion": {
"title": "Conclusion",
"type": "string",
"enum": [
"completed",
"action_required",
"cancelled",
"startup_failure",
"failure",
"neutral",
"skipped",
"stale",
"success",
"timed_out",
"in_progress",
"queued",
"requested",
"waiting"
],
"enumColors": {
"queued": "yellow",
"in_progress": "yellow",
"success": "green",
"failure": "red"
}
},
"createdAt": {
"title": "Created At",
"type": "string",
"format": "date-time"
},
"runStartedAt": {
"title": "Run Started At",
"type": "string",
"format": "date-time"
},
"updatedAt": {
"title": "Updated At",
"type": "string",
"format": "date-time"
},
"runNumber": {
"title": "Run Number",
"type": "number"
},
"runAttempt": {
"title": "Run Attempts",
"type": "number"
},
"link": {
"title": "Link",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"workflow": {
"target": "githubWorkflow",
"required": true,
"many": false
}
}
}
Port port-app-config.yml (click to expand)
resources:
- kind: repository
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
port:
entity:
mappings:
identifier: ".name" # The Entity identifier will be the repository name.
title: ".name"
blueprint: '"githubRepository"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: workflow
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
port:
entity:
mappings:
identifier: ".__repository + (.id|tostring)"
title: ".name"
blueprint: '"githubWorkflow"'
properties:
path: ".path"
status: ".state"
createdAt: ".created_at"
updatedAt: ".updated_at"
link: ".html_url"
relations:
repository: ".__repository"
- kind: workflow-run
selector:
query: .status != "completed" # JQ boolean query. If evaluated to false - skip syncing the object.
port:
entity:
mappings:
identifier: ".repository.name + (.id|tostring)"
title: ".display_title"
blueprint: '"githubWorkflowRun"'
properties:
name: ".name"
triggeringActor: ".triggering_actor.login"
status: ".status"
conclusion: ".conclusion"
createdAt: ".created_at"
runStartedAt: ".run_started_at"
updatedAt: ".updated_at"
deletedAt: ".deleted_at"
runNumber: ".run_number"
runAttempt: ".run_attempt"
link: ".html_url"
relations:
workflow: ".repository.name + (.workflow_id|tostring)"
learn more
  • Click Here for the GitHub workflow object structure.
  • Click Here for the GitHub workflow run object structure.

Map repositories and teamsโ€‹

The following example demonstrates how to ingest your GitHub repositories and their teams to Port.
You can use the following Port blueprint definitions and port-app-config.yml:

Team blueprint (click to expand)
{
"identifier": "githubTeam",
"title": "GitHub Team",
"icon": "Github",
"schema": {
"properties": {
"slug": {
"title": "Slug",
"type": "string"
},
"description": {
"title": "Description",
"type": "string"
},
"link": {
"title": "Link",
"icon": "Link",
"type": "string",
"format": "url"
},
"permission": {
"title": "Permission",
"type": "string"
},
"notification_setting": {
"title": "Notification Setting",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default Branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"githubTeams": {
"title": "GitHub Teams",
"target": "githubTeam",
"required": false,
"many": true
}
}
}
Port port-app-config.yml (click to expand)
createMissingRelatedEntities: true
resources:
- kind: team
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
members: false
port:
entity:
mappings:
identifier: ".id | tostring"
title: .name
blueprint: '"githubTeam"'
properties:
name: .name
slug: .slug
description: .description
link: .html_url
permission: .permission
notification_setting: .notification_setting
- kind: repository
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
include: "teams" # Boolean flag to indicate whether to include the repository teams.
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"githubRepository"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
relations:
githubTeams: "[.__teams[].id | tostring]"

Map teams and team membersโ€‹

The following shows how we can map teams and team members using the "members" selector.

Team Member blueprint (click to expand)
{
"identifier": "githubTeamMember",
"title": "Team Member",
"icon": "Github",
"schema": {
"properties": {
"name": {
"type": "string",
"title": "Name"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Team blueprint (click to expand)
{
"identifier": "githubTeam",
"title": "GitHub Team",
"icon": "Github",
"schema": {
"properties": {
"slug": {
"title": "Slug",
"type": "string"
},
"description": {
"title": "Description",
"type": "string"
},
"link": {
"title": "Link",
"icon": "Link",
"type": "string",
"format": "url"
},
"permission": {
"title": "Permission",
"type": "string"
},
"notification_setting": {
"title": "Notification Setting",
"type": "string"
},
"members": {
"title": "Members",
"type": "array"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"team_member": {
"title": "teamMember",
"target": "githubTeamMember",
"required": false,
"many": true
}
}
}
Port port-app-config.yaml (click to expand)
  - kind: team
selector:
query: 'true'
members: true
port:
entity:
mappings:
identifier: .id | tostring
title: .name
blueprint: '"githubTeam"'
properties:
slug: .slug
description: .description
link: .url
permission: .permission
notification_setting: .notificationSetting
relations:
team_member: '[.members.nodes[].login]'
- kind: team
selector:
query: 'true'
members: true
port:
itemsToParse: .members.nodes
entity:
mappings:
identifier: .login
title: .login
blueprint: '"githubTeamMember"'
properties:
name: .name

Map repositories, repository admins and usersโ€‹

The following example demonstrates how to ingest your GitHub repositories, their admins and related users to Port.
You can use the following Port blueprint definitions and port-app-config.yml:

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"admins": {
"title": "Admins",
"target": "githubUser",
"required": false,
"many": true
}
}
}
Github Users blueprint (click to expand)
{
"identifier": "githubUser",
"title": "Github User",
"icon": "Microservice",
"schema": {
"properties": {
"email": {
"title": "Email",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"user": {
"title": "User",
"target": "user",
"required": false,
"many": false
}
}
}
Users blueprint (click to expand)
{
"identifier": "user",
"title": "user",
"icon": "Microservice",
"schema": {
"properties": {
"email":{
"title":"Email",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Port port-app-config.yml (click to expand)
createMissingRelatedEntities: true
resources:
- kind: repository
selector:
query: "true"
include: "collaborators"
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"githubRepository"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
relations:
admins: "[.__collaborators[] | select(.is_admin == true) | .login]"
- kind: user
selector:
query: "true"
port:
entity:
mappings:
identifier: .login
title: if (.name != "" and .name) then .name else .login end
blueprint: '"githubUser"'
relations:
user: .email
- kind: user
selector:
query: "true"
port:
entity:
mappings:
identifier: .email
title: .email
blueprint: '"user"'
properties:
email: .email

Supported GitHub user types

As Github has strict privacy policies, the GitHub API will only return emails in the following cases:

  1. The user has a public email address.
  2. Your organization is working with a GitHub Enterprise Cloud plan, and the user has an SAML SSO identity configured inside the GitHub organization.

In other cases, the GitHub API will return a null value for the user's email.

User supported fields

For the user kind, only the following fields are supported: .name, .login, and .email.
Other fields from the GitHub User API are not available.

Map repositories and collaboratorsโ€‹

The following example demonstrates how to ingest your GitHub repositories and their collaborators to Port.
You can use the following Port blueprint definitions and port-app-config.yml:

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Collaborator blueprint (click to expand)
{
"identifier": "githubCollaborator",
"title": "Github Collaborator",
"icon": "Github",
"schema": {
"properties": {
"login": {
"type": "string",
"title": "Login"
},
"url": {
"type": "string",
"title": "Url",
"format": "url"
},
"type": {
"type": "string",
"title": "Type"
},
"site_admin": {
"type": "boolean",
"title": "Site admin"
},
"role": {
"type": "string",
"title": "Role"
}
},
"required": [
"login"
]
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"repository": {
"title": "repository",
"target": "githubRepository",
"required": true,
"many": false
}
}
}
Port port-app-config.yml (click to expand)
createMissingRelatedEntities: true
resources:
- kind: repository
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"githubRepository"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch

- kind: collaborator
selector:
query: "true"
port:
entity:
mappings:
identifier: .__repository + "/" + .login
title: .login
blueprint: '"githubCollaborator"'
properties:
login: .login
url: .html_url
type: .type
site_admin: .site_admin
role: .role_name
relations:
repository: .__repository

Map repositories, dependabot alerts, and code scan alertsโ€‹

The following example shows how to ingest your GitHub repositories and their alerts (Dependabot and Code scan alerts) into Port. You can use the following Port blueprint definitions and port-app-config.yml:

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Dependabot Alert blueprint (click to expand)
{
"identifier": "githubDependabotAlert",
"title": "Dependabot Alert",
"icon": "Github",
"schema": {
"properties": {
"severity": {
"title": "Severity",
"type": "string",
"enum": ["low", "medium", "high", "critical"],
"enumColors": {
"low": "yellow",
"medium": "orange",
"high": "red",
"critical": "red"
},
"icon": "DefaultProperty"
},
"state": {
"title": "State",
"type": "string",
"enum": ["auto_dismissed", "dismissed", "fixed", "open"],
"enumColors": {
"auto_dismissed": "green",
"dismissed": "green",
"fixed": "green",
"open": "red"
},
"icon": "DefaultProperty"
},
"packageName": {
"icon": "DefaultProperty",
"title": "Package Name",
"type": "string"
},
"packageEcosystem": {
"title": "Package Ecosystem",
"type": "string"
},
"manifestPath": {
"title": "Manifest Path",
"type": "string"
},
"scope": {
"title": "Scope",
"type": "string"
},
"ghsaID": {
"title": "GHSA ID",
"type": "string"
},
"cveID": {
"title": "CVE ID",
"type": "string"
},
"url": {
"title": "URL",
"type": "string",
"format": "url"
},
"references": {
"icon": "Vulnerability",
"title": "References",
"type": "array",
"items": {
"type": "string",
"format": "url"
}
},
"alertCreatedAt": {
"icon": "DefaultProperty",
"type": "string",
"title": "Alert Created At",
"format": "date-time"
},
"alertUpdatedAt": {
"icon": "DefaultProperty",
"type": "string",
"title": "Alert Updated At",
"format": "date-time"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "githubRepository",
"required": true,
"many": false
}
}
}
Code scan Alert blueprint (click to expand)
{
"identifier": "githubCodeScanAlerts",
"title": "Code Scan Alerts",
"icon": "Microservice",
"schema": {
"properties": {
"description": {
"title": "Alert description",
"type": "string"
},
"severity": {
"title": "Alert severity",
"type": "string"
},
"tags": {
"items": {
"type": "string"
},
"title": "Alert tags",
"type": "array"
},
"url": {
"title": "alert URL",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "githubRepository",
"required": true,
"many": false
}
}
}
Port port-app-config.yml (click to expand)
resources:
- kind: repository
selector:
query: "true"
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"githubRepository"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: dependabot-alert
selector:
query: "true"
states: ["open", "fixed"] # other options: auto_fixed, dismissed
port:
entity:
mappings:
identifier: .__repository + "-" + (.number | tostring)
title: .number | tostring
blueprint: '"githubDependabotAlert"'
properties:
state: .state
severity: .security_advisory.severity
packageName: .dependency.package.name
packageEcosystem: .dependency.package.ecosystem
manifestPath: .dependency.manifest_path
scope: .dependency.scope
ghsaID: .security_advisory.ghsa_id
cveID: .security_advisory.cve_id
url: .html_url
references: "[.security_advisory.references[].url]"
alertCreatedAt: .created_at
alertUpdatedAt: .updated_at
relations:
repository: .__repository
- kind: code-scanning-alerts
selector:
query: "true"
state: "dismissed" # other options: open, closed, fixed
port:
entity:
mappings:
identifier: .__repository + "-" + (.number | tostring)
title: .rule.name
blueprint: '"githubCodeScanAlerts"'
properties:
state: .state
severity: .rule.severity
tags: .rule.tags
description: .rule.description
url: .html_url
relations:
repository: .__repository

Map repositories, deployments and environmentsโ€‹

The following example demonstrates how to ingest your GitHub repositories, their deployments and environments to Port, you may use the following Port blueprint definitions and port-app-config.yml:

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Deployment Environment blueprint (click to expand)
{
"identifier": "githubRepoEnvironment",
"title": "Deployment Environments",
"icon": "Environment",
"schema": {
"properties": {
"url": {
"icon": "DefaultProperty",
"title": "URL",
"type": "string",
"format": "url"
},
"createdAt": {
"title": "Created At",
"type": "string",
"format": "date-time",
"icon": "DefaultProperty"
},
"updatedAt": {
"title": "Updated At",
"type": "string",
"format": "date-time"
},
"protectedBranches": {
"title": "Protected Branches",
"type": "boolean"
},
"customBranchPolicies": {
"title": "Custom Branch Policies",
"type": "boolean"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"repository": {
"target": "githubRepository",
"required": true,
"many": false
}
}
}
Deployment blueprint (click to expand)
{
"identifier": "githubDeployment",
"title": "Deployment",
"icon": "Deployment",
"schema": {
"properties": {
"description": {
"title": "Description",
"type": "string"
},
"ref": {
"title": "Ref",
"type": "string"
},
"sha": {
"title": "Sha",
"type": "string"
},
"transientEnvironment": {
"title": "Transient Running Service",
"type": "boolean"
},
"productionEnvironment": {
"title": "Production Running Service",
"type": "boolean"
},
"createdAt": {
"title": "Created At",
"type": "string",
"format": "date-time"
},
"url": {
"title": "URL",
"type": "string",
"icon": "Link",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"deployment_environment": {
"title": "Deployment Environment",
"target": "githubRepoEnvironment",
"required": false,
"many": false
}
}
}
Port port-app-config.yml (click to expand)
createMissingRelatedEntities: true
resources:
- kind: repository
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
port:
entity:
mappings:
identifier: ".name" # The Entity identifier will be the repository name.
title: ".name"
blueprint: '"githubRepository"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: environment
selector:
query: "true"
port:
entity:
mappings:
identifier: .__repository + "-" + .name
title: .name
blueprint: '"githubRepoEnvironment"'
properties:
url: .html_url
customBranchPolicies: .deployment_branch_policy.custom_branches_policies
protectedBranches: .deployment_branch_policy.protected_branches
createdAt: .created_at
updatedAt: .updated_at
relations:
repository: .__repository
- kind: deployment
selector:
query: "true"
port:
entity:
mappings:
identifier: .__repository + "-" + (.id|tostring)
title: .task + "-" + .environment
blueprint: '"githubDeployment"'
properties:
description: .description
ref: .ref
sha: .sha
productionEnvironment: .production_environment
transientEnvironment: .transient_environment
createdAt: .created_at
url: .url
relations:
deployment_environment: .__repository + "-" + .environment

Map repositories, repository releases and tagsโ€‹

The following example demonstrates how to ingest your GitHub repositories, their releases and tags to Port, you may use the following Port blueprint definitions and port-app-config.yml:

Repository blueprint (click to expand)
{
"identifier": "githubRepository",
"title": "Repository",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Repository URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Tag blueprint (click to expand)
{
"identifier": "githubTag",
"title": "Tag",
"icon": "Github",
"schema": {
"properties": {
"commit_sha": {
"icon": "DefaultProperty",
"type": "string",
"title": "Commit sha"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "githubRepository",
"required": false,
"many": false
}
}
}
Release blueprint (click to expand)
{
"identifier": "githubRelease",
"title": "Release",
"icon": "Github",
"schema": {
"properties": {
"release_creation_time": {
"icon": "DefaultProperty",
"type": "string",
"title": "Release creation time",
"format": "date-time"
},
"author": {
"type": "string",
"title": "Author"
},
"description": {
"type": "string",
"title": "Description"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "githubRepository",
"required": false,
"many": false
},
"tag": {
"title": "Tag",
"target": "githubTag",
"required": false,
"many": false
}
}
}
Port port-app-config.yml (click to expand)
resources:
- kind: repository
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
port:
entity:
mappings:
identifier: ".name" # The Entity identifier will be the repository name.
title: ".name"
blueprint: '"githubRepository"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: tag
selector:
query: 'true'
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"githubTag"'
properties:
commit_sha: .commit.sha
relations:
repository: .__repository
- kind: release
selector:
query: 'true'
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"githubRelease"'
properties:
author: .author.login
description: .body
release_creation_time: .created_at
relations:
tag: .tag_name
repository: .__repository

Map supported resourcesโ€‹

The examples above show specific use cases, but Port's GitHub integration supports the ingestion of many other GitHub objects. To adapt the examples above, use the GitHub API reference to learn about the available fields for the different supported objects:

When adding the ingestion of other resources, remember to add an entry to the resources array and change the value provided to the kind key accordingly.