70 lines
2.9 KiB
JavaScript
70 lines
2.9 KiB
JavaScript
// Pure helpers for the application promotion pipeline: producing the next
|
|
// version's deployment plan and advancing assignment rings. No I/O, so both are
|
|
// unit-tested; the controller persists/pushes the results.
|
|
|
|
// Bump the trailing numeric component of a version string (1.2.3 -> 1.2.4,
|
|
// 126 -> 127). Falls back to appending ".1" when no number is present.
|
|
export function bumpVersion(version = '') {
|
|
const text = String(version).trim();
|
|
if (!text) return '1.0.0';
|
|
const match = text.match(/^(.*?)(\d+)(\D*)$/);
|
|
if (!match) return `${text}.1`;
|
|
const [, head, num, tail] = match;
|
|
return `${head}${Number(num) + 1}${tail}`;
|
|
}
|
|
|
|
// Build a fresh deployment payload for the next version, based on an existing
|
|
// plan. The new plan is unpublished (no graphAppId), draft status, and keeps the
|
|
// application link so the catalog groups both versions.
|
|
export function cloneForNextVersion(deployment, { version, applicationId } = {}) {
|
|
if (!deployment) throw new Error('A source deployment is required');
|
|
const nextVersion = version || bumpVersion(extractVersion(deployment.name));
|
|
const baseName = deployment.name.replace(/\s+\d[\d.]*$/, '').trim() || deployment.name;
|
|
return {
|
|
name: `${baseName} ${nextVersion}`.trim(),
|
|
profileId: deployment.profileId || null,
|
|
scriptId: deployment.scriptId || null,
|
|
applicationId: applicationId || deployment.applicationId || null,
|
|
sourceFolder: deployment.sourceFolder || '',
|
|
intunewinFile: '',
|
|
commandStyle: deployment.commandStyle,
|
|
installBehavior: deployment.installBehavior,
|
|
restartBehavior: deployment.restartBehavior,
|
|
uiMode: deployment.uiMode,
|
|
requirements: { ...(deployment.requirements || {}) },
|
|
installCommand: deployment.installCommand,
|
|
uninstallCommand: deployment.uninstallCommand,
|
|
detectionType: deployment.detectionType,
|
|
detectionRule: deployment.detectionRule,
|
|
returnCodes: deployment.returnCodes || [],
|
|
assignments: deployment.assignments || [],
|
|
relationships: deployment.relationships || [],
|
|
status: 'draft',
|
|
graphAppId: '',
|
|
graphConnectionId: deployment.graphConnectionId || null,
|
|
notes: `Version ${nextVersion} created from ${deployment.name}.`,
|
|
visibility: deployment.visibility,
|
|
groupId: deployment.groupId || null
|
|
};
|
|
}
|
|
|
|
function extractVersion(name = '') {
|
|
const match = String(name).match(/(\d[\d.]*)\s*$/);
|
|
return match ? match[1] : '';
|
|
}
|
|
|
|
// Advance a named assignment ring to a new intent (e.g. promote "Broad" from
|
|
// available to required). Returns a new assignments array; unknown rings are a
|
|
// no-op so callers can detect "nothing changed".
|
|
export function setRingIntent(assignments = [], ring, intent) {
|
|
let changed = false;
|
|
const next = assignments.map((assignment) => {
|
|
if (assignment.ring?.toLowerCase() === String(ring).toLowerCase() && assignment.intent !== intent) {
|
|
changed = true;
|
|
return { ...assignment, intent };
|
|
}
|
|
return assignment;
|
|
});
|
|
return { assignments: next, changed };
|
|
}
|