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(config)!: forkProcessing #20759

Merged
merged 1 commit into from
Mar 5, 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
2 changes: 1 addition & 1 deletion docs/development/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ e.g. apply one set of labels for `backend/package.json` and a different set of l
module.exports = {
npmrc: '//registry.npmjs.org/:_authToken=abc123',
baseDir: '/tmp/renovate',
includeForks: true,
forkProcessing: 'enabled',
gradle: { enabled: false },
};
```
Expand Down
11 changes: 0 additions & 11 deletions docs/development/local-development.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,6 @@ To do this, see these GitHub guides:

## Tips and tricks

### Running Renovate against forked repositories

Quite often, the quickest way for you to test or fix something is to fork an existing repository.
But by default Renovate skips over repositories that are forked.
To override this default, you need to specify the setting `includeForks` as `true`.

Tell Renovate to run on your forked repository by doing one of the following:

1. Add `"includeForks": true` to the `renovate.json` file in your forked repository
1. Run Renovate with the CLI flag `--renovate-fork=true`

### Log files

Usually, `debug` is good enough to troubleshoot most problems or verify functionality.
Expand Down
18 changes: 10 additions & 8 deletions docs/usage/configuration-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,16 @@ If this option is enabled, reviewers will need to create a new PR if additional
!!! note
This option is only relevant if you set `forkToken`.

## forkProcessing

By default, Renovate will skip over any repositories that are forked if Renovate is using `autodiscover` mode.
This includes if the forked repository has a Renovate config file, because Renovate can't tell if that file was added by the original repository or not.
If you wish to enable processing of a forked repository by Renovate when autodiscovering, you need to add `"forkProcessing": "enabled"` to your repository config or run the CLI command with `--fork-processing=enabled`.

If you are running in non-autodiscover mode (e.g. supplying a list of repositories to Renovate) but wish to skip forked repositories, you need to configure `"forkProcessing": "disabled"` in your global config.

If you are using the hosted Mend Renovate then this option will be configured to `"enabled"` automatically if you "Selected" repositories individually but `"disabled"` if you installed for "All" repositories. If you have installed Renovate into "All" repositories but have a fork you want to use, then add `"forkProcessing": "enabled"` to the repository's `renovate.json` file.

## gitAuthor

You can customize the Git author that's used whenever Renovate creates a commit.
Expand Down Expand Up @@ -1417,14 +1427,6 @@ If you need to force permanent unstable updates for a package, you can add a pac

Also check out the `followTag` configuration option above if you wish Renovate to keep you pinned to a particular release tag.

## includeForks

By default, Renovate will skip over any repositories that are forked.
This includes if the forked repository has a Renovate config file, because Renovate can't tell if that file was added by the original repository or not.
If you wish to enable processing of a forked repository by Renovate, you need to add `"includeForks": true` to your repository config or run the CLI command with `--include-forks=true`.

If you are using the hosted Mend Renovate then this option will be configured to `true` automatically if you "Selected" repositories individually but remain as `false` if you installed for "All" repositories.

## includePaths

If you wish for Renovate to process only select paths in the repository, use `includePaths`.
Expand Down
2 changes: 1 addition & 1 deletion lib/config/__snapshots__/migration.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1`
"config:js-lib",
":dependencyDashboard",
],
"forkProcessing": "enabled",
"hostRules": [
{
"hostType": "docker",
Expand All @@ -142,7 +143,6 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1`
"ignorePaths": [
"node_modules/",
],
"includeForks": true,
"lockFileMaintenance": {
"automerge": true,
"exposeAllEnv": false,
Expand Down
34 changes: 34 additions & 0 deletions lib/config/migrations/custom/include-forks-migration.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { RenovateForkMigration } from './include-forks-migration';

describe('config/migrations/custom/include-forks-migration', () => {
it('should migrate true', () => {
expect(RenovateForkMigration).toMigrate(
{
includeForks: true,
},
{
forkProcessing: 'enabled',
}
);
});

it('should migrate false', () => {
expect(RenovateForkMigration).toMigrate(
{
includeForks: false,
},
{
forkProcessing: 'disabled',
}
);
});

it('should not migrate non boolean value', () => {
expect(RenovateForkMigration).toMigrate(
{
includeForks: 'test',
},
{}
);
});
});
13 changes: 13 additions & 0 deletions lib/config/migrations/custom/include-forks-migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import is from '@sindresorhus/is';
import { AbstractMigration } from '../base/abstract-migration';

export class RenovateForkMigration extends AbstractMigration {
override readonly deprecated = true;
override readonly propertyName = 'includeForks';

override run(value: unknown): void {
if (is.boolean(value)) {
this.setSafely('forkProcessing', value ? 'enabled' : 'disabled');
}
}
}
4 changes: 2 additions & 2 deletions lib/config/migrations/custom/renovate-fork-migration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('config/migrations/custom/renovate-fork-migration', () => {
renovateFork: true,
},
{
includeForks: true,
forkProcessing: 'enabled',
}
);
});
Expand All @@ -18,7 +18,7 @@ describe('config/migrations/custom/renovate-fork-migration', () => {
renovateFork: false,
},
{
includeForks: false,
forkProcessing: 'disabled',
}
);
});
Expand Down
2 changes: 1 addition & 1 deletion lib/config/migrations/custom/renovate-fork-migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class RenovateForkMigration extends AbstractMigration {

override run(value: unknown): void {
if (is.boolean(value)) {
this.setSafely('includeForks', value);
this.setSafely('forkProcessing', value ? 'enabled' : 'disabled');
}
}
}
9 changes: 5 additions & 4 deletions lib/config/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,12 +419,13 @@ const options: RenovateOptions[] = [
experimentalIssues: [17633],
},
{
name: 'includeForks',
name: 'forkProcessing',
description:
'Whether to process forked repositories. By default, all forked repositories are skipped.',
'Whether to process forked repositories. By default, all forked repositories are skipped when in autodiscover mode.',
stage: 'repository',
type: 'boolean',
default: false,
type: 'string',
allowedValues: ['auto', 'enabled', 'disabled'],
default: 'auto',
},
{
name: 'forkToken',
Expand Down
2 changes: 1 addition & 1 deletion lib/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export interface RenovateConfig
hostRules?: HostRule[];

ignorePresets?: string[];
includeForks?: boolean;
forkProcessing?: 'auto' | 'enabled' | 'disabled';
isFork?: boolean;

fileList?: string[];
Expand Down
2 changes: 1 addition & 1 deletion lib/modules/platform/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface RepoParams {
endpoint?: string;
gitUrl?: GitUrlOption;
forkToken?: string;
includeForks?: boolean;
forkProcessing?: 'enabled' | 'disabled';
renovateUsername?: string;
cloneSubmodules?: boolean;
ignorePrAuthor?: boolean;
Expand Down
2 changes: 2 additions & 0 deletions lib/workers/global/config/parse/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export function getConfig(input: string[]): AllConfig {
.replace(/^--dry-run$/, '--dry-run=true')
.replace(/^--require-config$/, '--require-config=true')
.replace('--aliases', '--registry-aliases')
.replace('--include-forks=true', '--fork-processing=enabled')
.replace('--include-forks', '--fork-processing=enabled')
)
.filter((a) => !a.startsWith('--git-fs'));
const options = getOptions();
Expand Down
6 changes: 6 additions & 0 deletions lib/workers/global/config/parse/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ export async function parseConfigs(
config.endpoint = ensureTrailingSlash(config.endpoint);
}

// Massage forkProcessing
if (!config.autodiscover && config.forkProcessing !== 'disabled') {
logger.debug('Enabling forkProcessing while in non-autodiscover mode');
config.forkProcessing = 'enabled';
}

// Remove log file entries
delete config.logFile;
delete config.logFileLevel;
Expand Down
2 changes: 1 addition & 1 deletion lib/workers/repository/configured.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export function checkIfConfigured(config: RenovateConfig): void {
if (config.enabled === false) {
throw new Error(REPOSITORY_DISABLED_BY_CONFIG);
}
if (config.isFork && !config.includeForks) {
if (config.isFork && config.forkProcessing !== 'enabled') {
throw new Error(REPOSITORY_FORKED);
}
}
33 changes: 26 additions & 7 deletions lib/workers/repository/init/apis.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('workers/repository/init/apis', () => {
config.warnings = [];
config.token = 'some-token';
delete config.optimizeForDisabled;
delete config.includeForks;
delete config.forkProcessing;
});

afterEach(() => {
Expand Down Expand Up @@ -53,15 +53,30 @@ describe('workers/repository/init/apis', () => {
isFork: true,
repoFingerprint: '123',
});
platform.getJsonFile.mockResolvedValueOnce({ includeForks: false });
platform.getJsonFile.mockResolvedValueOnce({
forkProcessing: 'disabled',
});
await expect(
initApis({
...config,
includeForks: false,
forkProcessing: 'disabled',
})
).rejects.toThrow(REPOSITORY_FORKED);
});

it('does not throw for includeForks=true', async () => {
platform.initRepo.mockResolvedValueOnce({
defaultBranch: 'master',
isFork: true,
repoFingerprint: '123',
});
platform.getJsonFile.mockResolvedValueOnce({
includeForks: true,
});
const workerPlatformConfig = await initApis(config);
expect(workerPlatformConfig).toBeTruthy();
});

it('ignores platform.getJsonFile() failures', async () => {
platform.initRepo.mockResolvedValueOnce({
defaultBranch: 'master',
Expand All @@ -73,7 +88,7 @@ describe('workers/repository/init/apis', () => {
initApis({
...config,
optimizeForDisabled: true,
includeForks: false,
forkProcessing: 'disabled',
isFork: true,
})
).resolves.not.toThrow();
Expand All @@ -85,7 +100,9 @@ describe('workers/repository/init/apis', () => {
isFork: false,
repoFingerprint: '123',
});
platform.getJsonFile.mockResolvedValueOnce({ includeForks: false });
platform.getJsonFile.mockResolvedValueOnce({
forkProcessing: 'disabled',
});
const workerPlatformConfig = await initApis({
...config,
optimizeForDisabled: true,
Expand All @@ -107,7 +124,9 @@ describe('workers/repository/init/apis', () => {
isFork: false,
repoFingerprint: '123',
});
platform.getJsonFile.mockResolvedValueOnce({ includeForks: false });
platform.getJsonFile.mockResolvedValueOnce({
forkProcessing: 'disabled',
});
const workerPlatformConfig = await initApis({
...config,
optimizeForDisabled: true,
Expand All @@ -124,7 +143,7 @@ describe('workers/repository/init/apis', () => {
isFork: false,
repoFingerprint: '123',
});
platform.getJsonFile.mockResolvedValueOnce({ includeForks: false });
platform.getJsonFile.mockResolvedValueOnce({ forkProcessing: false });
const workerPlatformConfig = await initApis({
...config,
optimizeForDisabled: true,
Expand Down
9 changes: 7 additions & 2 deletions lib/workers/repository/init/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
REPOSITORY_DISABLED_BY_CONFIG,
REPOSITORY_FORKED,
} from '../../../constants/error-messages';
import { logger } from '../../../logger';
import { RepoParams, RepoResult, platform } from '../../../modules/platform';

// TODO: fix types (#7154)
Expand Down Expand Up @@ -37,11 +38,15 @@ async function validateOptimizeForDisabled(
}

async function validateIncludeForks(config: RenovateConfig): Promise<void> {
if (!config.includeForks && config.isFork) {
if (config.forkProcessing !== 'enabled' && config.isFork) {
const renovateConfig = await getJsonFile(defaultConfigFile(config));
if (!renovateConfig?.includeForks) {
if (
renovateConfig?.includeForks !== true &&
renovateConfig?.forkProcessing !== 'enabled'
) {
throw new Error(REPOSITORY_FORKED);
}
logger.debug('Repository config enables forks - continuing');
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/workers/repository/onboarding/branch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export async function checkOnboardingBranch(
logger.debug('Repo is onboarded');
return { ...config, repoIsOnboarded };
}
if (config.isFork && !config.includeForks) {
if (config.isFork && config.forkProcessing !== 'enabled') {
throw new Error(REPOSITORY_FORKED);
}
logger.debug('Repo is not onboarded');
Expand Down