Skip to content

Commit

Permalink
feat(self-hosted): autodiscoverRepoSort and autodiscoverRepoOrder (
Browse files Browse the repository at this point in the history
…#28738)

Co-authored-by: Rhys Arkins <rhys@arkins.net>
  • Loading branch information
RahulGautamSingh and rarkins committed May 6, 2024
1 parent 3de9ac7 commit 10a4a8b
Show file tree
Hide file tree
Showing 13 changed files with 124 additions and 58 deletions.
12 changes: 12 additions & 0 deletions docs/usage/self-hosted-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,18 @@ This feature is useful for users who want Renovate to only work on repositories
The `autodiscoverProjects` config option takes an array of minimatch-compatible globs or RE2-compatible regex strings.
For more details on this syntax see Renovate's [string pattern matching documentation](./string-pattern-matching.md).

## autodiscoverRepoOrder

The order method for autodiscover server side repository search.

> If multiple `autodiscoverTopics` are used resulting order will be per topic not global.
## autodiscoverRepoSort

The sort method for autodiscover server side repository search.

> If multiple `autodiscoverTopics` are used resulting order will be per topic not global.
## autodiscoverTopics

Some platforms allow you to add tags, or topics, to repositories and retrieve repository lists by specifying those
Expand Down
37 changes: 0 additions & 37 deletions docs/usage/self-hosted-experimental.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,43 +32,6 @@ Skipping the check will speed things up, but may result in versions being return

If set to any value, Renovate will always paginate requests to GitHub fully, instead of stopping after 10 pages.

## `RENOVATE_X_AUTODISCOVER_REPO_ORDER`

<!-- prettier-ignore -->
!!! note
For the Forgejo and Gitea platform only.

The order method for autodiscover server side repository search.

> If multiple `autodiscoverTopics` are used resulting order will be per topic not global.
Allowed values:

- `asc`
- `desc`

Default value: `asc`.

## `RENOVATE_X_AUTODISCOVER_REPO_SORT`

<!-- prettier-ignore -->
!!! note
For the Forgejo and Gitea platform only.

The sort method for autodiscover server side repository search.

> If multiple `autodiscoverTopics` are used resulting order will be per topic not global.
Allowed values:

- `alpha`
- `created`
- `updated`
- `size`
- `id`

Default value: `alpha`.

## `RENOVATE_X_DELETE_CONFIG_FILE`

If `true` Renovate tries to delete the self-hosted config file after reading it.
Expand Down
2 changes: 2 additions & 0 deletions lib/config/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export class GlobalConfig {
'platform',
'endpoint',
'httpCacheTtlDays',
'autodiscoverRepoSort',
'autodiscoverRepoOrder',
'userAgent',
];

Expand Down
20 changes: 20 additions & 0 deletions lib/config/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ const options: RenovateOptions[] = [
globalOnly: true,
patternMatch: true,
},
{
name: 'autodiscoverRepoOrder',
description:
'The order method for autodiscover server side repository search.',
type: 'string',
default: null,
globalOnly: true,
allowedValues: ['asc', 'desc'],
supportedPlatforms: ['gitea'],
},
{
name: 'autodiscoverRepoSort',
description:
'The sort method for autodiscover server side repository search.',
type: 'string',
default: null,
globalOnly: true,
allowedValues: ['alpha', 'created', 'updated', 'size', 'id'],
supportedPlatforms: ['gitea'],
},
{
name: 'allowedEnv',
description:
Expand Down
3 changes: 3 additions & 0 deletions lib/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { LogLevel } from 'bunyan';
import type { PlatformId } from '../constants';
import type { LogLevelRemap } from '../logger/types';
import type { CustomManager } from '../modules/manager/custom/types';
import type { RepoSortMethod, SortMethod } from '../modules/platform/types';
import type { HostRule } from '../types';
import type { GitNoVerifyOption } from '../util/git/types';
import type { MergeConfidence } from '../util/merge-confidence/types';
Expand Down Expand Up @@ -159,6 +160,8 @@ export interface RepoGlobalConfig {
privateKey?: string;
privateKeyOld?: string;
httpCacheTtlDays?: number;
autodiscoverRepoSort?: RepoSortMethod;
autodiscoverRepoOrder?: SortMethod;
userAgent?: string;
}

Expand Down
10 changes: 4 additions & 6 deletions lib/modules/platform/gitea/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,6 @@ describe('modules/platform/gitea/index', () => {
hostRules.clear();

setBaseUrl('https://gitea.renovatebot.com/');

delete process.env.RENOVATE_X_AUTODISCOVER_REPO_SORT;
delete process.env.RENOVATE_X_AUTODISCOVER_REPO_ORDER;
});

async function initFakePlatform(
Expand Down Expand Up @@ -421,8 +418,6 @@ describe('modules/platform/gitea/index', () => {
});

it('Sorts repos', async () => {
process.env.RENOVATE_X_AUTODISCOVER_REPO_SORT = 'updated';
process.env.RENOVATE_X_AUTODISCOVER_REPO_ORDER = 'desc';
const scope = httpMock
.scope('https://gitea.com/api/v1')
.get('/repos/search')
Expand All @@ -438,7 +433,10 @@ describe('modules/platform/gitea/index', () => {
});
await initFakePlatform(scope);

const repos = await gitea.getRepos();
const repos = await gitea.getRepos({
sort: 'updated',
order: 'desc',
});
expect(repos).toEqual(['a/b', 'c/d']);
});
});
Expand Down
40 changes: 31 additions & 9 deletions lib/modules/platform/gitea/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import type {
Pr,
RepoParams,
RepoResult,
RepoSortMethod,
SortMethod,
UpdatePrConfig,
} from '../types';
import { repoFingerprint } from '../util';
Expand All @@ -49,8 +51,6 @@ import type {
PRMergeMethod,
PRUpdateParams,
Repo,
RepoSortMethod,
SortMethod,
} from './types';
import {
DRAFT_PREFIX,
Expand Down Expand Up @@ -159,19 +159,29 @@ async function lookupLabelByName(name: string): Promise<number | null> {
return labelList.find((l) => l.name === name)?.id ?? null;
}

async function fetchRepositories(topic?: string): Promise<string[]> {
interface FetchRepositoriesArgs {
topic?: string;
sort?: RepoSortMethod;
order?: SortMethod;
}

async function fetchRepositories({
topic,
sort,
order,
}: FetchRepositoriesArgs): Promise<string[]> {
const repos = await helper.searchRepos({
uid: botUserID,
archived: false,
...(topic && {
topic: true,
q: topic,
}),
...(process.env.RENOVATE_X_AUTODISCOVER_REPO_SORT && {
sort: process.env.RENOVATE_X_AUTODISCOVER_REPO_SORT as RepoSortMethod,
...(sort && {
sort,
}),
...(process.env.RENOVATE_X_AUTODISCOVER_REPO_ORDER && {
order: process.env.RENOVATE_X_AUTODISCOVER_REPO_ORDER as SortMethod,
...(order && {
order,
}),
});
return repos.filter(usableRepo).map((r) => r.full_name);
Expand Down Expand Up @@ -330,7 +340,16 @@ const platform: Platform = {
try {
if (config?.topics) {
logger.debug({ topics: config.topics }, 'Auto-discovering by topics');
const repos = await map(config.topics, fetchRepositories);
const fetchRepoArgs: FetchRepositoriesArgs[] = config.topics.map(
(topic) => {
return {
topic,
sort: config.sort,
order: config.order,
};
},
);
const repos = await map(fetchRepoArgs, fetchRepositories);
return deduplicateArray(repos.flat());
} else if (config?.namespaces) {
logger.debug(
Expand All @@ -348,7 +367,10 @@ const platform: Platform = {
);
return deduplicateArray(repos.flat());
} else {
return await fetchRepositories();
return await fetchRepositories({
sort: config?.sort,
order: config?.order,
});
}
} catch (err) {
logger.error({ err }, 'Gitea getRepos() error');
Expand Down
2 changes: 1 addition & 1 deletion lib/modules/platform/gitea/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ Repositories are ignored when one of the following conditions is met:
- Pull requests are disabled for that repository

You can change the default server-side sort method and order for autodiscover API.
Set those via [`RENOVATE_X_AUTODISCOVER_REPO_SORT`](../../../self-hosted-experimental.md#renovate_x_autodiscover_repo_sort) and [`RENOVATE_X_AUTODISCOVER_REPO_ORDER`](../../../self-hosted-experimental.md#renovate_x_autodiscover_repo_order).
Set those via [`autodiscoverRepoSort`](../../../self-hosted-configuration.md#autodiscoverRepoSort) and [`autodiscoverRepoOrder`](../../../self-hosted-configuration.md#autodiscoverRepoOrder).
Read the [Gitea swagger docs](https://try.gitea.io/api/swagger#/repository/repoSearch) for more details.
6 changes: 1 addition & 5 deletions lib/modules/platform/gitea/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { LongCommitSha } from '../../../util/git/types';
import type { Pr } from '../types';
import type { Pr, RepoSortMethod, SortMethod } from '../types';

export interface PrReviewersParams {
reviewers?: string[];
Expand Down Expand Up @@ -147,10 +147,6 @@ export interface CombinedCommitStatus {
statuses: CommitStatus[];
}

export type RepoSortMethod = 'alpha' | 'created' | 'updated' | 'size' | 'id';

export type SortMethod = 'asc' | 'desc';

export interface RepoSearchParams {
uid?: number;
archived?: boolean;
Expand Down
11 changes: 11 additions & 0 deletions lib/modules/platform/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,19 @@ export type EnsureCommentRemovalConfig =

export type EnsureIssueResult = 'updated' | 'created';

export type RepoSortMethod =
| 'alpha'
| 'created'
| 'updated'
| 'size'
| 'id'
| null;

export type SortMethod = 'asc' | 'desc' | null;
export interface AutodiscoverConfig {
topics?: string[];
sort?: RepoSortMethod;
order?: SortMethod;
includeMirrors?: boolean;
namespaces?: string[];
projects?: string[];
Expand Down
2 changes: 2 additions & 0 deletions lib/workers/global/autodiscover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export async function autodiscoverRepositories(
// Autodiscover list of repositories
let discovered = await platform.getRepos({
topics: config.autodiscoverTopics,
sort: config.autodiscoverRepoSort,
order: config.autodiscoverRepoOrder,
includeMirrors: config.includeMirrors,
namespaces: config.autodiscoverNamespaces,
projects: config.autodiscoverProjects,
Expand Down
12 changes: 12 additions & 0 deletions lib/workers/global/config/parse/env.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,18 @@ describe('workers/global/config/parse/env', () => {
expect(config.token).toBe('a');
});

it('massages converted experimental env vars', async () => {
const envParam: NodeJS.ProcessEnv = {
RENOVATE_X_AUTODISCOVER_REPO_SORT: 'alpha',
RENOVATE_X_DOCKER_MAX_PAGES: '10',
RENOVATE_AUTODISCOVER_REPO_ORDER: 'desc',
};
const config = await env.getConfig(envParam);
expect(config.autodiscoverRepoSort).toBe('alpha');
expect(config.autodiscoverRepoOrder).toBe('desc');
expect(config.dockerMaxPages).toBeUndefined();
});

describe('RENOVATE_CONFIG tests', () => {
let processExit: jest.SpyInstance<never, [code?: number]>;

Expand Down
25 changes: 25 additions & 0 deletions lib/workers/global/config/parse/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,30 @@ function massageEnvKeyValues(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
return result;
}

const convertedExperimentalEnvVars = [
'RENOVATE_X_AUTODISCOVER_REPO_SORT',
'RENOVATE_X_AUTODISCOVER_REPO_ORDER',
];

/**
* Massages the experimental env vars which have been converted to config options
*
* e.g. RENOVATE_X_AUTODISCOVER_REPO_SORT -> RENOVATE_AUTODISCOVER_REPO_SORT
*/
function massageConvertedExperimentalVars(
env: NodeJS.ProcessEnv,
): NodeJS.ProcessEnv {
const result = { ...env };
for (const key of convertedExperimentalEnvVars) {
if (env[key] !== undefined) {
const newKey = key.replace('RENOVATE_X_', 'RENOVATE_');
result[newKey] = env[key];
delete result[key];
}
}
return result;
}

export async function getConfig(
inputEnv: NodeJS.ProcessEnv,
): Promise<AllConfig> {
Expand All @@ -91,6 +115,7 @@ export async function getConfig(
env = renameEnvKeys(env);
// massage the values of migrated configuration keys
env = massageEnvKeyValues(env);
env = massageConvertedExperimentalVars(env);

const options = getOptions();

Expand Down

0 comments on commit 10a4a8b

Please sign in to comment.