mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 15:06:27 +00:00
feat(travis): remove supportPolicy (#11176)
This commit is contained in:
parent
edbe6aef5c
commit
123dc4444e
24 changed files with 51 additions and 510 deletions
|
@ -2302,12 +2302,6 @@ This works because Renovate will add a "renovate/stability-days" pending status
|
||||||
|
|
||||||
<!-- markdownlint-enable MD001 -->
|
<!-- markdownlint-enable MD001 -->
|
||||||
|
|
||||||
## supportPolicy
|
|
||||||
|
|
||||||
Language support is limited to those listed below:
|
|
||||||
|
|
||||||
- **Node.js** - [Read our Node.js documentation](https://docs.renovatebot.com/node#configuring-support-policy)
|
|
||||||
|
|
||||||
## suppressNotifications
|
## suppressNotifications
|
||||||
|
|
||||||
Use this field to suppress various types of warnings and other notifications from Renovate.
|
Use this field to suppress various types of warnings and other notifications from Renovate.
|
||||||
|
|
|
@ -17,45 +17,6 @@ Renovate can manage the Node.js version in the following files:
|
||||||
- The [`.nvmrc`](https://github.com/creationix/nvm#nvmrc) file for the [Node Version Manager](https://github.com/creationix/nvm)
|
- The [`.nvmrc`](https://github.com/creationix/nvm#nvmrc) file for the [Node Version Manager](https://github.com/creationix/nvm)
|
||||||
- The [`node_js`](https://docs.travis-ci.com/user/languages/javascript-with-nodejs/#Specifying-Node.js-versions) field in [`.travis.yml`](https://docs.travis-ci.com/user/customizing-the-build/)
|
- The [`node_js`](https://docs.travis-ci.com/user/languages/javascript-with-nodejs/#Specifying-Node.js-versions) field in [`.travis.yml`](https://docs.travis-ci.com/user/customizing-the-build/)
|
||||||
|
|
||||||
## How It Works
|
|
||||||
|
|
||||||
Node.js renovation in `package.json > engines` and in `.nvmrc` is enabled by default, if your existing version is pinned.
|
|
||||||
|
|
||||||
To enable `.travis.yml` renovation, you must:
|
|
||||||
|
|
||||||
1. Enable Travis renovation explicitly by setting the following Renovate configuration: `"travis": { "enabled": true }`
|
|
||||||
1. Optionally, configure a support policy (As documented below)
|
|
||||||
|
|
||||||
When Renovate processes your project's repository it will look for the files listed above and submit a single pull request that upgrades all Node.js versions simultaneously.
|
|
||||||
|
|
||||||
## Configuring Support Policy
|
|
||||||
|
|
||||||
Renovate supports a [`supportPolicy`](./configuration-options.md#supportpolicy) option that can be passed the following values and associated versions (current as of June 2021):
|
|
||||||
|
|
||||||
**Default:** `lts`
|
|
||||||
|
|
||||||
| supportPolicy | versions | description |
|
|
||||||
| ------------- | ---------- | -------------------------------------------------------- |
|
|
||||||
| all | 12, 14, 16 | All releases that have not passed their end date |
|
|
||||||
| lts | 12, 14 | All releases classified as LTS, including in maintenance |
|
|
||||||
| active | 14, 16 | All releases not in maintenance |
|
|
||||||
| lts_active | 14 | All releases both LTS and active |
|
|
||||||
| lts_latest | 14 | The latest LTS release |
|
|
||||||
| current | 16 | The latest release from "all" |
|
|
||||||
|
|
||||||
The version numbers associated with each support policy will be updated as new versions of Node.js are released, moved to LTS or maintenance, etc.
|
|
||||||
|
|
||||||
For example, to instruct Renovate to upgrade your project to the latest [Long-term Support](https://github.com/nodejs/Release#release-plan) release, you can use the following configuration:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"supportPolicy": ["lts_latest"]
|
|
||||||
```
|
|
||||||
|
|
||||||
We recommend that you define this support policy inside the `node` configuration object.
|
|
||||||
This way, it is applied to all Node.js-related files.
|
|
||||||
|
|
||||||
For additional language support see the [`supportPolicy` documentation](./configuration-options.md#supportpolicy).
|
|
||||||
|
|
||||||
## Configuring which version of npm Renovate uses
|
## Configuring which version of npm Renovate uses
|
||||||
|
|
||||||
When `binarySource=docker`, such as in the hosted WhiteSource Renovate App, Renovate will choose and install an `npm` version dynamically.
|
When `binarySource=docker`, such as in the hosted WhiteSource Renovate App, Renovate will choose and install an `npm` version dynamically.
|
||||||
|
|
|
@ -288,9 +288,6 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates node to t
|
||||||
Object {
|
Object {
|
||||||
"node": Object {
|
"node": Object {
|
||||||
"automerge": false,
|
"automerge": false,
|
||||||
"supportPolicy": Array [
|
|
||||||
"lts",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
"travis": Object {
|
"travis": Object {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|
|
@ -1645,15 +1645,6 @@ const options: RenovateOptions[] = [
|
||||||
mergeable: true,
|
mergeable: true,
|
||||||
cli: false,
|
cli: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'supportPolicy',
|
|
||||||
description:
|
|
||||||
'Dependency support policy, e.g. used for LTS vs non-LTS etc (Node only).',
|
|
||||||
type: 'array',
|
|
||||||
subType: 'string',
|
|
||||||
stage: 'package',
|
|
||||||
allowString: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'node',
|
name: 'node',
|
||||||
description: 'Configuration object for Node version renovation.',
|
description: 'Configuration object for Node version renovation.',
|
||||||
|
|
|
@ -12,7 +12,7 @@ import type {
|
||||||
const defaultConfig = getConfig();
|
const defaultConfig = getConfig();
|
||||||
|
|
||||||
interface TestRenovateConfig extends RenovateConfig {
|
interface TestRenovateConfig extends RenovateConfig {
|
||||||
node?: RenovateSharedConfig & { supportPolicy?: unknown };
|
node?: RenovateSharedConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe(getName(), () => {
|
describe(getName(), () => {
|
||||||
|
@ -356,7 +356,6 @@ describe(getName(), () => {
|
||||||
const config: TestRenovateConfig = {
|
const config: TestRenovateConfig = {
|
||||||
node: {
|
node: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
supportPolicy: ['lts'],
|
|
||||||
automerge: 'none' as never,
|
automerge: 'none' as never,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -372,9 +371,6 @@ describe(getName(), () => {
|
||||||
expect((migratedConfig.travis as RenovateSharedConfig).enabled).toBe(
|
expect((migratedConfig.travis as RenovateSharedConfig).enabled).toBe(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
expect(
|
|
||||||
(migratedConfig.node as TestRenovateConfig).supportPolicy
|
|
||||||
).toBeDefined();
|
|
||||||
});
|
});
|
||||||
it('migrates packageFiles', () => {
|
it('migrates packageFiles', () => {
|
||||||
const config: TestRenovateConfig = {
|
const config: TestRenovateConfig = {
|
||||||
|
|
|
@ -32,6 +32,7 @@ const removedOptions = [
|
||||||
'groupPrBody',
|
'groupPrBody',
|
||||||
'statusCheckVerify',
|
'statusCheckVerify',
|
||||||
'lazyGrouping',
|
'lazyGrouping',
|
||||||
|
'supportPolicy',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Returns a migrated config
|
// Returns a migrated config
|
||||||
|
|
|
@ -91,26 +91,6 @@ describe(getName(), () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getPackageUpdates', () => {
|
|
||||||
it('returns null', () => {
|
|
||||||
manager.getManagers().set('dummy', {
|
|
||||||
defaultConfig: {},
|
|
||||||
});
|
|
||||||
expect(manager.getPackageUpdates('unknown', null)).toBeNull();
|
|
||||||
expect(manager.getPackageUpdates('dummy', null)).toBeNull();
|
|
||||||
});
|
|
||||||
it('returns non-null', () => {
|
|
||||||
manager.getManagers().set('dummy', {
|
|
||||||
defaultConfig: {},
|
|
||||||
getPackageUpdates: () => Promise.resolve({ updates: [] }),
|
|
||||||
});
|
|
||||||
expect(manager.getPackageUpdates('dummy', {} as any)).not.toBeNull();
|
|
||||||
});
|
|
||||||
afterEach(() => {
|
|
||||||
manager.getManagers().delete('dummy');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getRangeStrategy', () => {
|
describe('getRangeStrategy', () => {
|
||||||
it('returns null', () => {
|
it('returns null', () => {
|
||||||
manager.getManagers().set('dummy', {
|
manager.getManagers().set('dummy', {
|
||||||
|
|
|
@ -17,8 +17,6 @@ import type {
|
||||||
ExtractConfig,
|
ExtractConfig,
|
||||||
ManagerApi,
|
ManagerApi,
|
||||||
PackageFile,
|
PackageFile,
|
||||||
PackageUpdateConfig,
|
|
||||||
PackageUpdateResult,
|
|
||||||
RangeConfig,
|
RangeConfig,
|
||||||
Result,
|
Result,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
@ -69,17 +67,6 @@ export async function extractAllPackageFiles(
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPackageUpdates(
|
|
||||||
manager: string,
|
|
||||||
config: PackageUpdateConfig
|
|
||||||
): Result<PackageUpdateResult> | null {
|
|
||||||
if (!managers.has(manager)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const m = managers.get(manager);
|
|
||||||
return m.getPackageUpdates ? m.getPackageUpdates(config) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function extractPackageFile(
|
export function extractPackageFile(
|
||||||
manager: string,
|
manager: string,
|
||||||
content: string,
|
content: string,
|
||||||
|
|
|
@ -4,11 +4,16 @@ exports[`manager/travis/extract extractPackageFile() returns results 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"deps": Array [
|
"deps": Array [
|
||||||
Object {
|
Object {
|
||||||
"currentValue": Array [
|
"currentValue": 6,
|
||||||
6,
|
"datasource": "github-tags",
|
||||||
8,
|
|
||||||
],
|
|
||||||
"depName": "node",
|
"depName": "node",
|
||||||
|
"lookupName": "nodejs/node",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"currentValue": 8,
|
||||||
|
"datasource": "github-tags",
|
||||||
|
"depName": "node",
|
||||||
|
"lookupName": "nodejs/node",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`manager/travis/package getPackageUpdates detects pinning 1`] = `
|
|
||||||
Object {
|
|
||||||
"sourceUrl": "https://github.com/nodejs/node",
|
|
||||||
"updates": Array [
|
|
||||||
Object {
|
|
||||||
"isRange": true,
|
|
||||||
"newMajor": 14,
|
|
||||||
"newValue": "10.0.1,12.3.0,null",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`manager/travis/package getPackageUpdates returns result if needing updates 1`] = `
|
|
||||||
Object {
|
|
||||||
"sourceUrl": "https://github.com/nodejs/node",
|
|
||||||
"updates": Array [
|
|
||||||
Object {
|
|
||||||
"isRange": true,
|
|
||||||
"newMajor": 14,
|
|
||||||
"newValue": "10,12,14",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
`;
|
|
|
@ -1,34 +0,0 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`manager/travis/update updateDependency falls back to 2 spaces 1`] = `"hello: world"`;
|
|
||||||
|
|
||||||
exports[`manager/travis/update updateDependency updates values 1`] = `
|
|
||||||
"dist: trusty
|
|
||||||
language: node_js
|
|
||||||
node_js:
|
|
||||||
- '6'
|
|
||||||
- '8'
|
|
||||||
services:
|
|
||||||
- redis-server
|
|
||||||
- mongodb
|
|
||||||
- mysql
|
|
||||||
addons:
|
|
||||||
postgresql: '9.5'
|
|
||||||
before_script:
|
|
||||||
- psql -c 'create database keyv_test;' -U postgres
|
|
||||||
- mysql -u root -e 'CREATE DATABASE keyv_test;'
|
|
||||||
- mysql -u root -e 'GRANT ALL PRIVILEGES ON keyv_test.* TO 'mysql'@'localhost';'
|
|
||||||
script: npm run test:full
|
|
||||||
after_success: npm run coverage
|
|
||||||
notifications:
|
|
||||||
email:
|
|
||||||
on_success: never
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`manager/travis/update updateDependency uses double quotes 1`] = `
|
|
||||||
"node_js:
|
|
||||||
- \\"6\\"
|
|
||||||
- \\"8\\"
|
|
||||||
"
|
|
||||||
`;
|
|
|
@ -12,7 +12,7 @@ describe(getName(), () => {
|
||||||
it('returns results', () => {
|
it('returns results', () => {
|
||||||
const res = extractPackageFile('node_js:\n - 6\n - 8\n');
|
const res = extractPackageFile('node_js:\n - 6\n - 8\n');
|
||||||
expect(res).toMatchSnapshot();
|
expect(res).toMatchSnapshot();
|
||||||
expect(res.deps).toHaveLength(1);
|
expect(res.deps).toHaveLength(2);
|
||||||
});
|
});
|
||||||
it('should handle invalid YAML', () => {
|
it('should handle invalid YAML', () => {
|
||||||
const res = extractPackageFile(invalidYAML);
|
const res = extractPackageFile(invalidYAML);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import is from '@sindresorhus/is';
|
import is from '@sindresorhus/is';
|
||||||
import { load } from 'js-yaml';
|
import { load } from 'js-yaml';
|
||||||
|
import * as datasourceGithubTags from '../../datasource/github-tags';
|
||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
import type { PackageDependency, PackageFile } from '../types';
|
import type { PackageDependency, PackageFile } from '../types';
|
||||||
|
|
||||||
|
@ -14,12 +15,12 @@ export function extractPackageFile(content: string): PackageFile | null {
|
||||||
}
|
}
|
||||||
let deps: PackageDependency[] = [];
|
let deps: PackageDependency[] = [];
|
||||||
if (doc && is.array(doc.node_js)) {
|
if (doc && is.array(doc.node_js)) {
|
||||||
deps = [
|
deps = doc.node_js.map((currentValue) => ({
|
||||||
{
|
|
||||||
depName: 'node',
|
depName: 'node',
|
||||||
currentValue: doc.node_js,
|
datasource: datasourceGithubTags.id,
|
||||||
},
|
lookupName: 'nodejs/node',
|
||||||
];
|
currentValue,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
if (!deps.length) {
|
if (!deps.length) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -2,12 +2,13 @@ import { LANGUAGE_NODE } from '../../constants/languages';
|
||||||
import * as nodeVersioning from '../../versioning/node';
|
import * as nodeVersioning from '../../versioning/node';
|
||||||
|
|
||||||
export { extractPackageFile } from './extract';
|
export { extractPackageFile } from './extract';
|
||||||
export { getPackageUpdates } from './package';
|
|
||||||
export { updateDependency } from './update';
|
|
||||||
|
|
||||||
export const language = LANGUAGE_NODE;
|
export const language = LANGUAGE_NODE;
|
||||||
|
|
||||||
export const defaultConfig = {
|
export const defaultConfig = {
|
||||||
fileMatch: ['^.travis.yml$'],
|
fileMatch: ['^.travis.yml$'],
|
||||||
|
major: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
versioning: nodeVersioning.id,
|
versioning: nodeVersioning.id,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
import { getName } from '../../../test/util';
|
|
||||||
import { getConfig } from '../../config/defaults';
|
|
||||||
import { getPkgReleases as _getPkgReleases } from '../../datasource';
|
|
||||||
import { getPackageUpdates } from './package';
|
|
||||||
|
|
||||||
const defaultConfig = getConfig();
|
|
||||||
const getPkgReleases: any = _getPkgReleases;
|
|
||||||
|
|
||||||
jest.mock('../../datasource');
|
|
||||||
|
|
||||||
describe(getName(), () => {
|
|
||||||
describe('getPackageUpdates', () => {
|
|
||||||
let config: any;
|
|
||||||
const RealDate = Date;
|
|
||||||
|
|
||||||
beforeAll(() => {
|
|
||||||
global.Date = class FakeDate extends RealDate {
|
|
||||||
constructor(arg?: number | string | Date) {
|
|
||||||
super(arg ?? '2020-10-28');
|
|
||||||
}
|
|
||||||
} as any;
|
|
||||||
});
|
|
||||||
afterAll(() => {
|
|
||||||
global.Date = RealDate;
|
|
||||||
});
|
|
||||||
beforeEach(() => {
|
|
||||||
config = {
|
|
||||||
...defaultConfig,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
it('returns empty if missing supportPolicy', async () => {
|
|
||||||
config.currentValue = ['6', '8'];
|
|
||||||
expect(await getPackageUpdates(config)).toEqual({ updates: [] });
|
|
||||||
});
|
|
||||||
it('returns empty if invalid supportPolicy', async () => {
|
|
||||||
config.currentValue = ['6', '8'];
|
|
||||||
config.supportPolicy = ['foo'];
|
|
||||||
expect(await getPackageUpdates(config)).toEqual({ updates: [] });
|
|
||||||
});
|
|
||||||
it('returns empty if matching', async () => {
|
|
||||||
config.currentValue = ['12', '14'];
|
|
||||||
config.supportPolicy = ['lts_active'];
|
|
||||||
expect(await getPackageUpdates(config)).toEqual({ updates: [] });
|
|
||||||
});
|
|
||||||
it('returns result if needing updates', async () => {
|
|
||||||
config.currentValue = ['6', '8', '10'];
|
|
||||||
config.supportPolicy = ['lts'];
|
|
||||||
// FIXME: explicit assert condition
|
|
||||||
expect(await getPackageUpdates(config)).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
it('detects pinning', async () => {
|
|
||||||
config.currentValue = ['8.4.0', '10.0.0', '12.0.0'];
|
|
||||||
config.supportPolicy = ['lts'];
|
|
||||||
getPkgReleases.mockReturnValueOnce({
|
|
||||||
releases: [
|
|
||||||
{
|
|
||||||
version: '4.4.4',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
version: '5.5.5',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
version: '6.11.0',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
version: '7.0.0',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
version: '8.9.4',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
version: '9.5.0',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
version: '10.0.1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
version: '12.3.0',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
// FIXME: explicit assert condition
|
|
||||||
expect(await getPackageUpdates(config)).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,62 +0,0 @@
|
||||||
import is from '@sindresorhus/is';
|
|
||||||
import { dequal } from 'dequal';
|
|
||||||
import { getPkgReleases } from '../../datasource';
|
|
||||||
import * as datasourceGithubTags from '../../datasource/github-tags';
|
|
||||||
import { logger } from '../../logger';
|
|
||||||
import { NodeJsPolicies, getPolicies } from '../../versioning/node/schedule';
|
|
||||||
import { getSatisfyingVersion, isVersion } from '../../versioning/semver';
|
|
||||||
import type { PackageUpdateConfig, PackageUpdateResult } from '../types';
|
|
||||||
|
|
||||||
export async function getPackageUpdates(
|
|
||||||
config: PackageUpdateConfig
|
|
||||||
): Promise<PackageUpdateResult> {
|
|
||||||
logger.trace('travis.getPackageUpdates()');
|
|
||||||
const { supportPolicy } = config;
|
|
||||||
if (!supportPolicy?.length) {
|
|
||||||
return { updates: [] };
|
|
||||||
}
|
|
||||||
const policies = getPolicies();
|
|
||||||
for (const policy of supportPolicy) {
|
|
||||||
if (!Object.keys(policies).includes(policy)) {
|
|
||||||
logger.warn({ policy }, `Unknown supportPolicy`);
|
|
||||||
return { updates: [] };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.debug({ supportPolicy }, `supportPolicy`);
|
|
||||||
let newValue: any[] = (supportPolicy as (keyof NodeJsPolicies)[])
|
|
||||||
.map((policy) => policies[policy])
|
|
||||||
.reduce((result, policy) => result.concat(policy), [])
|
|
||||||
.sort((a, b) => a - b);
|
|
||||||
const newMajor: number = newValue[newValue.length - 1];
|
|
||||||
if (config.rangeStrategy === 'pin' || isVersion(config.currentValue[0])) {
|
|
||||||
const versions = (
|
|
||||||
await getPkgReleases({
|
|
||||||
...config,
|
|
||||||
datasource: datasourceGithubTags.id,
|
|
||||||
depName: 'nodejs/node',
|
|
||||||
})
|
|
||||||
).releases.map((release) => release.version);
|
|
||||||
newValue = newValue
|
|
||||||
.map(String)
|
|
||||||
.map((value) => getSatisfyingVersion(versions, value));
|
|
||||||
}
|
|
||||||
if (is.string(config.currentValue[0])) {
|
|
||||||
newValue = newValue.map(String);
|
|
||||||
}
|
|
||||||
newValue.sort((a, b) => a - b);
|
|
||||||
|
|
||||||
(config.currentValue as any).sort((a, b) => a - b);
|
|
||||||
if (dequal(config.currentValue, newValue)) {
|
|
||||||
return { updates: [] };
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
sourceUrl: 'https://github.com/nodejs/node',
|
|
||||||
updates: [
|
|
||||||
{
|
|
||||||
newValue: newValue.join(','),
|
|
||||||
newMajor,
|
|
||||||
isRange: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1 +1,28 @@
|
||||||
This manager is intended to keep Travis config files (`.travis.yml`) up-to-date. Currently it manages only the `node_js` section of files only.
|
This manager is intended to keep Travis config files (`.travis.yml`) up-to-date.
|
||||||
|
Currently it manages only the `node_js` section of files only.
|
||||||
|
|
||||||
|
An important limitation is that Renovate does not currently "understand" Travis's node matrix concept, so it will try to update all found node versions to the latest LTS, e.g.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
node_js:
|
||||||
|
- - 8.10.0
|
||||||
|
- - 10.10.0
|
||||||
|
+ - 14.17.4
|
||||||
|
+ - 14.17.4
|
||||||
|
```
|
||||||
|
|
||||||
|
Due to this, major updates for Travis are disabled by default.
|
||||||
|
If you enable major updates and use a version matrix, then you will likely need to manually fix any major update PRs raised by Renovate.
|
||||||
|
Here's how to enable major updates in your Renovate config:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"travis": {
|
||||||
|
"major": {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you would like to see "build matrix" support in future, please contribute ideas to [issue #11175](https://github.com/renovatebot/renovate/issues/11175).
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
import { getName, loadFixture } from '../../../test/util';
|
|
||||||
import { updateDependency } from './update';
|
|
||||||
|
|
||||||
const content = loadFixture('travis.yml');
|
|
||||||
|
|
||||||
describe(getName(), () => {
|
|
||||||
describe('updateDependency', () => {
|
|
||||||
it('updates values', () => {
|
|
||||||
const upgrade: any = {
|
|
||||||
currentValue: ['8', '6', '4'],
|
|
||||||
newValue: '6,8',
|
|
||||||
};
|
|
||||||
const res = updateDependency({ fileContent: content, upgrade });
|
|
||||||
// FIXME: explicit assert condition
|
|
||||||
expect(res).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
it('falls back to 2 spaces', () => {
|
|
||||||
const upgrade: any = {
|
|
||||||
currentValue: [8, 6, 4],
|
|
||||||
newValue: '6,8',
|
|
||||||
};
|
|
||||||
const res = updateDependency({
|
|
||||||
fileContent: 'hello: world',
|
|
||||||
upgrade,
|
|
||||||
});
|
|
||||||
// FIXME: explicit assert condition
|
|
||||||
expect(res).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
it('uses double quotes', () => {
|
|
||||||
const upgrade: any = {
|
|
||||||
currentValue: ['6'],
|
|
||||||
newValue: '6,8',
|
|
||||||
};
|
|
||||||
const res = updateDependency({
|
|
||||||
fileContent: 'node_js:\n - "6"\n',
|
|
||||||
upgrade,
|
|
||||||
});
|
|
||||||
// FIXME: explicit assert condition
|
|
||||||
expect(res).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
it('returns null if error', () => {
|
|
||||||
const upgrade: any = {
|
|
||||||
currentValue: [8, 6, 4],
|
|
||||||
newValue: 6,
|
|
||||||
};
|
|
||||||
const res = updateDependency({ fileContent: content, upgrade });
|
|
||||||
expect(res).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,31 +0,0 @@
|
||||||
import is from '@sindresorhus/is';
|
|
||||||
import detectIndent from 'detect-indent';
|
|
||||||
import { logger } from '../../logger';
|
|
||||||
import type { UpdateDependencyConfig } from '../types';
|
|
||||||
|
|
||||||
export function updateDependency({
|
|
||||||
fileContent,
|
|
||||||
upgrade,
|
|
||||||
}: UpdateDependencyConfig): string | null {
|
|
||||||
try {
|
|
||||||
logger.debug(`travis.updateDependency(): ${upgrade.newValue}`);
|
|
||||||
const indent = detectIndent(fileContent).indent || ' ';
|
|
||||||
let quote: string;
|
|
||||||
if (is.string(upgrade.currentValue[0])) {
|
|
||||||
quote =
|
|
||||||
fileContent.split(`'`).length > fileContent.split(`"`).length
|
|
||||||
? `'`
|
|
||||||
: `"`;
|
|
||||||
} else {
|
|
||||||
quote = '';
|
|
||||||
}
|
|
||||||
let newString = `node_js:\n`;
|
|
||||||
upgrade.newValue.split(',').forEach((version) => {
|
|
||||||
newString += `${indent}- ${quote}${version}${quote}\n`;
|
|
||||||
});
|
|
||||||
return fileContent.replace(/node_js:(\n\s+-[^\n]+)+\n/, newString);
|
|
||||||
} catch (err) {
|
|
||||||
logger.debug({ err }, 'Error setting new .travis.yml node versions');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -50,17 +50,6 @@ export interface UpdateArtifactsConfig extends ManagerConfig {
|
||||||
newMajor?: number;
|
newMajor?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PackageUpdateConfig {
|
|
||||||
currentValue?: string;
|
|
||||||
rangeStrategy?: RangeStrategy;
|
|
||||||
supportPolicy?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PackageUpdateResult {
|
|
||||||
sourceUrl?: string;
|
|
||||||
updates: LookupUpdate[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RangeConfig<T = Record<string, any>> extends ManagerData<T> {
|
export interface RangeConfig<T = Record<string, any>> extends ManagerData<T> {
|
||||||
currentValue?: string;
|
currentValue?: string;
|
||||||
depName?: string;
|
depName?: string;
|
||||||
|
@ -253,8 +242,6 @@ export interface ManagerApi {
|
||||||
config?: ExtractConfig
|
config?: ExtractConfig
|
||||||
): Result<PackageFile | null>;
|
): Result<PackageFile | null>;
|
||||||
|
|
||||||
getPackageUpdates?(config: PackageUpdateConfig): Result<PackageUpdateResult>;
|
|
||||||
|
|
||||||
getRangeStrategy?(config: RangeConfig): RangeStrategy;
|
getRangeStrategy?(config: RangeConfig): RangeStrategy;
|
||||||
|
|
||||||
updateArtifacts?(
|
updateArtifacts?(
|
||||||
|
|
|
@ -13,49 +13,3 @@ export type NodeJsData = Record<string, NodeJsSchedule>;
|
||||||
export const nodeSchedule: NodeJsData = JSON.parse(
|
export const nodeSchedule: NodeJsData = JSON.parse(
|
||||||
dataFiles.get('data/node-js-schedule.json')
|
dataFiles.get('data/node-js-schedule.json')
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface NodeJsPolicies {
|
|
||||||
all: number[];
|
|
||||||
lts: number[];
|
|
||||||
active: number[];
|
|
||||||
lts_active: number[];
|
|
||||||
lts_latest: number[];
|
|
||||||
current: number[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getPolicies(): NodeJsPolicies {
|
|
||||||
const policies = {
|
|
||||||
all: [],
|
|
||||||
lts: [],
|
|
||||||
active: [],
|
|
||||||
lts_active: [],
|
|
||||||
lts_latest: [],
|
|
||||||
current: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
|
|
||||||
for (const [vRelease, data] of Object.entries(nodeSchedule)) {
|
|
||||||
const isAlive = new Date(data.start) < now && new Date(data.end) > now;
|
|
||||||
if (isAlive) {
|
|
||||||
const release = parseInt(vRelease.replace(/^v/, ''), 10);
|
|
||||||
policies.all.push(release);
|
|
||||||
const isMaintenance =
|
|
||||||
data.maintenance && new Date(data.maintenance) < now;
|
|
||||||
if (!isMaintenance) {
|
|
||||||
policies.active.push(release);
|
|
||||||
}
|
|
||||||
const isLts = data.lts && new Date(data.lts) < now;
|
|
||||||
if (isLts) {
|
|
||||||
policies.lts.push(release);
|
|
||||||
if (!isMaintenance) {
|
|
||||||
policies.lts_active.push(release);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
policies.current.push(policies.active[policies.active.length - 1]);
|
|
||||||
policies.lts_latest.push(policies.lts[policies.lts.length - 1]);
|
|
||||||
|
|
||||||
return policies;
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,30 +17,6 @@ Object {
|
||||||
"packageFile": "pom.xml",
|
"packageFile": "pom.xml",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"npm": Array [
|
|
||||||
Object {
|
|
||||||
"deps": Array [
|
|
||||||
Object {
|
|
||||||
"datasource": "npm",
|
|
||||||
"depName": "aaa",
|
|
||||||
"depType": "devDependencies",
|
|
||||||
"updates": Array [
|
|
||||||
"a",
|
|
||||||
"b",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"0": "a",
|
|
||||||
"1": "b",
|
|
||||||
"depName": "bbb",
|
|
||||||
"depType": "dependencies",
|
|
||||||
"updates": Array [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"packageFile": "package.json",
|
|
||||||
"packageJsonType": "app",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,10 @@ import {
|
||||||
mocked,
|
mocked,
|
||||||
} from '../../../../test/util';
|
} from '../../../../test/util';
|
||||||
import * as datasourceMaven from '../../../datasource/maven';
|
import * as datasourceMaven from '../../../datasource/maven';
|
||||||
import * as datasourceNpm from '../../../datasource/npm';
|
import type { PackageFile } from '../../../manager/types';
|
||||||
import * as _npm from '../../../manager/npm';
|
|
||||||
import type { ManagerApi, PackageFile } from '../../../manager/types';
|
|
||||||
import { fetchUpdates } from './fetch';
|
import { fetchUpdates } from './fetch';
|
||||||
import * as lookup from './lookup';
|
import * as lookup from './lookup';
|
||||||
|
|
||||||
const npm: ManagerApi = _npm;
|
|
||||||
const lookupUpdates = mocked(lookup).lookupUpdates;
|
const lookupUpdates = mocked(lookup).lookupUpdates;
|
||||||
|
|
||||||
jest.mock('./lookup');
|
jest.mock('./lookup');
|
||||||
|
@ -67,28 +64,10 @@ describe(getName(), () => {
|
||||||
deps: [{ datasource: datasourceMaven.id, depName: 'bbb' }],
|
deps: [{ datasource: datasourceMaven.id, depName: 'bbb' }],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
npm: [
|
|
||||||
{
|
|
||||||
packageFile: 'package.json',
|
|
||||||
packageJsonType: 'app',
|
|
||||||
deps: [
|
|
||||||
{
|
|
||||||
datasource: datasourceNpm.id,
|
|
||||||
depName: 'aaa',
|
|
||||||
depType: 'devDependencies',
|
|
||||||
},
|
|
||||||
{ depName: 'bbb', depType: 'dependencies' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
// TODO: fix types
|
|
||||||
npm.getPackageUpdates = jest.fn((_) => ['a', 'b'] as never);
|
|
||||||
lookupUpdates.mockResolvedValue({ updates: ['a', 'b'] } as never);
|
lookupUpdates.mockResolvedValue({ updates: ['a', 'b'] } as never);
|
||||||
await fetchUpdates(config, packageFiles);
|
await fetchUpdates(config, packageFiles);
|
||||||
expect(packageFiles).toMatchSnapshot();
|
expect(packageFiles).toMatchSnapshot();
|
||||||
expect(packageFiles.npm[0].deps[0].skipReason).toBeUndefined();
|
|
||||||
expect(packageFiles.npm[0].deps[0].updates).toHaveLength(2);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { getManagerConfig, mergeChildConfig } from '../../../config';
|
||||||
import type { ManagerConfig, RenovateConfig } from '../../../config/types';
|
import type { ManagerConfig, RenovateConfig } from '../../../config/types';
|
||||||
import { getDefaultConfig } from '../../../datasource';
|
import { getDefaultConfig } from '../../../datasource';
|
||||||
import { logger } from '../../../logger';
|
import { logger } from '../../../logger';
|
||||||
import { getPackageUpdates } from '../../../manager';
|
|
||||||
import type { PackageDependency, PackageFile } from '../../../manager/types';
|
import type { PackageDependency, PackageFile } from '../../../manager/types';
|
||||||
import { SkipReason } from '../../../types';
|
import { SkipReason } from '../../../types';
|
||||||
import { clone } from '../../../util/clone';
|
import { clone } from '../../../util/clone';
|
||||||
|
@ -38,11 +37,6 @@ async function fetchDepUpdates(
|
||||||
...dep,
|
...dep,
|
||||||
...(await lookupUpdates(depConfig as LookupUpdateConfig)),
|
...(await lookupUpdates(depConfig as LookupUpdateConfig)),
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
dep = {
|
|
||||||
...dep,
|
|
||||||
...(await getPackageUpdates(packageFileConfig.manager, depConfig)),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
dep.updates = dep.updates || [];
|
dep.updates = dep.updates || [];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue