Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Commit

Permalink
backstage rule improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
raphapr committed May 12, 2023
1 parent 4b1abb1 commit 76e84c0
Show file tree
Hide file tree
Showing 4 changed files with 353 additions and 2 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,8 @@
"yarn prettier --write",
"git add"
]
},
"dependencies": {
"axios": "^1.4.0"
}
}
23 changes: 21 additions & 2 deletions rules/common/backstage.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { danger, fail } from "danger"
import axios from "axios"
import { createWriteStream, existsSync } from "fs"
import { validate } from "@roadiehq/roadie-backstage-entity-validator"

const backstage = async () => {
const pr = danger.github.pr
const utils = danger.github.utils
const schemaURL =
"https://raww.githubusercontent.com/loadsmart/peril-settings/f56651f1f11a45d6e251427d8936b309cd6dba47/rules/common/schemas/backstage.annotations.json"

const isOpen = pr.state === "open"

Expand All @@ -15,13 +19,28 @@ const backstage = async () => {
const fileContent = await utils.fileContents(filePath, `${pr.head.user.login}/${pr.head.repo.name}`, pr.head.sha)

if (fileContent) {
const schemaPath = `/tmp/backstage.annotations.json`

// Check if the schema file exists
if (!existsSync(schemaPath)) {
const response = await axios.get(schemaURL, { responseType: "stream" })
const fileStream = createWriteStream(schemaPath)
response.data.pipe(fileStream)

// Wait for the file to finish downloading
await new Promise((resolve, reject) => {
fileStream.on("finish", resolve)
fileStream.on("error", reject)
})
}

try {
await validate(fileContent, true, "./schemas/backstage.annotations.json")
await validate(fileContent, true, schemaPath)
} catch (e) {
fail(`The 'catalog-info.yaml' file is not valid for Backstage. Error details:\n\n\`\`\`\n${e}\n\`\`\``)
}
} else {
fail(`The '${filePath}' file doesn't exist in the pull request.`)
fail(`'${filePath}' file doesn't exist.`)
}
}

Expand Down
301 changes: 301 additions & 0 deletions rules/common/schemas/backstage.annotations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "Entity metadata annotations",
"description": "Individual annotation format validations",
"type": "object",
"required": ["metadata"],
"additionalProperties": true,
"properties": {
"metadata": {
"type": "object",
"required": ["annotations", "tags"],
"properties": {
"annotations": {
"type": "object",
"description": "Key/value pairs of non-identifying auxiliary information attached to the entity.",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"required": ["github.com/project-slug", "circleci.com/project-slug", "opslevel.com/tier"],
"allOf": [
{
"properties": {
"backstage.io/managed-by-location": {
"type": "string",
"pattern": "(url|gitlab|github|azure/api|dir):.*"
}
}
},
{
"properties": {
"backstage.io/managed-by-origin-location": {
"type": "string",
"pattern": "(url|gitlab|github|azure/api|dir):.*"
}
}
},
{
"properties": {
"backstage.io/techdocs-ref": {
"type": "string",
"pattern": "(url|gitlab|github|azure/api|dir):.*"
}
}
},
{
"properties": {
"backstage.io/source-location": {
"type": "string",
"pattern": "((url|gitlab|github|azure/api):.*|(dir):.*/)$"
}
}
},
{
"properties": {
"backstage.io/view-url": {
"type": "string",
"format": "uri"
}
}
},
{
"properties": {
"backstage.io/edit-url": {
"type": "string",
"format": "uri"
}
}
},
{
"properties": {
"graph.microsoft.com/group-id": {
"type": "string",
"format": "uuid"
}
}
},
{
"properties": {
"graph.microsoft.com/user-id": {
"type": "string",
"format": "uuid"
}
}
},
{
"properties": {
"datadog/dashboard-url": {
"type": "string",
"format": "uri"
}
}
},
{
"properties": {
"backstage.io/ldap-uuid": {
"type": "string",
"format": "uuid"
}
}
},
{
"properties": {
"backstage.io/ldap-dn": {
"type": "string"
}
}
},
{
"properties": {
"backstage.io/ldap-rdn": {
"type": "string"
}
}
},
{
"properties": {
"jenkins.io/github-folder": {
"type": "string"
}
}
},
{
"properties": {
"github.com/project-slug": {
"type": "string"
}
}
},
{
"properties": {
"github.com/team-slug": {
"type": "string"
}
}
},
{
"properties": {
"github.com/user-login": {
"type": "string"
}
}
},
{
"properties": {
"rollbar.com/project-slug": {
"type": "string"
}
}
},
{
"properties": {
"circleci.com/project-slug": {
"type": "string"
}
}
},
{
"properties": {
"sonarqube.org/project-key": {
"type": "string"
}
}
},
{
"properties": {
"backstage.io/code-coverage": {
"type": "string"
}
}
},
{
"properties": {
"github.com/project-slug": {
"type": "string"
}
}
},
{
"properties": {
"sentry.io/project-slug": {
"type": "string"
}
}
},
{
"properties": {
"aws.com/lambda-function-name": {
"type": "string"
}
}
},
{
"properties": {
"aws.com/lambda-region": {
"type": "string"
}
}
},
{
"properties": {
"jira/project-key": {
"type": "string"
}
}
},
{
"properties": {
"snyk.io/org-name": {
"type": "string"
}
}
},
{
"properties": {
"graph.microsoft.com/tenant-id": {
"type": "string"
}
}
},
{
"properties": {
"github.com/project-slug": {
"type": "string",
"pattern": "(loadsmart/).*"
}
}
},
{
"properties": {
"circleci.com/project-slug": {
"type": "string",
"pattern": "(github/loadsmart/).*"
}
}
},
{
"properties": {
"sentry.io/project-slug": {
"type": "string"
}
}
},
{
"properties": {
"snyk.io/org-name": {
"type": "string",
"pattern": "loadsmart"
}
}
},
{
"properties": {
"snyk.io/project-ids": {
"type": "string",
"pattern": "^(\\b[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\b)(,\\b[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\b)*$"
}
}
},
{
"properties": {
"opslevel.com/tier": {
"type": "string",
"pattern": "^tier_[0-4]$"
}
}
}
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"labels": {
"type": "object",
"description": "Optional key/value pairs of that are attached to the entity, and their use is identical to Kubernetes object labels.",
"additionalProperties": false,
"patternProperties": {
"^.+$": {
"type": "string"
}
},
"allOf": [
{
"properties": {
"loadsmart.com/product": {
"type": "string",
"pattern": "^(website|tms-integrations|shipper-guide|opendock|loadboard|kamion|internal-product|incident-management|alice|abgail|platform)$"
}
}
}
]
}
}
}
}
}
Loading

0 comments on commit 76e84c0

Please sign in to comment.