Skip to main content

Check out Port for yourself 

Resource mapping examples

General permissions limitation with gitHub cloud app

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
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 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.