diff --git a/.github/actions/update-project-versions/__tests__/index.test.js b/.github/actions/update-project-versions/__tests__/index.test.js index 0411ae4..70d156d 100644 --- a/.github/actions/update-project-versions/__tests__/index.test.js +++ b/.github/actions/update-project-versions/__tests__/index.test.js @@ -297,6 +297,28 @@ describe('updateBuildGradleContent', () => { expect(updated).toContain(`description = 'My project'`); }); + it('updates springCloudVersion declared with set() in an ext block', () => { + const content = `ext {\n\tset('springCloudVersion', "2024.0.1-SNAPSHOT")\n}\n`; + const { updated, updatedProperties } = updateBuildGradleContent( + content, '4.2.9', { 'spring-cloud': '2024.0.9' }); + expect(updated).toBe(`ext {\n\tset('springCloudVersion', "2024.0.9")\n}\n`); + expect(updatedProperties).toEqual(['springCloudVersion: 2024.0.9']); + }); + + it('handles set() with either quote style and spacing', () => { + const content = `ext {\n set( "springCloudVersion" , 'x' )\n}\n`; + const { updated } = updateBuildGradleContent(content, '4.2.9', { 'spring-cloud': '2024.0.9' }); + expect(updated).toBe(`ext {\n set( "springCloudVersion" , '2024.0.9' )\n}\n`); + }); + + it('leaves set() of a key that is not a project version alone', () => { + const content = `ext {\n\tset('javaVersion', "17")\n\tset('springCloudVersion', "2024.0.9")\n}\n`; + const { updated, updatedProperties } = updateBuildGradleContent( + content, '4.2.9', { 'spring-cloud': '2024.0.9' }); + expect(updated).toBe(content); + expect(updatedProperties).toEqual([]); + }); + // spring-cloud-function's Gradle samples declare these in an ext block rather than in // gradle.properties, so a release used to leave them at whatever they had been pinned at // - Boot 2.1.0.BUILD-SNAPSHOT in a train releasing against Boot 4. diff --git a/.github/actions/update-project-versions/dist/index.js b/.github/actions/update-project-versions/dist/index.js index a908286..3972def 100644 --- a/.github/actions/update-project-versions/dist/index.js +++ b/.github/actions/update-project-versions/dist/index.js @@ -28857,20 +28857,36 @@ function updateBuildGradleContent(content, projectVersion, versions = {}) { // // A key that resolves to no project is left alone, which is what keeps `javaVersion` and // similar build settings out of it. + // + // Two spellings of the same extra property are recognised: + // springCloudVersion = "2024.0.1-SNAPSHOT" + // set('springCloudVersion', "2024.0.1-SNAPSHOT") <- what start.spring.io generates const updatedProperties = []; + const ASSIGNMENT = /^(\s*)([a-zA-Z][a-zA-Z0-9]*Version)(\s*=\s*)(['"])([^'"]+)(['"])(.*)$/; + const SET_CALL = /^(\s*set\(\s*)(['"])([a-zA-Z][a-zA-Z0-9]*Version)(['"])(\s*,\s*)(['"])([^'"]+)(['"])(.*)$/; const updated = withProjectVersion.split('\n').map((line) => { - const match = line.match( - /^(\s*)([a-zA-Z][a-zA-Z0-9]*Version)(\s*=\s*)(['"])([^'"]+)(['"])(.*)$/ - ); - if (!match) return line; + let key, currentValue, rewrite; + let match = line.match(ASSIGNMENT); + if (match) { + const [, indent, k, separator, openQuote, value, closeQuote, trailing] = match; + key = k; + currentValue = value; + rewrite = v => `${indent}${k}${separator}${openQuote}${v}${closeQuote}${trailing}`; + } else if ((match = line.match(SET_CALL))) { + const [, head, keyOpen, k, keyClose, comma, openQuote, value, closeQuote, trailing] = match; + key = k; + currentValue = value; + rewrite = v => `${head}${keyOpen}${k}${keyClose}${comma}${openQuote}${v}${closeQuote}${trailing}`; + } else { + return line; + } - const [, indent, key, separator, openQuote, currentValue, closeQuote, trailing] = match; const projectName = camelToKebab(key.slice(0, -'Version'.length)); const targetVersion = versions[projectName]; if (!targetVersion || currentValue === targetVersion) return line; updatedProperties.push(`${key}: ${targetVersion}`); - return `${indent}${key}${separator}${openQuote}${targetVersion}${closeQuote}${trailing}`; + return rewrite(targetVersion); }).join('\n'); // Inline dependency coordinates - "group:artifact:version" - for artifacts this train diff --git a/.github/actions/update-project-versions/src/index.js b/.github/actions/update-project-versions/src/index.js index d0db3e5..81a732d 100644 --- a/.github/actions/update-project-versions/src/index.js +++ b/.github/actions/update-project-versions/src/index.js @@ -632,20 +632,36 @@ function updateBuildGradleContent(content, projectVersion, versions = {}) { // // A key that resolves to no project is left alone, which is what keeps `javaVersion` and // similar build settings out of it. + // + // Two spellings of the same extra property are recognised: + // springCloudVersion = "2024.0.1-SNAPSHOT" + // set('springCloudVersion', "2024.0.1-SNAPSHOT") <- what start.spring.io generates const updatedProperties = []; + const ASSIGNMENT = /^(\s*)([a-zA-Z][a-zA-Z0-9]*Version)(\s*=\s*)(['"])([^'"]+)(['"])(.*)$/; + const SET_CALL = /^(\s*set\(\s*)(['"])([a-zA-Z][a-zA-Z0-9]*Version)(['"])(\s*,\s*)(['"])([^'"]+)(['"])(.*)$/; const updated = withProjectVersion.split('\n').map((line) => { - const match = line.match( - /^(\s*)([a-zA-Z][a-zA-Z0-9]*Version)(\s*=\s*)(['"])([^'"]+)(['"])(.*)$/ - ); - if (!match) return line; + let key, currentValue, rewrite; + let match = line.match(ASSIGNMENT); + if (match) { + const [, indent, k, separator, openQuote, value, closeQuote, trailing] = match; + key = k; + currentValue = value; + rewrite = v => `${indent}${k}${separator}${openQuote}${v}${closeQuote}${trailing}`; + } else if ((match = line.match(SET_CALL))) { + const [, head, keyOpen, k, keyClose, comma, openQuote, value, closeQuote, trailing] = match; + key = k; + currentValue = value; + rewrite = v => `${head}${keyOpen}${k}${keyClose}${comma}${openQuote}${v}${closeQuote}${trailing}`; + } else { + return line; + } - const [, indent, key, separator, openQuote, currentValue, closeQuote, trailing] = match; const projectName = camelToKebab(key.slice(0, -'Version'.length)); const targetVersion = versions[projectName]; if (!targetVersion || currentValue === targetVersion) return line; updatedProperties.push(`${key}: ${targetVersion}`); - return `${indent}${key}${separator}${openQuote}${targetVersion}${closeQuote}${trailing}`; + return rewrite(targetVersion); }).join('\n'); // Inline dependency coordinates - "group:artifact:version" - for artifacts this train