diff --git a/docs/usage/assets/images/merge-confidence.png b/docs/usage/assets/images/merge-confidence.png new file mode 100644 index 0000000000000000000000000000000000000000..ccddd8c6b64d8fc4dffd0ad274c18e2c8c514781 Binary files /dev/null and b/docs/usage/assets/images/merge-confidence.png differ diff --git a/docs/usage/merge-confidence.md b/docs/usage/merge-confidence.md new file mode 100644 index 0000000000000000000000000000000000000000..aba870267e0b902a713e56b45b303e8814b5aaae --- /dev/null +++ b/docs/usage/merge-confidence.md @@ -0,0 +1,98 @@ +# Merge Confidence + +Look at the Merge Confidence badges before merging to: + +- Prevent updates which break in production +- See at a glance if you should update + +Merge Confidence finds and flags undeclared breaking releases. +It analyzes test and release adoption data across Mend Renovate’s early-adopting user base. + + + +## Pull request badges + +Merge Confidence adds the following badges to your pull requests: + +- **Age**: The age of the package +- **Adoption**: The percentage of this package's users (within Renovate) which are using this release +- **Passing**: The percentage of updates which have passing tests for this package +- **Confidence**: The confidence level for this update + +## Supported platforms + +Merge Confidence badges for pull requests are available on any supported platform or Renovate distribution, including Mend Remediate. + +## Supported languages + +Data is available for packages from: + +- npm +- Maven +- PyPI + +We plan to support more languages soon. + +## Enabling and disabling + +If you use the Mend Renovate App then the badges are enabled automatically. + +If you're self-hosting Renovate, you can enable the badges by adding the `mergeConfidence:all-badges` preset to the `extends` array in your Renovate config: + +```json +{ + "extends": ["mergeConfidence:all-badges"] +} +``` + +<!-- prettier-ignore --> +!!! note + The `mergeConfidence:age-confidence-badges` preset can be used to only show the Age and Confidence badges. + +If you want to disable the badges in the app, add the `mergeConfidence:all-badges` preset to the `ignorePresets` array in your config: + +```json +{ + "ignorePresets": ["mergeConfidence:all-badges"] +} +``` + +## Confidence levels and their meaning + +Merge Confidence uses the following confidence levels: + +- **Low**: We think the update contains breaking changes. Often this is expected because it's a `major` version update, but updates can have unknown breaking changes +- **Neutral**: We don't have enough data about the update, or we can't decide if the update should be Low or High confidence +- **High**: We rank updates as High confidence when the combination of `Age`, `Adoption` and `Passing` tests means there's a very low chance of breaking changes +- **Very High**: We only use this for updates which are months old and have either high `Adoption` or have very high test `Passing` scores + +## How it works + +Mend's hosted Renovate App has created millions of pull requests on `github.com` to help developers update their dependencies since 2017. +We bundle and analyze metrics such as package `Age`, package `Adoption`, and `Passing` tests. +This way we can find packages that have undeclared breaking changes. + +### Algorithm + +The algorithm that decides on the values is private and is not something we plan to share. +Similar to a search engine's algorithm, we plan to adjust and improve it over time, for example by using historical data to set a baseline confidence level for packages. + +### Data + +We plan to expose much more of the data via a companion website, such as number of users of a package and popular repositories which already updated to the version in question. + +## Explanations + +### Package ranking + +npm packages less than three days old can be [unpublished](https://docs.npmjs.com/policies/unpublish), which can result in a service impact if you have updated to a package that gets unpublished. +This is why npm packages can only get the **High** Confidence badge when they are at least three days old. + +### Percentage values weighting + +The percentages for `Adoption` and `Passing` are weighted towards Organizations, private repositories, and projects with high test reliability. +This means those values aren't _raw_ percentages. + +## Questions and feedback + +You are invited to [start a discussion](https://github.com/renovatebot/renovate/discussions/new/choose) if you have anything you'd like to discuss. diff --git a/lib/config/migrations/custom/extends-migration.spec.ts b/lib/config/migrations/custom/extends-migration.spec.ts index 33dbe7faeda63a8219c2374a96d3c4f8c3f9f1ea..6829ac6993585b609580193070760ea054958aef 100644 --- a/lib/config/migrations/custom/extends-migration.spec.ts +++ b/lib/config/migrations/custom/extends-migration.spec.ts @@ -72,4 +72,15 @@ describe('config/migrations/custom/extends-migration', () => { ); GlobalConfig.reset(); }); + + it('migrate merge confidence config preset to internal preset', () => { + expect(ExtendsMigration).toMigrate( + { + extends: ['github>whitesource/merge-confidence:beta'], + }, + { + extends: ['mergeConfidence:all-badges'], + } + ); + }); }); diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index d4e7ffe914f7423a8fd65fe27805d40ae96cd3bb..de8bec2829d2414245ee1ce08d51eaab657723a9 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -2341,6 +2341,13 @@ const options: RenovateOptions[] = [ Pending: '{{{displayPending}}}', References: '{{{references}}}', 'Package file': '{{{packageFile}}}', + Age: "[](https://docs.renovatebot.com/merge-confidence/)", + Adoption: + "[](https://docs.renovatebot.com/merge-confidence/)", + Passing: + "[](https://docs.renovatebot.com/merge-confidence/)", + Confidence: + "[](https://docs.renovatebot.com/merge-confidence/)", }, }, { diff --git a/lib/config/presets/common.ts b/lib/config/presets/common.ts index c7055516f6d8c09cb2c73be29c0d98e10fc70bdd..2e36e863f0cc26a571e642f93969e4a7cc55f7af 100644 --- a/lib/config/presets/common.ts +++ b/lib/config/presets/common.ts @@ -27,6 +27,7 @@ export const removedPresets: Record<string, string | null> = { 'helpers:oddIsUnstable': null, 'helpers:oddIsUnstablePackages': null, 'group:jsTestMonMajor': 'group:jsTestNonMajor', + 'github>whitesource/merge-confidence:beta': 'mergeConfidence:all-badges', }; const renamedMonorepos: Record<string, string> = { diff --git a/lib/config/presets/index.ts b/lib/config/presets/index.ts index 24459e102cb960bb44ee27dd3524dd9ec0f17b05..4fdd4710298b6fe22ae5a8b1bb0f81ca183a8af7 100644 --- a/lib/config/presets/index.ts +++ b/lib/config/presets/index.ts @@ -140,6 +140,7 @@ export function parsePreset(input: string): ParsedPreset { 'docker', 'group', 'helpers', + 'mergeConfidence', 'monorepo', 'npm', 'packages', diff --git a/lib/config/presets/internal/index.ts b/lib/config/presets/internal/index.ts index e37788d17fc4c839ebe35ad41b79488540e72781..db49d357708c580d2ed24ac21ff52fa39be3d7fe 100644 --- a/lib/config/presets/internal/index.ts +++ b/lib/config/presets/internal/index.ts @@ -4,6 +4,7 @@ import * as defaultPreset from './default'; import * as dockerPreset from './docker'; import * as groupPreset from './group'; import * as helpersPreset from './helpers'; +import * as mergeConfidence from './merge-confidence'; import * as monorepoPreset from './monorepo'; import * as npm from './npm'; import * as packagesPreset from './packages'; @@ -21,6 +22,7 @@ export const groups: Record<string, Record<string, Preset>> = { docker: dockerPreset.presets, group: groupPreset.presets, helpers: helpersPreset.presets, + mergeConfidence: mergeConfidence.presets, monorepo: monorepoPreset.presets, npm: npm.presets, packages: packagesPreset.presets, diff --git a/lib/config/presets/internal/merge-confidence.ts b/lib/config/presets/internal/merge-confidence.ts new file mode 100644 index 0000000000000000000000000000000000000000..3225581848c308ad6d469432c34341c32e319d3d --- /dev/null +++ b/lib/config/presets/internal/merge-confidence.ts @@ -0,0 +1,32 @@ +import type { Preset } from '../types'; + +export const presets: Record<string, Preset> = { + 'all-badges': { + description: 'Show all Merge Confidence badges for pull requests.', + packageRules: [ + { + matchDatasources: ['maven', 'npm', 'pypi'], + matchUpdateTypes: ['patch', 'minor', 'major'], + prBodyColumns: [ + 'Package', + 'Change', + 'Age', + 'Adoption', + 'Passing', + 'Confidence', + ], + }, + ], + }, + 'age-confidence-badges': { + description: + 'Show only the Age and Confidence Merge Confidence badges for pull requests.', + packageRules: [ + { + matchDatasources: ['maven', 'npm', 'pypi'], + matchUpdateTypes: ['patch', 'minor', 'major'], + prBodyColumns: ['Package', 'Change', 'Age', 'Confidence'], + }, + ], + }, +};