From 5b184ca4df58b7c7a74cf8e7c255f7e57d05fe86 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 2 Sep 2025 15:52:24 +0000 Subject: [PATCH 1/4] Add renovate.json --- renovate.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..7190a60b --- /dev/null +++ b/renovate.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json" +} -- 2.52.0 From 3c5afc4448ea5c9f5042524d312a8cb89e4e6a6f Mon Sep 17 00:00:00 2001 From: "Trez.One" Date: Wed, 3 Sep 2025 10:49:52 -0400 Subject: [PATCH 2/4] renovate.json customizations. --- extract-docker-images.js | 57 ++++++++++++++++++++++++++++++++++++++++ renovate.json | 50 ++++++++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 extract-docker-images.js diff --git a/extract-docker-images.js b/extract-docker-images.js new file mode 100644 index 00000000..ad3e1620 --- /dev/null +++ b/extract-docker-images.js @@ -0,0 +1,57 @@ +const fs = require('fs'); +const yaml = require('js-yaml'); + +/** + * Recursively traverse the object and extract all image entries. + * @param {object} obj - The YAML object to traverse. + * @param {Array} path - Key path for generating service names. + * @returns {Array} - List of {depName, currentValue, service}. + */ +function extractImages(obj, path = []) { + const result = []; + + if (typeof obj !== 'object' || obj === null) return result; + + // Resolve merged objects (anchors or << merges) + let mergedObj = {}; + if (obj['<<']) { + const merge = obj['<<']; + if (Array.isArray(merge)) { + merge.forEach(m => Object.assign(mergedObj, m)); + } else if (typeof merge === 'object') { + Object.assign(mergedObj, merge); + } + } + // Merge top-level keys last to override anchor defaults + Object.assign(mergedObj, obj); + + // If an image key exists, capture it + if (mergedObj.image) { + const [depName, currentValue] = mergedObj.image.split(':'); + result.push({ + depName: depName, + currentValue: currentValue || 'latest', + service: path.join('/') || 'root' + }); + } + + // Recursively traverse all keys + for (const [key, value] of Object.entries(mergedObj)) { + // Skip the << key since we've already processed it + if (key === '<<') continue; + result.push(...extractImages(value, [...path, key])); + } + + return result; +}; + +module.exports = function extractDockerImages(fileContent) { + try { + // Parse YAML with anchors preserved + const doc = yaml.load(fileContent, { schema: yaml.DEFAULT_FULL_SCHEMA }); + return extractImages(doc); + } catch (err) { + console.error('Failed parsing docker-compose.yml:', err); + return []; + } +}; diff --git a/renovate.json b/renovate.json index 7190a60b..dd6dbd97 100644 --- a/renovate.json +++ b/renovate.json @@ -1,3 +1,51 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json" + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"], + "prHourlyLimit": 2, + "prConcurrentLimit": 5, + "dependencyDashboard": true, + "labels": ["dependencies", "renovate"], + "schedule": ["before 6am on monday"], + + "docker": { + "enabled": true + }, + + "packageRules": [ + { + "matchDatasources": ["docker"], + "matchPackageNames": ["clickhouse/clickhouse-server"], + "enabled": false + }, + { + "matchDatasources": ["docker"], + "matchPackagePatterns": [".*-alpine$"], + "allowedVersions": "/.*-alpine$/" + }, + { + "matchDatasources": ["docker"], + "matchPackagePatterns": ["^.*:latest$"], + "enabled": false + } + ], + + "regexManagers": [], + + "packageFiles": [ + { + "fileMatch": ["docker-compose\\.ya?ml$"], + "manager": "regex", + "extractVersion": "custom", + "datasourceTemplate": "docker", + "depNameTemplate": "{{service | split(\"/\") | last}}/{{depName}}", + "versioningTemplate": "docker", + "extractor": "file:extract-docker-images.js" + } + ], + + "branchNameStrict": true, + "branchPrefix": "renovate/", + "commitMessageAction": "Update", + "commitMessageTopic": "{{service | split(\"/\") | last}}/{{depName}}", + "prTitle": "Update {{service | split(\"/\") | last}}/{{depName}}: {{currentValue}} → {{newVersion}}" } -- 2.52.0 From 1225accef287af77b88e9554eefec8e62a7c3302 Mon Sep 17 00:00:00 2001 From: "Trez.One" Date: Wed, 3 Sep 2025 11:00:38 -0400 Subject: [PATCH 3/4] Modifying extractor. --- extract-docker-images.js | 76 ++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 46 deletions(-) diff --git a/extract-docker-images.js b/extract-docker-images.js index ad3e1620..d37e01db 100644 --- a/extract-docker-images.js +++ b/extract-docker-images.js @@ -1,57 +1,41 @@ const fs = require('fs'); const yaml = require('js-yaml'); -/** - * Recursively traverse the object and extract all image entries. - * @param {object} obj - The YAML object to traverse. - * @param {Array} path - Key path for generating service names. - * @returns {Array} - List of {depName, currentValue, service}. - */ -function extractImages(obj, path = []) { +module.exports = function extractDockerImages(fileContent) { const result = []; - if (typeof obj !== 'object' || obj === null) return result; + try { + const doc = yaml.load(fileContent, { schema: yaml.DEFAULT_SCHEMA }); - // Resolve merged objects (anchors or << merges) - let mergedObj = {}; - if (obj['<<']) { - const merge = obj['<<']; - if (Array.isArray(merge)) { - merge.forEach(m => Object.assign(mergedObj, m)); - } else if (typeof merge === 'object') { - Object.assign(mergedObj, merge); + if (!doc.services) return []; + + for (const [serviceName, serviceDef] of Object.entries(doc.services)) { + let image = serviceDef.image; + + // Resolve anchors/merges if image is not directly present + if (!image && serviceDef['<<']) { + const merge = serviceDef['<<']; + if (Array.isArray(merge)) { + merge.forEach(m => { + if (m.image) image = m.image; + }); + } else if (merge.image) { + image = merge.image; + } + } + + if (image) { + const [depName, currentValue] = image.split(':'); + result.push({ + depName: depName, + currentValue: currentValue || 'latest', + service: serviceName // <- added for Renovate PR title + }); + } } - } - // Merge top-level keys last to override anchor defaults - Object.assign(mergedObj, obj); - - // If an image key exists, capture it - if (mergedObj.image) { - const [depName, currentValue] = mergedObj.image.split(':'); - result.push({ - depName: depName, - currentValue: currentValue || 'latest', - service: path.join('/') || 'root' - }); - } - - // Recursively traverse all keys - for (const [key, value] of Object.entries(mergedObj)) { - // Skip the << key since we've already processed it - if (key === '<<') continue; - result.push(...extractImages(value, [...path, key])); + } catch (err) { + console.error('Failed parsing docker-compose.yml:', err); } return result; }; - -module.exports = function extractDockerImages(fileContent) { - try { - // Parse YAML with anchors preserved - const doc = yaml.load(fileContent, { schema: yaml.DEFAULT_FULL_SCHEMA }); - return extractImages(doc); - } catch (err) { - console.error('Failed parsing docker-compose.yml:', err); - return []; - } -}; -- 2.52.0 From 4abbb5925fb5d55ec37e49a42f2dad3481613455 Mon Sep 17 00:00:00 2001 From: "Trez.One" Date: Wed, 3 Sep 2025 17:34:32 -0400 Subject: [PATCH 4/4] Modifying renovate.json. --- renovate.json | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/renovate.json b/renovate.json index dd6dbd97..cf4777b9 100644 --- a/renovate.json +++ b/renovate.json @@ -26,6 +26,10 @@ "matchDatasources": ["docker"], "matchPackagePatterns": ["^.*:latest$"], "enabled": false + }, + { + "matchDatasources": ["docker"], + "description": "Docker image used by service {{service}} ({{depName}})" } ], @@ -37,7 +41,7 @@ "manager": "regex", "extractVersion": "custom", "datasourceTemplate": "docker", - "depNameTemplate": "{{service | split(\"/\") | last}}/{{depName}}", + "depNameTemplate": "{{service}}/{{depName}}", "versioningTemplate": "docker", "extractor": "file:extract-docker-images.js" } @@ -45,7 +49,9 @@ "branchNameStrict": true, "branchPrefix": "renovate/", + "branchName": "{{service}}/{{depName}}-{{newVersion}}", + "commitMessageAction": "Update", - "commitMessageTopic": "{{service | split(\"/\") | last}}/{{depName}}", - "prTitle": "Update {{service | split(\"/\") | last}}/{{depName}}: {{currentValue}} → {{newVersion}}" + "commitMessageTopic": "{{service}}/{{depName}}", + "commitMessageExtra": "{{currentValue}} → {{newVersion}}" } -- 2.52.0