diff --git a/lib/manager/travis/__fixtures__/matrix_alias.yml b/lib/manager/travis/__fixtures__/matrix_alias.yml new file mode 100644 index 0000000000000000000000000000000000000000..0ec43788f5c796051cbb957450b54f0423e8cab8 --- /dev/null +++ b/lib/manager/travis/__fixtures__/matrix_alias.yml @@ -0,0 +1,5 @@ +matrix: + include: + - env: js-tests + language: node_js + node_js: '11.10.1' diff --git a/lib/manager/travis/__fixtures__/matrix_invalid.yml b/lib/manager/travis/__fixtures__/matrix_invalid.yml new file mode 100644 index 0000000000000000000000000000000000000000..a13a252e2731aa50d5f1f4d5a49f99f4d0d09483 --- /dev/null +++ b/lib/manager/travis/__fixtures__/matrix_invalid.yml @@ -0,0 +1,4 @@ +jobs: + include: + - invalid: '1.0' + diff --git a/lib/manager/travis/__fixtures__/matrix_jobs.yml b/lib/manager/travis/__fixtures__/matrix_jobs.yml new file mode 100644 index 0000000000000000000000000000000000000000..62139533e2b837688301bc15c876ed018ba68985 --- /dev/null +++ b/lib/manager/travis/__fixtures__/matrix_jobs.yml @@ -0,0 +1,5 @@ +jobs: + include: + - env: js-tests + language: node_js + node_js: '11.10.1' diff --git a/lib/manager/travis/__fixtures__/matrix_jobs_array.yml b/lib/manager/travis/__fixtures__/matrix_jobs_array.yml new file mode 100644 index 0000000000000000000000000000000000000000..c379d5a128d2af2246c985694f9c10062cbcf197 --- /dev/null +++ b/lib/manager/travis/__fixtures__/matrix_jobs_array.yml @@ -0,0 +1,5 @@ +jobs: + include: + - env: js-tests + language: node_js + node_js: ['11.10.1', '11.10.2'] diff --git a/lib/manager/travis/__fixtures__/matrix_jobs_array2.yml b/lib/manager/travis/__fixtures__/matrix_jobs_array2.yml new file mode 100644 index 0000000000000000000000000000000000000000..58b70eff6dbc1ad621838b0d5327261ce6e930e3 --- /dev/null +++ b/lib/manager/travis/__fixtures__/matrix_jobs_array2.yml @@ -0,0 +1,7 @@ +jobs: + include: + - env: js-tests + language: node_js + node_js: + - '11.10.1' + - '11.10.2' diff --git a/lib/manager/travis/extract.spec.ts b/lib/manager/travis/extract.spec.ts index abeb3a98e46a473838da30f15c4673ee47f28da9..1488759e584341db42ed4629f34e9bc2974d2cb3 100644 --- a/lib/manager/travis/extract.spec.ts +++ b/lib/manager/travis/extract.spec.ts @@ -1,7 +1,12 @@ import { loadFixture } from '../../../test/util'; -import { extractPackageFile } from './extract'; +import { extractPackageFile } from '.'; const invalidYAML = loadFixture('invalid.yml'); +const matrixYAMLwithNodeSyntaxString = loadFixture('matrix_jobs.yml'); +const matrixYAMLwithNodeSyntaxArray = loadFixture('matrix_jobs_array.yml'); +const matrixYAMLwithNodeSyntaxArray2 = loadFixture('matrix_jobs_array2.yml'); +const matrixYAMLwithNodeSyntaxAlias = loadFixture('matrix_alias.yml'); +const invalidMatrixYAML = loadFixture('matrix_invalid.yml'); describe('manager/travis/extract', () => { describe('extractPackageFile()', () => { @@ -9,14 +14,89 @@ describe('manager/travis/extract', () => { const res = extractPackageFile('blahhhhh:foo:@what\n'); expect(res).toBeNull(); }); + it('returns results', () => { const res = extractPackageFile('node_js:\n - 6\n - 8\n'); expect(res).toMatchSnapshot(); expect(res.deps).toHaveLength(2); }); + it('should handle invalid YAML', () => { const res = extractPackageFile(invalidYAML); expect(res).toBeNull(); }); + + it('handles matrix node_js syntax with node_js string', () => { + const res = extractPackageFile(matrixYAMLwithNodeSyntaxString); + expect(res).toEqual({ + deps: [ + { + currentValue: '11.10.1', + datasource: 'github-tags', + depName: 'node', + lookupName: 'nodejs/node', + }, + ], + }); + }); + + it('handles matrix node_js syntax with node_js array', () => { + const res = extractPackageFile(matrixYAMLwithNodeSyntaxArray); + expect(res).toEqual({ + deps: [ + { + currentValue: '11.10.1', + datasource: 'github-tags', + depName: 'node', + lookupName: 'nodejs/node', + }, + { + currentValue: '11.10.2', + datasource: 'github-tags', + depName: 'node', + lookupName: 'nodejs/node', + }, + ], + }); + }); + + it('handles matrix node_js syntax with node_js array 2', () => { + const res = extractPackageFile(matrixYAMLwithNodeSyntaxArray2); + expect(res).toEqual({ + deps: [ + { + currentValue: '11.10.1', + datasource: 'github-tags', + depName: 'node', + lookupName: 'nodejs/node', + }, + { + currentValue: '11.10.2', + datasource: 'github-tags', + depName: 'node', + lookupName: 'nodejs/node', + }, + ], + }); + }); + + it('handles matrix node_js syntax with alias', () => { + const res = extractPackageFile(matrixYAMLwithNodeSyntaxAlias); + expect(res).toEqual({ + deps: [ + { + currentValue: '11.10.1', + datasource: 'github-tags', + depName: 'node', + lookupName: 'nodejs/node', + }, + ], + }); + }); + + it('handles invalid matrix node_js syntax', () => { + const res = extractPackageFile(invalidMatrixYAML); + expect(res).toBeNull(); + }); }); }); diff --git a/lib/manager/travis/extract.ts b/lib/manager/travis/extract.ts index 58ffe64021f2364037a836fc63b877aa39669178..c50ad28bf022027067310a10fc2893e5afe0d2b7 100644 --- a/lib/manager/travis/extract.ts +++ b/lib/manager/travis/extract.ts @@ -3,12 +3,14 @@ import { load } from 'js-yaml'; import * as datasourceGithubTags from '../../datasource/github-tags'; import { logger } from '../../logger'; import type { PackageDependency, PackageFile } from '../types'; +import type { TravisMatrixItem, TravisYaml } from './types'; export function extractPackageFile(content: string): PackageFile | null { - // TODO: fix type - let doc: any; + let doc: TravisYaml | null; try { - doc = load(content, { json: true }); + doc = load(content, { + json: true, + }); } catch (err) { logger.warn({ err, content }, 'Failed to parse .travis.yml file.'); return null; @@ -22,6 +24,41 @@ export function extractPackageFile(content: string): PackageFile | null { currentValue: currentValue.toString(), })); } + + // Handle the matrix syntax + let matrix_include: TravisMatrixItem[] | undefined; + if (doc?.jobs?.include) { + matrix_include = doc.jobs.include; + } else if (doc?.matrix?.include) { + matrix_include = doc.matrix.include; + } + + if (!is.array(matrix_include)) { + return deps.length ? { deps } : null; + } + + for (const item of matrix_include) { + if (item?.node_js) { + if (is.array(item.node_js)) { + item.node_js.forEach((currentValue) => { + deps.push({ + depName: 'node', + datasource: datasourceGithubTags.id, + lookupName: 'nodejs/node', + currentValue: currentValue.toString(), + }); + }); + } else if (is.string(item.node_js)) { + deps.push({ + depName: 'node', + datasource: datasourceGithubTags.id, + lookupName: 'nodejs/node', + currentValue: item.node_js.toString(), + }); + } + } + } + if (!deps.length) { return null; } diff --git a/lib/manager/travis/readme.md b/lib/manager/travis/readme.md index fb728f0b74355522eb0fb381e5a90e08e7fa07ac..6e5cbaed906c636858c40d3cc91a1ed790e973ff 100644 --- a/lib/manager/travis/readme.md +++ b/lib/manager/travis/readme.md @@ -1,14 +1,14 @@ This manager is intended to keep Travis config files (`.travis.yml`) up-to-date, this file controls the CI build environment. Currently Renovate can only update the `node_js` section of this file. -An important limitation is that Renovate does not currently "understand" [Travis's Build Matrix concept](https://docs.travis-ci.com/user/build-matrix/#matrix-expansion), so it will try to update all found Node.js versions to the latest LTS, e.g. +Renovate "understands" [Travis's Build Matrix concept](https://docs.travis-ci.com/user/build-matrix/#matrix-expansion) as well, so it will try to update all found Node.js versions to the latest LTS, e.g. ```diff node_js: - - 8.10.0 - - 10.10.0 -+ - 14.17.4 -+ - 14.17.4 ++ - 16.13.0 ++ - 16.13.0 ``` Due to this, major updates for Travis are disabled by default. @@ -24,5 +24,3 @@ Here's how to enable major updates in your Renovate config: } } ``` - -If you would like to see "build matrix" support in future, please contribute ideas to [issue #11175](https://github.com/renovatebot/renovate/issues/11175). diff --git a/lib/manager/travis/types.ts b/lib/manager/travis/types.ts new file mode 100644 index 0000000000000000000000000000000000000000..937eb4ded0b39fb9306689dababe5192e83f1b25 --- /dev/null +++ b/lib/manager/travis/types.ts @@ -0,0 +1,19 @@ +// travis.yml syntax description: +// - regular: https://docs.travis-ci.com/user/tutorial/ +// - matrix: https://docs.travis-ci.com/user/build-matrix/ + +export type TravisNodeJs = string | string[]; + +export interface TravisYaml { + node_js?: TravisNodeJs; + jobs?: TravisMatrix; + matrix?: TravisMatrix; +} + +export interface TravisMatrixItem { + node_js?: TravisNodeJs; +} + +export interface TravisMatrix { + include?: TravisMatrixItem[]; +}