From 853f02844d0ee6df667b256bcc690a4350e71cf2 Mon Sep 17 00:00:00 2001 From: Tobias <tobias.gabriel@sap.com> Date: Tue, 8 Aug 2023 14:07:47 +0200 Subject: [PATCH] feat(github-actions): autodetect GitHub Actions registry urls for Enterprise Server (#23042) --- .../manager/github-actions/extract.spec.ts | 79 +++++++++++++++++++ lib/modules/manager/github-actions/extract.ts | 26 ++++++ 2 files changed, 105 insertions(+) diff --git a/lib/modules/manager/github-actions/extract.spec.ts b/lib/modules/manager/github-actions/extract.spec.ts index bdd27790e6..ec9bea9051 100644 --- a/lib/modules/manager/github-actions/extract.spec.ts +++ b/lib/modules/manager/github-actions/extract.spec.ts @@ -1,7 +1,12 @@ import { Fixtures } from '../../../../test/fixtures'; +import { GlobalConfig } from '../../../config/global'; import { extractPackageFile } from '.'; describe('modules/manager/github-actions/extract', () => { + beforeEach(() => { + GlobalConfig.reset(); + }); + describe('extractPackageFile()', () => { it('returns null for empty', () => { expect( @@ -37,6 +42,80 @@ describe('modules/manager/github-actions/extract', () => { ).toHaveLength(8); }); + it('use github.com as registry when no settings provided', () => { + const res = extractPackageFile( + Fixtures.get('workflow_2.yml'), + 'workflow_2.yml' + ); + expect(res?.deps[0].registryUrls).toBeUndefined(); + }); + + it('use github.enterprise.com first and then github.com as registry running against github.enterprise.com', () => { + GlobalConfig.set({ + platform: 'github', + endpoint: 'https://github.enterprise.com', + }); + const res = extractPackageFile( + Fixtures.get('workflow_2.yml'), + 'workflow_2.yml' + ); + expect(res?.deps[0].registryUrls).toEqual([ + 'https://github.enterprise.com', + 'https://github.com', + ]); + }); + + it('use github.enterprise.com first and then github.com as registry running against github.enterprise.com/api/v3', () => { + GlobalConfig.set({ + platform: 'github', + endpoint: 'https://github.enterprise.com/api/v3', + }); + const res = extractPackageFile( + Fixtures.get('workflow_2.yml'), + 'workflow_2.yml' + ); + expect(res?.deps[0].registryUrls).toEqual([ + 'https://github.enterprise.com', + 'https://github.com', + ]); + }); + + it('use github.com only as registry when running against non-GitHub', () => { + GlobalConfig.set({ + platform: 'bitbucket', + endpoint: 'https://bitbucket.enterprise.com', + }); + const res = extractPackageFile( + Fixtures.get('workflow_2.yml'), + 'workflow_2.yml' + ); + expect(res?.deps[0].registryUrls).toBeUndefined(); + }); + + it('use github.com only as registry when running against github.com', () => { + GlobalConfig.set({ + platform: 'github', + endpoint: 'https://github.com', + }); + const res = extractPackageFile( + Fixtures.get('workflow_2.yml'), + 'workflow_2.yml' + ); + expect(res?.deps[0].registryUrls).toBeUndefined(); + }); + + it('use github.com only as registry when running against api.github.com', () => { + GlobalConfig.set({ + platform: 'github', + endpoint: 'https://api.github.com', + }); + const res = extractPackageFile( + Fixtures.get('workflow_2.yml'), + 'workflow_2.yml' + ); + expect(res?.deps[0].registryUrls).toBeUndefined(); + }); + it('extracts multiple action tag lines with double quotes and comments', () => { const res = extractPackageFile( Fixtures.get('workflow_3.yml'), diff --git a/lib/modules/manager/github-actions/extract.ts b/lib/modules/manager/github-actions/extract.ts index 92a9814b97..0671794f4f 100644 --- a/lib/modules/manager/github-actions/extract.ts +++ b/lib/modules/manager/github-actions/extract.ts @@ -1,5 +1,6 @@ import is from '@sindresorhus/is'; import { load } from 'js-yaml'; +import { GlobalConfig } from '../../../config/global'; import { logger } from '../../../logger'; import { newlineRegex, regEx } from '../../../util/regex'; import { GithubTagsDatasource } from '../../datasource/github-tags'; @@ -17,7 +18,31 @@ const actionRe = regEx( const shaRe = regEx(/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/); const shaShortRe = regEx(/^[a-f0-9]{6,7}$/); +// detects if we run against a Github Enterprise Server and adds the URL to the beginning of the registryURLs for looking up Actions +// This reflects the behavior of how GitHub looks up Actions +// First on the Enterprise Server, then on GitHub.com +function detectCustomGitHubRegistryUrlsForActions(): PackageDependency { + const endpoint = GlobalConfig.get('endpoint'); + const registryUrls = ['https://github.com']; + if (endpoint && GlobalConfig.get('platform') === 'github') { + const parsedEndpoint = new URL(endpoint); + + if ( + parsedEndpoint.host !== 'github.com' && + parsedEndpoint.host !== 'api.github.com' + ) { + registryUrls.unshift( + `${parsedEndpoint.protocol}//${parsedEndpoint.host}` + ); + return { registryUrls }; + } + } + return {}; +} + function extractWithRegex(content: string): PackageDependency[] { + const customRegistryUrlsPackageDependency = + detectCustomGitHubRegistryUrlsForActions(); logger.trace('github-actions.extractWithRegex()'); const deps: PackageDependency[] = []; for (const line of content.split(newlineRegex)) { @@ -58,6 +83,7 @@ function extractWithRegex(content: string): PackageDependency[] { depType: 'action', replaceString, autoReplaceStringTemplate: `${quotes}{{depName}}${path}@{{#if newDigest}}{{newDigest}}${quotes}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}${quotes}{{/unless}}`, + ...customRegistryUrlsPackageDependency, }; if (shaRe.test(currentValue)) { dep.currentValue = tag; -- GitLab