From 96b8e6ddc98655ece4b412cd7477c96528ceef12 Mon Sep 17 00:00:00 2001 From: Michael Kriese <michael.kriese@visualon.de> Date: Thu, 8 Feb 2024 08:59:28 +0100 Subject: [PATCH] feat(manager/github-actions): support full qualified actions (#27117) --- .../manager/github-actions/extract.spec.ts | 44 +++++++++++++++++++ lib/modules/manager/github-actions/extract.ts | 29 ++++++++++-- lib/modules/manager/github-actions/index.ts | 2 + 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/lib/modules/manager/github-actions/extract.spec.ts b/lib/modules/manager/github-actions/extract.spec.ts index 4f96931d87..7234e08c81 100644 --- a/lib/modules/manager/github-actions/extract.spec.ts +++ b/lib/modules/manager/github-actions/extract.spec.ts @@ -1,3 +1,4 @@ +import { codeBlock } from 'common-tags'; import { Fixtures } from '../../../../test/fixtures'; import { GlobalConfig } from '../../../config/global'; import { extractPackageFile } from '.'; @@ -387,6 +388,49 @@ describe('modules/manager/github-actions/extract', () => { ]); }); + it('extracts actions with fqdn', () => { + const res = extractPackageFile( + codeBlock` + jobs: + build: + steps: + - name: "test1" + uses: https://github.com/actions/setup-node@56337c425554a6be30cdef71bf441f15be286854 # tag=v3.1.1 + - name: "test2" + uses: https://code.forgejo.org/actions/setup-node@56337c425554a6be30cdef71bf441f15be286854 # v3.1.1 + - name: "test3" + uses: https://code.domain.test/actions/setup-node@56337c425554a6be30cdef71bf441f15be286854 # v3.1.1 + + `, + 'sample.yml', + ); + expect(res).toMatchObject({ + deps: [ + { + currentDigest: '56337c425554a6be30cdef71bf441f15be286854', + currentValue: 'v3.1.1', + replaceString: + 'https://github.com/actions/setup-node@56337c425554a6be30cdef71bf441f15be286854 # tag=v3.1.1', + datasource: 'github-tags', + registryUrls: ['https://github.com/'], + }, + { + currentDigest: '56337c425554a6be30cdef71bf441f15be286854', + currentValue: 'v3.1.1', + replaceString: + 'https://code.forgejo.org/actions/setup-node@56337c425554a6be30cdef71bf441f15be286854 # v3.1.1', + datasource: 'gitea-tags', + registryUrls: ['https://code.forgejo.org/'], + }, + { + skipReason: 'unsupported-url', + }, + ], + }); + + expect(res!.deps[2]).not.toHaveProperty('registryUrls'); + }); + it('extracts multiple action runners from yaml configuration file', () => { const res = extractPackageFile(runnerTestWorkflow, 'workflow.yml'); diff --git a/lib/modules/manager/github-actions/extract.ts b/lib/modules/manager/github-actions/extract.ts index c1446e5f84..9b6ccf4a72 100644 --- a/lib/modules/manager/github-actions/extract.ts +++ b/lib/modules/manager/github-actions/extract.ts @@ -2,8 +2,10 @@ import is from '@sindresorhus/is'; import { GlobalConfig } from '../../../config/global'; import { logger } from '../../../logger'; import { isNotNullOrUndefined } from '../../../util/array'; +import { detectPlatform } from '../../../util/common'; import { newlineRegex, regEx } from '../../../util/regex'; import { parseSingleYaml } from '../../../util/yaml'; +import { GiteaTagsDatasource } from '../../datasource/gitea-tags'; import { GithubRunnersDatasource } from '../../datasource/github-runners'; import { GithubTagsDatasource } from '../../datasource/github-tags'; import * as dockerVersioning from '../../versioning/docker'; @@ -13,7 +15,7 @@ import type { Workflow } from './types'; const dockerActionRe = regEx(/^\s+uses: ['"]?docker:\/\/([^'"]+)\s*$/); const actionRe = regEx( - /^\s+-?\s+?uses: (?<replaceString>['"]?(?<depName>[\w-]+\/[.\w-]+)(?<path>\/.*)?@(?<currentValue>[^\s'"]+)['"]?(?:\s+#\s*(?:renovate\s*:\s*)?(?:pin\s+|tag\s*=\s*)?@?(?<tag>v?\d+(?:\.\d+(?:\.\d+)?)?))?)/, + /^\s+-?\s+?uses: (?<replaceString>['"]?(?<registryUrl>https:\/\/[.\w-]+\/)?(?<depName>[\w-]+\/[.\w-]+)(?<path>\/.*)?@(?<currentValue>[^\s'"]+)['"]?(?:\s+#\s*(?:renovate\s*:\s*)?(?:pin\s+|tag\s*=\s*)?@?(?<tag>v?\d+(?:\.\d+(?:\.\d+)?)?))?)/, ); // SHA1 or SHA256, see https://github.blog/2020-10-19-git-2-29-released/ @@ -69,6 +71,7 @@ function extractWithRegex(content: string): PackageDependency[] { path = '', tag, replaceString, + registryUrl = '', } = tagMatch.groups; let quotes = ''; if (replaceString.indexOf("'") >= 0) { @@ -84,8 +87,10 @@ function extractWithRegex(content: string): PackageDependency[] { versioning: dockerVersioning.id, depType: 'action', replaceString, - autoReplaceStringTemplate: `${quotes}{{depName}}${path}@{{#if newDigest}}{{newDigest}}${quotes}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}${quotes}{{/unless}}`, - ...customRegistryUrlsPackageDependency, + autoReplaceStringTemplate: `${quotes}${registryUrl}{{depName}}${path}@{{#if newDigest}}{{newDigest}}${quotes}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}${quotes}{{/unless}}`, + ...(registryUrl + ? detectDatasource(registryUrl) + : customRegistryUrlsPackageDependency), }; if (shaRe.test(currentValue)) { dep.currentValue = tag; @@ -105,6 +110,24 @@ function extractWithRegex(content: string): PackageDependency[] { return deps; } +function detectDatasource(registryUrl: string): PackageDependency { + const platform = detectPlatform(registryUrl); + + switch (platform) { + case 'github': + return { registryUrls: [registryUrl] }; + case 'gitea': + return { + registryUrls: [registryUrl], + datasource: GiteaTagsDatasource.id, + }; + } + + return { + skipReason: 'unsupported-url', + }; +} + function extractContainer(container: unknown): PackageDependency | undefined { if (is.string(container)) { return getDep(container); diff --git a/lib/modules/manager/github-actions/index.ts b/lib/modules/manager/github-actions/index.ts index 305543bcf6..a50258fed8 100644 --- a/lib/modules/manager/github-actions/index.ts +++ b/lib/modules/manager/github-actions/index.ts @@ -1,4 +1,5 @@ import type { Category } from '../../../constants'; +import { GiteaTagsDatasource } from '../../datasource/gitea-tags'; import { GithubRunnersDatasource } from '../../datasource/github-runners'; import { GithubTagsDatasource } from '../../datasource/github-tags'; export { extractPackageFile } from './extract'; @@ -13,6 +14,7 @@ export const defaultConfig = { export const categories: Category[] = ['ci']; export const supportedDatasources = [ + GiteaTagsDatasource.id, GithubTagsDatasource.id, GithubRunnersDatasource.id, ]; -- GitLab