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/migration): migrate config with a PR #15122

Merged
merged 67 commits into from
Jun 18, 2022
Merged
Show file tree
Hide file tree
Changes from 66 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
a9f4663
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 14, 2022
534b461
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti Apr 14, 2022
b29fb4f
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 17, 2022
a2265e7
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 17, 2022
9113358
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 17, 2022
15d45ad
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti Apr 17, 2022
f395e0f
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 17, 2022
6bd6c6c
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 18, 2022
bb692ca
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 18, 2022
44d7aff
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 18, 2022
814166c
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 18, 2022
c3c7fca
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 19, 2022
8fe5ab3
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 19, 2022
4a9af8b
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 19, 2022
b727bb8
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 20, 2022
d3762a4
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 20, 2022
741abb0
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 20, 2022
5d6e3fd
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 20, 2022
15dbe78
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 20, 2022
bac194e
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 20, 2022
3f44f77
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 20, 2022
b0d4edf
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti Apr 24, 2022
ed0877c
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 24, 2022
7aa4d1d
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 24, 2022
7f17942
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 24, 2022
c509a03
Merge branch 'main' into feat-config-migrate
viceice Apr 25, 2022
8d68f0b
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti Apr 26, 2022
2c5773b
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Apr 26, 2022
34c570b
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 2, 2022
9693765
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 2, 2022
0f0ec56
Merge branch 'feat-config-migrate' of https://github.com/Gabriel-Ladz…
Gabriel-Ladzaretti May 2, 2022
4d2c0d5
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti May 2, 2022
f03924b
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 2, 2022
a2a2d37
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 2, 2022
847e19c
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 2, 2022
c311a0a
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti May 2, 2022
73ff6aa
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 2, 2022
8b02ac0
Update docs/usage/configuration-options.md
Gabriel-Ladzaretti May 3, 2022
a92d157
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti May 4, 2022
d251c88
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 8, 2022
57470e1
Merge branch 'feat-config-migrate' of https://github.com/Gabriel-Ladz…
Gabriel-Ladzaretti May 8, 2022
a8a6036
Merge branch 'main' into feat-config-migrate
rarkins May 11, 2022
faba41e
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 11, 2022
56deb3b
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti May 11, 2022
3d8c0d1
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 11, 2022
1985465
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 11, 2022
6b80990
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 12, 2022
4335d29
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 16, 2022
a60701e
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti May 16, 2022
9a17882
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 16, 2022
f3932d8
Apply suggestions from code review
Gabriel-Ladzaretti May 17, 2022
d1e164e
Apply suggestions from code review
Gabriel-Ladzaretti May 17, 2022
8800917
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 17, 2022
f204391
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 18, 2022
fd05258
Update docs/usage/configuration-options.md
Gabriel-Ladzaretti May 18, 2022
b1f4174
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 22, 2022
d2bd864
Merge branch 'feat-config-migrate' of https://github.com/Gabriel-Ladz…
Gabriel-Ladzaretti May 22, 2022
843dfee
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 25, 2022
445c43e
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti May 31, 2022
4f68a05
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti May 31, 2022
593df89
feat(config/migration): migrate config with a PR
Gabriel-Ladzaretti Jun 12, 2022
29b9f05
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti Jun 12, 2022
cf52885
Update lib/workers/repository/config-migration/pr/index.ts
viceice Jun 13, 2022
adef597
Merge branch 'main' into feat-config-migrate
rarkins Jun 13, 2022
81c1437
Merge branch 'main' into feat-config-migrate
Gabriel-Ladzaretti Jun 16, 2022
d39cb33
Merge branch 'main' into feat-config-migrate
rarkins Jun 18, 2022
228b176
Merge branch 'main' into feat-config-migrate
rarkins Jun 18, 2022
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
25 changes: 25 additions & 0 deletions docs/usage/configuration-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,31 @@ If enabled, all issues created by Renovate are set as confidential, even in a pu
!!! note
This option is applicable to GitLab only.

## configMigration

If enabled, Renovate will raise a pull request if config file migration is needed.
viceice marked this conversation as resolved.
Show resolved Hide resolved

We're adding new features to Renovate bot often.
Most times you can keep using your Renovate config and benefit from the new features right away.
But sometimes you need to change your Renovate configuration.
To help you with this, Renovate will create config migration pull requests.

Example:

After we changed the [`baseBranches`](https://docs.renovatebot.com/configuration-options/#basebranches) feature, the Renovate configuration migration pull request would make this change:

```diff
{
- "baseBranch": "main"
+ "baseBranches": ["main"]
}
```

<!-- prettier-ignore -->
!!! info
This feature writes plain JSON for `.json` files, and JSON5 for `.json5` files.
JSON5 content can potentially be down leveled (`.json` files) and all comments will be removed.

## configWarningReuseIssue

Renovate's default behavior is to reuse/reopen a single Config Warning issue in each repository so as to keep the "noise" down.
Expand Down
7 changes: 7 additions & 0 deletions lib/config/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ const options: RenovateOptions[] = [
globalOnly: true,
cli: false,
},
{
name: 'configMigration',
description: 'Enable this to get config migration PRs when needed.',
stage: 'repository',
type: 'boolean',
default: false,
},
{
name: 'productLinks',
description: 'Links which are used in PRs, issues and comments.',
Expand Down
5 changes: 5 additions & 0 deletions lib/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ export interface RenovateConfig
RenovateSharedConfig,
UpdateConfig<PackageRule>,
AssigneesAndReviewersConfig,
ConfigMigration,
Record<string, unknown> {
depName?: string;
baseBranches?: string[];
Expand Down Expand Up @@ -431,6 +432,10 @@ export interface PackageRuleInputConfig extends Record<string, unknown> {
packageRules?: (PackageRule & PackageRuleInputConfig)[];
}

export interface ConfigMigration {
configMigration?: boolean;
}

export interface MigratedConfig {
isMigrated: boolean;
migratedConfig: RenovateConfig;
Expand Down
3 changes: 3 additions & 0 deletions lib/util/template/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ const prBodyFields = [
'table',
'notes',
'changelogs',
'hasWarningsErrors',
'errors',
'warnings',
'configDescription',
'controls',
'footer',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"filename": "renovate.json",
"content": "{\n \"extends\": [\n \":separateMajorReleases\",\n \":prImmediately\",\n \":renovatePrefix\",\n \":semanticPrefixFixDepsChoreOthers\",\n \":updateNotScheduled\",\n \":automergeDisabled\",\n \":maintainLockFilesDisabled\",\n \":autodetectPinVersions\",\n \"group:monorepos\"\n ],\n \"onboarding\": false,\n \"rangeStrategy\": \"replace\",\n \"semanticCommits\": \"enabled\",\n \"timezone\": \"US/Central\",\n \"baseBranches\": [\n \"main\"\n ]\n}\n"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"filename": "renovate.json5",
"content": "{\n extends: [\n ':separateMajorReleases',\n ':prImmediately',\n ':renovatePrefix',\n ':semanticPrefixFixDepsChoreOthers',\n ':updateNotScheduled',\n ':automergeDisabled',\n ':maintainLockFilesDisabled',\n ':autodetectPinVersions',\n 'group:monorepos',\n ],\n onboarding: false,\n rangeStrategy: 'replace',\n semanticCommits: 'enabled',\n timezone: 'US/Central',\n baseBranches: [\n 'main',\n ],\n}\n"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"extends": [
":separateMajorReleases",
":prImmediately",
":renovatePrefix",
":semanticPrefixFixDepsChoreOthers",
":updateNotScheduled",
":automergeDisabled",
":maintainLockFilesDisabled",
":autodetectPinVersions",
"group:monorepos"
],
"onboarding": false,
"rangeStrategy": "replace",
"semanticCommits": "enabled",
"timezone": "US/Central",
"baseBranches": [
"main"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
viceice marked this conversation as resolved.
Show resolved Hide resolved
"extends": [
":separateMajorReleases",
":prImmediately",
":renovatePrefix",
":semanticPrefixFixDepsChoreOthers",
":updateNotScheduled",
":automergeDisabled",
":maintainLockFilesDisabled",
":autodetectPinVersions",
"group:monorepos",
"helpers:oddIsUnstablePackages"
],
"onboarding": false,
"pinVersions": false,
"semanticCommits": true,
"timezone": "US/Central",
"baseBranch": "main"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
extends: [
':separateMajorReleases',
':prImmediately',
':renovatePrefix',
':semanticPrefixFixDepsChoreOthers',
':updateNotScheduled',
':automergeDisabled',
':maintainLockFilesDisabled',
':autodetectPinVersions',
'group:monorepos',
'helpers:oddIsUnstablePackages'
],
onboarding: false,
pinVersions: false,
semanticCommits: true,
timezone: 'US/Central',
baseBranch: 'main' // thats a comment
}
46 changes: 46 additions & 0 deletions lib/workers/repository/config-migration/branch/commit-message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { RenovateConfig } from '../../../../config/types';
import * as template from '../../../../util/template';
import type { CommitMessage } from '../../model/commit-message';
import { CommitMessageFactory } from '../../model/commit-message-factory';

export class ConfigMigrationCommitMessageFactory {
Gabriel-Ladzaretti marked this conversation as resolved.
Show resolved Hide resolved
private readonly config: RenovateConfig;

private readonly configFile: string;

constructor(config: RenovateConfig, configFile: string) {
this.config = config;
this.configFile = configFile;
}

create(): CommitMessage {
const { commitMessage } = this.config;

this.config.commitMessageAction =
this.config.commitMessageAction === 'Update'
? ''
: this.config.commitMessageAction;

this.config.commitMessageTopic =
this.config.commitMessageTopic === 'dependency {{depName}}'
? `Migrate config ${this.configFile}`
: this.config.commitMessageTopic;

this.config.commitMessageExtra = '';
this.config.semanticCommitScope = 'config';

const commitMessageFactory = new CommitMessageFactory(this.config);
const commit = commitMessageFactory.create();

if (commitMessage) {
commit.subject = template.compile(commitMessage, {
...this.config,
commitMessagePrefix: '',
});
} else {
commit.subject = `Migrate config ${this.configFile}`;
}

return commit;
}
}
179 changes: 179 additions & 0 deletions lib/workers/repository/config-migration/branch/create.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import { Fixtures } from '../../../../../test/fixtures';
import { RenovateConfig, getConfig, platform } from '../../../../../test/util';
import { commitFiles } from '../../../../util/git';
import { createConfigMigrationBranch } from './create';
import type { MigratedData } from './migrated-data';

jest.mock('../../../../util/git');

describe('workers/repository/config-migration/branch/create', () => {
const raw = Fixtures.getJson('./renovate.json');
const indent = ' ';
const renovateConfig = JSON.stringify(raw, undefined, indent) + '\n';
const filename = 'renovate.json';

let config: RenovateConfig;
let migratedConfigData: MigratedData;

beforeEach(() => {
jest.clearAllMocks();
config = getConfig();
migratedConfigData = { content: renovateConfig, filename };
});

describe('createConfigMigrationBranch', () => {
it('applies the default commit message', async () => {
await createConfigMigrationBranch(config, migratedConfigData);
expect(commitFiles).toHaveBeenCalledWith({
branchName: 'renovate/migrate-config',
files: [
{
type: 'addition',
path: 'renovate.json',
contents: renovateConfig,
},
],
message: 'Migrate config renovate.json',
platformCommit: false,
});
});

it('commits via platform', async () => {
config.platformCommit = true;

await createConfigMigrationBranch(config, migratedConfigData);

expect(platform.commitFiles).toHaveBeenCalledWith({
branchName: 'renovate/migrate-config',
files: [
{
type: 'addition',
path: 'renovate.json',
contents: renovateConfig,
},
],
message: 'Migrate config renovate.json',
platformCommit: true,
});
});

it('applies supplied commit message', async () => {
const message = 'We can migrate config if we want to, or we can not';

config.commitMessage = message;

await createConfigMigrationBranch(config, migratedConfigData);

expect(commitFiles).toHaveBeenCalledWith({
branchName: 'renovate/migrate-config',
files: [
{
type: 'addition',
path: 'renovate.json',
contents: renovateConfig,
},
],
message: message,
platformCommit: false,
});
});

describe('applies the commitMessagePrefix value', () => {
it('to the default commit message', async () => {
config.commitMessagePrefix = 'PREFIX:';
config.commitMessage = '';

const message = `PREFIX: migrate config renovate.json`;
await createConfigMigrationBranch(config, migratedConfigData);

expect(commitFiles).toHaveBeenCalledWith({
branchName: 'renovate/migrate-config',
files: [
{
type: 'addition',
path: 'renovate.json',
contents: renovateConfig,
},
],
message: message,
platformCommit: false,
});
});

it('to the supplied commit message prefix, topic & action', async () => {
const prefix = 'PREFIX:';
const topic = 'thats a topic';
const action = 'action';

const message = `${prefix} ${action} ${topic}`;

config.commitMessagePrefix = prefix;
config.commitMessageTopic = topic;
config.commitMessageAction = action;

await createConfigMigrationBranch(config, migratedConfigData);

expect(commitFiles).toHaveBeenCalledWith({
branchName: 'renovate/migrate-config',
files: [
{
type: 'addition',
path: 'renovate.json',
contents: renovateConfig,
},
],
message: message,
platformCommit: false,
});
});
});

describe('applies semanticCommit prefix', () => {
it('to the default commit message', async () => {
const prefix = 'chore(config)';
const message = `${prefix}: migrate config renovate.json`;

config.semanticCommits = 'enabled';

await createConfigMigrationBranch(config, migratedConfigData);

expect(commitFiles).toHaveBeenCalledWith({
branchName: 'renovate/migrate-config',
files: [
{
type: 'addition',
path: 'renovate.json',
contents: renovateConfig,
},
],
message: message,
platformCommit: false,
});
});

it('to the supplied commit message topic', async () => {
const prefix = 'chore(config)';
const topic = 'supplied topic';
const message = `${prefix}: ${topic}`;

config.semanticCommits = 'enabled';
config.commitMessageTopic = topic;

await createConfigMigrationBranch(config, migratedConfigData);

expect(commitFiles).toHaveBeenCalledWith({
branchName: 'renovate/migrate-config',
files: [
{
type: 'addition',
path: 'renovate.json',
contents: renovateConfig,
},
],
message: message,
platformCommit: false,
});
});
});
});
});
Loading