Resource mapping examples
When using the GitHub Cloud app with Port, certain fields and data points may not be accessible due to the lack of write
API permissions. These limitations affect advanced repository settings, security features (such as code scanning and secret scanning status), and other GitHub objects that require elevated permissions to retrieve data.
If you need to ingest these fields, consider one of the following approaches:
-
Use our self-hosted GitHub app which gives you options to enable appropriate
write
permissions. -
Implement a GitHub workflow to manually gather and send the required data to Port.
Refer to specific sections below where these limitations might apply.
Map repositories and pull requests
In the following example you will ingest your GitHub repositories, their README.md file contents and pull requests to Port, you may use the following Port blueprint definitions and port-app-config.yml
:
Repository blueprint
{
"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
{
"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
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.
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: ".status" # 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
- 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 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).
Map files and file contents
The following example demonstrates ingestion of dependencies from a package.json
file in your repository into Port:
Package blueprint
{
"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
- 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 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.