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
writepermissions. - 
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โ
The following example demonstrates how to ingest your GitHub repositories, their README.md file contents and 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.
    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: ".number"
            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: .head.repo.name
- Refer to the setup section to learn more about the 
port-app-config.ymlsetup 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 (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 port-app-config.yml (click to expand)
resources:
  - kind: file
    selector:
      query: 'true'
      files:
        - path: '**/package.json'
        - repos:
            - stale
    port:
      itemsToParse: .file.content.dependencies | to_entries
      entity:
        mappings:
          identifier: >-
            .item.key + "_" + if (.item.value | startswith("^")) then
            .item.value[1:] else . end
          title: .item.key + "@" + .item.value
          blueprint: '"package"'
          properties:
            package: .item.key
            version: .item.value
          relations: {}
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 repositories, workflows and workflow runsโ
The following example demonstrates how to ingest your GitHub repositories, their workflows and workflow runs 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": {}
}
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: ".repo + (.id|tostring)"
          title: ".name"
          blueprint: '"githubWorkflow"'
          properties:
            path: ".path"
            status: ".state"
            createdAt: ".created_at"
            updatedAt: ".updated_at"
            link: ".html_url"
          relations:
            repository: ".repo"
  - 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)"
- Refer to the setup section to learn more about the 
port-app-config.ymlsetup 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).
Map repositories and issuesโ
The following example demonstrates how to ingest your GitHub repositories and their issues 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": {}
}
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.
    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:
            repository: ".repo"
- Refer to the setup section to learn more about the 
port-app-config.ymlsetup 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).
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.
            - backend-service
            - frontend-service
    port:
      entity:
        mappings:
          identifier: ".folder.name"
          title: ".folder.name"
          blueprint: '"githubRepository"'
          properties:
            url: .repo.html_url + "/tree/" + .repo.default_branch  + "/" + .folder.path
            readme: file://README.md
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
- Refer to the setup section to learn more about the 
port-app-config.ymlsetup 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, repository folders and pull requestsโ
The following example demonstrates how to ingest your GitHub repositories, the repository's root folders and the repository 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"
      },
      "link": {
        "format": "url",
        "type": "string"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "relations": {
    "repository": {
      "title": "Repository",
      "target": "githubRepository",
      "required": false,
      "many": false
    }
  }
}
Folder blueprint (click to expand)
{
  "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": {
    "repository": {
      "title": "Repository",
      "target": "githubRepository",
      "required": false,
      "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: 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:
            repository: .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:
            repository: .repo.name
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:
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 (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.
    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: '"githubRepository"'
          properties:
            readme: file://README.md
            url: .html_url
            defaultBranch: .default_branch
          relations:
            githubTeams: "[.teams[].id | tostring]"
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.
Map repositories, deployments and environmentsโ
The following example demonstrates how to ingest your GitHub repositories, their deployments and environments 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": {}
}
Running Service blueprint (click to expand)
{
  "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": {
    "repository": {
      "target": "githubRepository",
      "required": true,
      "many": false
    }
  }
}
Deployment blueprint (click to expand)
{
  "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 (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: .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
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": "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": {
    "repository": {
      "title": "Repository",
      "target": "githubRepository",
      "required": false,
      "many": true
    }
  }
}
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"
    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]"
            alertCreatedAt: .created_at
            alertUpdatedAt: .updated_at
          relations:
            repository: .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:
            repository: .repo
For Code scan alerts, only open alerts on the default branch are supported.
allow_squash_merge- Advanced security status (e.g., whether code scanning or secret scanning is enabled)
 
If you need to ingest these fields, consider using a self-hosted GitHub app with the appropriate permissions or creating a GitHub workflow to manually gather and ingest this data into Port.
For users who need access to the full range of repository fields, including enabling WRITE permissions, we recommend setting up a self-hosted GitHub app. This allows full customization of permissions, ensuring all necessary data can be ingested into Port. Refer to our Self-Hosted Installation Guide for detailed instructions.
Alternatively, you can create a GitHub workflow that gathers the required data and sends it to Port, allowing you to work around the limitations of the Cloud app.
Map repositories and branchesโ
The following example demonstrates how to ingest your GitHub repositories and their branches 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": {}
}
Branch blueprint (click to expand)
{
  "identifier": "github_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": {}
}
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 + "_" + .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
Map repositories and last contributorโ
The following example demonstrates how to ingest your GitHub repositories and their last contributor to Port.
You can use the following Port blueprint definitions and port-app-config.yml:
Branch blueprint (click to expand)
{
  "identifier": "github_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"
      },
      "last_contributor": {
        "title": "Last contributor",
        "icon": "TwoUsers",
        "type": "string",
        "format": "user"
      },
      "last_push": {
        "title": "Last push",
        "icon": "GitPullRequest",
        "description": "Last commit to the main branch",
        "type": "string",
        "format": "date-time"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "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"
      },
      "last_contributor": {
        "title": "Last contributor",
        "icon": "TwoUsers",
        "type": "string",
        "format": "user"
      },
      "last_push": {
        "icon": "GitPullRequest",
        "title": "Last push",
        "description": "Last commit to the main branch",
        "type": "string",
        "format": "date-time"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "relations": {
    "github_branch": {
      "title": "Github Branch",
      "target": "github_branch",
      "required": false,
      "many": false
    }
  }
}
Port port-app-config.yml (click to expand)
resources:
  - kind: branch
    selector:
      query: .branch.name == .repository.default_branch
    port:
      entity:
        mappings:
          identifier: .repository.name + "-" + .branch.name
          blueprint: '"github_branch"'
          properties:
            last_contributor: .branch.commit.commit.author.email | ascii_downcase
            last_push: .branch.commit.commit.committer.date
  - kind: repository
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: .name
          title: .name
          blueprint: '"githubRepository"'
          properties:
            readme: file://README.md
            url: .html_url
            language: .language
          relations:
            github_branch: .name + "-" + .default_branch
The last contributor is the author of the last commit in the default branch of the repository
Map repositories and branch protection rulesโ
The following example demonstrates how to ingest your GitHub repositories and their main branch protection rules 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": {}
}
Branch blueprint (click to expand)
{
  "identifier": "branch_protection",
  "title": "Branch",
  "icon": "Microservice",
  "schema": {
    "properties": {
      "require_approval_count": {
        "title": "Require approvals",
        "type": "number",
        "icon": "DefaultProperty",
        "description": "The number of approvals required before merging a pull request"
      },
      "is_protected": {
        "title": "Is branch protected",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Indicates whether certain rules must be met before changes can be merged"
      },
      "require_code_owner_review": {
        "title": "Require code owner review",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Requires review from code owners before a pull request can be merged"
      },
      "allow_deletions": {
        "title": "Allow deletions",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Allows users with bypass permissions to delete matching references in the branch"
      },
      "allow_force_pushes": {
        "title": "Allow force pushes",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Permits users with push access to force push changes to the branch"
      },
      "url": {
        "title": "Branch url",
        "type": "string",
        "format": "url",
        "description": "URL of the branch in the repository"
      },
      "require_signed_commits": {
        "title": "Require signed commits",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Ensures that commits pushed to the branch are signed"
      },
      "require_linear_history": {
        "title": "Require linear history",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Enforces a linear history in the branch by preventing merge commits"
      },
      "restrict_creations": {
        "title": "Restrict creations",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Restricts the creation of matching references in the branch, allowing only users with bypass permissions"
      },
      "restrict_updates": {
        "title": "Restrict updates",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Prevents updates to matching references in the branch, limiting changes to users with bypass permissions"
      },
      "require_conversation_resolution": {
        "title": "Require resolution",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Ensures that all comments and conversations are resolved before merging a pull request"
      },
      "lock_branch": {
        "title": "Lock branch",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Locks the branch, preventing any changes from being made unless explicitly unlocked"
      },
      "block_force_pushes": {
        "title": "Block force pushes",
        "type": "boolean",
        "icon": "DefaultProperty",
        "description": "Prevent users with push access from force pushing to refs"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "repository": {
      "title": "Repository",
      "target": "githubRepository",
      "required": false,
      "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: '.repository.default_branch == .branch.name'
    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
            require_signed_commits: .branch.protectionRules.required_signatures.enabled
            require_linear_history: .branch.protectionRules.required_linear_history.enabled
            restrict_creations: .branch.protectionRules.block_creations.enabled
            restrict_updates: .branch.protectionRules.restrict_updates.enabled
            require_conversation_resolution: >-
             .branch.protectionRules.required_conversation_resolution.enabled
            lock_branch: .branch.protectionRules.lock_branch.enabled
            block_force_pushes: .branch.protectionRules.allow_force_pushes.enabled == false
          relations:
            repository: .repository.name
Currently only default branch protection rules are supported
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 User blueprint (click to expand)
{
  "identifier": "githubUser",
  "title": "Github User",
  "icon": "Github",
  "schema": {
    "properties": {
      "email": {
        "title": "Email",
        "type": "string"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "aggregationProperties": {},
  "relations": {
    "github_team": {
      "title": "Github Team",
      "target": "githubTeam",
      "required": false,
      "many": true
    }
  }
}
Port port-app-config.yml (click to expand)
createMissingRelatedEntities: true
resources:
  - kind: repository
    selector:
      query: "true"
      collaborators: true
    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"'
          relations:
            user: .email
Supported GitHub user types
As Github has strict privacy policies, the GitHub API will only return emails in the following cases:
- The user has a public email address
 - 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.
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, repository releases and tagsโ
The following example demonstrates how to ingest your GitHub repositories, their releases and tags 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": {}
}
Tag blueprint (click to expand)
{
  "identifier": "tag",
  "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": "release",
  "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": "tag",
      "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: release
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: .release.name
          title: .release.name
          blueprint: '"release"'
          properties:
            author: .release.author.login
            description: .release.body
            release_creation_time: .release.created_at
          relations:
            tag: .release.tag_name
            repository: .repo.name
  - kind: tag
    selector:
      query: 'true'
    port:
      entity:
        mappings:
          identifier: .tag.name
          title: .tag.name
          blueprint: '"tag"'
          properties:
            commit_sha: .commit.sha
          relations:
            repository: .repo.name
Map repositories and repository custom propertiesโ
The following example shows how to ingest your GitHub repositories and their custom properties to Port.
You can use the following 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"
      },
      "custom_properties": {
        "items": {
          "type": "object"
        },
        "type": "array",
        "title": "Custom Properties"
      }
    },
    "required": []
  },
  "mirrorProperties": {},
  "calculationProperties": {},
  "relations": {}
}
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.
      customProperties: true
    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
            custom_properties: .customProperties
Map supported resourcesโ
The examples above show 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:
repositorypull-requestenvironmentdeploymentworkflowworkflow-runissuefolderfileuser
For theuserkind, only the following fields are supported:.name,.login, and.email.
Other fields from the GitHub User API are not available.teamdependabot-alertbranchescode-scanningreleasestags
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.