GitHub (Ocean)
The GitHub Ocean integration allows you to model GitHub resources in your software catalog and ingest data into them.
Core support
If you are migrating from the old GitHub app integration, disable the "Create default resources" toggle in the Advanced Configuration section before clicking Connect.
For a self-hosted GitHub Ocean installation, set createPortResourcesOrigin: Empty in your values file. This registers only the integration without creating default blueprints or mappings.
Leaving this toggle enabled will create new default blueprints and mappings that may conflict with your existing data. See the migration guide for detailed instructions.
Prerequisites
- A GitHub account with permissions to create access tokens.
- Your Port user role is set to
Admin.
Setup
Choose your preferred authentication and installation method below. Not sure which to pick? See the installation methods overview.
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 transform data.
Managing your configuration
You can manage your GitHub Ocean configuration in two ways:
-
Port UI: Go to the data sources page, click on the installed GitHub Ocean integration, and modify the YAML configuration directly. This applies the configuration globally to all organizations and repositories the integration can access.
-
GitHub file: Set
repoManagedMapping: truein the integration configuration YAML to load the mapping from aport-app-config.ymlfile in your GitHub organization. Create this file in the.github-privaterepository on the default branch for it to take effect as an org-level mapping.GitHub file configuration limitations- Only org-level configuration is supported — repository-level
port-app-config.ymlfiles are not yet supported for GitHub Ocean. - Multi-organization setups are not supported when using GitHub file configuration.
- Only org-level configuration is supported — repository-level
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.
Multi-organization support
The GitHub integration supports syncing data from multiple GitHub organizations with a classic PAT (v3.0.0-beta+) or GitHub App authentication (v6.5.0+).
- GitHub App setup: The integration discovers and syncs every organization where the GitHub App is installed. Set
githubOrganizationonly when you want to limit the sync to one organization. - Enterprise-owned apps: Create or transfer the GitHub App to your enterprise so it is available to install in all of its organizations. You must still install the app in each organization you want to sync.
- Classic PAT setup: Set
organizations: ["org1", "org2", "org3"]in your mapping to choose organizations. Iforganizationsis not specified, the integration syncs all organizations the classic PAT can access.
Multi-organization mapping example (click to expand)
deleteDependentEntities: true
createMissingRelatedEntities: true
enableMergeEntity: true
organizations:
- org1
- org2
# ... rest of your mapping (repositoryType, resources, etc.) ...
Precedence:
If githubOrganization is set in the environment variables or config and organizations are also listed in the Port mapping, the integration prioritizes single-organization behavior and syncs only the githubOrganization.
Performance considerations:
Syncing multiple organizations increases the number of API calls to GitHub and may slow down the integration. The more organizations you sync, the longer the resync time and the higher the API rate limit consumption.
Default mapping configuration
This is the complete default mapping for the GitHub Ocean integration.
Complete default mapping (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"
includedFiles:
- README.md
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: .__includedFiles["README.md"]
url: .html_url
language: if .language then .language else "" end
relations:
organization: .owner.login
- kind: pull-request
selector:
query: "true"
states: ["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
Mapping & selectors per resource
For blueprint and mapping examples per resource type, see the examples page.
Set up live events
This integration supports live events, allowing real-time updates to your software catalog without waiting for the next scheduled sync.
Note that different events are supported depending on the resource type.
- Hosted by Port
- Self-hosted
Live events base URL
For integrations installed using the Hosted by Port method, you can obtain the live events base URL from the Get an integration API. The response includes liveEventsUuid and liveEventsIngestHostname in the appSpec section.
Call the endpoint with your integration's identifier:
curl -X GET \
'https://api.port.io/v1/integration/<INTEGRATION_IDENTIFIER>' \
-H 'Authorization: Bearer <PORT_ACCESS_TOKEN>'
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters select which Port API instance to use:
- EU (app.port.io) →
https://api.port.io - US (app.us.port.io) →
https://api.us.port.io
In the response, look for the following fields under spec.appSpec:
{
"spec": {
"appSpec": {
"liveEventsUuid": "abcdefghijk",
"liveEventsIngestHostname": "ingest.ocean.getport.io"
}
}
}
Combine them to build the live events base URL:
https://<liveEventsIngestHostname>/live-events/<liveEventsUuid>
For example, with the values above, the live events base URL is:
https://ingest.ocean.getport.io/live-events/abcdefghijk
This is the same URL configured for the integration.
BaseUrl & webhook configuration
To enable real-time updates of the data in your software catalog, you need to define the liveEvents.baseUrl parameter.
This parameter should be set to the URL of your GitHub integration instance, which needs to have the option to setup webhooks via HTTP requests/receive HTTP requests, so ensure the network is configured accordingly.
- If GitHub and the integration are in the same cluster/network: Use an internal URL (e.g., a Kubernetes service DNS name).
For Kubernetes deployments, create a service to expose the integration pod and use the service URL asliveEvents.baseUrl. If both the source system and integration are in the same cluster, an internal ClusterIP service is sufficient. - If GitHub is external to the integration's network: The integration must be exposed via an ingress, load balancer, or public URL that GitHub can reach.
If liveEvents.baseUrl is not provided, the integration will continue to function correctly. In such a configuration, to retrieve the latest information from the target system, the scheduledResyncInterval parameter has to be set, or a manual resync will need to be triggered through Port's UI.
To test webhooks or live event delivery to your local environment, expose your local pod or service to the internet using ngrok (e.g. ngrok http http://localhost:8000)
Incremental sync
In addition to the standard full resync, this integration supports incremental sync for the following resource kinds:
repositorypull-requestworkflow-rundeploymentreleasecode-scanning-alertsdependabot-alertissue
Any other kind in your mapping is not fetched incrementally, and continues to be kept up to date by the full resync.
Incremental sync is currently in closed beta and is only available to select organizations. It will be generally available in the upcoming weeks.
See Incremental sync for how it works, its current limitations, and how to enable it for your organization.
Capabilities
The GitHub Ocean integration supports a rich set of data ingestion capabilities. See the capabilities page for full details on each feature.
Key capabilities include:
- Ingest Git objects — Automatically ingest GitHub resources (repositories, pull requests, issues, and more) based on real-time events.
- Ingest organizations — Sync organization-level data as parent entities for repositories and teams (available from v3.0.0-beta).
- Enrich entities with file contents — Attach files from repositories using the
includedFilesselector and map them with JQ via.__includedFilesinstead of the deprecatedfile://prefix. - Ingest files from repositories — Fetch JSON and YAML files from repositories and create Port entities from their contents.
- Ingest agent skills — Discover
SKILL.mdAgent Skills and map them into your catalog. - Ingest agent plugins — Detect agent plugin packages per repository and normalize provider support.
- Repository search API — Use GitHub's repository search API for granular repository filtering when ingesting data.
- Parallel event processing — Configure multiple async workers to handle GitHub webhook events in parallel, preventing race conditions while maintaining event ordering.
- Personal account ingestion — Optionally ingest the authenticated user's personal GitHub account as a pseudo-organization.
- Incremental sync - Sync recently created or updated resources on a short interval, in parallel to the full resync.
Monitoring and sync status
To learn more about how to monitor and check the sync status of your integration, see the relevant documentation.
Examples
For blueprint and configuration examples across all supported resource kinds, see the GitHub Ocean examples page.
To view and test the integration's mapping against live API responses, use the jq playground in your data sources page.
Relevant guides
For relevant guides and examples, see the guides section.