diff --git a/lib/modules/manager/buildkite/__fixtures__/pipeline2.yml b/lib/modules/manager/buildkite/__fixtures__/pipeline2.yml index 0db18c7a43e33ae47865a836c15a5d54849834df..8f2a0c889803305400008d12b92f718abcf0c298 100644 --- a/lib/modules/manager/buildkite/__fixtures__/pipeline2.yml +++ b/lib/modules/manager/buildkite/__fixtures__/pipeline2.yml @@ -2,7 +2,7 @@ steps: # Prebuild the app image, upload it to a registry for later steps - name: "Docker Build" plugins: - docker-compose#v1.3.2: + docker-compose#v1.3.2: # Comment at the end.... build: app image-repository: index.docker.io/org/repo diff --git a/lib/modules/manager/buildkite/__fixtures__/pipeline7.yml b/lib/modules/manager/buildkite/__fixtures__/pipeline7.yml new file mode 100644 index 0000000000000000000000000000000000000000..45d64a26524ae41496f2a0fd2b3079f8477f0646 --- /dev/null +++ b/lib/modules/manager/buildkite/__fixtures__/pipeline7.yml @@ -0,0 +1,8 @@ +.docker-options: &some-options + propagate-environment: true + copy-checkout: true + +.python3-container: &python3-container + ssh://git@github.some-domain.com/some-org/some-plugin#v3.2.7: + some-config: some-value + <<: *some-options diff --git a/lib/modules/manager/buildkite/extract.spec.ts b/lib/modules/manager/buildkite/extract.spec.ts index 6fd8c5fe1e860f986a4828cb8204ac59e09687e3..234a8a9bb1b4e94177c36e98de1fd1608f33446e 100644 --- a/lib/modules/manager/buildkite/extract.spec.ts +++ b/lib/modules/manager/buildkite/extract.spec.ts @@ -49,5 +49,16 @@ describe('modules/manager/buildkite/extract', () => { expect(res).toHaveLength(1); expect(res).toEqual([expectedPackageDependency]); }); + + it('extracts plugins outside plugins sections', () => { + const res = extractPackageFile(Fixtures.get('pipeline7.yml'))?.deps; + const expectedPackageDependency: PackageDependency = { + currentValue: 'v3.2.7', + datasource: 'github-tags', + depName: 'some-org/some-plugin', + registryUrls: ['https://github.some-domain.com'], + }; + expect(res).toEqual([expectedPackageDependency]); + }); }); }); diff --git a/lib/modules/manager/buildkite/extract.ts b/lib/modules/manager/buildkite/extract.ts index ac345a369d7d43689b3ebf052526d7b0c1c3d390..83131c44878c9d52769513596281d986217d75a3 100644 --- a/lib/modules/manager/buildkite/extract.ts +++ b/lib/modules/manager/buildkite/extract.ts @@ -9,85 +9,66 @@ export function extractPackageFile(content: string): PackageFile | null { const deps: PackageDependency[] = []; try { const lines = content.split(newlineRegex); - let isPluginsSection = false; - let pluginsIndent = ''; - for (let lineNumber = 1; lineNumber <= lines.length; lineNumber += 1) { - const lineIdx = lineNumber - 1; - const line = lines[lineIdx]; - const pluginsSection = regEx( - /^(?<pluginsIndent>\s*)(-?\s*)plugins:/ + + for (const line of lines) { + // Search each line for plugin names + const depLineMatch = regEx( + /^[\s-]*(?<depName>[^#\s]+)#(?<currentValue>[^:]+)/ ).exec(line); - if (pluginsSection?.groups) { - logger.trace(`Matched plugins on line ${lineNumber}`); - isPluginsSection = true; - pluginsIndent = pluginsSection.groups.pluginsIndent; - } else if (isPluginsSection) { - logger.debug(`serviceImageLine: "${line}"`); - const { currentIndent } = regEx(/^(?<currentIndent>\s*)/).exec(line) - ?.groups ?? /* istanbul ignore next: should never happen */ { - currentIndent: '', - }; - const depLineMatch = regEx( - /^\s+(?:-\s+)?(?<depName>[^#]+)#(?<currentValue>[^:]+)/ - ).exec(line); - if (currentIndent.length <= pluginsIndent.length) { - isPluginsSection = false; - pluginsIndent = ''; - } else if (depLineMatch?.groups) { - const { depName, currentValue } = depLineMatch.groups; - logger.trace('depLineMatch'); - let skipReason: SkipReason | undefined; - let repo: string | undefined; - const gitPluginMatch = regEx( - /(ssh:\/\/git@|https:\/\/)(?<registry>[^/]+)\/(?<gitPluginName>.*)/ - ).exec(depName); - if (gitPluginMatch?.groups) { - logger.debug('Examining git plugin'); - const { registry, gitPluginName } = gitPluginMatch.groups; - const gitDepName = gitPluginName.replace(regEx('\\.git$'), ''); - const dep: PackageDependency = { - depName: gitDepName, - currentValue: currentValue, - registryUrls: ['https://' + registry], - datasource: GithubTagsDatasource.id, - }; - deps.push(dep); - continue; - } else if (isVersion(currentValue)) { - const splitName = depName.split('/'); - if (splitName.length === 1) { - repo = `buildkite-plugins/${depName}-buildkite-plugin`; - } else if (splitName.length === 2) { - repo = `${depName}-buildkite-plugin`; - } else { - logger.warn( - { dependency: depName }, - 'Something is wrong with buildkite plugin name' - ); - skipReason = 'invalid-dependency-specification'; - } - } else { - logger.debug( - { currentValue }, - 'Skipping non-pinned current version' - ); - skipReason = 'invalid-version'; - } + + if (depLineMatch?.groups) { + const { depName, currentValue } = depLineMatch.groups; + logger.trace('depLineMatch'); + let skipReason: SkipReason | undefined; + let repo: string | undefined; + logger.debug({ depName }, 'Found BuildKite plugin'); + // Plugins may simply be git repos. If so, we need to parse out the registry. + const gitPluginMatch = regEx( + /(ssh:\/\/git@|https:\/\/)(?<registry>[^/]+)\/(?<gitPluginName>.*)/ + ).exec(depName); + if (gitPluginMatch?.groups) { + logger.debug('Examining git plugin'); + const { registry, gitPluginName } = gitPluginMatch.groups; + const gitDepName = gitPluginName.replace(regEx('\\.git$'), ''); const dep: PackageDependency = { - depName, - currentValue, - skipReason, + depName: gitDepName, + currentValue: currentValue, + registryUrls: ['https://' + registry], + datasource: GithubTagsDatasource.id, }; - if (repo) { - dep.datasource = GithubTagsDatasource.id; - dep.packageName = repo; - } deps.push(dep); + continue; + } else if (isVersion(currentValue)) { + const splitName = depName.split('/'); + if (splitName.length === 1) { + repo = `buildkite-plugins/${depName}-buildkite-plugin`; + } else if (splitName.length === 2) { + repo = `${depName}-buildkite-plugin`; + } else { + logger.warn( + { dependency: depName }, + 'Something is wrong with BuildKite plugin name' + ); + skipReason = 'invalid-dependency-specification'; + } + } else { + logger.debug({ currentValue }, 'Skipping non-pinned current version'); + skipReason = 'invalid-version'; + } + const dep: PackageDependency = { + depName, + currentValue, + skipReason, + }; + if (repo) { + dep.datasource = GithubTagsDatasource.id; + dep.packageName = repo; } + deps.push(dep); } } } catch (err) /* istanbul ignore next */ { - logger.warn({ err }, 'Error extracting buildkite plugins'); + logger.warn({ err }, 'Error extracting BuildKite plugins'); } if (!deps.length) {