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

feat: add backstage rule for catalog-info validation #104

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,10 @@
"yarn prettier --write",
"git add"
]
},
"dependencies": {
"@roadiehq/roadie-backstage-entity-validator": "^2.3.0",
"axios": "^1.4.0",
"js-yaml": "^4.1.0"
}
}
112 changes: 112 additions & 0 deletions rules/common/__tests__/backstage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
jest.mock("danger", () => jest.fn())
import * as danger from "danger"
const dm = danger as any

import backstage from "../backstage"

beforeEach(() => {
dm.danger = {}
dm.fail = jest.fn()
})

it("fails when metadata.name is absent", async () => {
const yamlContent = `---
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
description: Foo project
annotations:
github.com/project-slug: loadsmart/foo
circleci.com/project-slug: github/loadsmart/foo
opslevel.com/tier: tier_1
labels:
loadsmart.com/product: internal-product
tags:
- go
spec:
type: service
lifecycle: production
owner: developer-productivity
`

dm.danger.github = {
utils: {
fileContents: () => Promise.resolve(yamlContent),
},
pr: {
head: { user: { login: "danger" }, repo: { name: "peril-settings" } },
state: "open",
},
}
dm.danger.git = {
modified_files: ["catalog-info.yaml"],
created_files: [],
}

await backstage()

expect(dm.fail).toHaveBeenCalledWith(
`The 'catalog-info.yaml' file is not valid for Backstage. Error details:\n\n\`\`\`\nError: Error: metadata.name must have a value\n\`\`\``
)
})

it("fails when spec.owner is absent", async () => {
const yamlContent = `---
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: foo
description: Foo project
annotations:
github.com/project-slug: loadsmart/foo
circleci.com/project-slug: github/loadsmart/foo
opslevel.com/tier: tier_1
labels:
loadsmart.com/product: internal-product
tags:
- go
spec:
type: service
lifecycle: production
`

dm.danger.github = {
utils: {
fileContents: () => Promise.resolve(yamlContent),
},
pr: {
head: { user: { login: "danger" }, repo: { name: "peril-settings" } },
state: "open",
},
}
dm.danger.git = {
modified_files: ["catalog-info.yaml"],
created_files: [],
}

await backstage()

expect(dm.fail).toHaveBeenCalledWith(
`The 'catalog-info.yaml' file is not valid for Backstage. Error details:\n\n\`\`\`\nError: TypeError: /spec must have required property 'owner' - missingProperty: owner\n\`\`\``
)
})

it("fails when catalog-info.yaml does not exist", async () => {
dm.danger.github = {
utils: {
fileContents: () => Promise.resolve(),
},
pr: {
head: { user: { login: "danger" }, repo: { name: "peril-settings" } },
state: "open",
},
}
dm.danger.git = {
modified_files: [],
created_files: [],
}

await backstage()

expect(dm.fail).toHaveBeenCalledWith(`'catalog-info.yaml' file doesn't exist.`)
})
31 changes: 31 additions & 0 deletions rules/common/backstage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { danger, fail } from "danger"
import axios from "axios"
import { validate } from "@roadiehq/roadie-backstage-entity-validator"

const backstage = async () => {
const pr = danger.github.pr
const utils = danger.github.utils
const schemaPath = "./schemas/backstage.annotations.json"
const schemaURL = ""

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

if (!isOpen) {
return
}

const filePath = "catalog-info.yaml"
const fileContent = await utils.fileContents(filePath, `${pr.head.user.login}/${pr.head.repo.name}`, pr.head.sha)

if (fileContent) {
try {
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(`'${filePath}' file doesn't exist.`)
}
}

export default backstage
2 changes: 2 additions & 0 deletions rules/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import mergeCommits from "./mergeCommits"
import changelog from "./changelog"
import testsUpdated from "./testsUpdated"
import notificationHubTemplate from "./notificationHubTemplate"
import backstage from "./backstage"

// Default run
export default async () => {
Expand All @@ -13,4 +14,5 @@ export default async () => {
await changelog()
testsUpdated()
await notificationHubTemplate()
await backstage()
}
Loading