diff --git a/renovate-config.json5 b/renovate-config.json5 index f111c96b..078e8c1b 100644 --- a/renovate-config.json5 +++ b/renovate-config.json5 @@ -138,17 +138,17 @@ }, ], "customManagers": [ - // actionlint release and commit used by the common lint workflow. + // Annotated GitHub release, tag, or branch values paired with immutable commits. { "customType": "regex", - "description": "Update actionlint and its jsDelivr commit", + "description": "Update annotated GitHub values and their jsDelivr commits", "managerFilePatterns": [ - "/^\\.github/workflows/__call-common-lint[.]ya?ml$/", + "/^(?:\\.github/workflows/.*[.]ya?ml|actions/[^/]+/action[.]ya?ml)$/", ], "matchStrings": [ - "# renovate: datasource=(?[a-zA-Z0-9-._]+?) depName=(?[^\\s]+?)\\s+actionlint_version=\\\"(?v?[0-9.]+)\\\"\\s+actionlint_ref=\\\"(?[a-fA-F0-9]{40})\\\"", + "# renovate: datasource=(?[a-zA-Z0-9-._]+?) depName=(?[^\\s]+?)(?:\\s+versioning=(?[^\\s]+?))?\\s+[a-zA-Z0-9_]+?_(?:branch|release|tag|version)=\\\"(?[^\\\"\\s]+)\\\"\\s+[a-zA-Z0-9_]+?_ref=\\\"(?[a-fA-F0-9]{40})\\\"", ], - "versioningTemplate": "semver", + "versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}semver{{/if}}", }, // cdnjs URLs in Jekyll config files, front matter, data YAML, and simple HTML attrs, with optional adjacent SRI hashes. { diff --git a/tests/renovate-config.test.mjs b/tests/renovate-config.test.mjs index c50f2b0f..2b7af6d5 100644 --- a/tests/renovate-config.test.mjs +++ b/tests/renovate-config.test.mjs @@ -7,8 +7,8 @@ import {extractPackageFile as extractCdnUrlPackageFile} from 'renovate/dist/modu import {extractPackageFile as extractRegexPackageFile} from 'renovate/dist/modules/manager/custom/regex/index.js'; const renovateConfig = JSON5.parse(fs.readFileSync('renovate-config.json5', 'utf8')); -const actionlintManager = renovateConfig.customManagers.find( - manager => manager.description === 'Update actionlint and its jsDelivr commit', +const githubRefManager = renovateConfig.customManagers.find( + manager => manager.description === 'Update annotated GitHub values and their jsDelivr commits', ); const jekyllNpmCdnManager = renovateConfig.customManagers.find( manager => manager.datasourceTemplate === 'npm' @@ -39,24 +39,28 @@ function extractNpmDependencies(manager, fileName, content) { return extractRegexPackageFile(content, fileName, manager)?.deps ?? []; } -test('extracts the actionlint release and jsDelivr commit', () => { - const fileName = '.github/workflows/__call-common-lint.yml'; - const content = fs.readFileSync(fileName, 'utf8'); - assert.ok(actionlintManager, 'Expected to find the actionlint custom manager'); +function extractGitHubRefDependencies(fileName, content) { + assert.ok(githubRefManager, 'Expected to find the annotated GitHub ref custom manager'); assert.ok( - matchesManagerFilePattern(fileName, actionlintManager.managerFilePatterns), - `Expected the actionlint manager to scan ${fileName}`, + matchesManagerFilePattern(fileName, githubRefManager.managerFilePatterns), + `Expected the annotated GitHub ref manager to scan ${fileName}`, ); - const dependencies = extractRegexPackageFile(content, fileName, actionlintManager)?.deps ?? []; + const dependencies = extractRegexPackageFile(content, fileName, githubRefManager)?.deps ?? []; + return dependencies.map(dependency => ({ + currentDigest: dependency.currentDigest, + currentValue: dependency.currentValue, + datasource: dependency.datasource, + depName: dependency.depName, + versioning: dependency.versioning, + })); +} + +test('extracts the actionlint release and jsDelivr commit', () => { + const fileName = '.github/workflows/__call-common-lint.yml'; + const content = fs.readFileSync(fileName, 'utf8'); assert.deepEqual( - dependencies.map(dependency => ({ - currentDigest: dependency.currentDigest, - currentValue: dependency.currentValue, - datasource: dependency.datasource, - depName: dependency.depName, - versioning: dependency.versioning, - })), + extractGitHubRefDependencies(fileName, content), [{ currentDigest: '914e7df21a07ef503a81201c76d2b11c789d3fca', currentValue: 'v1.7.12', @@ -67,6 +71,25 @@ test('extracts the actionlint release and jsDelivr commit', () => { ); }); +test('extracts a GitHub branch and jsDelivr commit from a composite action', () => { + const fileName = 'actions/setup_python/action.yml'; + const content = ` + # renovate: datasource=github-digest depName=pyenv/pyenv-installer versioning=exact + pyenv_installer_branch="master" + pyenv_installer_ref="63a9e6a216796aeba2535a3bac8e79ba5d95166d" + `; + assert.deepEqual( + extractGitHubRefDependencies(fileName, content), + [{ + currentDigest: '63a9e6a216796aeba2535a3bac8e79ba5d95166d', + currentValue: 'master', + datasource: 'github-digest', + depName: 'pyenv/pyenv-installer', + versioning: 'exact', + }], + ); +}); + function nextTestVersion(currentValue) { const match = /^(.*?)(\d+)$/.exec(currentValue); assert.ok(match, `Expected a version ending in a number: ${currentValue}`);