Examples
Mapping projects, README.md and merge requests
In the following example you will ingest your GitLab projects, their README.md file contents and merge requests to Port, you may use the following Port blueprint definitions and integration configuration:
Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"url": {
"title": "URL",
"type": "string",
"format": "url"
},
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"description": {
"title": "Description",
"type": "string"
},
"language": {
"title": "Language",
"type": "string"
},
"namespace": {
"title": "Namespace",
"type": "string"
},
"fullPath": {
"title": "Full Path",
"type": "string"
},
"defaultBranch": {
"title": "Default Branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Merge request blueprint
{
"identifier": "gitlabMergeRequest",
"title": "Merge Request",
"icon": "GitVersion",
"schema": {
"properties": {
"creator": {
"title": "Creator",
"type": "string"
},
"status": {
"title": "Status",
"type": "string",
"enum": [
"opened",
"closed",
"merged",
"locked"
],
"enumColors": {
"opened": "yellow",
"closed": "red",
"merged": "green",
"locked": "blue"
}
},
"createdAt": {
"title": "Created 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": {
"title": "Link",
"format": "url",
"type": "string"
},
"leadTimeHours": {
"title": "Lead Time in hours",
"type": "number"
},
"reviewers": {
"title": "Reviewers",
"type": "array",
"items": {
"type": "string"
}
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"service": {
"title": "Service",
"target": "service",
"required": false,
"many": false
}
}
}
Ocean integration configuration
resources:
- kind: project
selector:
query: "true"
port:
entity:
mappings:
identifier: .path_with_namespace | gsub(" "; "")
title: .name
blueprint: '"service"'
properties:
url: .web_url
readme: file://README.md
description: .description
language: .__languages | to_entries | max_by(.value) | .key
namespace: .namespace.name
fullPath: .namespace.full_path
defaultBranch: .default_branch
- kind: merge-request
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .title
blueprint: '"gitlabMergeRequest"'
properties:
creator: .author.name
status: .state
createdAt: .created_at
updatedAt: .updated_at
mergedAt: .merged_at
link: .web_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)
reviewers: .reviewers | map(.name)
relations:
service: .references.full | gsub("!.+"; "")
- Refer to the setup section to learn more about the integration configuration setup process.
- We leverage JQ JSON processor to map and transform GitLab objects to Port entities.
- Click Here for the GitLab project object structure.
- Click Here for the GitLab merge request object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your projects alongside their README.md
file contents and merge requests.
Mapping files and file contents
The following example shows how to ingest dependencies from a package.json
file in your GitLab repository into Port.
You can use the following Port blueprint definitions and integration configuration:
Package blueprint
{
"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": {}
}
Ocean integration configuration
resources:
- kind: file
selector:
query: 'true'
files:
path: '**/package.json'
repos:
# The repository NAME should be used here, not the URL slug, e.g. "Repo Name" not "repo-name"
- MyRepoName
port:
itemsToParse: .file.content.dependencies | to_entries
entity:
mappings:
identifier: >-
.item.key + "_" + if (.item.value | startswith("^")) then
.item.value[1:] else .item.value 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
Mapping Groups, Subgroups and Projects
In the following example you will ingest your GitLab groups, subgroups and projects to Port, you may use the following Port blueprint definitions and integration configuration:
Group blueprint
{
"identifier": "gitlabGroup",
"title": "Group",
"icon": "GitLab",
"schema": {
"properties": {
"visibility": {
"icon": "Lock",
"title": "Visibility",
"type": "string",
"enum": [
"public",
"internal",
"private"
],
"enumColors": {
"public": "red",
"internal": "yellow",
"private": "green"
}
},
"url": {
"title": "URL",
"format": "url",
"type": "string",
"icon": "Link"
},
"description": {
"title": "Description",
"type": "string",
"icon": "BlankPage"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {}
}
Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"url": {
"title": "URL",
"type": "string",
"format": "url"
},
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"description": {
"title": "Description",
"type": "string"
},
"language": {
"title": "Language",
"type": "string"
},
"namespace": {
"title": "Namespace",
"type": "string"
},
"fullPath": {
"title": "Full Path",
"type": "string"
},
"defaultBranch": {
"title": "Default Branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"group": {
"title": "Group",
"target": "gitlabGroup",
"required": true,
"many": false
}
}
}
Ocean integration configuration
deleteDependentEntities: true
createMissingRelatedEntities: true
enableMergeEntity: true
resources:
- kind: group
selector:
query: "true"
port:
entity:
mappings:
identifier: .full_path
title: .name
blueprint: '"gitlabGroup"'
properties:
url: .web_url
visibility: .visibility
description: .description
- kind: project
selector:
query: "true"
port:
entity:
mappings:
identifier: .path_with_namespace | gsub(" "; "")
title: .name
blueprint: '"service"'
properties:
url: .web_url
readme: file://README.md
description: .description
language: .__languages | to_entries | max_by(.value) | .key
namespace: .namespace.name
fullPath: .namespace.full_path
defaultBranch: .default_branch
relations:
group: >-
.path_with_namespace | gsub(" "; "") | split("/") | .[:-1] |
join("/")
- Refer to the setup section to learn more about the integration configuration setup process.
- We leverage JQ JSON processor to map and transform GitLab objects to Port entities.
- Click Here for the GitLab project object structure.
- Click Here for the GitLab subgroup object structure.
Mapping projects, pipelines and jobs
In the following example you will ingest your GitLab projects, their pipelines and jobs runs to Port, you may use the following Port blueprint definitions and integration configuration:
Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"url": {
"title": "URL",
"type": "string",
"format": "url"
},
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"description": {
"title": "Description",
"type": "string"
},
"language": {
"title": "Language",
"type": "string"
},
"namespace": {
"title": "Namespace",
"type": "string"
},
"fullPath": {
"title": "Full Path",
"type": "string"
},
"defaultBranch": {
"title": "Default Branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Pipeline blueprint
{
"identifier": "gitlabPipeline",
"title": "Pipeline",
"icon": "GitLab",
"schema": {
"properties": {
"createdAt": {
"title": "Created At",
"type": "string",
"format": "date-time"
},
"updatedAt": {
"title": "Updated At",
"type": "string",
"format": "date-time"
},
"creator": {
"title": "Creator",
"type": "string"
},
"status": {
"title": "Status",
"type": "string",
"enum": [
"created",
"waiting_for_resource",
"preparing",
"pending",
"running",
"success",
"failed",
"canceled",
"skipped",
"manual",
"scheduled"
],
"enumColors": {
"created": "yellow",
"waiting_for_resource": "yellow",
"preparing": "yellow",
"pending": "yellow",
"running": "yellow",
"success": "green",
"failed": "red",
"canceled": "red",
"skipped": "red",
"manual": "blue",
"scheduled": "blue"
}
},
"stages": {
"title": "Stages",
"type": "array",
"items": {
"type": "string"
}
},
"link": {
"title": "Link",
"type": "string",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"service": {
"title": "Service",
"target": "service",
"required": true,
"many": false
}
}
}
Job blueprint
{
"identifier": "gitlabJob",
"title": "Job",
"icon": "GitLab",
"schema": {
"properties": {
"createdAt": {
"title": "Created At",
"type": "string",
"format": "date-time"
},
"startedAt": {
"title": "Started At",
"type": "string",
"format": "date-time"
},
"finishedAt": {
"title": "Finished At",
"type": "string",
"format": "date-time"
},
"creator": {
"title": "Creator",
"type": "string"
},
"stage": {
"title": "Stage",
"type": "string"
},
"status": {
"title": "Status",
"type": "string",
"enum": [
"failed",
"warning",
"pending",
"running",
"manual",
"scheduled",
"canceled",
"success",
"skipped",
"created"
],
"enumColors": {
"failed": "red",
"warning": "red",
"pending": "yellow",
"running": "yellow",
"manual": "blue",
"scheduled": "blue",
"canceled": "red",
"success": "green",
"skipped": "red",
"created": "yellow"
}
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {
"pipeline": {
"target": "gitlabPipeline",
"required": false,
"many": false
}
}
}
Ocean integration configuration
resources:
- kind: project
selector:
query: "true"
port:
entity:
mappings:
identifier: .path_with_namespace | gsub(" "; "")
title: .name
blueprint: '"service"'
properties:
url: .web_url
description: .description
language: .__languages | to_entries | max_by(.value) | .key
namespace: .namespace.name
fullPath: .namespace.full_path
defaultBranch: .default_branch
- kind: pipeline
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .title // (.id | tostring)
blueprint: '"gitlabPipeline"'
properties:
creator: .user.name
status: .status
createdAt: .created_at
updatedAt: .updated_at
description: .description
link: .web_url
relations:
service: .__project.path_with_namespace | gsub(" "; "")
- kind: job
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .name
blueprint: '"gitlabJob"'
properties:
creator: .user.name
startedAt: .started_at
updatedAt: .updated_at
finishedAt: .finished_at
stage: .stage
status: .status
link: .web_url
relations:
pipeline: .pipeline.id | tostring
- Refer to the setup section to learn more about the integration configuration setup process.
- We leverage JQ JSON processor to map and transform GitLab objects to Port entities.
- Click Here for the GitLab project object structure.
- Click Here for the GitLab pipeline object structure.
- Click Here for the GitLab job object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your projects alongside their pipelines and jobs.
Mapping projects and monorepos
In the following example you will ingest your GitLab projects and their monorepo folders to Port, you may use the following Port blueprint definitions and integration configuration:
Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"url": {
"title": "URL",
"type": "string",
"format": "url"
},
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"description": {
"title": "Description",
"type": "string"
},
"language": {
"title": "Language",
"type": "string"
},
"namespace": {
"title": "Namespace",
"type": "string"
},
"fullPath": {
"title": "Full Path",
"type": "string"
},
"defaultBranch": {
"title": "Default Branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Ocean integration configuration
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: '"gitlabProject"'
properties:
url: >-
.repo.web_url + "/tree/" + .repo.default_branch + "/" +
.folder.path
description: .repo.description
namespace: .repo.namespace.name
full_path: .repo.path_with_namespace + "/" + folder.path
language: .repo.__languages | to_entries | max_by(.value) | .key
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
You can also specify different path for each monorepo repository, for example:
- 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/"
repos:
- gaming-apps
- path: "microservices/"
repos:
- backend-services
- Refer to the setup section to learn more about the integration configuration setup process.
- We leverage JQ JSON processor to map and transform GitLab objects to Port entities.
- Click Here for the GitLab project object structure.
- Click Here for the GitLab repository tree object structure.
Mapping projects and folders
In the following example you will ingest your GitLab projects and their folders to Port, you may use the following Port blueprint definitions and integration configuration:
Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"url": {
"title": "URL",
"type": "string",
"format": "url"
},
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"description": {
"title": "Description",
"type": "string"
},
"language": {
"title": "Language",
"type": "string"
},
"namespace": {
"title": "Namespace",
"type": "string"
},
"fullPath": {
"title": "Full Path",
"type": "string"
},
"defaultBranch": {
"title": "Default Branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Folder blueprint
{
"identifier": "gitlabFolder",
"title": "Folder",
"icon": "Gitlab",
"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: .web_url
defaultBranch: .default_branch
- 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: '"gitlabFolder"'
properties:
url: >-
.repo.web_url + "/tree/" + .repo.default_branch + "/" +
.folder.path
readme: file://README.md
relations:
service: .repo.name
- Refer to the setup section to learn more about the integration configuration setup process.
- We leverage JQ JSON processor to map and transform GitLab objects to Port entities.
- Click Here for the GitLab project object structure.
- Click Here for the GitLab repository tree object structure.
Mapping projects and issues
In the following example you will ingest your GitLab projects and their issues to Port, you may use the following Port blueprint definitions and integration configuration:
Service blueprint
{
"identifier": "service",
"title": "Service",
"icon": "Microservice",
"schema": {
"properties": {
"url": {
"title": "URL",
"type": "string",
"format": "url"
},
"readme": {
"title": "README",
"type": "string",
"format": "markdown"
},
"description": {
"title": "Description",
"type": "string"
},
"language": {
"title": "Language",
"type": "string"
},
"namespace": {
"title": "Namespace",
"type": "string"
},
"fullPath": {
"title": "Full Path",
"type": "string"
},
"defaultBranch": {
"title": "Default Branch",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Issue blueprint
{
"identifier": "gitlabIssue",
"title": "Issue",
"icon": "GitLab",
"schema": {
"properties": {
"link": {
"title": "Link",
"type": "string",
"format": "url"
},
"description": {
"title": "Description",
"type": "string",
"format": "markdown"
},
"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"
},
"creator": {
"title": "Creator",
"type": "string"
},
"status": {
"title": "Status",
"type": "string",
"enum": ["opened", "closed"],
"enumColors": {
"opened": "green",
"closed": "purple"
}
},
"labels": {
"title": "Labels",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"relations": {
"service": {
"target": "service",
"title": "Service",
"required": true,
"many": false
}
}
}
Ocean integration configuration
resources:
- kind: project
selector:
query: "true"
port:
entity:
mappings:
identifier: .path_with_namespace | gsub(" "; "")
title: .name
blueprint: '"service"'
properties:
url: .web_url
description: .description
language: .__languages | to_entries | max_by(.value) | .key
namespace: .namespace.name
fullPath: .namespace.full_path
defaultBranch: .default_branch
- kind: issue
selector:
query: "true"
port:
entity:
mappings:
identifier: .id | tostring
title: .title
blueprint: '"gitlabIssue"'
properties:
creator: .author.name
status: .state
createdAt: .created_at
closedAt: .closed_at
updatedAt: .updated_at
description: .description
link: .web_url
labels: "[.labels[]]"
relations:
service: .references.full | gsub("#.+"; "")
- Refer to the setup section to learn more about the integration configuration setup process.
- We leverage JQ JSON processor to map and transform GitLab objects to Port entities.
- Click Here for the GitLab project object structure.
- Click Here for the GitLab issue object structure.
After creating the blueprints and saving the integration configuration, you will see new entities in Port matching your projects alongside their issues.
Mapping supported resources
The above examples shows a specific use cases, but Port's GitLab integration supports the ingestion of many other GitLab objects, to adapt the examples above, use the GitLab 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.