Skip to content

Commit 954f874

Browse files
committed
feat(version-bump): add custom version bump targets
- Added `bump_targets` input to action.yml - Created `CustomUpdater` service - Updated `UpdaterService` to handle custom - Improved version update flexibility - Updated changelog and dist/index.js
1 parent 79a20d5 commit 954f874

11 files changed

Lines changed: 222 additions & 22 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
workflow_dispatch:
77

88
permissions:
9-
contents: write # required for pushing + uploading release assets
9+
contents: write # required for pushing + uploading release assets
1010

1111
jobs:
1212
release:

.github/workflows/tag-after-merge.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
if: env.release_type != 'patch'
7979
run: |
8080
awk "/^## v${{ env.version }}[[:space:]]/{flag=1; next} /^## /{flag=0} flag" CHANGELOG.md > RELEASE_NOTES.md
81-
81+
8282
if [ "${{ env.release_type }}" = "major" ]; then
8383
echo "## 🚀 Major Release" > FINAL_NOTES.md
8484
elif [ "${{ env.release_type }}" = "minor" ]; then

CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ All notable changes for each version of the Ambient Music extension.
66

77
## v0.10.2 2025-08-27
88

9-
109
### Changed
1110

1211
- restructure service initialization

action.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,14 @@ inputs:
2222
description: 'The target path where the version bump should be applied. If not provided, the action will run in the root directory.'
2323
required: false
2424
default: '.'
25-
25+
bump_targets:
26+
description: |
27+
Optional list of version update targets.
28+
Provide the `path` and the `variable` to update, the Action will build regex automatically.
29+
Example:
30+
'[{"path": "setup.py", "variable": "version"}, {"path": "Dockerfile", "variable": "APP_VERSION"}]'
31+
required: false
32+
default: '[]'
2633
outputs:
2734
new_version:
2835
description: 'The new bumped version'

dist/index.js

Lines changed: 119 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/**
2-
* universal-version-bump v0.10.1
2+
* universal-version-bump v0.10.3
33
* Universal Version Bump
44
*
55
* Description: A GitHub Action to automatically bump versions across any app (Node, Python, PHP, Docker, etc.)
66
* Author: Taj <[email protected]>
77
* Homepage: https://github.com/taj54/universal-version-bump#readme
88
* License: MIT
9-
* Generated on Wed, 27 Aug 2025 10:24:47 GMT
9+
* Generated on Fri, 29 Aug 2025 12:57:13 GMT
1010
*/
1111
require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
1212
/******/ var __webpack_modules__ = ({
@@ -32667,12 +32667,13 @@ var __importStar = (this && this.__importStar) || (function () {
3266732667
};
3266832668
})();
3266932669
Object.defineProperty(exports, "__esModule", ({ value: true }));
32670-
exports.TARGET_PATH = exports.GIT_TAG = exports.TARGET_PLATFORM = exports.RELEASE_TYPE = void 0;
32670+
exports.BUMP_TARGETS = exports.TARGET_PATH = exports.GIT_TAG = exports.TARGET_PLATFORM = exports.RELEASE_TYPE = void 0;
3267132671
const core = __importStar(__nccwpck_require__(9999));
3267232672
exports.RELEASE_TYPE = (core.getInput('release_type') || 'patch');
3267332673
exports.TARGET_PLATFORM = core.getInput('target_platform');
3267432674
exports.GIT_TAG = core.getInput('git_tag') === 'true';
3267532675
exports.TARGET_PATH = core.getInput('target_path') || '.';
32676+
exports.BUMP_TARGETS = JSON.parse(core.getInput('bump_targets') || '[]');
3267632677

3267732678

3267832679
/***/ }),
@@ -32801,7 +32802,8 @@ async function run() {
3280132802
const { updaterService, gitService, changelogService } = await initializeServices();
3280232803
const platform = updaterService.getPlatform(targetPlatform);
3280332804
core.info(`Detected platform: ${platform}`);
32804-
const version = updaterService.updateVersion(platform, releaseType);
32805+
const bumpTargets = JSON.parse(config_1.BUMP_TARGETS);
32806+
const version = updaterService.updateVersion(platform, releaseType, bumpTargets);
3280532807
core.setOutput('new_version', version);
3280632808
// Generate and update changelog
3280732809
const latestTag = await gitService.getLatestTag();
@@ -33266,6 +33268,7 @@ __exportStar(__nccwpck_require__(5417), exports);
3326633268
Object.defineProperty(exports, "__esModule", ({ value: true }));
3326733269
exports.UpdaterService = void 0;
3326833270
const errors_1 = __nccwpck_require__(4830);
33271+
const customUpdater_1 = __nccwpck_require__(5432);
3326933272
/**
3327033273
* Service for managing version updates.
3327133274
*/
@@ -33302,17 +33305,124 @@ class UpdaterService {
3330233305
* @param releaseType The type of release (major, minor, patch).
3330333306
* @returns The new version string.
3330433307
*/
33305-
updateVersion(platform, releaseType) {
33306-
const updater = this.updaterRegistry.getUpdater(platform);
33307-
if (!updater) {
33308-
throw new errors_1.VersionBumpError(`No updater found for platform: ${platform}`);
33308+
updateVersion(platform, releaseType, bumpTargets = []) {
33309+
if (platform === 'custom') {
33310+
if (bumpTargets.length === 0) {
33311+
throw new errors_1.VersionBumpError('No bump_targets provided for custom platform.');
33312+
}
33313+
let lastBumpedVersion = '';
33314+
for (const target of bumpTargets) {
33315+
const customUpdater = new customUpdater_1.CustomUpdater(target.path, target.variable);
33316+
lastBumpedVersion = customUpdater.bumpVersion(releaseType);
33317+
}
33318+
return lastBumpedVersion;
33319+
}
33320+
else {
33321+
const updater = this.updaterRegistry.getUpdater(platform);
33322+
if (!updater) {
33323+
throw new errors_1.VersionBumpError(`No updater found for platform: ${platform}`);
33324+
}
33325+
return updater.bumpVersion(releaseType);
3330933326
}
33310-
return updater.bumpVersion(releaseType);
3331133327
}
3331233328
}
3331333329
exports.UpdaterService = UpdaterService;
3331433330

3331533331

33332+
/***/ }),
33333+
33334+
/***/ 5432:
33335+
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
33336+
33337+
"use strict";
33338+
33339+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
33340+
if (k2 === undefined) k2 = k;
33341+
var desc = Object.getOwnPropertyDescriptor(m, k);
33342+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
33343+
desc = { enumerable: true, get: function() { return m[k]; } };
33344+
}
33345+
Object.defineProperty(o, k2, desc);
33346+
}) : (function(o, m, k, k2) {
33347+
if (k2 === undefined) k2 = k;
33348+
o[k2] = m[k];
33349+
}));
33350+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
33351+
Object.defineProperty(o, "default", { enumerable: true, value: v });
33352+
}) : function(o, v) {
33353+
o["default"] = v;
33354+
});
33355+
var __importStar = (this && this.__importStar) || (function () {
33356+
var ownKeys = function(o) {
33357+
ownKeys = Object.getOwnPropertyNames || function (o) {
33358+
var ar = [];
33359+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33360+
return ar;
33361+
};
33362+
return ownKeys(o);
33363+
};
33364+
return function (mod) {
33365+
if (mod && mod.__esModule) return mod;
33366+
var result = {};
33367+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
33368+
__setModuleDefault(result, mod);
33369+
return result;
33370+
};
33371+
})();
33372+
Object.defineProperty(exports, "__esModule", ({ value: true }));
33373+
exports.CustomUpdater = void 0;
33374+
const core = __importStar(__nccwpck_require__(9999));
33375+
const versionUtil_1 = __nccwpck_require__(2431);
33376+
const fileHandler_1 = __nccwpck_require__(1013);
33377+
const manifestParser_1 = __nccwpck_require__(2521);
33378+
class CustomUpdater {
33379+
constructor(filePath, variableName) {
33380+
this.platform = 'custom';
33381+
this.currentVersion = null;
33382+
this.filePath = filePath;
33383+
this.variableName = variableName;
33384+
this.fileHandler = new fileHandler_1.FileHandler();
33385+
this.manifestParser = new manifestParser_1.ManifestParser(this.fileHandler);
33386+
}
33387+
canHandle() {
33388+
// This updater is explicitly called, so it can always handle if constructed.
33389+
return true;
33390+
}
33391+
getCurrentVersion() {
33392+
if (this.currentVersion) {
33393+
return this.currentVersion;
33394+
}
33395+
try {
33396+
// eslint-disable-next-line no-useless-escape
33397+
const regex = new RegExp(`(${this.variableName}\s*=\s*['"]?)([\\d.]+)(['"]?)`);
33398+
this.currentVersion = this.manifestParser.getVersion(this.filePath, 'regex', {
33399+
regex: regex,
33400+
});
33401+
return this.currentVersion;
33402+
}
33403+
catch (error) {
33404+
core.debug(`Could not read or parse version from ${this.filePath}: ${error}`);
33405+
}
33406+
return null;
33407+
}
33408+
bumpVersion(releaseType) {
33409+
const oldVersion = this.getCurrentVersion();
33410+
if (!oldVersion) {
33411+
throw new Error(`Could not find current version for variable '${this.variableName}' in file '${this.filePath}'`);
33412+
}
33413+
const newVersion = (0, versionUtil_1.calculateNextVersion)(oldVersion, releaseType);
33414+
// eslint-disable-next-line no-useless-escape
33415+
const regexReplace = new RegExp(`(${this.variableName}\s*=\s*['"]?)${oldVersion}(['"]?)`);
33416+
this.manifestParser.updateVersion(this.filePath, newVersion, 'regex', {
33417+
regexReplace: regexReplace,
33418+
});
33419+
core.info(`Bumped ${this.variableName} in ${this.filePath} from ${oldVersion} to ${newVersion}`);
33420+
return newVersion;
33421+
}
33422+
}
33423+
exports.CustomUpdater = CustomUpdater;
33424+
33425+
3331633426
/***/ }),
3331733427

3331833428
/***/ 553:

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,4 @@
5353
"vitest": "^3.2.4",
5454
"yaml": "^2.8.1"
5555
}
56-
}
56+
}

src/config/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export const RELEASE_TYPE = (core.getInput('release_type') || 'patch') as semver
55
export const TARGET_PLATFORM = core.getInput('target_platform');
66
export const GIT_TAG = core.getInput('git_tag') === 'true';
77
export const TARGET_PATH = core.getInput('target_path') || '.';
8+
export const BUMP_TARGETS = JSON.parse(core.getInput('bump_targets') || '[]');

src/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
FileNotFoundError,
88
InvalidManifestError,
99
} from './errors';
10-
import { RELEASE_TYPE, TARGET_PLATFORM, GIT_TAG, TARGET_PATH } from './config';
10+
import { RELEASE_TYPE, TARGET_PLATFORM, GIT_TAG, TARGET_PATH, BUMP_TARGETS } from './config';
1111
import * as core from '@actions/core';
1212

1313
async function initializeServices() {
@@ -37,7 +37,8 @@ async function run() {
3737
const platform = updaterService.getPlatform(targetPlatform);
3838
core.info(`Detected platform: ${platform}`);
3939

40-
const version = updaterService.updateVersion(platform, releaseType);
40+
const bumpTargets = JSON.parse(BUMP_TARGETS);
41+
const version = updaterService.updateVersion(platform, releaseType, bumpTargets);
4142
core.setOutput('new_version', version);
4243

4344
// Generate and update changelog

src/services/updaterService.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import semver from 'semver';
22
import { PlatformDetectionError, VersionBumpError } from '../errors';
33
import { UpdaterRegistry } from '../registry/updaterRegistry';
4+
import { CustomUpdater } from '../updaters/customUpdater';
45

56
/**
67
* Service for managing version updates.
@@ -47,11 +48,27 @@ export class UpdaterService {
4748
* @param releaseType The type of release (major, minor, patch).
4849
* @returns The new version string.
4950
*/
50-
updateVersion(platform: string, releaseType: semver.ReleaseType): string {
51-
const updater = this.updaterRegistry.getUpdater(platform);
52-
if (!updater) {
53-
throw new VersionBumpError(`No updater found for platform: ${platform}`);
51+
updateVersion(
52+
platform: string,
53+
releaseType: semver.ReleaseType,
54+
bumpTargets: Array<{ path: string; variable: string }> = [],
55+
): string {
56+
if (platform === 'custom') {
57+
if (bumpTargets.length === 0) {
58+
throw new VersionBumpError('No bump_targets provided for custom platform.');
59+
}
60+
let lastBumpedVersion: string = '';
61+
for (const target of bumpTargets) {
62+
const customUpdater = new CustomUpdater(target.path, target.variable);
63+
lastBumpedVersion = customUpdater.bumpVersion(releaseType);
64+
}
65+
return lastBumpedVersion;
66+
} else {
67+
const updater = this.updaterRegistry.getUpdater(platform);
68+
if (!updater) {
69+
throw new VersionBumpError(`No updater found for platform: ${platform}`);
70+
}
71+
return updater.bumpVersion(releaseType);
5472
}
55-
return updater.bumpVersion(releaseType);
5673
}
5774
}

0 commit comments

Comments
 (0)