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