Skip to content

Commit 8cdf28d

Browse files
authored
Merge pull request #2666 from port-labs/PORTN-3235-docs-map-prs-to-service-in-a-monorepo
PORTN-3235 Map prs to service in a monorepo guide
2 parents d362449 + 9497e74 commit 8cdf28d

File tree

2 files changed

+270
-0
lines changed

2 files changed

+270
-0
lines changed
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
---
2+
displayed_sidebar: null
3+
description: Automatically map pull requests to services in a monorepo using file path analysis
4+
---
5+
6+
# Map PRs to services in a monorepo
7+
8+
## Overview
9+
This guide demonstrates how to implement an automation in Port to map GitHub pull requests to sub-components in your monorepo based on the files that were changed.
10+
11+
This functionality streamlines monorepo management by enabling teams to quickly understand which sub-components are affected by each change without manual analysis. In this guide will refer to those sub-components as 'services'.
12+
13+
## Prerequisites
14+
15+
- Complete the [onboarding process](/getting-started/overview).
16+
- A GitHub repository with a monorepo structure containing multiple sub-components.
17+
- Port's [GitHub App](/build-your-software-catalog/sync-data-to-catalog/git/github/github.md) installed.
18+
- Access to GitHub API tokens for automation.
19+
20+
:::info Monorepo structure assumptions
21+
This guide assumes that the sub-components are organized in directories with a `service.yml` file (or similar configuration file). You can modify the path pattern to match your actual service configuration file (e.g., `**/package.json`, `**/docker-compose.yml`, etc.).
22+
:::
23+
24+
25+
26+
## Set up data model
27+
28+
After installing Port's [GitHub App](/build-your-software-catalog/sync-data-to-catalog/git/github/github.md), several blueprints are automatically created in your portal, including the `githubPullRequest` blueprint. However you need to update the blueprint with some additional properties in this setup.
29+
30+
31+
### Update the pull request blueprint
32+
33+
1. Go to the [blueprints](https://app.getport.io/settings/blueprints) page of your portal.
34+
35+
2. Find the `githubPullRequest` blueprint and click on it.
36+
37+
3. Click on the `Edit JSON` button in the top right corner.
38+
39+
4. Add the snippet below to the `schema` section:
40+
41+
```json showLineNumbers
42+
"file_change_url": {
43+
"type": "string",
44+
"title": "File change URL",
45+
"format": "url"
46+
}
47+
```
48+
49+
5. Add the following snippet to the `relations` section:
50+
51+
```json showLineNumbers
52+
"services": {
53+
"title": "Services",
54+
"target": "service",
55+
"required": false,
56+
"many": true
57+
}
58+
```
59+
60+
6. Click "Save" to update the blueprint.
61+
62+
## Update the data source
63+
64+
The first step is to configure how services are mapped from your monorepo structure. We'll use Port's file ingestion feature to automatically create service entities based on file paths.
65+
66+
<h3>Add the service mapping configuration</h3>
67+
68+
Follow the steps below to update the data source:
69+
70+
1. Go to the [Data sources](https://app.getport.io/settings/data-sources) page of your portal.
71+
72+
2. Find the GitHub exporter and click on it.
73+
74+
3. Add the following yaml to the mapping section:
75+
76+
<details>
77+
<summary><b>Service mapping configuration (Click to expand)</b></summary>
78+
79+
```yaml showLineNumbers
80+
- kind: file
81+
selector:
82+
query: 'true'
83+
files:
84+
- path: '**/service.yml' # or your actual service configuration file
85+
repos:
86+
- platform
87+
port:
88+
entity:
89+
mappings:
90+
identifier: .file.path | split("/")[:-1] | join("/")
91+
title: .file.content.service_name
92+
blueprint: '"service"'
93+
```
94+
95+
</details>
96+
97+
**Note**: Adjust the `path` pattern and `repos` list according to your monorepo structure. The `identifier` mapping extracts the directory path above the service configuration file (e.g., `service.yml`), which becomes the service identifier.
98+
99+
6. Click "Save & Resync" to update the data source.
100+
101+
:::tip Service file structure
102+
This configuration assumes each service (sub-component) has a `service.yml` file in its root directory. You can modify the path pattern to match your actual service configuration file (e.g., `**/package.json`, `**/docker-compose.yml`, etc.).
103+
:::
104+
105+
<h3>Update the pull request kind to include the file change URL</h3>
106+
107+
1. Still in the [data sources](https://app.getport.io/settings/data-sources) page of your portal.
108+
109+
2. Update the `pull-request` kind to include the `file_change_url` property.
110+
111+
<details>
112+
<summary><b>Pull request kind configuration (Click to expand)</b></summary>
113+
114+
```yaml showLineNumbers
115+
- kind: pull-request
116+
selector:
117+
query: 'true'
118+
port:
119+
entity:
120+
mappings:
121+
identifier: .id|tostring
122+
title: .title
123+
blueprint: '"githubPullRequest"'
124+
properties:
125+
status: .status
126+
label: .labels
127+
// highlight-start
128+
file_change_url: .commits_url | split("/")[:8] | join("/") + "/files"
129+
// highlight-end
130+
// other properties...
131+
```
132+
</details>
133+
134+
3. Click "Save & Resync" to update the data source.
135+
136+
## Set up automations
137+
138+
Now we'll create a two-step automation workflow that:
139+
1. Fetches the files changed in a pull request
140+
2. Updates the PR with relations to the affected services
141+
142+
### Get PR files changed
143+
144+
This automation triggers when a new pull request is created and fetches the list of changed files.
145+
146+
1. Go to the [automations](https://app.getport.io/settings/automations) page of your portal.
147+
148+
2. Click on `+ Automation`.
149+
150+
3. Click on the `Edit JSON` button in the top right corner.
151+
152+
4. Copy and paste the following JSON schema:
153+
154+
<details>
155+
<summary><b>Get files changed automation (Click to expand)</b></summary>
156+
157+
```json showLineNumbers
158+
{
159+
"identifier": "get_files_changed_for_a_pr",
160+
"title": "Get files changed for a PR",
161+
"description": "",
162+
"trigger": {
163+
"type": "automation",
164+
"event": {
165+
"type": "ENTITY_CREATED",
166+
"blueprintIdentifier": "githubPullRequest"
167+
},
168+
"condition": {
169+
"type": "JQ",
170+
"expressions": [],
171+
"combinator": "and"
172+
}
173+
},
174+
"invocationMethod": {
175+
"type": "WEBHOOK",
176+
"url": "{{ .event.diff.after.properties.file_change_url }}",
177+
"agent": false,
178+
"synchronized": true,
179+
"method": "GET",
180+
"headers": {
181+
"Authorization": "Bearer {{ .secrets.YOUR_GITHUB_TOKEN }}",
182+
"X-GitHub-Api-Version": "2022-11-28",
183+
"Identifier": "{{ .event.context.entityIdentifier | tostring }}"
184+
},
185+
"body": {}
186+
},
187+
"publish": true
188+
}
189+
```
190+
191+
</details>
192+
193+
5. Click "Save" to create the automation.
194+
195+
:::info GitHub token requirement
196+
This automation requires a GitHub personal access token with `repo` scope permissions. Make sure to add this token to your Port secrets as `YOUR_GITHUB_TOKEN`.
197+
:::
198+
199+
### Update PR with service relations
200+
201+
This automation triggers after the first automation completes successfully and creates relations between the PR and the affected services.
202+
203+
Follow the steps below to create the automation:
204+
205+
1. Go back to the [automations](https://app.getport.io/settings/automations) page.
206+
207+
2. Click on `+ Automation` and select `Edit JSON`.
208+
209+
3. Copy and paste the following JSON schema:
210+
211+
<details>
212+
<summary><b>Update PR with service relations automation (Click to expand)</b></summary>
213+
214+
```json showLineNumbers
215+
{
216+
"identifier": "update_pr_with_service",
217+
"title": "Update PR with files changed",
218+
"description": "",
219+
"trigger": {
220+
"type": "automation",
221+
"event": {
222+
"type": "RUN_UPDATED",
223+
"actionIdentifier": "get_files_changed_for_a_pr"
224+
},
225+
"condition": {
226+
"type": "JQ",
227+
"expressions": [
228+
".diff.after.status == \"SUCCESS\""
229+
],
230+
"combinator": "and"
231+
}
232+
},
233+
"invocationMethod": {
234+
"type": "UPSERT_ENTITY",
235+
"blueprintIdentifier": "githubPullRequest",
236+
"mapping": {
237+
"identifier": "{{ .event.diff.before.payload.headers.Identifier | tostring }}",
238+
"relations": {
239+
"service": "{{ .event.diff.before.response | map(.filename | split(\"/\")[:-1] | join(\"/\")) }}"
240+
}
241+
}
242+
},
243+
"publish": true
244+
}
245+
```
246+
247+
</details>
248+
249+
5. Click "Save" to create the automation.
250+
251+
:::info Automation chain
252+
This automation is chained to the first one, meaning it will only execute after the "Get files changed for a PR" automation completes successfully. The chain ensures proper sequencing of operations.
253+
:::
254+
255+
## Let's test it
256+
257+
1. Create a new pull request in your GitHub repository.
258+
259+
2. Check the PR in Port.
260+
261+
3. Check the services that were affected by the PR.
262+
263+
4. Check the [Audit log](https://app.getport.io/settings/AuditLog) to see the chain of actions

src/components/guides-section/consts.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,13 @@ export const availableGuides = [
13781378
logos: ["AI", "Slack", "PagerDuty"],
13791379
link: "/guides/all/generate-incident-updates-with-ai",
13801380
},
1381+
{
1382+
title: "Map PRs to services in a monorepo",
1383+
description: "Automatically map GitHub pull requests to services in a monorepo using file path analysis",
1384+
tags: ["SDLC", "GitHub", "Automations"],
1385+
logos: ["GitHub"],
1386+
link: "/guides/all/map-prs-to-services-in-monorepo",
1387+
},
13811388
{
13821389
title: "Trigger GitHub Copilot from Port",
13831390
description: "Learn how to set up GitHub Copilot triggers from Port to enable AI-powered coding assistance",

0 commit comments

Comments
 (0)