Ingest API paths from an OpenAPI spec in a GitHub repository into Port
This guide includes one or more steps that require integration with GitHub.
Port supports two GitHub integrations:
- GitHub (Legacy) - uses a GitHub app, which is soon to be deprecated.
- GitHub (Ocean) - uses the Ocean framework, recommended for new integrations.
Both integration options are present in this guide via tabs, choose the one that fits your needs.
The following example demonstrates how to create an apiPath blueprint, and ingest all API paths in your spec JSON file using Port's GitHub file ingesting feature.
To ingest the packages to Port, the GitHub integration is used.
Prerequisites
This guide assumes you have a Port account.
- GitHub (Legacy)
- GitHub (Ocean)
- Install Port's GitHub app in your organisation or in repositories you are interested in.
- Install the GitHub Ocean integration.
GitHub configuration
To ingest GitHub objects, use one of the following methods:
- Using Port's UI
- Using GitHub
To manage your GitHub integration configuration using Port:
- Go to the data sources page of your portal.
- Under
Exporters, click on your desired GitHub organization. - A window will open containing the default YAML configuration of your GitHub integration.
- Here you can modify the configuration to suit your needs, by adding/removing entries.
- When finished, click
resyncto apply any changes.
Using this method applies the configuration to all repositories that the GitHub app has permissions to.
When configuring the integration using Port, the YAML configuration is global, allowing you to specify mappings for multiple Port blueprints.
To manage your GitHub integration configuration using a config file in GitHub:
- Go to the data sources page of your portal.
- Under
Exporters, click on your desired GitHub organization. - A window will open containing the default YAML configuration of your GitHub integration.
- Scroll all the way down, and turn on the
Manage this integration using the "port-app-config.yml" filetoggle.
This will clear the configuration in Port's UI.
When configuring the integration using GitHub, you can choose either a global or granular configuration:
- Global configuration: create a
.github-privaterepository in your organization and add theport-app-config.ymlfile to the repository.- Using this method applies the configuration to all repositories that the GitHub app has permissions to (unless it is overridden by a granular
port-app-config.ymlin a repository).
- Using this method applies the configuration to all repositories that the GitHub app has permissions to (unless it is overridden by a granular
- Granular configuration: add the
port-app-config.ymlfile to the.githubdirectory of your desired repository.- Using this method applies the configuration only to the repository where the
port-app-config.ymlfile exists.
- Using this method applies the configuration only to the repository where the
When using global configuration using GitHub, the configuration specified in the port-app-config.yml file will only be applied if the file is in the default branch of the repository (usually main).
When using Port's UI, the specified configuration will override any port-app-config.yml file in your GitHub repository/ies.
Setting up the blueprint and mapping configuration
Create the following blueprint definition and mapping configuration:
API path blueprint (click to expand)
{
"identifier": "apiPath",
"description": "This blueprint represents an OpenAPI path in our software catalog",
"title": "API Paths",
"icon": "Swagger",
"schema": {
"properties": {
"method": {
"type": "string",
"title": "Method",
"default": "get",
"enum": ["get", "post", "delete", "put", "patch"],
"enumColors": {
"get": "yellow",
"post": "green",
"delete": "red",
"put": "purple",
"patch": "purple"
}
},
"serverUrl": {
"type": "string",
"title": "Server URL",
"format": "url"
},
"path": {
"title": "Path",
"type": "string"
},
"parameters": {
"items": {
"type": "object"
},
"title": "Parameters",
"type": "array"
},
"requestBody": {
"title": "Request Body",
"type": "object"
},
"responses": {
"title": "Responses",
"type": "object"
},
"description": {
"title": "Description",
"type": "string"
},
"version": {
"title": "Version",
"type": "string"
},
"summary": {
"title": "Summary",
"type": "string"
},
"tags": {
"title": "Tags",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "repository",
"required": false,
"many": false
}
}
}
- GitHub (Legacy)
- GitHub (Ocean)
API path mapping configuration (click to expand)
resources:
- kind: file
selector:
query: 'true'
files:
- path: '**/openapi.json' # or .yaml
port:
itemsToParse: >-
.file.content | [[. as $root | .paths | to_entries[] as $entries |
{version: $root.info.version, servers: $root.servers, title:
$root.info.title, path: $entries.key, methods: ($entries.value |
to_entries[] as $inner | {method: ($inner.key), rest: $inner.value,
path: $entries.key})}][] | {id: (.title + "-" + .path +
.methods.method), path, method: .methods.method, summary:
.methods.rest.summary, description: .methods.rest.description,
parameters: .methods.rest.parameters, requestBody:
.methods.rest.requestBody, responses: .methods.rest.responses, tags:
.methods.rest.tags, project: .title, version, serverUrl:
.servers[0].url}]
entity:
mappings:
identifier: '.item.id | sub("[^A-Za-z0-9@_.:/=-]"; "-"; "g")'
title: .item.method + .item.path
blueprint: '"apiPath"'
properties:
method: .item.method
serverUrl: .item.serverUrl
path: .item.path
parameters: .item.parameters
requestBody: .item.requestBody
responses: .item.responses
description: .item.description
version: .item.version
summary: .item.summary
tags: .item.tags
relations: {}
API path mapping configuration (click to expand)
resources:
- kind: file
selector:
query: 'true'
files:
- path: '**/openapi.json' # or .yaml
organization: my-org # Optional if githubOrganization is set (required if not set)
repos:
- name: MyRepo
branch: main
port:
itemsToParse: >-
.content | [[. as $root | .paths | to_entries[] as $entries |
{version: $root.info.version, servers: $root.servers, title:
$root.info.title, path: $entries.key, methods: ($entries.value |
to_entries[] as $inner | {method: ($inner.key), rest: $inner.value,
path: $entries.key})}][] | {id: (.title + "-" + .path +
.methods.method), path, method: .methods.method, summary:
.methods.rest.summary, description: .methods.rest.description,
parameters: .methods.rest.parameters, requestBody:
.methods.rest.requestBody, responses: .methods.rest.responses, tags:
.methods.rest.tags, project: .title, version, serverUrl:
.servers[0].url}]
entity:
mappings:
identifier: '.item.id | sub("[^A-Za-z0-9@_.:/=-]"; "-"; "g")'
title: .item.method + .item.path
blueprint: '"apiPath"'
properties:
method: .item.method
serverUrl: .item.serverUrl
path: .item.path
parameters: .item.parameters
requestBody: .item.requestBody
responses: .item.responses
description: .item.description
version: .item.version
summary: .item.summary
tags: .item.tags
relations:
repository: .__repository
GitHub (Ocean) uses .content instead of .file.content for file content. The files selector supports organization and repos (with name and branch) for scoping. Use .__repository for the repository relation.
Then click on Resync and wait for the entities to be ingested in your Port environment.