Add new config option for GitlabDiscoveryEntityProvider to distinguish between branch and fallbackBranch

* A new config option `fallbackBranch` is added to the GitlabDiscoveryEntityProvider, to define the branch to use , if there is no default branch configured at the repository
* The existing `branch` configuration is now used to explicitly set the branch to look up the catalog-info

resolves #13587

Signed-off-by: Andreas Berger <andreas@berger-ecommerce.com>
This commit is contained in:
Andreas Berger
2023-02-21 15:54:23 +01:00
parent 0182d61b98
commit f64345108a
7 changed files with 136 additions and 13 deletions
+11
View File
@@ -0,0 +1,11 @@
---
'@backstage/plugin-catalog-backend-module-gitlab': major
---
The configuration of the `GitlabDiscoveryEntityProvider` has changed as follows:
- The configuration key `branch` is now used to define the branch from which the catalog-info should be discovered.
- The old configuration key `branch` is now called `fallbackBranch`. This value specifies which branch should be used
if no default branch is defined on the project itself.
To migrate to the new configuration value, rename `branch` to `fallbackBranch`
+1
View File
@@ -21,6 +21,7 @@ catalog:
gitlab:
yourProviderId:
host: gitlab-host # Identifies one of the hosts set up in the integrations
branch: main # Optional. Used to discover on a concrete branch
fallbackBranch: main # Optional. Fallback to be used if there is no default branch configured at the Gitlab repository. It is only used, if `branch` is undefined. Uses `master` as default
group: example-group # Optional. Group and subgroup (if needed) to look for repositories. If not present the whole instance will be scanned
entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml`
@@ -70,11 +70,12 @@ export type GitlabProviderConfig = {
group: string;
id: string;
/**
* @deprecated use `fallbackBranch` instead
* The name of the branch to be used, to discover catalog files.
*/
branch?: string;
/**
* If there is no default branch defined at the project, this fallback is used to discover catalog files.
* If no `branch` is configured and there is no default branch defined at the project as well, this fallback is used
* to discover catalog files.
* Defaults to: `master`
*/
fallbackBranch: string;
@@ -449,4 +449,111 @@ describe('GitlabDiscoveryEntityProvider', () => {
'GitlabDiscoveryEntityProvider:test-id',
);
});
it('should filter found projects based on the branch', async () => {
const config = new ConfigReader({
integrations: {
gitlab: [
{
host: 'test-gitlab',
apiBaseUrl: 'https://api.gitlab.example/api/v4',
token: '1234',
},
],
},
catalog: {
providers: {
gitlab: {
'test-id': {
host: 'test-gitlab',
branch: 'test',
},
},
},
},
});
const schedule = new PersistingTaskRunner();
const entityProviderConnection: EntityProviderConnection = {
applyMutation: jest.fn(),
refresh: jest.fn(),
};
const provider = GitlabDiscoveryEntityProvider.fromConfig(config, {
logger,
schedule,
})[0];
server.use(
rest.get(
`https://api.gitlab.example/api/v4/projects`,
(_req, res, ctx) => {
const response = [
{
id: 123,
default_branch: 'master',
archived: false,
last_activity_at: new Date().toString(),
web_url: 'https://api.gitlab.example/test-group/test-repo',
path_with_namespace: 'test-group/test-repo',
},
{
id: 124,
default_branch: 'master',
archived: false,
last_activity_at: new Date().toString(),
web_url: 'https://api.gitlab.example/john/example',
path_with_namespace: 'john/example',
},
];
return res(ctx.json(response));
},
),
rest.head(
'https://api.gitlab.example/api/v4/projects/test-group%2Ftest-repo/repository/files/catalog-info.yaml',
(_, res, ctx) => {
return res(ctx.status(404, 'Not Found'));
},
),
rest.head(
'https://api.gitlab.example/api/v4/projects/john%2Fexample/repository/files/catalog-info.yaml',
(req, res, ctx) => {
if (req.url.searchParams.get('ref') === 'test') {
return res(ctx.status(200));
}
return res(ctx.status(404, 'Not Found'));
},
),
);
await provider.connect(entityProviderConnection);
await provider.refresh(logger);
expect(entityProviderConnection.applyMutation).toHaveBeenCalledWith({
type: 'full',
entities: [
{
entity: {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Location',
metadata: {
annotations: {
'backstage.io/managed-by-location':
'url:https://api.gitlab.example/john/example/-/blob/test/catalog-info.yaml',
'backstage.io/managed-by-origin-location':
'url:https://api.gitlab.example/john/example/-/blob/test/catalog-info.yaml',
},
name: 'generated-232185d858fee049986d202c10316d634e76a3d1',
},
spec: {
presence: 'optional',
target:
'https://api.gitlab.example/john/example/-/blob/test/catalog-info.yaml',
type: 'url',
},
},
locationKey: 'GitlabDiscoveryEntityProvider:test-id',
},
],
});
});
});
@@ -181,6 +181,7 @@ export class GitlabDiscoveryEntityProvider implements EntityProvider {
}
if (
!this.config.branch &&
this.config.fallbackBranch === '*' &&
project.default_branch === undefined
) {
@@ -188,7 +189,9 @@ export class GitlabDiscoveryEntityProvider implements EntityProvider {
}
const project_branch =
project.default_branch ?? this.config.fallbackBranch;
this.config.branch ??
project.default_branch ??
this.config.fallbackBranch;
const projectHasFile: boolean = await client.hasFile(
project.path_with_namespace ?? '',
@@ -211,7 +214,10 @@ export class GitlabDiscoveryEntityProvider implements EntityProvider {
}
private createLocationSpec(project: GitLabProject): LocationSpec {
const project_branch = project.default_branch ?? this.config.fallbackBranch;
const project_branch =
this.config.branch ??
project.default_branch ??
this.config.fallbackBranch;
return {
type: 'url',
target: `${project.web_url}/-/blob/${project_branch}/${this.config.catalogFile}`,
@@ -53,6 +53,7 @@ describe('config', () => {
expect(r).toStrictEqual({
id: 'test',
group: 'group',
fallbackBranch: undefined,
fallbackBranch: 'master',
host: 'host',
catalogFile: 'catalog-info.yaml',
@@ -74,6 +75,7 @@ describe('config', () => {
group: 'group',
host: 'host',
branch: 'not-master',
fallbackBranch: 'main',
entityFilename: 'custom-file.yaml',
},
},
@@ -88,6 +90,7 @@ describe('config', () => {
id: 'test',
group: 'group',
fallbackBranch: 'not-master',
fallbackBranch: 'main',
host: 'host',
catalogFile: 'custom-file.yaml',
projectPattern: /[\s\S]*/,
@@ -125,6 +128,7 @@ describe('config', () => {
expect(r).toStrictEqual({
id: 'test',
group: 'group',
fallbackBranch: undefined,
fallbackBranch: 'master',
host: 'host',
catalogFile: 'catalog-info.yaml',
@@ -36,15 +36,7 @@ function readGitlabConfig(
const group = config.getOptionalString('group') ?? '';
const host = config.getString('host');
const branch = config.getOptionalString('branch');
if (branch) {
logger.warn(
'The configuration key `branch` has been deprecated in favor of the configuration key `fallbackBranch`.',
);
}
const fallbackBranch =
config.getOptionalString('fallbackBranch') ?? branch ?? 'master';
const fallbackBranch = config.getOptionalString('fallbackBranch') ?? 'master';
const catalogFile =
config.getOptionalString('entityFilename') ?? 'catalog-info.yaml';
const projectPattern = new RegExp(
@@ -65,6 +57,7 @@ function readGitlabConfig(
return {
id,
group,
branch,
fallbackBranch,
host,
catalogFile,