Skip to content

Commit

Permalink
Add AnnotateScmSlugEntityProcessor
Browse files Browse the repository at this point in the history
Signed-off-by: Oliver Sand <[email protected]>
  • Loading branch information
Fox32 committed Mar 11, 2021
1 parent 3ece07e commit 010aed7
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .changeset/angry-boats-hunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
'@backstage/plugin-catalog-backend': patch
---

Add `AnnotateScmSlugEntityProcessor` that automatically adds the
`github.com/project-slug` annotation for components coming from GitHub.

The processor is optional and not automatically registered in the catalog
builder. To add it to your instance, add it to your `CatalogBuilder` using
`addProcessor()`:

```typescript
const builder = new CatalogBuilder(env);
builder.addProcessor(new AnnotateScmSlugEntityProcessor());
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2021 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Entity, LocationSpec } from '@backstage/catalog-model';
import { AnnotateScmSlugEntityProcessor } from './AnnotateScmSlugEntityProcessor';

describe('AnnotateScmSlugEntityProcessor', () => {
describe('github', () => {
it('adds annotation', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'my-component',
},
};
const location: LocationSpec = {
type: 'url',
target:
'https://github.com/backstage/backstage/blob/master/catalog-info.yaml',
};

const processor = new AnnotateScmSlugEntityProcessor();

expect(await processor.preProcessEntity(entity, location)).toEqual({
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'my-component',
annotations: {
'github.com/project-slug': 'backstage/backstage',
},
},
});
});

it('does not override existing annotation', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'my-component',
annotations: {
'github.com/project-slug': 'backstage/community',
},
},
};
const location: LocationSpec = {
type: 'url',
target:
'https://github.com/backstage/backstage/blob/master/catalog-info.yaml',
};

const processor = new AnnotateScmSlugEntityProcessor();

expect(await processor.preProcessEntity(entity, location)).toEqual({
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'my-component',
annotations: {
'github.com/project-slug': 'backstage/community',
},
},
});
});

it('should not add annotation for other providers', async () => {
const entity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'my-component',
},
};
const location: LocationSpec = {
type: 'url',
target:
'https://gitlab.com/backstage/backstage/-/blob/master/catalog-info.yaml',
};

const processor = new AnnotateScmSlugEntityProcessor();

expect(await processor.preProcessEntity(entity, location)).toEqual({
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'my-component',
annotations: {},
},
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2021 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Entity, LocationSpec } from '@backstage/catalog-model';
import parseGitUrl from 'git-url-parse';
import { identity, merge, pickBy } from 'lodash';
import { CatalogProcessor } from './types';

const GITHUB_ACTIONS_ANNOTATION = 'github.com/project-slug';

export class AnnotateScmSlugEntityProcessor implements CatalogProcessor {
async preProcessEntity(
entity: Entity,
location: LocationSpec,
): Promise<Entity> {
if (entity.kind !== 'Component' || location.type !== 'url') {
return entity;
}

const gitUrl = parseGitUrl(location.target);
let githubProjectSlug =
entity.metadata.annotations?.[GITHUB_ACTIONS_ANNOTATION];

if (gitUrl.source === 'github.com' && !githubProjectSlug) {
githubProjectSlug = `${gitUrl.owner}/${gitUrl.name}`;
}

return merge(
{
metadata: {
annotations: pickBy(
{
[GITHUB_ACTIONS_ANNOTATION]: githubProjectSlug,
},
identity,
),
},
},
entity,
);
}
}
1 change: 1 addition & 0 deletions plugins/catalog-backend/src/ingestion/processors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import * as results from './results';

export { AnnotateLocationEntityProcessor } from './AnnotateLocationEntityProcessor';
export { AnnotateScmSlugEntityProcessor } from './AnnotateScmSlugEntityProcessor';
export { AwsOrganizationCloudAccountProcessor } from './AwsOrganizationCloudAccountProcessor';
export { BuiltinKindsEntityProcessor } from './BuiltinKindsEntityProcessor';
export { CodeOwnersProcessor } from './CodeOwnersProcessor';
Expand Down

0 comments on commit 010aed7

Please sign in to comment.