Skip to main content

Check out Port for yourselfย 

Examples

Basic create/update exampleโ€‹

In this example you will create blueprints for ciJob and image entities, and a relation between them. Then you will add some Python code to create new entities in Port every time the Azure Pipeline is triggered:

Image blueprint
{
"identifier": "image",
"title": "Image",
"icon": "Docker",
"schema": {
"properties": {
"synkHighVulnerabilities": {
"type": "string",
"icon": "Snyk",
"title": "Synk High Vaulnerabilities"
},
"synkMediumVulnerabilities": {
"type": "string",
"icon": "Snyk",
"title": "Synk Medium Vaulnerabilities"
},
"imageTag": {
"type": "string",
"title": "Image Tag"
},
"gitRepoUrl": {
"type": "string",
"format": "url",
"title": "Git Url",
"description": "Git Url for the sourcecode"
},
"imageRegistry": {
"type": "string",
"format": "url",
"title": "Image Registry",
"description": "Docker registry"
},
"unitTestCoverage": {
"type": "number",
"title": "Unit Test coverage (%)",
"description": "The unit test coverage pecentage"
},
"integTestCoverage": {
"type": "number",
"title": "Integ Test coverage (%)",
"description": "The integration test coverage pecentage"
},
"size": {
"type": "number",
"title": "Image Size (GB)",
"description": "The image size in Gigabyte"
}
},
"required": []
},
"calculationProperties": {}
}
CI Job blueprint (including the image relation)
{
"identifier": "ciJob",
"title": "CI Job",
"icon": "CICD",
"schema": {
"properties": {
"triggeredBy": {
"type": "string",
"icon": "TwoUsers",
"title": "Triggered By",
"description": "The user who triggered the run"
},
"commitHash": {
"type": "string",
"title": "Commit Hash"
},
"jobBranch": {
"type": "string",
"icon": "Git",
"format": "url",
"title": "Job branch"
},
"runLink": {
"type": "string",
"format": "url",
"title": "Action Run Link"
}
},
"required": []
},
"relations": {
"image": {
"title": "Job Images",
"target": "image",
"required": false,
"many": true
}
},
"calculationProperties": {}
}

After creating the blueprints, you can add a Python script for creating/updating a Port entity:

import os
import requests
import json

# Env vars passed by the pipeline variables
CLIENT_ID = os.environ['PORT_CLIENT_ID']
CLIENT_SECRET = os.environ['PORT_CLIENT_SECRET']
API_URL = 'https://api.getport.io/v1'

credentials = {
'clientId': CLIENT_ID,
'clientSecret': CLIENT_SECRET
}
token_response = requests.post(f"{API_URL}/auth/access_token", json=credentials)
# use this access token + header for all http requests to Port
access_token = token_response.json()['accessToken']
headers = {
'Authorization': f'Bearer {access_token}'
}

entity_json = {
"identifier": "new-cijob-run",
"properties": {
"triggeredBy": os.environ['QUEUED_BY'],
"commitHash": os.environ['GIT_SHA'],
"actionJob": os.environ['JOB_NAME'],
"jobLink": os.environ['JOB_URL']
},
"relations": {
"image": ["example-image"]
}
}

create_response = requests.post(f'{API_URL}/blueprints/{blueprint_id}/entities?upsert=true&create_missing_related_entities=true', json=entity_json, headers=headers)
Selecting a Port API URL by account region

The baseUrl, port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters are used to select which instance or Port API will be used.

Port exposes two API instances, one for the EU region of Port, and one for the US region of Port.

note

Please notice that you have also created the image relation, and added a related image entity called example-image. This is the artifact of the ciJob, and you will update it later. The creation was done using the create_missing_related_entities=true flag in the API url, allowing the relation to be created even though the example-image entity doesn't exist yet.

After adding your new Python script to your repository, add the following code to your Azure pipeline yml file to call your script and update/create a new ciJob entity:

steps:
# ... other tasks and steps
- script: |
pip install -r port_requirements.txt
- task: PythonScript@0
env:
PORT_CLIENT_ID: $(PORT_CLIENT_ID)
PORT_CLIENT_SECRET: $(PORT_CLIENT_SECRET)
QUEUED_BY: $(Build.QueuedBy)
GIT_SHA: $(Build.SourceVersion)
JOB_NAME: $(Build.DefinitionName)
JOB_URL: "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_build/results?buildId=$(Build.BuildId)"
inputs:
scriptSource: "filePath"
scriptPath: "main.py"

Basic get exampleโ€‹

The following example gets the new-cijob-run entity from the previous example, this can be useful if your CI process creates a build artifact and then references some of its data (for example, the run link of the latest ciJob).

Add the following snippet to your Python code:

entity_id = "new-cijob-run"
blueprint_id = "ciJob"

get_response = requests.get(f"{API_URL}/blueprints/{blueprint_id}/entities/{entity_id}",
headers=headers)
entity = get_response.json()['entity']
print(f"Image tag is: {entity['properties']['runLink']}")

Relation exampleโ€‹

In the following example you will update the example-image entity that was automatically created when creating the ciJob entity shown in the previous example.

Add the following snippet to your Python code:

image_entity_json = {
"identifier": "example-image",
"team": [],
"properties": {
"imageTag": "v1",
"synkHighVulnerabilities": "0",
"synkMediumVulnerabilities": "0",
"gitRepoUrl": "https://github.com/my-org/my-cool-repo",
"imageRegistry": "docker.io/cool-image",
"size": "0.71",
"unitTestCoverage": "20",
"unitTestCoverage": "50"
},
"relations": {}
}

create_image_response = requests.post(f'{API_URL}/blueprints/image/entities?upsert=true', json=image_entity_json, headers=headers)

That's it! The entity is created or updated and is visible in the UI.