mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 06:56:24 +00:00
parent
83b4bead48
commit
7d4cd7ca60
10 changed files with 594 additions and 33 deletions
|
@ -1,5 +1,6 @@
|
||||||
const { parse } = require('../util/purl');
|
const { parse } = require('../util/purl');
|
||||||
|
|
||||||
|
const orb = require('./orb');
|
||||||
const docker = require('./docker');
|
const docker = require('./docker');
|
||||||
const github = require('./github');
|
const github = require('./github');
|
||||||
const go = require('./go');
|
const go = require('./go');
|
||||||
|
@ -10,6 +11,7 @@ const pypi = require('./pypi');
|
||||||
const terraform = require('./terraform');
|
const terraform = require('./terraform');
|
||||||
|
|
||||||
const datasources = {
|
const datasources = {
|
||||||
|
orb,
|
||||||
docker,
|
docker,
|
||||||
github,
|
github,
|
||||||
go,
|
go,
|
||||||
|
@ -53,6 +55,10 @@ const manualChangelogUrls = {
|
||||||
// Use this object to define manual source URLs for packages
|
// Use this object to define manual source URLs for packages
|
||||||
// Only necessary if the datasource is unable to locate the source URL itself
|
// Only necessary if the datasource is unable to locate the source URL itself
|
||||||
const manualSourceUrls = {
|
const manualSourceUrls = {
|
||||||
|
orb: {
|
||||||
|
'hutson/library-release-workflows':
|
||||||
|
'https://github.com/hyper-expanse/library-release-workflows',
|
||||||
|
},
|
||||||
docker: {
|
docker: {
|
||||||
node: 'https://github.com/nodejs/node',
|
node: 'https://github.com/nodejs/node',
|
||||||
},
|
},
|
||||||
|
|
69
lib/datasource/orb.js
Normal file
69
lib/datasource/orb.js
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
const got = require('got');
|
||||||
|
const { isVersion, sortVersions } = require('../versioning/semver');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getPkgReleases,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* orb.getPkgReleases
|
||||||
|
*
|
||||||
|
* This function will fetch an orb from CircleCI and return all semver versions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
async function getPkgReleases(purl) {
|
||||||
|
const { fullname: dependency } = purl;
|
||||||
|
logger.debug({ dependency }, 'orb.getPkgReleases()');
|
||||||
|
const cacheNamespace = 'orb';
|
||||||
|
const cacheKey = dependency;
|
||||||
|
const cachedResult = await renovateCache.get(cacheNamespace, cacheKey);
|
||||||
|
// istanbul ignore if
|
||||||
|
if (cachedResult) {
|
||||||
|
return cachedResult;
|
||||||
|
}
|
||||||
|
const url = 'https://circleci.com/graphql-unstable';
|
||||||
|
const body = {
|
||||||
|
query: `{orb(name:"${dependency}"){name, homeUrl, versions {version, createdAt}}}`,
|
||||||
|
variables: {},
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const res = (await got.post(url, {
|
||||||
|
body,
|
||||||
|
json: true,
|
||||||
|
retry: 5,
|
||||||
|
})).body.data.orb;
|
||||||
|
// Simplify response before caching and returning
|
||||||
|
const dep = {
|
||||||
|
name: dependency,
|
||||||
|
versions: {},
|
||||||
|
};
|
||||||
|
if (res.homeUrl && res.homeUrl.length) {
|
||||||
|
dep.homepage = res.homeUrl;
|
||||||
|
}
|
||||||
|
dep.homepage =
|
||||||
|
dep.homepage || `https://circleci.com/orbs/registry/orb/${dependency}`;
|
||||||
|
dep.releases = res.versions.map(v => v.version);
|
||||||
|
dep.releases = dep.releases.filter(v => isVersion(v));
|
||||||
|
dep.releases = dep.releases.sort(sortVersions);
|
||||||
|
dep.releases = dep.releases.map(version => ({
|
||||||
|
version,
|
||||||
|
}));
|
||||||
|
logger.trace({ dep }, 'dep');
|
||||||
|
const cacheMinutes = 30;
|
||||||
|
await renovateCache.set(cacheNamespace, cacheKey, dep, cacheMinutes);
|
||||||
|
return dep;
|
||||||
|
} catch (err) /* istanbul ignore next */ {
|
||||||
|
if (err.statusCode === 404 || err.code === 'ENOTFOUND') {
|
||||||
|
logger.info({ dependency }, `CircleCI Orb lookup failure: not found`);
|
||||||
|
logger.debug({
|
||||||
|
err,
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
logger.warn(
|
||||||
|
{ err, dependency },
|
||||||
|
'CircleCI Orb lookup failure: Unknown error'
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,27 +5,63 @@ module.exports = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function extractPackageFile(content) {
|
function extractPackageFile(content) {
|
||||||
logger.debug('circleci.extractPackageFile()');
|
|
||||||
const deps = [];
|
const deps = [];
|
||||||
let lineNumber = 0;
|
try {
|
||||||
for (const line of content.split('\n')) {
|
const lines = content.split('\n');
|
||||||
const match = line.match(/^\s*- image:\s*'?"?([^\s'"]+)'?"?\s*$/);
|
for (let lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {
|
||||||
if (match) {
|
const line = lines[lineNumber];
|
||||||
const currentFrom = match[1];
|
const orbs = line.match(/^\s*orbs:\s*$/);
|
||||||
const dep = getDep(currentFrom);
|
if (orbs) {
|
||||||
logger.debug(
|
logger.trace(`Matched orbs on line ${lineNumber}`);
|
||||||
{
|
let foundOrb;
|
||||||
dockerRegistry: dep.dockerRegistry,
|
do {
|
||||||
depName: dep.depName,
|
foundOrb = false;
|
||||||
currentValue: dep.currentValue,
|
const orbLine = lines[lineNumber + 1];
|
||||||
currentDigest: dep.currentDigest,
|
logger.trace(`orbLine: "${orbLine}"`);
|
||||||
},
|
const orbMatch = orbLine.match(/^\s+([^:]+):\s(.+)$/);
|
||||||
'CircleCI docker image'
|
if (orbMatch) {
|
||||||
);
|
logger.trace('orbMatch');
|
||||||
dep.lineNumber = lineNumber;
|
foundOrb = true;
|
||||||
deps.push(dep);
|
lineNumber += 1;
|
||||||
|
const depName = orbMatch[1];
|
||||||
|
const [orbName, currentValue] = orbMatch[2].split('@');
|
||||||
|
const dep = {
|
||||||
|
depType: 'orb',
|
||||||
|
depName,
|
||||||
|
currentValue,
|
||||||
|
lineNumber,
|
||||||
|
purl: 'pkg:orb/' + orbName,
|
||||||
|
commitMessageTopic: '{{{depName}}} orb',
|
||||||
|
versionScheme: 'semver',
|
||||||
|
rangeStrategy: 'pin',
|
||||||
|
};
|
||||||
|
deps.push(dep);
|
||||||
|
}
|
||||||
|
} while (foundOrb);
|
||||||
|
}
|
||||||
|
const match = line.match(/^\s*- image:\s*'?"?([^\s'"]+)'?"?\s*$/);
|
||||||
|
if (match) {
|
||||||
|
const currentFrom = match[1];
|
||||||
|
const dep = getDep(currentFrom);
|
||||||
|
logger.debug(
|
||||||
|
{
|
||||||
|
dockerRegistry: dep.dockerRegistry,
|
||||||
|
depName: dep.depName,
|
||||||
|
currentValue: dep.currentValue,
|
||||||
|
currentDigest: dep.currentDigest,
|
||||||
|
},
|
||||||
|
'CircleCI docker image'
|
||||||
|
);
|
||||||
|
dep.depType = 'docker';
|
||||||
|
dep.lineNumber = lineNumber;
|
||||||
|
deps.push(dep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lineNumber += 1;
|
} catch (err) /* istanbul ignore next */ {
|
||||||
|
logger.error(
|
||||||
|
{ err, message: err.message },
|
||||||
|
'Error extracting buildkite plugins'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (!deps.length) {
|
if (!deps.length) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -6,22 +6,40 @@ module.exports = {
|
||||||
|
|
||||||
function updateDependency(fileContent, upgrade) {
|
function updateDependency(fileContent, upgrade) {
|
||||||
try {
|
try {
|
||||||
const newFrom = getNewFrom(upgrade);
|
|
||||||
logger.debug(`circleci.updateDependency(): ${newFrom}`);
|
|
||||||
const lines = fileContent.split('\n');
|
const lines = fileContent.split('\n');
|
||||||
const lineToChange = lines[upgrade.lineNumber];
|
const lineToChange = lines[upgrade.lineNumber];
|
||||||
const imageLine = new RegExp(/^(\s*- image:\s*'?"?)[^\s'"]+('?"?\s*)$/);
|
if (upgrade.depType === 'docker') {
|
||||||
if (!lineToChange.match(imageLine)) {
|
const newFrom = getNewFrom(upgrade);
|
||||||
logger.debug('No image line found');
|
logger.debug(`circleci.updateDependency(): ${newFrom}`);
|
||||||
return null;
|
const imageLine = new RegExp(/^(\s*- image:\s*'?"?)[^\s'"]+('?"?\s*)$/);
|
||||||
|
if (!lineToChange.match(imageLine)) {
|
||||||
|
logger.debug('No image line found');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const newLine = lineToChange.replace(imageLine, `$1${newFrom}$2`);
|
||||||
|
if (newLine === lineToChange) {
|
||||||
|
logger.debug('No changes necessary');
|
||||||
|
return fileContent;
|
||||||
|
}
|
||||||
|
lines[upgrade.lineNumber] = newLine;
|
||||||
|
return lines.join('\n');
|
||||||
}
|
}
|
||||||
const newLine = lineToChange.replace(imageLine, `$1${newFrom}$2`);
|
if (upgrade.depType === 'orb') {
|
||||||
if (newLine === lineToChange) {
|
const orbLine = new RegExp(`^(\\s+${upgrade.depName}:\\s[^@]+@).+$`);
|
||||||
logger.debug('No changes necessary');
|
if (!lineToChange.match(orbLine)) {
|
||||||
return fileContent;
|
logger.debug('No image line found');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const newLine = lineToChange.replace(orbLine, `$1${upgrade.newValue}`);
|
||||||
|
if (newLine === lineToChange) {
|
||||||
|
logger.debug('No changes necessary');
|
||||||
|
return fileContent;
|
||||||
|
}
|
||||||
|
lines[upgrade.lineNumber] = newLine;
|
||||||
|
return lines.join('\n');
|
||||||
}
|
}
|
||||||
lines[upgrade.lineNumber] = newLine;
|
logger.error('Unknown circleci depType');
|
||||||
return lines.join('\n');
|
return null;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.info({ err }, 'Error setting new CircleCI image value');
|
logger.info({ err }, 'Error setting new CircleCI image value');
|
||||||
return null;
|
return null;
|
||||||
|
|
98
test/_fixtures/circleci/config2.yml
Normal file
98
test/_fixtures/circleci/config2.yml
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
version: 2.1
|
||||||
|
|
||||||
|
orbs:
|
||||||
|
release-workflows: hutson/library-release-workflows@4.1.0
|
||||||
|
no-version: abc/def
|
||||||
|
volatile: zzz/zzz@volatile
|
||||||
|
|
||||||
|
test_plan: &test_plan
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run: pip install --no-cache-dir pipenv==2018.11.26
|
||||||
|
- run: pipenv install --dev --python python
|
||||||
|
- run: pipenv run tox
|
||||||
|
|
||||||
|
# TODO: Upload binary distributable to Circle CI using the `Artifact` feature
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
python_3_4_test_plan:
|
||||||
|
<<: [*test_plan]
|
||||||
|
docker:
|
||||||
|
- image: python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077
|
||||||
|
environment:
|
||||||
|
TOXENV: py34
|
||||||
|
|
||||||
|
python_3_5_test_plan:
|
||||||
|
<<: [*test_plan]
|
||||||
|
docker:
|
||||||
|
- image: python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077
|
||||||
|
environment:
|
||||||
|
TOXENV: py35
|
||||||
|
|
||||||
|
python_3_6_test_plan:
|
||||||
|
<<: [*test_plan]
|
||||||
|
docker:
|
||||||
|
- image: python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077
|
||||||
|
environment:
|
||||||
|
TOXENV: py36
|
||||||
|
|
||||||
|
python_3_7_test_plan:
|
||||||
|
<<: [*test_plan]
|
||||||
|
docker:
|
||||||
|
- image: python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077
|
||||||
|
environment:
|
||||||
|
TOXENV: py37
|
||||||
|
|
||||||
|
pypy_3_6_test_plan:
|
||||||
|
# TODO: We do not use this job because, at the time of writing, pipenv has not released a version
|
||||||
|
# with support for pypy - https://github.com/pypa/pipenv/issues/3313
|
||||||
|
<<: [*test_plan]
|
||||||
|
docker:
|
||||||
|
- image: pypy:3-6@sha256:eb6325b75c1c70b4992eaa1bdd29e24e5f14d5324b4714a49f3e67783473214b
|
||||||
|
environment:
|
||||||
|
TOXENV: pypy
|
||||||
|
|
||||||
|
python_lint_test_plan:
|
||||||
|
<<: [*test_plan]
|
||||||
|
docker:
|
||||||
|
- image: python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077
|
||||||
|
environment:
|
||||||
|
TOXENV: lint
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
build_and_test:
|
||||||
|
jobs:
|
||||||
|
- python_3_4_test_plan
|
||||||
|
- python_3_5_test_plan
|
||||||
|
- python_3_6_test_plan
|
||||||
|
- python_3_7_test_plan
|
||||||
|
- python_lint_test_plan
|
||||||
|
- release-workflows/deliver:
|
||||||
|
# TODO: Upload all binary distributables to the GitHub Release page.
|
||||||
|
# TODO: Where do we build and upload the source distributable, `sdist`, for upload to the GitHub Release page?
|
||||||
|
context: github-interaction
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only: master
|
||||||
|
requires:
|
||||||
|
- python_3_4_test_plan
|
||||||
|
- python_3_5_test_plan
|
||||||
|
- python_3_6_test_plan
|
||||||
|
- python_3_7_test_plan
|
||||||
|
- python_lint_test_plan
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
jobs:
|
||||||
|
# TODO: Re-use the build artifacts from the `build_and_test` workflow.
|
||||||
|
- release-workflows/python-deploy:
|
||||||
|
context: pypi-interaction
|
||||||
|
# TODO: Share these `filters` once we can publish workflows in Orbs - https://circleci.ideas.aha.io/ideas/CCI-I-615
|
||||||
|
filters:
|
||||||
|
tags:
|
||||||
|
# Match only semantically valid semver tags - Authored by David Fichtmueller - https://github.com/semver/semver/issues/232#issue-48635632
|
||||||
|
# TODO: Support all PEP440-valid tag names.
|
||||||
|
only: /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$/
|
||||||
|
branches:
|
||||||
|
ignore: /.*/
|
81
test/datasource/__snapshots__/orb.spec.js.snap
Normal file
81
test/datasource/__snapshots__/orb.spec.js.snap
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`datasource/orb getPkgReleases processes homeUrl 1`] = `
|
||||||
|
Object {
|
||||||
|
"homepage": "https://google.com",
|
||||||
|
"name": "hyper-expanse/library-release-workflows",
|
||||||
|
"releases": Array [
|
||||||
|
Object {
|
||||||
|
"version": "3.0.0",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.0.0",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.0",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.1",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.2",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.3",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.4",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.5",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.6",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.2.0",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"versions": Object {},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`datasource/orb getPkgReleases processes real data 1`] = `
|
||||||
|
Object {
|
||||||
|
"homepage": "https://circleci.com/orbs/registry/orb/hyper-expanse/library-release-workflows",
|
||||||
|
"name": "hyper-expanse/library-release-workflows",
|
||||||
|
"releases": Array [
|
||||||
|
Object {
|
||||||
|
"version": "3.0.0",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.0.0",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.0",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.1",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.2",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.3",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.4",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.5",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.1.6",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"version": "4.2.0",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"versions": Object {},
|
||||||
|
}
|
||||||
|
`;
|
85
test/datasource/orb.spec.js
Normal file
85
test/datasource/orb.spec.js
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
const got = require('got');
|
||||||
|
const datasource = require('../../lib/datasource');
|
||||||
|
|
||||||
|
jest.mock('got');
|
||||||
|
|
||||||
|
const orbData = {
|
||||||
|
data: {
|
||||||
|
orb: {
|
||||||
|
name: 'hutson/library-release-workflows',
|
||||||
|
homeUrl: '',
|
||||||
|
versions: [
|
||||||
|
{ version: '4.2.0', createdAt: '2018-12-13T23:19:09.356Z' },
|
||||||
|
{ version: '4.1.6', createdAt: '2018-12-12T18:56:42.563Z' },
|
||||||
|
{ version: '4.1.5', createdAt: '2018-12-12T17:13:31.542Z' },
|
||||||
|
{ version: '4.1.4', createdAt: '2018-12-11T22:13:29.297Z' },
|
||||||
|
{ version: '4.1.3', createdAt: '2018-12-11T21:40:44.870Z' },
|
||||||
|
{ version: '4.1.2', createdAt: '2018-12-11T21:28:37.846Z' },
|
||||||
|
{ version: '4.1.1', createdAt: '2018-12-11T18:24:13.119Z' },
|
||||||
|
{ version: '4.1.0', createdAt: '2018-12-11T18:14:41.116Z' },
|
||||||
|
{ version: '4.0.0', createdAt: '2018-12-11T17:41:26.595Z' },
|
||||||
|
{ version: '3.0.0', createdAt: '2018-12-11T05:28:14.080Z' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('datasource/orb', () => {
|
||||||
|
describe('getPkgReleases', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
return global.renovateCache.rmAll();
|
||||||
|
});
|
||||||
|
it('returns null for empty result', async () => {
|
||||||
|
got.mockReturnValueOnce({ body: {} });
|
||||||
|
expect(
|
||||||
|
await datasource.getPkgReleases(
|
||||||
|
'pkg:orb/hyper-expanse/library-release-workflows'
|
||||||
|
)
|
||||||
|
).toBeNull();
|
||||||
|
});
|
||||||
|
it('returns null for 404', async () => {
|
||||||
|
got.mockImplementationOnce(() =>
|
||||||
|
Promise.reject({
|
||||||
|
statusCode: 404,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
await datasource.getPkgReleases(
|
||||||
|
'pkg:orb/hyper-expanse/library-release-workflows'
|
||||||
|
)
|
||||||
|
).toBeNull();
|
||||||
|
});
|
||||||
|
it('returns null for unknown error', async () => {
|
||||||
|
got.mockImplementationOnce(() => {
|
||||||
|
throw new Error();
|
||||||
|
});
|
||||||
|
expect(
|
||||||
|
await datasource.getPkgReleases(
|
||||||
|
'pkg:orb/hyper-expanse/library-release-workflows'
|
||||||
|
)
|
||||||
|
).toBeNull();
|
||||||
|
});
|
||||||
|
it('processes real data', async () => {
|
||||||
|
got.post.mockReturnValueOnce({
|
||||||
|
body: orbData,
|
||||||
|
});
|
||||||
|
const res = await datasource.getPkgReleases(
|
||||||
|
'pkg:orb/hyper-expanse/library-release-workflows'
|
||||||
|
);
|
||||||
|
expect(res).toMatchSnapshot();
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
});
|
||||||
|
it('processes homeUrl', async () => {
|
||||||
|
orbData.data.orb.homeUrl = 'https://google.com';
|
||||||
|
got.post.mockReturnValueOnce({
|
||||||
|
body: orbData,
|
||||||
|
});
|
||||||
|
const res = await datasource.getPkgReleases(
|
||||||
|
'pkg:orb/hyper-expanse/library-release-workflows'
|
||||||
|
);
|
||||||
|
expect(res).toMatchSnapshot();
|
||||||
|
expect(res.homepage).toEqual('https://google.com');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -10,6 +10,7 @@ Array [
|
||||||
"currentFrom": "node",
|
"currentFrom": "node",
|
||||||
"currentValue": undefined,
|
"currentValue": undefined,
|
||||||
"depName": "node",
|
"depName": "node",
|
||||||
|
"depType": "docker",
|
||||||
"dockerRegistry": undefined,
|
"dockerRegistry": undefined,
|
||||||
"lineNumber": 12,
|
"lineNumber": 12,
|
||||||
"purl": "pkg:docker/node",
|
"purl": "pkg:docker/node",
|
||||||
|
@ -22,6 +23,7 @@ Array [
|
||||||
"currentFrom": "node:4",
|
"currentFrom": "node:4",
|
||||||
"currentValue": "4",
|
"currentValue": "4",
|
||||||
"depName": "node",
|
"depName": "node",
|
||||||
|
"depType": "docker",
|
||||||
"dockerRegistry": undefined,
|
"dockerRegistry": undefined,
|
||||||
"lineNumber": 57,
|
"lineNumber": 57,
|
||||||
"purl": "pkg:docker/node",
|
"purl": "pkg:docker/node",
|
||||||
|
@ -34,6 +36,7 @@ Array [
|
||||||
"currentFrom": "node:6",
|
"currentFrom": "node:6",
|
||||||
"currentValue": "6",
|
"currentValue": "6",
|
||||||
"depName": "node",
|
"depName": "node",
|
||||||
|
"depType": "docker",
|
||||||
"dockerRegistry": undefined,
|
"dockerRegistry": undefined,
|
||||||
"lineNumber": 61,
|
"lineNumber": 61,
|
||||||
"purl": "pkg:docker/node",
|
"purl": "pkg:docker/node",
|
||||||
|
@ -46,9 +49,117 @@ Array [
|
||||||
"currentFrom": "node:8.9.0",
|
"currentFrom": "node:8.9.0",
|
||||||
"currentValue": "8.9.0",
|
"currentValue": "8.9.0",
|
||||||
"depName": "node",
|
"depName": "node",
|
||||||
|
"depType": "docker",
|
||||||
"dockerRegistry": undefined,
|
"dockerRegistry": undefined,
|
||||||
"lineNumber": 65,
|
"lineNumber": 65,
|
||||||
"purl": "pkg:docker/node",
|
"purl": "pkg:docker/node",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`lib/manager/circleci/extract extractPackageFile() extracts orbs too 1`] = `
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"commitMessageTopic": "{{{depName}}} orb",
|
||||||
|
"currentValue": "4.1.0",
|
||||||
|
"depName": "release-workflows",
|
||||||
|
"depType": "orb",
|
||||||
|
"lineNumber": 3,
|
||||||
|
"purl": "pkg:orb/hutson/library-release-workflows",
|
||||||
|
"rangeStrategy": "pin",
|
||||||
|
"versionScheme": "semver",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"commitMessageTopic": "{{{depName}}} orb",
|
||||||
|
"currentValue": undefined,
|
||||||
|
"depName": "no-version",
|
||||||
|
"depType": "orb",
|
||||||
|
"lineNumber": 4,
|
||||||
|
"purl": "pkg:orb/abc/def",
|
||||||
|
"rangeStrategy": "pin",
|
||||||
|
"versionScheme": "semver",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"commitMessageTopic": "{{{depName}}} orb",
|
||||||
|
"currentValue": "volatile",
|
||||||
|
"depName": "volatile",
|
||||||
|
"depType": "orb",
|
||||||
|
"lineNumber": 5,
|
||||||
|
"purl": "pkg:orb/zzz/zzz",
|
||||||
|
"rangeStrategy": "pin",
|
||||||
|
"versionScheme": "semver",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"currentDepTag": "python:3.7",
|
||||||
|
"currentDepTagDigest": "python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentDigest": "sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentFrom": "python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentValue": "3.7",
|
||||||
|
"depName": "python",
|
||||||
|
"depType": "docker",
|
||||||
|
"dockerRegistry": undefined,
|
||||||
|
"lineNumber": 20,
|
||||||
|
"purl": "pkg:docker/python",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"currentDepTag": "python:3.7",
|
||||||
|
"currentDepTagDigest": "python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentDigest": "sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentFrom": "python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentValue": "3.7",
|
||||||
|
"depName": "python",
|
||||||
|
"depType": "docker",
|
||||||
|
"dockerRegistry": undefined,
|
||||||
|
"lineNumber": 27,
|
||||||
|
"purl": "pkg:docker/python",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"currentDepTag": "python:3.7",
|
||||||
|
"currentDepTagDigest": "python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentDigest": "sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentFrom": "python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentValue": "3.7",
|
||||||
|
"depName": "python",
|
||||||
|
"depType": "docker",
|
||||||
|
"dockerRegistry": undefined,
|
||||||
|
"lineNumber": 34,
|
||||||
|
"purl": "pkg:docker/python",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"currentDepTag": "python:3.7",
|
||||||
|
"currentDepTagDigest": "python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentDigest": "sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentFrom": "python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentValue": "3.7",
|
||||||
|
"depName": "python",
|
||||||
|
"depType": "docker",
|
||||||
|
"dockerRegistry": undefined,
|
||||||
|
"lineNumber": 41,
|
||||||
|
"purl": "pkg:docker/python",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"currentDepTag": "pypy:3-6",
|
||||||
|
"currentDepTagDigest": "pypy:3-6@sha256:eb6325b75c1c70b4992eaa1bdd29e24e5f14d5324b4714a49f3e67783473214b",
|
||||||
|
"currentDigest": "sha256:eb6325b75c1c70b4992eaa1bdd29e24e5f14d5324b4714a49f3e67783473214b",
|
||||||
|
"currentFrom": "pypy:3-6@sha256:eb6325b75c1c70b4992eaa1bdd29e24e5f14d5324b4714a49f3e67783473214b",
|
||||||
|
"currentValue": "3-6",
|
||||||
|
"depName": "pypy",
|
||||||
|
"depType": "docker",
|
||||||
|
"dockerRegistry": undefined,
|
||||||
|
"lineNumber": 50,
|
||||||
|
"purl": "pkg:docker/pypy",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"currentDepTag": "python:3.7",
|
||||||
|
"currentDepTagDigest": "python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentDigest": "sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentFrom": "python:3.7@sha256:3870d35b962a943df72d948580fc66ceaaee1c4fbd205930f32e0f0760eb1077",
|
||||||
|
"currentValue": "3.7",
|
||||||
|
"depName": "python",
|
||||||
|
"depType": "docker",
|
||||||
|
"dockerRegistry": undefined,
|
||||||
|
"lineNumber": 57,
|
||||||
|
"purl": "pkg:docker/python",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { extractPackageFile } = require('../../../lib/manager/circleci/extract');
|
const { extractPackageFile } = require('../../../lib/manager/circleci/extract');
|
||||||
|
|
||||||
const yamlFile = fs.readFileSync('test/_fixtures/circleci/config.yml', 'utf8');
|
const file1 = fs.readFileSync('test/_fixtures/circleci/config.yml', 'utf8');
|
||||||
|
const file2 = fs.readFileSync('test/_fixtures/circleci/config2.yml', 'utf8');
|
||||||
|
|
||||||
describe('lib/manager/circleci/extract', () => {
|
describe('lib/manager/circleci/extract', () => {
|
||||||
describe('extractPackageFile()', () => {
|
describe('extractPackageFile()', () => {
|
||||||
|
@ -13,9 +14,14 @@ describe('lib/manager/circleci/extract', () => {
|
||||||
expect(extractPackageFile('nothing here', config)).toBe(null);
|
expect(extractPackageFile('nothing here', config)).toBe(null);
|
||||||
});
|
});
|
||||||
it('extracts multiple image lines', () => {
|
it('extracts multiple image lines', () => {
|
||||||
const res = extractPackageFile(yamlFile, config);
|
const res = extractPackageFile(file1, config);
|
||||||
expect(res.deps).toMatchSnapshot();
|
expect(res.deps).toMatchSnapshot();
|
||||||
expect(res.deps).toHaveLength(4);
|
expect(res.deps).toHaveLength(4);
|
||||||
});
|
});
|
||||||
|
it('extracts orbs too', () => {
|
||||||
|
const res = extractPackageFile(file2, config);
|
||||||
|
expect(res.deps).toMatchSnapshot();
|
||||||
|
// expect(res.deps).toHaveLength(4);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,12 +2,17 @@ const fs = require('fs');
|
||||||
const dcUpdate = require('../../../lib/manager/circleci/update');
|
const dcUpdate = require('../../../lib/manager/circleci/update');
|
||||||
|
|
||||||
const yamlFile = fs.readFileSync('test/_fixtures/circleci/config.yml', 'utf8');
|
const yamlFile = fs.readFileSync('test/_fixtures/circleci/config.yml', 'utf8');
|
||||||
|
const yamlFile2 = fs.readFileSync(
|
||||||
|
'test/_fixtures/circleci/config2.yml',
|
||||||
|
'utf8'
|
||||||
|
);
|
||||||
|
|
||||||
describe('manager/circleci/update', () => {
|
describe('manager/circleci/update', () => {
|
||||||
describe('updateDependency', () => {
|
describe('updateDependency', () => {
|
||||||
it('replaces existing value', () => {
|
it('replaces existing value', () => {
|
||||||
const upgrade = {
|
const upgrade = {
|
||||||
lineNumber: 65,
|
lineNumber: 65,
|
||||||
|
depType: 'docker',
|
||||||
depName: 'node',
|
depName: 'node',
|
||||||
newValue: '8.10.0',
|
newValue: '8.10.0',
|
||||||
newDigest: 'sha256:abcdefghijklmnop',
|
newDigest: 'sha256:abcdefghijklmnop',
|
||||||
|
@ -19,6 +24,7 @@ describe('manager/circleci/update', () => {
|
||||||
it('returns same', () => {
|
it('returns same', () => {
|
||||||
const upgrade = {
|
const upgrade = {
|
||||||
lineNumber: 12,
|
lineNumber: 12,
|
||||||
|
depType: 'docker',
|
||||||
depName: 'node',
|
depName: 'node',
|
||||||
};
|
};
|
||||||
const res = dcUpdate.updateDependency(yamlFile, upgrade);
|
const res = dcUpdate.updateDependency(yamlFile, upgrade);
|
||||||
|
@ -27,6 +33,7 @@ describe('manager/circleci/update', () => {
|
||||||
it('returns null if mismatch', () => {
|
it('returns null if mismatch', () => {
|
||||||
const upgrade = {
|
const upgrade = {
|
||||||
lineNumber: 17,
|
lineNumber: 17,
|
||||||
|
depType: 'docker',
|
||||||
depName: 'postgres',
|
depName: 'postgres',
|
||||||
newValue: '9.6.8',
|
newValue: '9.6.8',
|
||||||
newDigest: 'sha256:abcdefghijklmnop',
|
newDigest: 'sha256:abcdefghijklmnop',
|
||||||
|
@ -38,5 +45,49 @@ describe('manager/circleci/update', () => {
|
||||||
const res = dcUpdate.updateDependency(null, null);
|
const res = dcUpdate.updateDependency(null, null);
|
||||||
expect(res).toBe(null);
|
expect(res).toBe(null);
|
||||||
});
|
});
|
||||||
|
it('replaces orbs', () => {
|
||||||
|
const upgrade = {
|
||||||
|
currentValue: '4.1.0',
|
||||||
|
depName: 'release-workflows',
|
||||||
|
depType: 'orb',
|
||||||
|
lineNumber: 3,
|
||||||
|
newValue: '4.2.0',
|
||||||
|
};
|
||||||
|
const res = dcUpdate.updateDependency(yamlFile2, upgrade);
|
||||||
|
expect(res).not.toEqual(yamlFile2);
|
||||||
|
expect(res.includes(upgrade.newValue)).toBe(true);
|
||||||
|
});
|
||||||
|
it('returns same orb', () => {
|
||||||
|
const upgrade = {
|
||||||
|
currentValue: '4.0.0',
|
||||||
|
depName: 'release-workflows',
|
||||||
|
depType: 'orb',
|
||||||
|
lineNumber: 3,
|
||||||
|
newValue: '4.1.0',
|
||||||
|
};
|
||||||
|
const res = dcUpdate.updateDependency(yamlFile2, upgrade);
|
||||||
|
expect(res).toEqual(yamlFile2);
|
||||||
|
});
|
||||||
|
it('returns null for orb mismatch', () => {
|
||||||
|
const upgrade = {
|
||||||
|
currentValue: '4.1.0',
|
||||||
|
depName: 'release-workflows',
|
||||||
|
depType: 'orb',
|
||||||
|
lineNumber: 2,
|
||||||
|
newValue: '4.2.0',
|
||||||
|
};
|
||||||
|
const res = dcUpdate.updateDependency(yamlFile2, upgrade);
|
||||||
|
expect(res).toBeNull();
|
||||||
|
});
|
||||||
|
it('returns null for unknown depType', () => {
|
||||||
|
const upgrade = {
|
||||||
|
currentValue: '4.1.0',
|
||||||
|
depName: 'release-workflows',
|
||||||
|
lineNumber: 3,
|
||||||
|
newValue: '4.2.0',
|
||||||
|
};
|
||||||
|
const res = dcUpdate.updateDependency(yamlFile2, upgrade);
|
||||||
|
expect(res).toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue