UNPKG

@elbaph/generate-dependabot-config-from-package-json

Version:
123 lines (122 loc) 4.99 kB
import path from 'node:path'; import fs from 'node:fs'; import semver from 'semver'; function parsePackageJson(packageJsonPath) { let json = fs.readFileSync(packageJsonPath, 'utf8'); let parsedJson = JSON.parse(json); return parsedJson; } export function generateConfig(options, packageJsonPaths) { const dependabotConfig = { version: 2, updates: [], }; const updateTypes = []; if (options.majorUpdates) { updateTypes.push('major'); } if (options.minorUpdates) { updateTypes.push('minor'); } if (options.patchUpdates) { updateTypes.push('patch'); } const baseUpdateTypes = updateTypes; for (const packageJsonPath of packageJsonPaths) { const packageJsonDirname = path.relative(process.cwd(), path.dirname(packageJsonPath)); const updateConfig = { 'package-ecosystem': 'npm', labels: options.labels.split(','), directory: `/${packageJsonDirname}`, schedule: { interval: options.scheduleInterval }, 'versioning-strategy': options.versioningStrategy, groups: { 'production-dependencies': { 'applies-to': 'version-updates', 'dependency-type': 'production', 'update-types': baseUpdateTypes, }, 'development-dependencies': { 'applies-to': 'version-updates', 'dependency-type': 'development', 'update-types': baseUpdateTypes, }, }, ignore: [], }; if (options.separateSecurityFixes) { updateConfig.groups['production-security-fixes'] = { 'applies-to': 'security-updates', 'dependency-type': 'production', }; updateConfig.groups['development-security-fixes'] = { 'applies-to': 'security-updates', 'dependency-type': 'development', }; } const packageJson = parsePackageJson(packageJsonPath); const allDependencies = { ...packageJson.dependencies, ...packageJson.devDependencies, }; const dependabotIgnoredDependencyVersions = []; for (const dependencyName in allDependencies) { const semverRange = allDependencies[dependencyName]; if (semverRange.startsWith('file:')) { continue; } const currentVersionFromRange = semver.coerce(semverRange); if (currentVersionFromRange === null) { throw new Error(`Couldn't convert '${semverRange}' to valid SemVer.`); } const nextMajor = `${currentVersionFromRange.major + 1}.0.0`; const nextMinor = `${currentVersionFromRange.major}.${currentVersionFromRange.minor + 1}.0`; const nextPatch = `${currentVersionFromRange.major}.${currentVersionFromRange.minor}.${currentVersionFromRange.patch + 1}`; const allowMajor = semver.satisfies(nextMajor, semverRange); const allowMinor = semver.satisfies(nextMinor, semverRange); const allowPatch = semver.satisfies(nextPatch, semverRange); const ignoredUpdateTypes = []; if (!allowMajor && options.majorUpdates) { ignoredUpdateTypes.push('version-update:semver-major'); } if (!allowMinor && options.minorUpdates) { ignoredUpdateTypes.push('version-update:semver-minor'); } if (!allowPatch && options.patchUpdates) { ignoredUpdateTypes.push('version-update:semver-patch'); } if (ignoredUpdateTypes.length === 3) { dependabotIgnoredDependencyVersions.push({ 'dependency-name': dependencyName, }); } else if (ignoredUpdateTypes.length > 0) { dependabotIgnoredDependencyVersions.push({ 'dependency-name': dependencyName, 'update-types': ignoredUpdateTypes, }); } } updateConfig.ignore = dependabotIgnoredDependencyVersions; if (!options.majorUpdates) { updateConfig.ignore.push({ 'dependency-name': '*', 'update-types': ['version-update:semver-major'], }); } if (!options.minorUpdates) { updateConfig.ignore.push({ 'dependency-name': '*', 'update-types': ['version-update:semver-minor'], }); } if (!options.patchUpdates) { updateConfig.ignore.push({ 'dependency-name': '*', 'update-types': ['version-update:semver-patch'], }); } dependabotConfig.updates.push(updateConfig); } return dependabotConfig; }