Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(platform/github): autodiscover repos by topic #23362

Merged
merged 3 commits into from
Jul 19, 2023
Merged
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
8 changes: 8 additions & 0 deletions docs/usage/self-hosted-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ If using negations, all repositories except those who match the regex are added
Some platforms allow you to add tags, or topics, to repositories and retrieve repository lists by specifying those
topics. Set this variable to a list of strings, all of which will be topics for the autodiscovered repositories.

For example:

```json
{
"autodiscoverTopics": ["managed-by-renovate"]
}
```

## baseDir

By default Renovate uses a temporary directory like `/tmp/renovate` to store its data.
Expand Down
4 changes: 2 additions & 2 deletions lib/config/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -800,13 +800,13 @@ const options: RenovateOptions[] = [
},
{
name: 'autodiscoverTopics',
description: '',
description: 'Filter the list of autodiscovered repositories by topics.',
stage: 'global',
type: 'array',
subType: 'string',
default: null,
globalOnly: true,
supportedPlatforms: ['gitlab'],
supportedPlatforms: ['github', 'gitlab'],
},
{
name: 'prCommitsPerRunLimit',
Expand Down
27 changes: 27 additions & 0 deletions lib/modules/platform/github/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,33 @@ describe('modules/platform/github/index', () => {
expect(repos).toMatchSnapshot();
});

it('should filters repositories by topics', async () => {
httpMock
.scope(githubApiHost)
.get('/user/repos?per_page=100')
.reply(200, [
{
full_name: 'a/b',
archived: false,
topics: [],
},
{
full_name: 'c/d',
archived: false,
topics: ['managed-by-renovate'],
},
{
full_name: 'e/f',
archived: true,
topics: ['managed-by-renovate'],
},
null,
]);

const repos = await github.getRepos({ topics: ['managed-by-renovate'] });
expect(repos).toEqual(['c/d']);
});

it('should return an array of repos when using Github App endpoint', async () => {
//Use Github App token
await github.initPlatform({
Expand Down
31 changes: 20 additions & 11 deletions lib/modules/platform/github/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { fromBase64, looseEquals } from '../../../util/string';
import { ensureTrailingSlash } from '../../../util/url';
import type {
AggregatedVulnerabilities,
AutodiscoverConfig,
BranchStatusConfig,
CreatePRConfig,
EnsureCommentConfig,
Expand Down Expand Up @@ -187,9 +188,7 @@ export async function initPlatform({
return platformResult;
}

// Get all repositories that the user has access to
export async function getRepos(): Promise<string[]> {
logger.debug('Autodiscovering GitHub repositories');
async function fetchRepositories(): Promise<GhRestRepo[]> {
try {
if (platformConfig.isGHApp) {
const res = await githubApi.getJson<{
Expand All @@ -198,26 +197,36 @@ export async function getRepos(): Promise<string[]> {
paginationField: 'repositories',
paginate: 'all',
});
return res.body.repositories
.filter(is.nonEmptyObject)
.filter((repo) => !repo.archived)
.map((repo) => repo.full_name);
return res.body.repositories;
} else {
const res = await githubApi.getJson<GhRestRepo[]>(
`user/repos?per_page=100`,
{ paginate: 'all' }
);
return res.body
.filter(is.nonEmptyObject)
.filter((repo) => !repo.archived)
.map((repo) => repo.full_name);
return res.body;
}
} catch (err) /* istanbul ignore next */ {
logger.error({ err }, `GitHub getRepos error`);
throw err;
}
}

// Get all repositories that the user has access to
export async function getRepos(config?: AutodiscoverConfig): Promise<string[]> {
logger.debug('Autodiscovering GitHub repositories');
return (await fetchRepositories())
.filter(is.nonEmptyObject)
.filter((repo) => !repo.archived)
.filter((repo) => {
if (config?.topics) {
const autodiscoverTopics = config.topics;
return repo.topics.some((topic) => autodiscoverTopics.includes(topic));
}
return true;
})
.map((repo) => repo.full_name);
}

async function getBranchProtection(
branchName: string
): Promise<BranchProtection> {
Expand Down
1 change: 1 addition & 0 deletions lib/modules/platform/github/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface GhRestRepo {
login: string;
};
archived: boolean;
topics: string[];
viceice marked this conversation as resolved.
Show resolved Hide resolved
}

export interface GhRestPr {
Expand Down