Skip to content

Commit 2197818

Browse files
authored
feat(presets): Package abandonment preset (#36210)
1 parent 337d39b commit 2197818

File tree

8 files changed

+85
-0
lines changed

8 files changed

+85
-0
lines changed

docs/usage/key-concepts/dashboard.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,24 @@ Here is an example of how this can look:
6666
| npm | `airbnb-prop-types` | ![Available](https://img.shields.io/badge/available-green?style=flat-square) |
6767
| npm | `left-pad` | ![Unavailable](https://img.shields.io/badge/unavailable-orange?style=flat-square) |
6868

69+
#### Abandonment detection
70+
71+
Renovate includes the `abandonments:recommended` preset (automatically included in `config:best-practices`) to help identify potentially abandoned packages. This preset:
72+
73+
- Sets a default [`abandonmentThreshold`](../configuration-options.md#abandonmentthreshold) of `1 year` for all packages
74+
- Includes community-sourced overrides for packages that appear abandoned but are still maintained
75+
- Prevents updates to truly abandoned packages while allowing updates to packages with irregular release schedules
76+
77+
**Usage:**
78+
79+
```json
80+
{
81+
"extends": ["abandonments:recommended"]
82+
}
83+
```
84+
85+
You can contribute additional overrides by updating the [`abandonments.json`](https://github.com/renovatebot/renovate/blob/main/lib/data/abandonments.json) file.
86+
6987
### Visibility into rejected/deferred updates
7088

7189
Renovate's Dependency Dashboard shows an overview of all updates that are still "to do".
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import data from '../../../data/abandonments.json';
2+
import type { PackageRule } from '../../types';
3+
import type { Preset } from '../types';
4+
5+
function loadAbandonmentPresets(): Record<string, Preset> {
6+
const packageRules: PackageRule[] = [
7+
{
8+
matchPackageNames: ['*'],
9+
abandonmentThreshold: '1 year',
10+
},
11+
];
12+
13+
for (const [datasource, datasourceAbandonments] of Object.entries(data)) {
14+
if (datasource === '$schema') {
15+
continue;
16+
}
17+
18+
for (const [packageName, threshold] of Object.entries(
19+
datasourceAbandonments,
20+
)) {
21+
const abandonmentThreshold = threshold === 'eternal' ? null : threshold;
22+
packageRules.push({
23+
matchDatasources: [datasource],
24+
matchPackageNames: [packageName],
25+
abandonmentThreshold,
26+
});
27+
}
28+
}
29+
30+
return {
31+
recommended: { packageRules },
32+
};
33+
}
34+
35+
export const presets: Record<string, Preset> = loadAbandonmentPresets();

lib/config/presets/internal/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const presets: Record<string, Preset> = {
1212
'helpers:pinGitHubActionDigests',
1313
':configMigration',
1414
':pinDevDependencies',
15+
'abandonments:recommended',
1516
],
1617
},
1718
'js-app': {

lib/config/presets/internal/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Preset, PresetConfig } from '../types';
2+
import * as configAbandonments from './abandonments';
23
import * as configPreset from './config';
34
import * as customManagersPreset from './custom-managers';
45
import * as defaultPreset from './default';
@@ -19,6 +20,7 @@ import * as workaroundsPreset from './workarounds';
1920
/* eslint sort-keys: ["error", "asc", {caseSensitive: false, natural: true}] */
2021

2122
export const groups: Record<string, Record<string, Preset>> = {
23+
abandonments: configAbandonments.presets,
2224
config: configPreset.presets,
2325
customManagers: customManagersPreset.presets,
2426
default: defaultPreset.presets,

lib/config/presets/parse.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export function parsePreset(input: string): ParsedPreset {
5353
return { presetSource, repo: str, presetName: '', params };
5454
}
5555
const presetsPackages = [
56+
'abandonments',
5657
'compatibility',
5758
'config',
5859
'customManagers',

lib/data/abandonments.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"$schema": "../../tools/schemas/abandonments-schema.json",
3+
"npm": {
4+
"@types/*": "eternal",
5+
"lodash": "6 years"
6+
}
7+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "Exceptions for abandoned packages",
4+
"description": "Community-sourced overrides for packages that appear abandoned but are still maintained",
5+
"type": "object",
6+
"properties": {
7+
"$schema": { "type": "string" }
8+
},
9+
"additionalProperties": {
10+
"type": "object",
11+
"additionalProperties": {
12+
"type": "string"
13+
}
14+
}
15+
}

tools/schemas/schema.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,9 @@ export const SourceUrlsSchema = z
6565
$schema: z.string(),
6666
})
6767
.catchall(z.record(z.string(), z.string().url()));
68+
69+
export const AbandonmentsSchema = z
70+
.object({
71+
$schema: z.string(),
72+
})
73+
.catchall(z.record(z.string(), z.string()));

0 commit comments

Comments
 (0)