Skip to content

Commit

Permalink
feat(gitlabci): add support for multidoc yaml (#28521)
Browse files Browse the repository at this point in the history
  • Loading branch information
RahulGautamSingh committed Apr 19, 2024
1 parent f4d4177 commit 20d7611
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 49 deletions.
32 changes: 32 additions & 0 deletions lib/modules/manager/gitlabci/__fixtures__/gitlab-ci.multi-doc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
image:
# comment
name: renovate/renovate:19.70.8-slim

services:
# comment
- mariadb:10.4.11
# another comment
- other/image:1.0.0

include:
- local: 'lib/modules/manager/gitlabci/__fixtures__/include.yml'
- local: 'lib/modules/manager/gitlabci/__fixtures__/include.yml' # Loop detection
- local: 'lib/modules/manager/gitlabci/__fixtures__/include.1.yml'
- local: 'lib/modules/manager/gitlabci/__fixtures__/*/.gitlab-ci.yml'
- project: 'my-group/my-project'
ref: master
file: '/templates/.gitlab-ci-template.yml'

script:
- !reference [.setup, script]
---
image:
# comment
name: renovate/renovate:19.70.8-slim

services:
# comment
- mariadb:10.4.11
# another comment
- name: other/image:1.0.0
alias: imagealias
17 changes: 11 additions & 6 deletions lib/modules/manager/gitlabci/extract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,24 @@ describe('modules/manager/gitlabci/extract', () => {
).toBeNull();
});

it('extracts from multidoc yaml', async () => {
const res = await extractAllPackageFiles(config, [
'lib/modules/manager/gitlabci/__fixtures__/gitlab-ci.multi-doc.yaml',
]);
expect(res).toHaveLength(3);

const deps = res?.map((entry) => entry.deps).flat();
expect(deps).toHaveLength(8);
});

it('extracts multiple included image lines', async () => {
const res = await extractAllPackageFiles(config, [
'lib/modules/manager/gitlabci/__fixtures__/gitlab-ci.3.yaml',
]);
expect(res).toMatchSnapshot();
expect(res).toHaveLength(3);

const deps: PackageDependency[] = [];
res?.forEach((e) => {
e.deps.forEach((d) => {
deps.push(d);
});
});
const deps = res?.map((entry) => entry.deps).flat();
expect(deps).toHaveLength(5);
});

Expand Down
99 changes: 56 additions & 43 deletions lib/modules/manager/gitlabci/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { logger } from '../../../logger';
import { readLocalFile } from '../../../util/fs';
import { regEx } from '../../../util/regex';
import { trimLeadingSlash } from '../../../util/url';
import { parseSingleYaml } from '../../../util/yaml';
import { parseYaml } from '../../../util/yaml';
import { GitlabTagsDatasource } from '../../datasource/gitlab-tags';
import type {
ExtractConfig,
Expand Down Expand Up @@ -165,43 +165,54 @@ export function extractPackageFile(
let deps: PackageDependency[] = [];
try {
// TODO: use schema (#9610)
const doc = parseSingleYaml<GitlabPipeline>(replaceReferenceTags(content), {
json: true,
});
if (is.object(doc)) {
for (const [property, value] of Object.entries(doc)) {
switch (property) {
case 'image':
{
const dep = extractFromImage(
value as Image,
config.registryAliases,
);
if (dep) {
deps.push(dep);
const docs = parseYaml<GitlabPipeline>(
replaceReferenceTags(content),
null,
{
json: true,
},
);
for (const doc of docs) {
if (is.object(doc)) {
for (const [property, value] of Object.entries(doc)) {
switch (property) {
case 'image':
{
const dep = extractFromImage(
value as Image,
config.registryAliases,
);
if (dep) {
deps.push(dep);
}
}
}
break;
break;

case 'services':
deps.push(
...extractFromServices(value as Services, config.registryAliases),
);
break;
case 'services':
deps.push(
...extractFromServices(
value as Services,
config.registryAliases,
),
);
break;

default:
deps.push(...extractFromJob(value as Job, config.registryAliases));
break;
default:
deps.push(
...extractFromJob(value as Job, config.registryAliases),
);
break;
}
}
deps = deps.filter(is.truthy);
}
deps = deps.filter(is.truthy);
}

const includedComponents = getAllIncludeComponents(doc);
for (const includedComponent of includedComponents) {
const dep = extractDepFromIncludeComponent(includedComponent);
if (dep) {
deps.push(dep);
const includedComponents = getAllIncludeComponents(doc);
for (const includedComponent of includedComponents) {
const dep = extractDepFromIncludeComponent(includedComponent);
if (dep) {
deps.push(dep);
}
}
}
} catch (err) /* istanbul ignore next */ {
Expand Down Expand Up @@ -241,10 +252,10 @@ export async function extractAllPackageFiles(
);
continue;
}
let doc: GitlabPipeline;
let docs: GitlabPipeline[];
try {
// TODO: use schema (#9610)
doc = parseSingleYaml(replaceReferenceTags(content), {
docs = parseYaml(replaceReferenceTags(content), null, {
json: true,
});
} catch (err) {
Expand All @@ -255,20 +266,22 @@ export async function extractAllPackageFiles(
continue;
}

if (is.array(doc?.include)) {
for (const includeObj of doc.include.filter(isGitlabIncludeLocal)) {
const fileObj = trimLeadingSlash(includeObj.local);
for (const doc of docs) {
if (is.array(doc?.include)) {
for (const includeObj of doc.include.filter(isGitlabIncludeLocal)) {
const fileObj = trimLeadingSlash(includeObj.local);
if (!seen.has(fileObj)) {
seen.add(fileObj);
filesToExamine.push(fileObj);
}
}
} else if (is.string(doc?.include)) {
const fileObj = trimLeadingSlash(doc.include);
if (!seen.has(fileObj)) {
seen.add(fileObj);
filesToExamine.push(fileObj);
}
}
} else if (is.string(doc?.include)) {
const fileObj = trimLeadingSlash(doc.include);
if (!seen.has(fileObj)) {
seen.add(fileObj);
filesToExamine.push(fileObj);
}
}

const result = extractPackageFile(content, file, config);
Expand Down

0 comments on commit 20d7611

Please sign in to comment.