From ceaabda3b6cf55e58d559710d3863890f1c7657f Mon Sep 17 00:00:00 2001 From: Dmitry Dobrynin Date: Sat, 5 Apr 2025 20:15:44 +0200 Subject: [PATCH 1/9] =?UTF-8?q?=E2=9C=A8=20Add=20support=20for=20dynamic?= =?UTF-8?q?=20fields=20for=20python=20parser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 +- packages/gitmoji-changelog-cli/package.json | 1 + .../src/presets/python.js | 125 +++++++++++++----- yarn.lock | 5 + 4 files changed, 98 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index 4cc4e8e..edb9e6a 100644 --- a/package.json +++ b/package.json @@ -28,5 +28,6 @@ }, "workspaces": [ "packages/*" - ] + ], + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/packages/gitmoji-changelog-cli/package.json b/packages/gitmoji-changelog-cli/package.json index e1daa5d..4f3ff53 100644 --- a/packages/gitmoji-changelog-cli/package.json +++ b/packages/gitmoji-changelog-cli/package.json @@ -45,6 +45,7 @@ "semver": "^5.6.0", "semver-compare": "^1.0.0", "simple-git": "^1.113.0", + "smol-toml": "^1.3.1", "toml": "^3.0.0", "yaml": "^1.10.2", "yargs": "^17.3.1" diff --git a/packages/gitmoji-changelog-cli/src/presets/python.js b/packages/gitmoji-changelog-cli/src/presets/python.js index 7aed44c..59bbf37 100644 --- a/packages/gitmoji-changelog-cli/src/presets/python.js +++ b/packages/gitmoji-changelog-cli/src/presets/python.js @@ -1,29 +1,60 @@ -const toml = require('toml') const fs = require('fs') +const path = require('path') +const toml = require('smol-toml') +const { execSync } = require('child_process') module.exports = async () => { try { - const pyprojectPromise = new Promise((resolve, reject) => { - try { - resolve(toml.parse(fs.readFileSync('pyproject.toml', 'utf-8'))) - } catch (err) { - reject(err) - } - }) - - const projectFile = await pyprojectPromise - const name = recursiveKeySearch('name', projectFile)[0] - const version = recursiveKeySearch('version', projectFile)[0] - let description = recursiveKeySearch('description', projectFile)[0] + const pyproject = toml.parse(fs.readFileSync('pyproject.toml', 'utf-8')) + const dynamicFields = pyproject.project.dynamic || [] + const name = pyproject.project.name if (!name) { throw new Error('Could not find name metadata in pyproject.toml') } + + let version = pyproject.project.version + const isDynamicVersion = dynamicFields.includes('version') + if (isDynamicVersion) { + const backend = pyproject['build-system']?.['build-backend'] + if (!backend) { + throw new Error('Cannot resolve dynamic version: build-backend is not set') + } + + switch (backend) { + case 'hatchling.build': + version = getHatchVersion() + break + + case 'flit_core.buildapi': + version = getFlitVersion() + break + + case 'setuptools.build_meta': + version = getSetuptoolsScmVersion() + break + + case 'pdm.backend': + version = getPdmVersion() + break + + default: + throw new Error(`Unsupported build-backend: ${backend}`) + } + } if (!version) { - throw new Error('Could not find version metadata in pyproject.toml') + throw new Error('Could not find version metadata (static or dynamic)') } - if (!description) { - description = '' + + let description = pyproject.project.description + const isDynamicDescription = dynamicFields.includes('description') + if (isDynamicDescription) { + let readme = pyproject.project.readme + if (typeof readme === 'object') { + readme = readme.file + } + + description = getDescriptionFromReadme(readme) } return { @@ -31,38 +62,62 @@ module.exports = async () => { version, description, } + } catch (e) { return null } } -function recursiveKeySearch(key, data) { - // https://codereview.stackexchange.com/a/143914 - if (data === null) { - return [] +function getHatchVersion() { + try { + const version = execSync('hatch version', { encoding: 'utf-8' }).trim() + return version + } catch (e) { + throw new Error('Failed to run `hatch version`: ' + e.message) + } +} + + +function getFlitVersion() { + try { + const output = execSync('flit info', { encoding: 'utf-8' }) + const match = output.match(/^Version:\s*(.+)$/m) + if (match) return match[1].trim() + throw new Error('Could not extract version from `flit info` output') + } catch (e) { + throw new Error('Failed to run `flit info`: ' + e.message) } +} + - if (data !== Object(data)) { - return [] +function getSetuptoolsScmVersion() { + try { + return execSync('python -m setuptools_scm', { encoding: 'utf-8' }).trim() + } catch (e) { + throw new Error('Failed to run `setuptools_scm`: ' + e.message) } +} - let results = [] - if (data.constructor === Array) { - for (let i = 0, len = data.length; i < len; i += 1) { - results = results.concat(recursiveKeySearch(key, data[i])) - } - return results +function getPdmVersion() { + try { + return execSync('pdm show --version', { encoding: 'utf-8' }).trim() + } catch (e) { + throw new Error('Failed to run `pdm show --version`: ' + e.message) } +} - for (let i = 0; i < Object.keys(data).length; i += 1) { - const dataKey = Object.keys(data)[i] - if (key === dataKey) { - results.push(data[key]) - } - results = results.concat(recursiveKeySearch(key, data[dataKey])) + +function getDescriptionFromReadme(readmePath = 'README.md') { + if (!fs.existsSync(readmePath)) { + throw new Error(`README file not found: ${readmePath}`) } - return results + const content = fs.readFileSync(readmePath, 'utf-8').trim() + + const paragraphs = content.split(/\r?\n\r?\n/) + const first = paragraphs.find(p => p.trim().length > 0) + + return first?.replace(/^#\s*/, '').trim() || null } diff --git a/yarn.lock b/yarn.lock index e11df11..55be497 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8082,6 +8082,11 @@ smart-buffer@^4.1.0: resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== +smol-toml@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/smol-toml/-/smol-toml-1.3.1.tgz#d9084a9e212142e3cab27ef4e2b8e8ba620bfe15" + integrity sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ== + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" From 9f4f944c37b4483f4130e208d7206b6ee6772740 Mon Sep 17 00:00:00 2001 From: Dmitry Dobrynin Date: Sat, 5 Apr 2025 21:32:42 +0200 Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=A7=AA=20Add=20tests=20for=20dynamic?= =?UTF-8?q?=20fields=20and=20refine=20pyproject=20parser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/presets/python.js | 25 +-- .../src/presets/python.spec.js | 199 +++++++++++++++++- 2 files changed, 205 insertions(+), 19 deletions(-) diff --git a/packages/gitmoji-changelog-cli/src/presets/python.js b/packages/gitmoji-changelog-cli/src/presets/python.js index 59bbf37..b6ed7b7 100644 --- a/packages/gitmoji-changelog-cli/src/presets/python.js +++ b/packages/gitmoji-changelog-cli/src/presets/python.js @@ -1,19 +1,20 @@ const fs = require('fs') const path = require('path') const toml = require('smol-toml') -const { execSync } = require('child_process') +const child_process = require('child_process') module.exports = async () => { try { const pyproject = toml.parse(fs.readFileSync('pyproject.toml', 'utf-8')) - const dynamicFields = pyproject.project.dynamic || [] + const meta = pyproject.project || pyproject.tool?.poetry + const dynamicFields = meta.dynamic || [] - const name = pyproject.project.name + const name = meta.name if (!name) { throw new Error('Could not find name metadata in pyproject.toml') } - let version = pyproject.project.version + let version = meta.version const isDynamicVersion = dynamicFields.includes('version') if (isDynamicVersion) { const backend = pyproject['build-system']?.['build-backend'] @@ -46,15 +47,15 @@ module.exports = async () => { throw new Error('Could not find version metadata (static or dynamic)') } - let description = pyproject.project.description + let description = meta.description || '' const isDynamicDescription = dynamicFields.includes('description') if (isDynamicDescription) { - let readme = pyproject.project.readme + let readme = meta.readme if (typeof readme === 'object') { readme = readme.file } - description = getDescriptionFromReadme(readme) + description = getDescriptionFromReadme(readme) || '' } return { @@ -71,7 +72,7 @@ module.exports = async () => { function getHatchVersion() { try { - const version = execSync('hatch version', { encoding: 'utf-8' }).trim() + const version = child_process.execSync('hatch version', { encoding: 'utf-8' }).trim() return version } catch (e) { throw new Error('Failed to run `hatch version`: ' + e.message) @@ -81,7 +82,7 @@ function getHatchVersion() { function getFlitVersion() { try { - const output = execSync('flit info', { encoding: 'utf-8' }) + const output = child_process.execSync('flit info', { encoding: 'utf-8' }) const match = output.match(/^Version:\s*(.+)$/m) if (match) return match[1].trim() throw new Error('Could not extract version from `flit info` output') @@ -93,7 +94,7 @@ function getFlitVersion() { function getSetuptoolsScmVersion() { try { - return execSync('python -m setuptools_scm', { encoding: 'utf-8' }).trim() + return child_process.execSync('python -m setuptools_scm', { encoding: 'utf-8' }).trim() } catch (e) { throw new Error('Failed to run `setuptools_scm`: ' + e.message) } @@ -102,7 +103,7 @@ function getSetuptoolsScmVersion() { function getPdmVersion() { try { - return execSync('pdm show --version', { encoding: 'utf-8' }).trim() + return child_process.execSync('pdm show --version', { encoding: 'utf-8' }).trim() } catch (e) { throw new Error('Failed to run `pdm show --version`: ' + e.message) } @@ -111,7 +112,7 @@ function getPdmVersion() { function getDescriptionFromReadme(readmePath = 'README.md') { if (!fs.existsSync(readmePath)) { - throw new Error(`README file not found: ${readmePath}`) + return '' } const content = fs.readFileSync(readmePath, 'utf-8').trim() diff --git a/packages/gitmoji-changelog-cli/src/presets/python.spec.js b/packages/gitmoji-changelog-cli/src/presets/python.spec.js index 797aa17..5e404e8 100644 --- a/packages/gitmoji-changelog-cli/src/presets/python.spec.js +++ b/packages/gitmoji-changelog-cli/src/presets/python.spec.js @@ -1,8 +1,13 @@ const fs = require('fs') +const child_process = require('child_process') const loadProjectInfo = require('./python.js') -describe('getPackageInfo', () => { +describe('getPackageInfo | python', () => { + afterEach(() => { + jest.restoreAllMocks() + }) + it('should extract metadata from a pyproject.toml made by poetry', async () =>{ // Note the TOML section is distinct for poetry fs.readFileSync.mockReturnValue(` @@ -43,32 +48,32 @@ describe('getPackageInfo', () => { "Development Status :: 4 - Beta", "Programming Language :: Python" ] - + dependencies = [ "httpx", "gidgethub[httpx]>4.0.0", "django>2.1; os_name != 'nt'", "django>2.0; os_name == 'nt'" ] - + [project.optional-dependencies] test = [ "pytest < 5.0.0", "pytest-cov[all]" ] - + [project.urls] homepage = "example.com" documentation = "readthedocs.org" repository = "github.com" changelog = "github.com/me/spam/blob/master/CHANGELOG.md" - + [project.scripts] spam-cli = "spam:main_cli" - + [project.gui-scripts] spam-gui = "spam:main_gui" - + [project.entry-points."spam.magical"] tomatoes = "spam:main_tomatoes" `) @@ -133,5 +138,185 @@ describe('getPackageInfo', () => { }) }) +describe('getPackageInfo | python | dynamic version', () => { + afterEach(() => { + jest.restoreAllMocks() + }) + + it('should extract version from dynamic field for hatch', async () => { + fs.readFileSync.mockReturnValue(` + [build-system] + build-backend = "hatchling.build" + + [project] + name = "hatch-package-name" + dynamic = ["version"] + + [tool.hatch.version] + path = "src/__init__.py" + `) + jest.spyOn(child_process, 'execSync').mockReturnValue('0.0.1\n') + + const result = await loadProjectInfo() + + expect(result.version).toEqual('0.0.1') + }) + + it('should extract version from dynamic field for flit', async () => { + fs.readFileSync.mockReturnValue(` + [build-system] + build-backend = "flit_core.buildapi" + + [project] + name = "flit-package-name" + dynamic = ["version"] + + [tool.flit.module] + name = "flit_package_name" + `) + jest.spyOn(child_process, 'execSync').mockReturnValue( + `Module: flit_package_name\nVersion: 0.2.3` + ) + + const result = await loadProjectInfo() + + expect(result.version).toEqual('0.2.3') + }) + + it('should extract version using setuptools_scm', async () => { + fs.readFileSync.mockReturnValue(` + [build-system] + build-backend = "setuptools.build_meta" + + [project] + name = "setuptools-package" + dynamic = ["version"] + + [tool.setuptools_scm] + `) + jest.spyOn(child_process, 'execSync').mockReturnValue('1.2.3\n') + + const result = await loadProjectInfo() + + expect(result.version).toEqual('1.2.3') + }) + + it('should extract version from dynamic field for pdm', async () => { + fs.readFileSync.mockReturnValue(` + [build-system] + build-backend = "pdm.backend" + + [project] + name = "pdm-package" + dynamic = ["version"] + + [tool.pdm.version] + source = "file" + `) + jest.spyOn(child_process, 'execSync').mockReturnValue('3.4.5\n') + + const result = await loadProjectInfo() + + expect(result.version).toEqual('3.4.5') + }) +}) + +describe('getPackageInfo | python | dynamic description', () => { + afterEach(() => { + jest.restoreAllMocks() + }) + + it('should extract description from README.md (string path)', async () => { + fs.readFileSync.mockImplementation((filePath) => { + console.log(filePath) + if (filePath === 'pyproject.toml') { + return ` + [project] + name = "my-lib" + version = "1.0.0" + dynamic = ["description"] + readme = "README.md" + ` + } + if (filePath === 'README.md') { + return ` +# My Awesome Library + +This is a longer description. + ` + } + }) + fs.existsSync.mockReturnValue(true) + + const result = await loadProjectInfo() + expect(result.description).toBe('My Awesome Library') + }) + + it('should extract description from readme.file object path', async () => { + fs.readFileSync.mockImplementation((filePath) => { + if (filePath === 'pyproject.toml') { + return ` + [project] + name = "obj-readme" + version = "1.0.0" + dynamic = ["description"] + + [project.readme] + file = "README.rst" + ` + } + if (filePath === 'README.rst') { + return ` +# Title from rst + +More details follow... + ` + } + }) + fs.existsSync.mockReturnValue(true) + + const result = await loadProjectInfo() + expect(result.description).toBe('Title from rst') + }) + + it('should return empty description if README is empty', async () => { + fs.readFileSync.mockImplementation((filePath) => { + if (filePath === 'pyproject.toml') { + return ` + [project] + name = "empty-readme" + version = "1.0.0" + dynamic = ["description"] + readme = "README.md" + ` + } + if (filePath === 'README.md') { + return `` + } + }) + fs.existsSync.mockReturnValue(true) + + const result = await loadProjectInfo() + expect(result.description).toBe('') + }) + + it('should fallback to empty description if README file not found', async () => { + fs.readFileSync.mockImplementation((filePath) => { + if (filePath === 'pyproject.toml') { + return ` + [project] + name = "no-readme" + version = "1.0.0" + dynamic = ["description"] + readme = "README.md" + ` + } + }) + fs.existsSync.mockReturnValue(false) + + const result = await loadProjectInfo() + expect(result.description).toBe('') + }) +}) jest.mock('fs') From 6cf2e68b47c34e0fb9f1ae7b5fa37cb6c16feeba Mon Sep 17 00:00:00 2001 From: Dmitry Dobrynin Date: Sat, 5 Apr 2025 22:30:24 +0200 Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=9A=A8=20Linting=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/presets/python.js | 18 ++++++++--------- .../src/presets/python.spec.js | 20 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/packages/gitmoji-changelog-cli/src/presets/python.js b/packages/gitmoji-changelog-cli/src/presets/python.js index b6ed7b7..fe5d353 100644 --- a/packages/gitmoji-changelog-cli/src/presets/python.js +++ b/packages/gitmoji-changelog-cli/src/presets/python.js @@ -1,12 +1,11 @@ const fs = require('fs') -const path = require('path') const toml = require('smol-toml') -const child_process = require('child_process') +const ChildProcess = require('child_process') module.exports = async () => { try { const pyproject = toml.parse(fs.readFileSync('pyproject.toml', 'utf-8')) - const meta = pyproject.project || pyproject.tool?.poetry + const meta = pyproject.project || (pyproject.tool && pyproject.tool.poetry) const dynamicFields = meta.dynamic || [] const name = meta.name @@ -17,7 +16,7 @@ module.exports = async () => { let version = meta.version const isDynamicVersion = dynamicFields.includes('version') if (isDynamicVersion) { - const backend = pyproject['build-system']?.['build-backend'] + const backend = pyproject['build-system'] && pyproject['build-system']['build-backend'] if (!backend) { throw new Error('Cannot resolve dynamic version: build-backend is not set') } @@ -63,7 +62,6 @@ module.exports = async () => { version, description, } - } catch (e) { return null } @@ -72,7 +70,7 @@ module.exports = async () => { function getHatchVersion() { try { - const version = child_process.execSync('hatch version', { encoding: 'utf-8' }).trim() + const version = ChildProcess.execSync('hatch version', { encoding: 'utf-8' }).trim() return version } catch (e) { throw new Error('Failed to run `hatch version`: ' + e.message) @@ -82,7 +80,7 @@ function getHatchVersion() { function getFlitVersion() { try { - const output = child_process.execSync('flit info', { encoding: 'utf-8' }) + const output = ChildProcess.execSync('flit info', { encoding: 'utf-8' }) const match = output.match(/^Version:\s*(.+)$/m) if (match) return match[1].trim() throw new Error('Could not extract version from `flit info` output') @@ -94,7 +92,7 @@ function getFlitVersion() { function getSetuptoolsScmVersion() { try { - return child_process.execSync('python -m setuptools_scm', { encoding: 'utf-8' }).trim() + return ChildProcess.execSync('python -m setuptools_scm', { encoding: 'utf-8' }).trim() } catch (e) { throw new Error('Failed to run `setuptools_scm`: ' + e.message) } @@ -103,7 +101,7 @@ function getSetuptoolsScmVersion() { function getPdmVersion() { try { - return child_process.execSync('pdm show --version', { encoding: 'utf-8' }).trim() + return ChildProcess.execSync('pdm show --version', { encoding: 'utf-8' }).trim() } catch (e) { throw new Error('Failed to run `pdm show --version`: ' + e.message) } @@ -120,5 +118,5 @@ function getDescriptionFromReadme(readmePath = 'README.md') { const paragraphs = content.split(/\r?\n\r?\n/) const first = paragraphs.find(p => p.trim().length > 0) - return first?.replace(/^#\s*/, '').trim() || null + return first ? first.replace(/^#\s*/, '').trim() : null } diff --git a/packages/gitmoji-changelog-cli/src/presets/python.spec.js b/packages/gitmoji-changelog-cli/src/presets/python.spec.js index 5e404e8..815456a 100644 --- a/packages/gitmoji-changelog-cli/src/presets/python.spec.js +++ b/packages/gitmoji-changelog-cli/src/presets/python.spec.js @@ -1,5 +1,5 @@ const fs = require('fs') -const child_process = require('child_process') +const ChildProcess = require('child_process') const loadProjectInfo = require('./python.js') @@ -155,7 +155,7 @@ describe('getPackageInfo | python | dynamic version', () => { [tool.hatch.version] path = "src/__init__.py" `) - jest.spyOn(child_process, 'execSync').mockReturnValue('0.0.1\n') + jest.spyOn(ChildProcess, 'execSync').mockReturnValue('0.0.1\n') const result = await loadProjectInfo() @@ -174,8 +174,8 @@ describe('getPackageInfo | python | dynamic version', () => { [tool.flit.module] name = "flit_package_name" `) - jest.spyOn(child_process, 'execSync').mockReturnValue( - `Module: flit_package_name\nVersion: 0.2.3` + jest.spyOn(ChildProcess, 'execSync').mockReturnValue( + 'Module: flit_package_name\nVersion: 0.2.3' ) const result = await loadProjectInfo() @@ -194,7 +194,7 @@ describe('getPackageInfo | python | dynamic version', () => { [tool.setuptools_scm] `) - jest.spyOn(child_process, 'execSync').mockReturnValue('1.2.3\n') + jest.spyOn(ChildProcess, 'execSync').mockReturnValue('1.2.3\n') const result = await loadProjectInfo() @@ -213,7 +213,7 @@ describe('getPackageInfo | python | dynamic version', () => { [tool.pdm.version] source = "file" `) - jest.spyOn(child_process, 'execSync').mockReturnValue('3.4.5\n') + jest.spyOn(ChildProcess, 'execSync').mockReturnValue('3.4.5\n') const result = await loadProjectInfo() @@ -228,7 +228,6 @@ describe('getPackageInfo | python | dynamic description', () => { it('should extract description from README.md (string path)', async () => { fs.readFileSync.mockImplementation((filePath) => { - console.log(filePath) if (filePath === 'pyproject.toml') { return ` [project] @@ -245,6 +244,7 @@ describe('getPackageInfo | python | dynamic description', () => { This is a longer description. ` } + return '' }) fs.existsSync.mockReturnValue(true) @@ -272,6 +272,7 @@ This is a longer description. More details follow... ` } + return '' }) fs.existsSync.mockReturnValue(true) @@ -290,9 +291,7 @@ More details follow... readme = "README.md" ` } - if (filePath === 'README.md') { - return `` - } + return '' }) fs.existsSync.mockReturnValue(true) @@ -311,6 +310,7 @@ More details follow... readme = "README.md" ` } + return '' }) fs.existsSync.mockReturnValue(false) From 8429555aae0dd8ca403035306ead3298c2f81898 Mon Sep 17 00:00:00 2001 From: Dmitry Dobrynin Date: Wed, 23 Apr 2025 01:03:59 +0200 Subject: [PATCH 4/9] =?UTF-8?q?=F0=9F=91=B7=20Upgrade=20Node=20to=20versio?= =?UTF-8?q?n=2018-alpine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3c88070..1d07efd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:12.14.1-alpine3.11 +FROM node:18-alpine3.20 ENV NODE_ENV=production # install dependencies From 01aec9748b6ddc516cde46af750069ed5c4c771d Mon Sep 17 00:00:00 2001 From: Dmitry Dobrynin Date: Wed, 23 Apr 2025 01:15:08 +0200 Subject: [PATCH 5/9] =?UTF-8?q?=F0=9F=94=A7=20Update=20engines.node=20to?= =?UTF-8?q?=20require=20Node.js=20>=3D18?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/gitmoji-changelog-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gitmoji-changelog-cli/package.json b/packages/gitmoji-changelog-cli/package.json index 4f3ff53..ca78919 100644 --- a/packages/gitmoji-changelog-cli/package.json +++ b/packages/gitmoji-changelog-cli/package.json @@ -15,7 +15,7 @@ "description": "Gitmoji Changelog CLI", "main": "src/index.js", "engines": { - "node": ">=10" + "node": ">=18" }, "bin": { "gitmoji-changelog": "./src/index.js" From 92095ecb24449116e3aec7cb25f2c638ebaef63f Mon Sep 17 00:00:00 2001 From: Dmitry Dobrynin Date: Wed, 23 Apr 2025 01:34:53 +0200 Subject: [PATCH 6/9] =?UTF-8?q?=F0=9F=94=A7=20Update=20Node=20version=20in?= =?UTF-8?q?=20GH=20Actions=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/canary-release.yml | 2 +- .github/workflows/test-and-lint.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/canary-release.yml b/.github/workflows/canary-release.yml index e30e8c3..ccd6ca6 100644 --- a/.github/workflows/canary-release.yml +++ b/.github/workflows/canary-release.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: - node-version: [12] + node-version: [18] steps: - name: Checkout project diff --git a/.github/workflows/test-and-lint.yml b/.github/workflows/test-and-lint.yml index 782904e..72df2ff 100644 --- a/.github/workflows/test-and-lint.yml +++ b/.github/workflows/test-and-lint.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [12] + node-version: [18] steps: - name: Checkout project From 8be906a69069d41f9a5400ab8e0149a02306bad7 Mon Sep 17 00:00:00 2001 From: Dmitry Dobrynin Date: Wed, 23 Apr 2025 01:41:08 +0200 Subject: [PATCH 7/9] =?UTF-8?q?=F0=9F=94=A7=20Update=20Node=20version=20to?= =?UTF-8?q?=20LTS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/canary-release.yml | 2 +- .github/workflows/test-and-lint.yml | 2 +- Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/canary-release.yml b/.github/workflows/canary-release.yml index ccd6ca6..f16a360 100644 --- a/.github/workflows/canary-release.yml +++ b/.github/workflows/canary-release.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: - node-version: [18] + node-version: [lts/*] steps: - name: Checkout project diff --git a/.github/workflows/test-and-lint.yml b/.github/workflows/test-and-lint.yml index 72df2ff..79bf471 100644 --- a/.github/workflows/test-and-lint.yml +++ b/.github/workflows/test-and-lint.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [18] + node-version: [lts/*] steps: - name: Checkout project diff --git a/Dockerfile b/Dockerfile index 1d07efd..87602f4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine3.20 +FROM node:lts-alpine3.20 ENV NODE_ENV=production # install dependencies From aba0600da5840e533e203f89d670f0bef9a24555 Mon Sep 17 00:00:00 2001 From: Dmitry Dobrynin Date: Wed, 23 Apr 2025 01:46:27 +0200 Subject: [PATCH 8/9] =?UTF-8?q?=F0=9F=94=A7=20Specify=20Node=20LTS=20versi?= =?UTF-8?q?on=20using=20.nvmrc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .nvmrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..b009dfb --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +lts/* From 1be62aae584f11e67f1768314ed2302c1e9e3704 Mon Sep 17 00:00:00 2001 From: Dmitry Dobrynin Date: Mon, 28 Apr 2025 23:58:44 +0200 Subject: [PATCH 9/9] =?UTF-8?q?=F0=9F=A9=B9=20Fixed=20Node=20versions=20in?= =?UTF-8?q?=20CI/CD=20configurations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/canary-release.yml | 4 +++- .github/workflows/test-and-lint.yml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/canary-release.yml b/.github/workflows/canary-release.yml index f16a360..3154ffa 100644 --- a/.github/workflows/canary-release.yml +++ b/.github/workflows/canary-release.yml @@ -11,16 +11,18 @@ jobs: strategy: matrix: - node-version: [lts/*] + node-version: [18] steps: - name: Checkout project uses: actions/checkout@v1 + - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} registry-url: 'https://registry.npmjs.org' + - name: Install dependencies run: yarn install --frozen-lockfile - name: Publish Canary version diff --git a/.github/workflows/test-and-lint.yml b/.github/workflows/test-and-lint.yml index 79bf471..abed234 100644 --- a/.github/workflows/test-and-lint.yml +++ b/.github/workflows/test-and-lint.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [lts/*] + node-version: [18, 20, 22] steps: - name: Checkout project