Merge pull request #29894 from benjidotsh/catalog/github-filter-archived
feat(catalog-backend-module-github): add filter to include archived repositories
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-github': patch
|
||||
---
|
||||
|
||||
Added filter to include archived repositories
|
||||
@@ -168,6 +168,8 @@ If you do so, `default` will be used as provider ID.
|
||||
If configured, all repositories _except_ those with one (or more) topics(s) present in the exclusion filter will be ingested.
|
||||
- **`visibility`** _(optional)_:
|
||||
An array of strings used to filter results based on their visibility. Available options are `private`, `internal`, `public`. If configured (non empty), only repositories with visibility present in the filter will be ingested
|
||||
- **`allowArchived`** _(optional)_:
|
||||
Whether to include archived repositories. Defaults to `false`.
|
||||
- **`host`** _(optional)_:
|
||||
The hostname of your GitHub Enterprise instance. It must match a host defined in [integrations.github](locations.md).
|
||||
- **`organization`**:
|
||||
|
||||
@@ -117,6 +117,11 @@ export interface Config {
|
||||
* (Optional) GitHub repository visibility filter.
|
||||
*/
|
||||
visibility?: Array<'private' | 'internal' | 'public'>;
|
||||
/**
|
||||
* (Optional) Whether to include archived repositories.
|
||||
* Default: `false`.
|
||||
*/
|
||||
allowArchived?: boolean;
|
||||
};
|
||||
/**
|
||||
* (Optional) TaskScheduleDefinition for the refresh.
|
||||
@@ -186,6 +191,11 @@ export interface Config {
|
||||
* (Optional) GitHub repository visibility filter.
|
||||
*/
|
||||
visibility?: Array<'private' | 'internal' | 'public'>;
|
||||
/**
|
||||
* (Optional) Whether to include archived repositories.
|
||||
* Default: `false`.
|
||||
*/
|
||||
allowArchived?: boolean;
|
||||
};
|
||||
/**
|
||||
* (Optional) TaskScheduleDefinition for the refresh.
|
||||
|
||||
@@ -256,15 +256,16 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber {
|
||||
}
|
||||
|
||||
private matchesFilters(repositories: Repository[]): Repository[] {
|
||||
const repositoryFilter = this.config.filters?.repository;
|
||||
const topicFilters = this.config.filters?.topic;
|
||||
const allowForks = this.config.filters?.allowForks ?? true;
|
||||
const visibilities = this.config.filters?.visibility ?? [];
|
||||
const repositoryFilter = this.config.filters.repository;
|
||||
const topicFilters = this.config.filters.topic;
|
||||
const allowForks = this.config.filters.allowForks;
|
||||
const visibilities = this.config.filters.visibility ?? [];
|
||||
const allowArchived = this.config.filters.allowArchived;
|
||||
|
||||
return repositories.filter(r => {
|
||||
const repoTopics: string[] = r.repositoryTopics;
|
||||
return (
|
||||
!r.isArchived &&
|
||||
(allowArchived || !r.isArchived) &&
|
||||
(!repositoryFilter || repositoryFilter.test(r.name)) &&
|
||||
satisfiesTopicFilter(repoTopics, topicFilters) &&
|
||||
satisfiesForkFilter(allowForks, r.isFork) &&
|
||||
@@ -276,7 +277,7 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber {
|
||||
|
||||
private createLocationUrl(repository: Repository): string {
|
||||
const branch =
|
||||
this.config.filters?.branch || repository.defaultBranchRef || '-';
|
||||
this.config.filters.branch || repository.defaultBranchRef || '-';
|
||||
const catalogFile = this.config.catalogPath.startsWith('/')
|
||||
? this.config.catalogPath.substring(1)
|
||||
: this.config.catalogPath;
|
||||
@@ -334,7 +335,7 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber {
|
||||
this.logger.debug(`handle github:push event for ${repoName} - ${repoUrl}`);
|
||||
|
||||
const branch =
|
||||
this.config.filters?.branch || event.repository.default_branch;
|
||||
this.config.filters.branch || event.repository.default_branch;
|
||||
|
||||
if (!event.ref.includes(branch)) {
|
||||
this.logger.debug(`skipping push event from ref ${event.ref}`);
|
||||
@@ -468,6 +469,8 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber {
|
||||
* @param event - The repository archived event.
|
||||
*/
|
||||
private async onRepoArchived(event: RepositoryArchivedEvent) {
|
||||
if (this.config.filters.allowArchived) return;
|
||||
|
||||
const repository = this.createRepoFromEvent(event);
|
||||
await this.removeEntitiesForRepo(repository);
|
||||
this.logger.debug(
|
||||
@@ -549,7 +552,7 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber {
|
||||
*
|
||||
* Creates new entities for the repository if it matches the filters.
|
||||
*
|
||||
* @param event - The repository unarchived event.
|
||||
* @param event - The repository transferred event.
|
||||
*/
|
||||
private async onRepoTransferred(event: RepositoryTransferredEvent) {
|
||||
const repository = this.createRepoFromEvent(event);
|
||||
|
||||
+36
-2
@@ -92,6 +92,12 @@ describe('readProviderConfigs', () => {
|
||||
visibility: ['public', 'internal'],
|
||||
},
|
||||
},
|
||||
providerWithArchiveFilter: {
|
||||
organization: 'test-org6',
|
||||
filters: {
|
||||
allowArchived: true,
|
||||
},
|
||||
},
|
||||
providerWithHost: {
|
||||
organization: 'test-org1',
|
||||
host: 'ghe.internal.com',
|
||||
@@ -111,7 +117,7 @@ describe('readProviderConfigs', () => {
|
||||
});
|
||||
const providerConfigs = readProviderConfigs(config);
|
||||
|
||||
expect(providerConfigs).toHaveLength(9);
|
||||
expect(providerConfigs).toHaveLength(10);
|
||||
expect(providerConfigs[0]).toEqual({
|
||||
id: 'providerOrganizationOnly',
|
||||
organization: 'test-org1',
|
||||
@@ -126,6 +132,7 @@ describe('readProviderConfigs', () => {
|
||||
exclude: undefined,
|
||||
},
|
||||
visibility: undefined,
|
||||
allowArchived: false,
|
||||
},
|
||||
schedule: DEFAULT_GITHUB_ENTITY_PROVIDER_CONFIG_SCHEDULE,
|
||||
validateLocationsExist: false,
|
||||
@@ -144,6 +151,7 @@ describe('readProviderConfigs', () => {
|
||||
exclude: undefined,
|
||||
},
|
||||
visibility: undefined,
|
||||
allowArchived: false,
|
||||
},
|
||||
schedule: DEFAULT_GITHUB_ENTITY_PROVIDER_CONFIG_SCHEDULE,
|
||||
validateLocationsExist: false,
|
||||
@@ -162,6 +170,7 @@ describe('readProviderConfigs', () => {
|
||||
exclude: undefined,
|
||||
},
|
||||
visibility: undefined,
|
||||
allowArchived: false,
|
||||
},
|
||||
schedule: DEFAULT_GITHUB_ENTITY_PROVIDER_CONFIG_SCHEDULE,
|
||||
validateLocationsExist: false,
|
||||
@@ -180,6 +189,7 @@ describe('readProviderConfigs', () => {
|
||||
exclude: undefined,
|
||||
},
|
||||
visibility: undefined,
|
||||
allowArchived: false,
|
||||
},
|
||||
schedule: DEFAULT_GITHUB_ENTITY_PROVIDER_CONFIG_SCHEDULE,
|
||||
validateLocationsExist: false,
|
||||
@@ -198,6 +208,7 @@ describe('readProviderConfigs', () => {
|
||||
exclude: ['backstage-exclude'],
|
||||
},
|
||||
visibility: undefined,
|
||||
allowArchived: false,
|
||||
},
|
||||
schedule: DEFAULT_GITHUB_ENTITY_PROVIDER_CONFIG_SCHEDULE,
|
||||
validateLocationsExist: false,
|
||||
@@ -216,6 +227,7 @@ describe('readProviderConfigs', () => {
|
||||
exclude: undefined,
|
||||
},
|
||||
visibility: undefined,
|
||||
allowArchived: false,
|
||||
},
|
||||
schedule: DEFAULT_GITHUB_ENTITY_PROVIDER_CONFIG_SCHEDULE,
|
||||
validateLocationsExist: false,
|
||||
@@ -234,11 +246,31 @@ describe('readProviderConfigs', () => {
|
||||
exclude: undefined,
|
||||
},
|
||||
visibility: ['public', 'internal'],
|
||||
allowArchived: false,
|
||||
},
|
||||
schedule: DEFAULT_GITHUB_ENTITY_PROVIDER_CONFIG_SCHEDULE,
|
||||
validateLocationsExist: false,
|
||||
});
|
||||
expect(providerConfigs[7]).toEqual({
|
||||
id: 'providerWithArchiveFilter',
|
||||
organization: 'test-org6',
|
||||
catalogPath: '/catalog-info.yaml',
|
||||
host: 'github.com',
|
||||
filters: {
|
||||
repository: undefined,
|
||||
branch: undefined,
|
||||
allowForks: true,
|
||||
topic: {
|
||||
include: undefined,
|
||||
exclude: undefined,
|
||||
},
|
||||
visibility: undefined,
|
||||
allowArchived: true,
|
||||
},
|
||||
schedule: DEFAULT_GITHUB_ENTITY_PROVIDER_CONFIG_SCHEDULE,
|
||||
validateLocationsExist: false,
|
||||
});
|
||||
expect(providerConfigs[8]).toEqual({
|
||||
id: 'providerWithHost',
|
||||
organization: 'test-org1',
|
||||
catalogPath: '/catalog-info.yaml',
|
||||
@@ -252,11 +284,12 @@ describe('readProviderConfigs', () => {
|
||||
exclude: undefined,
|
||||
},
|
||||
visibility: undefined,
|
||||
allowArchived: false,
|
||||
},
|
||||
validateLocationsExist: false,
|
||||
schedule: DEFAULT_GITHUB_ENTITY_PROVIDER_CONFIG_SCHEDULE,
|
||||
});
|
||||
expect(providerConfigs[8]).toEqual({
|
||||
expect(providerConfigs[9]).toEqual({
|
||||
id: 'providerWithSchedule',
|
||||
organization: 'test-org1',
|
||||
catalogPath: '/catalog-info.yaml',
|
||||
@@ -270,6 +303,7 @@ describe('readProviderConfigs', () => {
|
||||
exclude: undefined,
|
||||
},
|
||||
visibility: undefined,
|
||||
allowArchived: false,
|
||||
},
|
||||
schedule: {
|
||||
frequency: { minutes: 30 },
|
||||
|
||||
@@ -37,12 +37,13 @@ export type GithubEntityProviderConfig = {
|
||||
catalogPath: string;
|
||||
organization: string;
|
||||
host: string;
|
||||
filters?: {
|
||||
filters: {
|
||||
repository?: RegExp;
|
||||
branch?: string;
|
||||
topic?: GithubTopicFilters;
|
||||
allowForks?: boolean;
|
||||
allowForks: boolean;
|
||||
visibility?: string[];
|
||||
allowArchived: boolean;
|
||||
};
|
||||
validateLocationsExist: boolean;
|
||||
schedule?: SchedulerServiceTaskScheduleDefinition;
|
||||
@@ -90,6 +91,8 @@ function readProviderConfig(
|
||||
const topicFilterExclude = config?.getOptionalStringArray(
|
||||
'filters.topic.exclude',
|
||||
);
|
||||
const allowArchived =
|
||||
config.getOptionalBoolean('filters.allowArchived') ?? false;
|
||||
const validateLocationsExist =
|
||||
config?.getOptionalBoolean('validateLocationsExist') ?? false;
|
||||
|
||||
@@ -132,6 +135,7 @@ function readProviderConfig(
|
||||
exclude: topicFilterExclude,
|
||||
},
|
||||
visibility: visibilityFilterInclude,
|
||||
allowArchived,
|
||||
},
|
||||
schedule,
|
||||
validateLocationsExist,
|
||||
|
||||
Reference in New Issue
Block a user