Enforce code maturity with GitLab file search
Code maturity standards help teams to consistently follow engineering best practices like testing, linting, documentation, and CI. By tracking these signals with Port scorecards via GitLab file search, teams can monitor compliance, guide maturity, and reduce production risk.
This guide demonstrates how to set up a GitLab integration that uses file search to detect the presence of key configuration files (like .gitlab-ci.yml
, README.md
, or package.json
), and then visualize and score these practices in Port.
Common use casesโ
- Encourage consistency: Ensure all services have testing and deployment pipelines in place.
- Track adoption of practices: Identify which services still lack key maturity signals (e.g., no README, no linter config).
- Gate production deployments: Require a certain maturity level before deploying new services.
Prerequisitesโ
- You have a Port account and have completed the onboarding process.
- You have enabled GitLab advanced search API in your GitLab environment.
- You have installed Port's GitLab integration.
Set up data modelโ
Follow the steps below to update the Service
blueprint:
-
Navigate to the
Service
blueprint in your Port Builder. -
Hover over it, click on the
...
button on the right, and selectEdit JSON
. -
Add the following boolean properties to capture repository maturity signals:
Repository file check properties (Click to expand)
"hasCI": {
"type": "boolean",
"title": "Has CI"
},
"hasLicense": {
"type": "boolean",
"title": "Has License"
},
"usingFastapiPackage": {
"type": "boolean",
"title": "Uses FastAPI"
},
"usingOldLoggingPackage": {
"type": "boolean",
"title": "Use Old Logging"
},
"hasTests": {
"type": "boolean",
"title": "Has Test"
},
"hasContributingGuide": {
"type": "boolean",
"title": "Has Contributing Guide"
},
"hasLinter": {
"type": "boolean",
"title": "Has Linter"
},
"hasPoetryLock": {
"type": "boolean",
"title": "Has Poetry Lock"
},
"hasPythonVersionInPoetry": {
"type": "boolean",
"title": "Has Python Version in Poetry"
},
"hasTestInCi": {
"type": "boolean",
"title": "Has Test in CI"
},
"hasReadme": {
"type": "boolean",
"title": "Has Readme"
} -
Click
Save
to update the blueprint.
Update GitLab integration configuration
-
Go to your Data Source page.
-
Select the GitLab integration.
-
Add the following YAML block into the
Mapping
editor to detect file presence:GitLab Code Maturity Check Configuration (Click to expand)
supported search scopeCurrently only search in the repository files (
blobs
) are supported- kind: project
selector:
query: 'true'
includeLabels: 'false'
port:
entity:
mappings:
identifier: .path_with_namespace | gsub(" "; "")
title: .name
blueprint: '"gitlabRepository"'
properties:
url: .web_url
description: .description
language: .__languages | to_entries | max_by(.value) | .key
namespace: .namespace.name
fullPath: .namespace.full_path
defaultBranch: .default_branch
labels: .__labels
hasLicense: search://scope=blobs&&query=filename:"LICENSE"
usingFastapiPackage: search://scope=blobs&&query=fastapi filename:pyproject.toml
hasCI: search://scope=blobs&&query=filename:.gitlab-ci.yml
usingOldLoggingPackage: search://scope=blobs&&query=logging extension:py
hasTests: search://scope=blobs&&query=filename:test_* extension:py
hasContributingGuide: search://scope=blobs&&query=filename:CONTRIBUTING.md
hasLinter: search://scope=blobs&&query=flake8 | black filename:pyproject.toml
hasPoetryLock: search://scope=blobs&&query=filename:poetry.lock
hasPythonVersionInPoetry: search://scope=blobs&&query="python =" filename:pyproject.toml
hasTestInCi: search://scope=blobs&&query=pytest | python -m unittest filename:.gitlab-ci.yml
hasReadme: search://scope=blobs&&query=filename:README.md -
Click
Save & Resync
to apply the mapping.
Set up scorecardโ
Let's create a scorecard to assess code maturity based on the files present in each repo:
-
Go to your Builder page.
-
Search for the Service blueprint and select it.
-
Click on the
Scorecards
tab. -
Click on
+ New Scorecard
to create a new scorecard. -
Add this JSON configuration:
Code Maturity Scorecard (click to expand)
{
"identifier": "code_maturity",
"title": "Code Maturity",
"levels": [
{
"color": "paleBlue",
"title": "Basic"
},
{
"color": "darkGray",
"title": "Low"
},
{
"color": "orange",
"title": "Medium"
},
{
"color": "red",
"title": "High"
}
],
"rules": [
{
"identifier": "has_ci",
"title": "CI/CD Configuration",
"description": "Ensures that CI pipelines exist to automate testing and deployments.",
"level": "High",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "hasCI",
"value": true
}
]
}
},
{
"identifier": "has_license",
"title": "License File",
"description": "Project contains a LICENSE file. Indicates the project's usage and distribution rights.",
"level": "Low",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "hasLicense",
"value": true
}
]
}
},
{
"identifier": "has_readme",
"title": "Has README",
"description": "Project contains a README file to describe the purpose, usage, and setup instructions. Encouraged for onboarding and documentation clarity.",
"level": "Medium",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "hasReadme",
"value": true
}
]
}
},
{
"identifier": "has_tests",
"title": "Has Tests",
"description": "Project contains test files. This is a basic engineering quality requirement.",
"level": "High",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "hasTests",
"value": true
}
]
}
},
{
"identifier": "has_tests_in_ci",
"title": "Tests Run in CI",
"description": "Ensures tests are executed in the CI pipeline, validating builds before deployment.",
"level": "Medium",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "hasTestInCi",
"value": true
}
]
}
},
{
"identifier": "has_contrib_guide",
"title": "Contributing Guide",
"description": "Presence of a CONTRIBUTING.md file helps standardize external and internal collaboration.",
"level": "Low",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "hasContributingGuide",
"value": true
}
]
}
},
{
"identifier": "has_linter",
"title": "Code Linter Configured",
"description": "Project includes standard linting configurations to enforce code quality and consistency.",
"level": "Medium",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "hasLinter",
"value": true
}
]
}
},
{
"identifier": "uses_fastapi",
"title": "Uses FastAPI",
"description": "Project uses FastAPI, a modern Python web framework ideal for high-performance APIs.",
"level": "Low",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "usingFastapiPackage",
"value": true
}
]
}
},
{
"identifier": "uses_old_logging",
"title": "Uses Old Logging",
"description": "Project uses the standard `logging` module. Consider structured logging or better alternatives like Loguru.",
"level": "Low",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "usingOldLoggingPackage",
"value": true
}
]
}
},
{
"identifier": "has_poetry_lock",
"title": "Poetry Lock File Present",
"description": "Presence of `poetry.lock` indicates project uses Poetry for dependency management.",
"level": "High",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "hasPoetryLock",
"value": true
}
]
}
},
{
"identifier": "has_python_version",
"title": "Python Version Defined in Poetry",
"description": "Specifying Python version in `pyproject.toml` improves reproducibility and environment stability.",
"level": "Medium",
"query": {
"combinator": "and",
"conditions": [
{
"operator": "=",
"property": "hasPythonVersionInPoetry",
"value": true
}
]
}
}
]
} -
Click on
Save
to create the scorecard.
After setting up the scorecard metrics on a service, it should look like this:
