diff --git a/lib/modules/manager/github-actions/__fixtures__/workflow_4.yml b/lib/modules/manager/github-actions/__fixtures__/workflow_4.yml new file mode 100644 index 0000000000000000000000000000000000000000..ae34907103bdcff2c38527c762d45f540e182eca --- /dev/null +++ b/lib/modules/manager/github-actions/__fixtures__/workflow_4.yml @@ -0,0 +1,19 @@ +jobs: + test: + steps: + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # 1.2.3 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # 1.2 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # 1 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # v1.2.3 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # v1.2 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # v1 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # @v2.1.0 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # pin @v2.1.0 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # tag=v2.1.0 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # v2.1.0 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 #v2.1.0 + - uses: actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 #v2.1.0 + - uses: actions/checkout@1e204e # v2.1.0 + - uses: actions/checkout@01aecc#v2.1.0 + - uses: actions/checkout@689fcce700ae7ffc576f2b029b51b2ffb66d3abd # comment containing 2.1.0 + - uses: actions/checkout@689fcce700ae7ffc576f2b029b51b2ffb66d3abd # v2.1.0 additional comment diff --git a/lib/modules/manager/github-actions/__snapshots__/extract.spec.ts.snap b/lib/modules/manager/github-actions/__snapshots__/extract.spec.ts.snap index 19d013d7f76b8830b2d1c5f62dbf3b9ef9083953..47d08862bf382354049a679e4a00f946bf7f9aff 100644 --- a/lib/modules/manager/github-actions/__snapshots__/extract.spec.ts.snap +++ b/lib/modules/manager/github-actions/__snapshots__/extract.spec.ts.snap @@ -3,7 +3,7 @@ exports[`modules/manager/github-actions/extract extractPackageFile() extracts multiple action tag lines from yaml configuration file 1`] = ` [ { - "autoReplaceStringTemplate": "{{depName}}/shellcheck@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", + "autoReplaceStringTemplate": "{{depName}}/shellcheck@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", "commitMessageTopic": "{{{depName}}} action", "currentValue": "master", "datasource": "github-tags", @@ -14,7 +14,7 @@ exports[`modules/manager/github-actions/extract extractPackageFile() extracts mu "versioning": "docker", }, { - "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", + "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", "commitMessageTopic": "{{{depName}}} action", "currentDigest": "c308fdd69d26ed66f4506ebd74b180abe5362145", "currentValue": "v1.1.0", @@ -25,7 +25,7 @@ exports[`modules/manager/github-actions/extract extractPackageFile() extracts mu "versioning": "docker", }, { - "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", + "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", "commitMessageTopic": "{{{depName}}} action", "currentValue": "1.0.0", "datasource": "github-tags", @@ -35,7 +35,7 @@ exports[`modules/manager/github-actions/extract extractPackageFile() extracts mu "versioning": "docker", }, { - "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", + "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", "commitMessageTopic": "{{{depName}}} action", "currentDigest": "c308fdd69d26ed66f4506ebd74b180abe5362145", "currentValue": undefined, @@ -46,7 +46,7 @@ exports[`modules/manager/github-actions/extract extractPackageFile() extracts mu "versioning": "docker", }, { - "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", + "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", "commitMessageTopic": "{{{depName}}} action", "currentValue": "v2", "datasource": "github-tags", @@ -56,7 +56,7 @@ exports[`modules/manager/github-actions/extract extractPackageFile() extracts mu "versioning": "docker", }, { - "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", + "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", "commitMessageTopic": "{{{depName}}} action", "currentDigest": "ec3a7ce113134d7a93b817d10a8272cb61118579", "currentValue": "v2.4.0", @@ -67,7 +67,7 @@ exports[`modules/manager/github-actions/extract extractPackageFile() extracts mu "versioning": "docker", }, { - "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", + "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", "commitMessageTopic": "{{{depName}}} action", "currentDigest": "16499b5e05bf2e26879000db0c1d13f7e13fa3af", "currentValue": "v1.0.7", @@ -78,7 +78,7 @@ exports[`modules/manager/github-actions/extract extractPackageFile() extracts mu "versioning": "docker", }, { - "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", + "autoReplaceStringTemplate": "{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", "commitMessageTopic": "{{{depName}}} action", "currentValue": "v1.0.3", "datasource": "github-tags", @@ -93,7 +93,7 @@ exports[`modules/manager/github-actions/extract extractPackageFile() extracts mu exports[`modules/manager/github-actions/extract extractPackageFile() extracts multiple docker image lines from yaml configuration file 1`] = ` [ { - "autoReplaceStringTemplate": "{{depName}}/shellcheck@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", + "autoReplaceStringTemplate": "{{depName}}/shellcheck@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", "commitMessageTopic": "{{{depName}}} action", "currentValue": "master", "datasource": "github-tags", @@ -113,7 +113,7 @@ exports[`modules/manager/github-actions/extract extractPackageFile() extracts mu "replaceString": "replicated/dockerfilelint", }, { - "autoReplaceStringTemplate": "{{depName}}/cli@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", + "autoReplaceStringTemplate": "{{depName}}/cli@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}", "commitMessageTopic": "{{{depName}}} action", "currentValue": "master", "datasource": "github-tags", diff --git a/lib/modules/manager/github-actions/extract.spec.ts b/lib/modules/manager/github-actions/extract.spec.ts index 61fa2510c032d37adbc5cda640fec071aeb8af63..10a3e036ba92ba55b20d06c68192857afd4888b9 100644 --- a/lib/modules/manager/github-actions/extract.spec.ts +++ b/lib/modules/manager/github-actions/extract.spec.ts @@ -106,7 +106,7 @@ describe('modules/manager/github-actions/extract', () => { replaceString: 'actions/setup-node@56337c425554a6be30cdef71bf441f15be286854 # tag=v3.1.1', autoReplaceStringTemplate: - '{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}', + '{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}', currentValue: 'v3.1.1', currentDigest: '56337c425554a6be30cdef71bf441f15be286854', }, @@ -119,7 +119,7 @@ describe('modules/manager/github-actions/extract', () => { replaceString: "'actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561' # tag=v3.1.1", autoReplaceStringTemplate: - "'{{depName}}@{{#if newDigest}}{{newDigest}}'{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}'{{/unless}}", + "'{{depName}}@{{#if newDigest}}{{newDigest}}'{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}'{{/unless}}", currentValue: 'v3.1.1', currentDigest: '1f8c6b94b26d0feae1e387ca63ccbdc44d27b561', }, @@ -132,7 +132,7 @@ describe('modules/manager/github-actions/extract', () => { replaceString: '"actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561" # tag=v2.5.1', autoReplaceStringTemplate: - '"{{depName}}@{{#if newDigest}}{{newDigest}}"{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}"{{/unless}}', + '"{{depName}}@{{#if newDigest}}{{newDigest}}"{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}"{{/unless}}', currentValue: 'v2.5.1', currentDigest: '1f8c6b94b26d0feae1e387ca63ccbdc44d27b561', }, @@ -144,7 +144,7 @@ describe('modules/manager/github-actions/extract', () => { depType: 'action', replaceString: '"actions/checkout@v2"', autoReplaceStringTemplate: - '"{{depName}}@{{#if newDigest}}{{newDigest}}"{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}"{{/unless}}', + '"{{depName}}@{{#if newDigest}}{{newDigest}}"{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}"{{/unless}}', currentValue: 'v2', }, { @@ -155,10 +155,112 @@ describe('modules/manager/github-actions/extract', () => { depType: 'action', replaceString: '"actions/setup-java@v2"', autoReplaceStringTemplate: - '"{{depName}}@{{#if newDigest}}{{newDigest}}"{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}"{{/unless}}', + '"{{depName}}@{{#if newDigest}}{{newDigest}}"{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}"{{/unless}}', currentValue: 'v2', }, ]); }); + + it('extracts tags in different formats', () => { + const res = extractPackageFile( + Fixtures.get('workflow_4.yml'), + 'workflow_4.yml' + ); + expect(res?.deps).toMatchObject([ + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: '1.2.3', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # 1.2.3', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: '1.2', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # 1.2', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: '1', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # 1', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: 'v1.2.3', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # v1.2.3', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: 'v1.2', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # v1.2', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: 'v1', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # v1', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: 'v2.1.0', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # @v2.1.0', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: 'v2.1.0', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # pin @v2.1.0', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: 'v2.1.0', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # tag=v2.1.0', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: 'v2.1.0', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 # v2.1.0', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: 'v2.1.0', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 #v2.1.0', + }, + { + currentDigest: '1e204e9a9253d643386038d443f96446fa156a97', + currentValue: 'v2.1.0', + replaceString: + 'actions/checkout@1e204e9a9253d643386038d443f96446fa156a97 #v2.1.0', + }, + { + currentDigest: '1e204e', + currentValue: 'v2.1.0', + replaceString: 'actions/checkout@1e204e # v2.1.0', + }, + { + currentValue: '01aecc#v2.1.0', + replaceString: 'actions/checkout@01aecc#v2.1.0', + }, + { + currentDigest: '689fcce700ae7ffc576f2b029b51b2ffb66d3abd', + currentValue: undefined, + replaceString: + 'actions/checkout@689fcce700ae7ffc576f2b029b51b2ffb66d3abd', + }, + { + currentDigest: '689fcce700ae7ffc576f2b029b51b2ffb66d3abd', + currentValue: 'v2.1.0', + replaceString: + 'actions/checkout@689fcce700ae7ffc576f2b029b51b2ffb66d3abd # v2.1.0', + }, + ]); + }); }); }); diff --git a/lib/modules/manager/github-actions/extract.ts b/lib/modules/manager/github-actions/extract.ts index 0651a889685a93e842123e86e43c9d4c3b493cc2..205c61be428388a57e410cca001eb50b37c73156 100644 --- a/lib/modules/manager/github-actions/extract.ts +++ b/lib/modules/manager/github-actions/extract.ts @@ -9,11 +9,11 @@ import type { Container, 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+)?tag=(?<tag>\S+))?)/ + /^\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+)?)?))?)/ ); // SHA1 or SHA256, see https://github.blog/2020-10-19-git-2-29-released/ -const shaRe = regEx(/^[a-z0-9]{40}|[a-z0-9]{64}$/); +const shaRe = regEx(/^(?:[a-f0-9]{6,7}|[a-f0-9]{40}|[a-f0-9]{64})$/); function extractWithRegex(content: string): PackageDependency[] { logger.trace('github-actions.extractWithRegex()'); @@ -55,7 +55,7 @@ function extractWithRegex(content: string): PackageDependency[] { versioning: dockerVersioning.id, depType: 'action', replaceString, - autoReplaceStringTemplate: `${quotes}{{depName}}${path}@{{#if newDigest}}{{newDigest}}${quotes}{{#if newValue}} # tag={{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}${quotes}{{/unless}}`, + autoReplaceStringTemplate: `${quotes}{{depName}}${path}@{{#if newDigest}}{{newDigest}}${quotes}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}${quotes}{{/unless}}`, }; if (shaRe.test(currentValue)) { dep.currentValue = tag;