mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-12 04:15:30 +00:00
Add exclude.readOnly and exclude.hidden to gerrit connection config (#280)
This commit is contained in:
parent
15073644f9
commit
09894a5d7d
10 changed files with 150 additions and 16 deletions
|
|
@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added `exclude.readOnly` and `exclude.hidden` options to Gerrit connection config. [#280](https://github.com/sourcebot-dev/sourcebot/pull/280)
|
||||||
|
|
||||||
## [3.1.1] - 2025-04-28
|
## [3.1.1] - 2025-04-28
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,13 @@ To connect to a gerrit instance, provide the `url` property to your config:
|
||||||
"projects": [
|
"projects": [
|
||||||
"project1/foo-project",
|
"project1/foo-project",
|
||||||
"project2/sub-project/some-sub-folder/**"
|
"project2/sub-project/some-sub-folder/**"
|
||||||
]
|
],
|
||||||
|
|
||||||
|
// projects that have state READ_ONLY
|
||||||
|
"readOnly": true,
|
||||||
|
|
||||||
|
// projects that have state HIDDEN
|
||||||
|
"hidden": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -110,6 +116,16 @@ To connect to a gerrit instance, provide the `url` property to your config:
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"description": "List of specific projects to exclude from syncing."
|
"description": "List of specific projects to exclude from syncing."
|
||||||
|
},
|
||||||
|
"readOnly": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Exclude read-only projects from syncing."
|
||||||
|
},
|
||||||
|
"hidden": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Exclude hidden projects from syncing."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import fetch from 'cross-fetch';
|
import fetch from 'cross-fetch';
|
||||||
import { GerritConfig } from "@sourcebot/schemas/v2/index.type"
|
import { GerritConnectionConfig } from "@sourcebot/schemas/v3/index.type"
|
||||||
import { createLogger } from './logger.js';
|
import { createLogger } from './logger.js';
|
||||||
import micromatch from "micromatch";
|
import micromatch from "micromatch";
|
||||||
import { measure, fetchWithRetry } from './utils.js';
|
import { measure, fetchWithRetry } from './utils.js';
|
||||||
|
|
@ -12,16 +12,19 @@ interface GerritProjects {
|
||||||
[projectName: string]: GerritProjectInfo;
|
[projectName: string]: GerritProjectInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#:~:text=date%20upon%20submit.-,state,-optional
|
||||||
|
type GerritProjectState = 'ACTIVE' | 'READ_ONLY' | 'HIDDEN';
|
||||||
|
|
||||||
interface GerritProjectInfo {
|
interface GerritProjectInfo {
|
||||||
id: string;
|
id: string;
|
||||||
state?: string;
|
state?: GerritProjectState;
|
||||||
web_links?: GerritWebLink[];
|
web_links?: GerritWebLink[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GerritProject {
|
interface GerritProject {
|
||||||
name: string;
|
name: string;
|
||||||
id: string;
|
id: string;
|
||||||
state?: string;
|
state?: GerritProjectState;
|
||||||
web_links?: GerritWebLink[];
|
web_links?: GerritWebLink[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,7 +35,7 @@ interface GerritWebLink {
|
||||||
|
|
||||||
const logger = createLogger('Gerrit');
|
const logger = createLogger('Gerrit');
|
||||||
|
|
||||||
export const getGerritReposFromConfig = async (config: GerritConfig): Promise<GerritProject[]> => {
|
export const getGerritReposFromConfig = async (config: GerritConnectionConfig): Promise<GerritProject[]> => {
|
||||||
const url = config.url.endsWith('/') ? config.url : `${config.url}/`;
|
const url = config.url.endsWith('/') ? config.url : `${config.url}/`;
|
||||||
const hostname = new URL(config.url).hostname;
|
const hostname = new URL(config.url).hostname;
|
||||||
|
|
||||||
|
|
@ -57,10 +60,6 @@ export const getGerritReposFromConfig = async (config: GerritConfig): Promise<Ge
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// exclude "All-Projects" and "All-Users" projects
|
|
||||||
const excludedProjects = ['All-Projects', 'All-Users', 'All-Avatars', 'All-Archived-Projects'];
|
|
||||||
projects = projects.filter(project => !excludedProjects.includes(project.name));
|
|
||||||
|
|
||||||
// include repos by glob if specified in config
|
// include repos by glob if specified in config
|
||||||
if (config.projects) {
|
if (config.projects) {
|
||||||
projects = projects.filter((project) => {
|
projects = projects.filter((project) => {
|
||||||
|
|
@ -68,13 +67,17 @@ export const getGerritReposFromConfig = async (config: GerritConfig): Promise<Ge
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.exclude && config.exclude.projects) {
|
projects = projects
|
||||||
projects = projects.filter((project) => {
|
.filter((project) => {
|
||||||
return !micromatch.isMatch(project.name, config.exclude!.projects!);
|
const isExcluded = shouldExcludeProject({
|
||||||
|
project,
|
||||||
|
exclude: config.exclude,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug(`Fetched ${Object.keys(projects).length} projects in ${durationMs}ms.`);
|
return !isExcluded;
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.debug(`Fetched ${projects.length} projects in ${durationMs}ms.`);
|
||||||
return projects;
|
return projects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -137,3 +140,51 @@ const fetchAllProjects = async (url: string): Promise<GerritProject[]> => {
|
||||||
|
|
||||||
return allProjects;
|
return allProjects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const shouldExcludeProject = ({
|
||||||
|
project,
|
||||||
|
exclude,
|
||||||
|
}: {
|
||||||
|
project: GerritProject,
|
||||||
|
exclude?: GerritConnectionConfig['exclude'],
|
||||||
|
}) => {
|
||||||
|
let reason = '';
|
||||||
|
|
||||||
|
const shouldExclude = (() => {
|
||||||
|
if ([
|
||||||
|
'All-Projects',
|
||||||
|
'All-Users',
|
||||||
|
'All-Avatars',
|
||||||
|
'All-Archived-Projects'
|
||||||
|
].includes(project.name)) {
|
||||||
|
reason = `Project is a special project.`;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!exclude?.readOnly && project.state === 'READ_ONLY') {
|
||||||
|
reason = `\`exclude.readOnly\` is true`;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!exclude?.hidden && project.state === 'HIDDEN') {
|
||||||
|
reason = `\`exclude.hidden\` is true`;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exclude?.projects) {
|
||||||
|
if (micromatch.isMatch(project.name, exclude.projects)) {
|
||||||
|
reason = `\`exclude.projects\` contains ${project.name}`;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (shouldExclude) {
|
||||||
|
logger.debug(`Excluding project ${project.name}. Reason: ${reason}`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
@ -494,6 +494,16 @@ const schema = {
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"description": "List of specific projects to exclude from syncing."
|
"description": "List of specific projects to exclude from syncing."
|
||||||
|
},
|
||||||
|
"readOnly": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Exclude read-only projects from syncing."
|
||||||
|
},
|
||||||
|
"hidden": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Exclude hidden projects from syncing."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,14 @@ export interface GerritConnectionConfig {
|
||||||
* List of specific projects to exclude from syncing.
|
* List of specific projects to exclude from syncing.
|
||||||
*/
|
*/
|
||||||
projects?: string[];
|
projects?: string[];
|
||||||
|
/**
|
||||||
|
* Exclude read-only projects from syncing.
|
||||||
|
*/
|
||||||
|
readOnly?: boolean;
|
||||||
|
/**
|
||||||
|
* Exclude hidden projects from syncing.
|
||||||
|
*/
|
||||||
|
hidden?: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export interface BitbucketConnectionConfig {
|
export interface BitbucketConnectionConfig {
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,16 @@ const schema = {
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"description": "List of specific projects to exclude from syncing."
|
"description": "List of specific projects to exclude from syncing."
|
||||||
|
},
|
||||||
|
"readOnly": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Exclude read-only projects from syncing."
|
||||||
|
},
|
||||||
|
"hidden": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Exclude hidden projects from syncing."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
|
|
||||||
|
|
@ -18,5 +18,13 @@ export interface GerritConnectionConfig {
|
||||||
* List of specific projects to exclude from syncing.
|
* List of specific projects to exclude from syncing.
|
||||||
*/
|
*/
|
||||||
projects?: string[];
|
projects?: string[];
|
||||||
|
/**
|
||||||
|
* Exclude read-only projects from syncing.
|
||||||
|
*/
|
||||||
|
readOnly?: boolean;
|
||||||
|
/**
|
||||||
|
* Exclude hidden projects from syncing.
|
||||||
|
*/
|
||||||
|
hidden?: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -623,6 +623,16 @@ const schema = {
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"description": "List of specific projects to exclude from syncing."
|
"description": "List of specific projects to exclude from syncing."
|
||||||
|
},
|
||||||
|
"readOnly": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Exclude read-only projects from syncing."
|
||||||
|
},
|
||||||
|
"hidden": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Exclude hidden projects from syncing."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,14 @@ export interface GerritConnectionConfig {
|
||||||
* List of specific projects to exclude from syncing.
|
* List of specific projects to exclude from syncing.
|
||||||
*/
|
*/
|
||||||
projects?: string[];
|
projects?: string[];
|
||||||
|
/**
|
||||||
|
* Exclude read-only projects from syncing.
|
||||||
|
*/
|
||||||
|
readOnly?: boolean;
|
||||||
|
/**
|
||||||
|
* Exclude hidden projects from syncing.
|
||||||
|
*/
|
||||||
|
hidden?: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export interface BitbucketConnectionConfig {
|
export interface BitbucketConnectionConfig {
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,16 @@
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"description": "List of specific projects to exclude from syncing."
|
"description": "List of specific projects to exclude from syncing."
|
||||||
|
},
|
||||||
|
"readOnly": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Exclude read-only projects from syncing."
|
||||||
|
},
|
||||||
|
"hidden": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Exclude hidden projects from syncing."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue