GitHub Ocean (Beta)
Port's GitHub integration allows you to model GitHub resources in your software catalog and ingest data into them.
Overview
The integration allows you to:
- Map and organize GitHub resources and metadata into Port (see supported resources below).
- Detect changes (create/update/delete) in real-time and keep your catalog up to date.
- Manage Port entities using GitOps.
- Sync multiple GitHub organizations with a single integration instance.
Supported resources
The resources that can be ingested from GitHub into Port are listed below. It is possible to reference any field that appears in the API responses linked below in the mapping configuration.
organizationrepositorypull-requestfileissuefolderuserteamworkflowworkflow-rundependabot-alertcode-scanningbranchesenvironmentdeploymentreleasestagssecret-scanning
Setup
To install the integration, see the installation page.
Configuration
Port integrations use a YAML mapping block to ingest data from the third-party API into Port.
The mapping makes use of the JQ JSON processor to select, modify, concatenate, transform and perform other operations on existing fields and values from the integration API.
To ingest GitHub objects, you can use one of the following methods:
- Using Port's UI
- Using GitHub
To manage your GitHub Ocean configuration using Port:
- Go to the data sources page of your portal.
- Under
Exporters, click on the installed GitHub Ocean integration. - A window will open containing the default YAML configuration of your integration.
- Here you can modify the configuration to suit your needs, by adding or removing entries.
- When finished, click Resync to apply any changes.
Using this method applies the configuration to all organizations and repositories that the integration has permissions to.
When configuring the integration using Port, the YAML configuration is global, allowing you to specify mappings for multiple Port blueprints.
You can also manage your GitHub Ocean configuration using a config file in GitHub:
- Go to the data sources page of your portal.
- Under
Exporters, click on the installed GitHub Ocean integration. - In the configuration panel, set
repoManagedMapping: truein the integration configuration YAML.
This tells GitHub Ocean to load its mapping from a configuration file in your GitHub organization instead of using the mapping stored in Port (when this feature is enabled in the integration).
With GitHub Ocean, configuration from Git is currently org-level only:
- Create a
.github-privaterepository in your GitHub organization if it does not already exist. - Add a
port-app-config.ymlfile to the root of the.github-privaterepository. - The file must be present on the default branch (usually
main) to be applied.
Here is a minimal example of an org-level port-app-config.yml for GitHub Ocean:
deleteDependentEntities: true
createMissingRelatedEntities: true
resources:
- kind: organization
selector:
query: "true"
port:
entity:
mappings:
identifier: .login
title: .login
blueprint: '"githubOrganization"'
- kind: repository
selector:
query: "true"
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"githubRepository"'
When configuring GitHub Ocean using GitHub:
- The
port-app-config.ymlin.github-privateis treated as the single global mapping for the integration. - Changes to this file will be picked up on the default branch and applied on the next resync or relevant event processing.
- Granular configuration (that is,
port-app-config.ymlfiles that live inside individual repositories rather than.github-private) is not yet supported for GitHub Ocean. - Multi-organization setups are not supported in this mode: the integration reads the GitHub organization from its configuration or environment, and that organization will always be used even if the mapping file contains multiple orgs.
Repository type
The repositoryType parameter filters which repositories are ingested. It corresponds to the type parameter in GitHub's List organization repositories API.
Possible values (click to expand)
all(default): All repositories accessible to the provided token.public: Public repositories only.private: Private repositories only.forks: Forked repositories only.sources: Non-forked repositories only.
See the default mapping below for a usage example.
Default mapping configuration
This is the default mapping configuration for this integration:
Default mapping configuration (click to expand)
repositoryType: "all"
deleteDependentEntities: true
createMissingRelatedEntities: true
resources:
- kind: organization
selector:
query: "true"
port:
entity:
mappings:
identifier: .login
title: .login
blueprint: '"githubOrganization"'
properties:
login: .login
id: .id
nodeId: .node_id
url: .url
reposUrl: .repos_url
eventsUrl: .events_url
hooksUrl: .hooks_url
issuesUrl: .issues_url
membersUrl: .members_url
publicMembersUrl: .public_members_url
avatarUrl: .avatar_url
description: if .description then .description else "" end
- kind: repository
selector:
query: "true"
port:
entity:
mappings:
identifier: .name
title: .name
blueprint: '"githubRepository"'
properties:
description: if .description then .description else "" end
visibility: if .private then "private" else "public" end
defaultBranch: .default_branch
readme: file://README.md
url: .html_url
language: if .language then .language else "" end
relations:
organization: .owner.login
- kind: pull-request
selector:
query: "true"
state: "open"
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: ".state"
closedAt: ".closed_at"
updatedAt: ".updated_at"
mergedAt: ".merged_at"
createdAt: ".created_at"
prNumber: ".id"
link: ".html_url"
leadTimeHours: >-
(.created_at as $createdAt | .merged_at as $mergedAt |
($createdAt | sub("\\..*Z$"; "Z") | strptime("%Y-%m-%dT%H:%M:%SZ") | mktime) as $createdTimestamp |
($mergedAt | if . == null then null else sub("\\..*Z$"; "Z") |
strptime("%Y-%m-%dT%H:%M:%SZ") | mktime end) as $mergedTimestamp |
if $mergedTimestamp == null then null else
(((($mergedTimestamp - $createdTimestamp) / 3600) * 100 | floor) / 100) end)
relations:
repository: .__repository
Capabilities
For detailed information about data ingestion capabilities, see the capabilities page.
Examples
Refer to the examples page for practical configurations and their corresponding blueprint definitions.