Skip to main content

Resource mapping examples

Mapping repositories, file contents 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:

Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service 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"
},
"link": {
"format": "url",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"service": {
"title": "Service",
"target": "service",
"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: '"service"'
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"
prNumber: ".id"
link: ".html_url"
relations:
service: .head.repo.name
tip
  • 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).

Mapping repositories, workflows and workflow runs​

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

Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Workflow blueprint
{
"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": {
"service": {
"title": "Service",
"target": "service",
"required": false,
"many": false
}
}
}
Workflow run blueprint
{
"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
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: '"service"'
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: ".repo + (.id|tostring)"
title: ".name"
blueprint: '"githubWorkflow"'
properties:
path: ".path"
status: ".state"
createdAt: ".created_at"
updatedAt: ".updated_at"
link: ".html_url"
relations:
service: ".repo"
- kind: workflow-run
selector:
query: "true" # 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)"
tip
  • 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 workflow object structure.
  • Click Here for the GitHub workflow run 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 workflows and workflow runs. (Remember that the port-app-config.yml file has to be in the default branch of the repository to take effect).

Mapping repositories and issues​

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

Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Issue blueprint
{
"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": {
"service": {
"target": "service",
"required": true,
"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: '"service"'
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.
port:
entity:
mappings:
identifier: ".repo + (.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:
service: ".repo"
tip
  • 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.

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 issues. (Remember that the port-app-config.yml file has to be in the default branch of the repository to take effect).

Mapping repositories and monorepos​

In the following example you will 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:

Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Port port-app-config.yml
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.
- backend-service
- frontend-service
port:
entity:
mappings:
identifier: ".folder.name"
title: ".folder.name"
blueprint: '"service"'
properties:
url: .repo.html_url + "/tree/" + .repo.default_branch + "/" + .folder.path
readme: file://README.md
tip

To retrieve the root folders of your monorepo, you can use this 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.
- backend-service
- frontend-service
tip
  • 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.

Mapping repositories, repository folders and pull requests​

In the following example you will ingest your GitHub repositories, the repository's root folders and the repository pull requests to Port, you may use the following Port blueprint definitions and port-app-config.yml:

Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service 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"
},
"link": {
"format": "url",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"service": {
"title": "Service",
"target": "service",
"required": false,
"many": false
}
}
}
Folder blueprint
{
"identifier": "githubFolder",
"title": "Folder",
"icon": "Github",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Folder URL",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"service": {
"title": "Service",
"target": "service",
"required": false,
"many": false
}
}
}
Port port-app-config.yml
resources:
- kind: repository
selector:
query: "true"
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"service"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: pull-request
selector:
query: "true"
port:
entity:
mappings:
identifier: .head.repo.name + (.id|tostring)
title: .title
blueprint: '"githubPullRequest"'
properties:
creator: .user.login
assignees: "[.assignees[].login]"
reviewers: "[.requested_reviewers[].login]"
status: .status
closedAt: .closed_at
updatedAt: .updated_at
mergedAt: .merged_at
prNumber: .id
link: .html_url
relations:
service: .head.repo.name
- kind: folder
selector:
query: "true"
folders:
- path: "*" # Using "*" will ingest the folders from the root of each of repository as entities
repos: # Add any repositories you want to map folders from to the following list
- backend-service
- frontend-service
port:
entity:
mappings:
identifier: .folder.name
title: .folder.name
blueprint: '"githubFolder"'
properties:
url: >-
.repo.html_url + "/tree/" + .repo.default_branch + "/" +
.folder.path
readme: file://README.md
relations:
service: .repo.name

Mapping repositories and teams​

In the following example you will ingest your GitHub repositories and their teams to Port, you may use the following Port blueprint definitions and port-app-config.yml:

note

Teams are GitHub organization level resources, therefore you will need to specify the mapping of the teams in a global integration configuration (Through Port's UI or through the port-app-config.yml file in the .github-private repository).

Team blueprint
{
"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": {}
}
Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service URL",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"githubTeams": {
"title": "GitHub teams",
"target": "githubTeam",
"required": false,
"many": true
}
}
}
Port port-app-config.yml
createMissingRelatedEntities: true
resources:
- kind: team
selector:
query: "true" # JQ boolean query. If evaluated to false - skip syncing the object.
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.
teams: true # Boolean flag to indicate whether to include the repository teams.
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"service"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
relations:
githubTeams: "[.teams[].id | tostring]"
tip

To retrieve the teams of your repositories, you will need to add the teams property to the selector in the repository resource kind in your port-app-config.yml:

- kind: repository
selector:
query: 'true' # JQ boolean query. If evaluated to false - skip syncing the object.
teams: true # Boolean flag to indicate whether to include the repository teams.

Mapping repositories, deployments and environments​

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

Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Running Service blueprint
{
"identifier": "githubRepoEnvironment",
"title": "Running Service",
"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": {
"service": {
"target": "service",
"required": true,
"many": false
}
}
}
Deployment blueprint
{
"identifier": "deployment",
"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": {
"runningService": {
"title": "Running Service",
"target": "githubRepoEnvironment",
"required": false,
"many": false
}
}
}
Port port-app-config.yml
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: '"service"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: environment
selector:
query: "true"
port:
entity:
mappings:
identifier: .repo + '-' + .name
title: .name
blueprint: '"githubRepoEnvironment"'
properties:
url: .html_url
customBranchesPolicies: .custom_branches_policies
protectedBranches: .protected_branches
createdAt: .created_at
updatedAt: .updated_at
relations:
repository: .repo
- kind: deployment
selector:
query: "true"
port:
entity:
mappings:
identifier: .repo + '-' + (.id|tostring)
title: .task + '-' + .environment
blueprint: '"deployment"'
properties:
description: .description
ref: .ref
sha: .sha
productionEnvironment: .production_environment
transientEnvironment: .transient_environment
createdAt: .created_at
url: .url
relations:
environment: .repo + '-' + .environment

Mapping repositories, Dependabot Alerts and Code scan alerts​

In the following example you will ingest your GitHub repositories and their alerts (Dependabot and Code scan alerts) to Port, you may use the following Port blueprint definitions and port-app-config.yml:

Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Dependabot Alert blueprint
{
"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"
}
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"service": {
"title": "Service",
"target": "service",
"required": true,
"many": false
}
}
}
Code scan Alert blueprint
{
"identifier": "code_scan_alerts",
"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": {
"service": {
"title": "Service",
"target": "service",
"required": false,
"many": true
}
}
}
Port port-app-config.yml
resources:
- kind: repository
selector:
query: "true"
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"service"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: dependabot-alert
selector:
query: "true"
port:
entity:
mappings:
identifier: .repo.name + "-" + (.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]"
relations:
service: .repo.name
- kind: code-scanning-alerts
selector:
query: "true"
port:
entity:
mappings:
identifier: .repo + "-" + (.number | tostring)
title: .rule.name
blueprint: '"code_scan_alerts"'
properties:
state: .state
severity: .rule.severity
tags: .rule.tags
description: .rule.description
url: .html_url
relations:
service: .repo
supported alerts

For Code scan alerts only open alerts on the default branch are supported

Mapping repositories and branches​

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

Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Branch blueprint
{
"identifier": "branch",
"title": "Branch",
"icon": "Microservice",
"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": "service",
"required": false,
"many": true
}
}
}
Port port-app-config.yml
resources:
- kind: repository
selector:
query: 'true'
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"service"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: branch
selector:
query: 'true'
port:
entity:
mappings:
identifier: .repository.name + "_" + .branch.name
title: .repository.name + " " + .branch.name
blueprint: '"branch"'
properties:
is_protected: .branch.protected
commit_sha: .branch.commit.sha
commit_url: .branch.commit.url
relations:
repository: .repository.name

Mapping repositories and branch protection rules​

In the following example you will ingest your GitHub repositories and their main branch protection rules to Port, you may use the following Port blueprint definitions and port-app-config.yml:

Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service URL",
"type": "string",
"format": "url"
},
"defaultBranch": {
"title": "Default branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Branch blueprint
{
"identifier": "branch_protection",
"title": "Branch",
"icon": "Microservice",
"schema": {
"properties": {
"require_approval_count": {
"title": "Require approvals",
"type": "number",
"icon": "DefaultProperty"
},
"is_protected": {
"title": "Is branch protected",
"type": "boolean",
"icon": "DefaultProperty"
},
"require_code_owner_review": {
"title": "Require code owner review",
"type": "boolean",
"icon": "DefaultProperty"
},
"allow_deletions": {
"icon": "DefaultProperty",
"title": "Allow Deletions",
"type": "boolean"
},
"allow_force_pushes": {
"title": "Allow force pushes",
"type": "boolean",
"icon": "DefaultProperty"
},
"url": {
"title": "Branch URL",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "service",
"required": false,
"many": true
}
}
}
Port port-app-config.yml
resources:
- kind: repository
selector:
query: 'true'
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"service"'
properties:
readme: file://README.md
url: .html_url
defaultBranch: .default_branch
- kind: branch
selector:
query: 'true'
port:
entity:
mappings:
identifier: .repository.name + "_" + .branch.name
title: .repository.name + " " + .branch.name
blueprint: '"branch_protection"'
properties:
is_protected: .branch.protected
url: .branch._links.html
require_approval_count: >-
.branch.protectionRules.required_pull_request_reviews.required_approving_review_count
require_code_owner_review: >-
.branch.protectionRules.required_pull_request_reviews.require_code_owner_reviews
allow_force_pushes: .branch.protectionRules.allow_force_pushes.enabled
allow_deletions: .branch.protectionRules.allow_deletions.enabled
relations:
repository: .repository.name
supported branch protection rules

Currently only default branch protection rules are supported

Mapping repositories, repository admins and users​

In the following example you will ingest your GitHub repositories, their admins and related users to Port, you may use the following Port blueprint definitions and port-app-config.yml:

Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"url": {
"title": "Service URL",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"admins": {
"title": "Admins",
"target": "githubUser",
"required": false,
"many": true
}
}
}
Github Users blueprint
{
"identifier": "githubUser",
"title": "Github User",
"icon": "Microservice",
"schema": {
"properties": {},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"user": {
"title": "User",
"target": "user",
"required": false,
"many": false
}
}
}
Users blueprint
{
"identifier": "user",
"title": "user",
"icon": "Microservice",
"schema": {
"properties": {},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Port port-app-config.yml
createMissingRelatedEntities: true
resources:
- kind: repository
selector:
query: "true"
collaborators: true
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"service"'
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: .login
blueprint: '"githubUser"'
relations:
user: .email
- kind: user
selector:
query: "true"
port:
entity:
mappings:
identifier: .email
title: .email
blueprint: '"user"'
relations:
user: .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.

Mapping supported resources​

The above examples shows a specific use cases, but Port's GitHub app 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.