The UpdateSetManager class provides operations for managing ServiceNow update sets programmatically.
The UpdateSetManager enables you to:
- Set and get the current update set for a session
- List update sets from the
sys_update_settable with filtering - Create new update sets with optional description, application, and state
- Move
sys_update_xmlrecords between update sets - Clone an entire update set and its records into a new update set
- Inspect an update set to see its contents grouped by component type
constructor(instance: ServiceNowInstance)import { ServiceNowInstance, UpdateSetManager } from '@sonisoft/now-sdk-ext-core';
const updateSetManager = new UpdateSetManager(instance);Sets the current update set for the session using the concoursepicker API.
async setCurrentUpdateSet(options: SetUpdateSetOptions): Promise<void>| Parameter | Type | Description |
|---|---|---|
options |
SetUpdateSetOptions |
The update set name and sysId to set as current |
| Property | Type | Description |
|---|---|---|
name |
string |
Name of the update set |
sysId |
string |
sys_id of the update set |
ErrorifnameorsysIdis emptyErrorif the PUT request fails
await updateSetManager.setCurrentUpdateSet({
name: 'My Feature Update Set',
sysId: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6'
});
console.log('Current update set changed successfully');Retrieves the currently active update set using the concoursepicker API.
async getCurrentUpdateSet(): Promise<UpdateSetRecord | null>Promise<UpdateSetRecord | null> -- the current update set record with sys_id, name, and state fields populated.
Errorif the API call fails or returns a non-200 status
const current = await updateSetManager.getCurrentUpdateSet();
if (current) {
console.log(`Current update set: ${current.name}`);
console.log(`sys_id: ${current.sys_id}`);
console.log(`State: ${current.state}`);
}Lists update sets from the sys_update_set table using the Table API.
async listUpdateSets(options?: ListUpdateSetsOptions): Promise<UpdateSetRecord[]>| Parameter | Type | Default | Description |
|---|---|---|---|
options |
ListUpdateSetsOptions |
{} |
Optional query, limit, and fields options |
| Property | Type | Default | Description |
|---|---|---|---|
encodedQuery |
string |
- | Encoded query string for filtering (ServiceNow encoded query syntax) |
limit |
number |
100 |
Maximum number of records to return |
fields |
string |
- | Comma-separated list of fields to return |
Promise<UpdateSetRecord[]> -- an array of update set records.
Errorif the API call fails or returns a non-200 status
// List all update sets
const allSets = await updateSetManager.listUpdateSets();
console.log(`Found ${allSets.length} update sets`);
// List only "in progress" update sets with specific fields
const inProgress = await updateSetManager.listUpdateSets({
encodedQuery: 'state=in progress',
limit: 50,
fields: 'sys_id,name,state,description,sys_created_on'
});
inProgress.forEach(us => {
console.log(`${us.name} (${us.state}) - created: ${us.sys_created_on}`);
});Creates a new update set in the sys_update_set table.
async createUpdateSet(options: CreateUpdateSetOptions): Promise<UpdateSetRecord>| Parameter | Type | Description |
|---|---|---|
options |
CreateUpdateSetOptions |
The update set name and optional configuration |
| Property | Type | Default | Description |
|---|---|---|---|
name |
string |
- | Name of the update set (required) |
description |
string |
- | Description of the update set |
application |
string |
- | Application scope sys_id |
state |
string |
"in progress" |
State of the update set |
Promise<UpdateSetRecord> -- the created update set record.
Errorifnameis emptyErrorif the API call fails or returns a non-200/201 status
const newSet = await updateSetManager.createUpdateSet({
name: 'FEAT-1234 Login Page Redesign',
description: 'Update set for login page UI changes',
state: 'in progress'
});
console.log(`Created: ${newSet.name} (${newSet.sys_id})`);Moves sys_update_xml records to a target update set. Records can be selected by explicit sys_ids, by source update set, by time range, or by a combination of source update set and time range.
async moveRecordsToUpdateSet(
targetUpdateSetId: string,
options?: MoveRecordsOptions
): Promise<MoveRecordsResult>| Parameter | Type | Description |
|---|---|---|
targetUpdateSetId |
string |
The sys_id of the target update set |
options |
MoveRecordsOptions |
Options for selecting which records to move |
| Property | Type | Description |
|---|---|---|
recordSysIds |
string[] |
Specific record sys_ids to move |
timeRange |
{ start: string; end: string } |
Time range to select records by sys_created_on |
sourceUpdateSet |
string |
Source update set sys_id to move records from |
onProgress |
(message: string) => void |
Callback for progress updates |
At least one of recordSysIds, timeRange, or sourceUpdateSet must be provided.
Promise<MoveRecordsResult> containing:
moved: Number of records successfully movedfailed: Number of records that failed to moverecords: Details of each record processed (sys_id, name, type, status)errors: Details of errors encountered (sys_id, error message)
ErroriftargetUpdateSetIdis emptyErrorif no selection criteria is provided
// Move specific records by sys_id
const result = await updateSetManager.moveRecordsToUpdateSet(
'target-update-set-sys-id',
{
recordSysIds: ['record-1-sys-id', 'record-2-sys-id'],
onProgress: (msg) => console.log(msg)
}
);
console.log(`Moved: ${result.moved}, Failed: ${result.failed}`);
// Move all records from a source update set
const bulkResult = await updateSetManager.moveRecordsToUpdateSet(
'target-update-set-sys-id',
{ sourceUpdateSet: 'source-update-set-sys-id' }
);Clones an update set by creating a new update set and copying all sys_update_xml records from the source.
async cloneUpdateSet(
sourceUpdateSetId: string,
newName: string,
onProgress?: (message: string) => void
): Promise<CloneUpdateSetResult>| Parameter | Type | Description |
|---|---|---|
sourceUpdateSetId |
string |
The sys_id of the source update set to clone |
newName |
string |
The name for the new cloned update set |
onProgress |
(message: string) => void |
Optional callback for progress updates |
Promise<CloneUpdateSetResult> containing:
newUpdateSetId: sys_id of the newly created update setnewUpdateSetName: Name of the newly created update setsourceUpdateSetId: sys_id of the source update setsourceUpdateSetName: Name of the source update setrecordsCloned: Number of records clonedtotalSourceRecords: Total number of records in the source
ErrorifsourceUpdateSetIdornewNameis emptyErrorif the source update set is not foundErrorif the new update set cannot be created
const cloneResult = await updateSetManager.cloneUpdateSet(
'source-update-set-sys-id',
'My Feature v2 - Clone',
(msg) => console.log(msg)
);
console.log(`Cloned "${cloneResult.sourceUpdateSetName}" -> "${cloneResult.newUpdateSetName}"`);
console.log(`Records cloned: ${cloneResult.recordsCloned}/${cloneResult.totalSourceRecords}`);Inspects an update set by querying its sys_update_xml records and grouping them by component type.
async inspectUpdateSet(updateSetSysId: string): Promise<InspectUpdateSetResult>| Parameter | Type | Description |
|---|---|---|
updateSetSysId |
string |
The sys_id of the update set to inspect |
Promise<InspectUpdateSetResult> containing:
updateSet: Summary of the update set (sys_id, name, state, description)totalRecords: Total number of records in the update setcomponents: Array of component groups, each with atype,count, anditemslist
ErrorifupdateSetSysIdis emptyErrorif the update set is not found
const inspection = await updateSetManager.inspectUpdateSet('update-set-sys-id');
console.log(`Update Set: ${inspection.updateSet.name} (${inspection.updateSet.state})`);
console.log(`Total Records: ${inspection.totalRecords}`);
console.log('\nComponents:');
inspection.components.forEach(comp => {
console.log(` ${comp.type}: ${comp.count} records`);
comp.items.forEach(item => console.log(` - ${item}`));
});A record from the sys_update_set table.
interface UpdateSetRecord {
/** System ID */
sys_id: string;
/** Name of the update set */
name: string;
/** Description of the update set */
description?: string;
/** State of the update set (e.g., "in progress", "complete") */
state: string;
/** Application scope reference */
application?: string;
/** Created timestamp */
sys_created_on?: string;
/** Updated timestamp */
sys_updated_on?: string;
/** Created by user */
sys_created_by?: string;
/** Additional fields */
[key: string]: unknown;
}A record from the sys_update_xml table.
interface UpdateXmlRecord {
/** System ID */
sys_id: string;
/** Name of the update XML record */
name?: string;
/** Type of the record (e.g., "sys_script_include") */
type?: string;
/** Target name of the record */
target_name?: string;
/** Reference to the parent update set */
update_set: string;
/** XML payload */
payload?: string;
/** Category of the update */
category?: string;
/** Created timestamp */
sys_created_on?: string;
/** Additional fields */
[key: string]: unknown;
}Options for setting the current update set.
interface SetUpdateSetOptions {
/** Name of the update set */
name: string;
/** sys_id of the update set */
sysId: string;
}Options for listing update sets.
interface ListUpdateSetsOptions {
/** Encoded query string for filtering */
encodedQuery?: string;
/** Maximum number of records to return */
limit?: number;
/** Comma-separated list of fields to return */
fields?: string;
}Options for creating a new update set.
interface CreateUpdateSetOptions {
/** Name of the update set */
name: string;
/** Description of the update set */
description?: string;
/** Application scope sys_id */
application?: string;
/** State of the update set (defaults to "in progress") */
state?: string;
}Options for moving records between update sets.
interface MoveRecordsOptions {
/** Specific record sys_ids to move */
recordSysIds?: string[];
/** Time range to select records */
timeRange?: {
start: string;
end: string;
};
/** Source update set sys_id to move records from */
sourceUpdateSet?: string;
/** Callback for progress updates */
onProgress?: (message: string) => void;
}Result of moving records between update sets.
interface MoveRecordsResult {
/** Number of records successfully moved */
moved: number;
/** Number of records that failed to move */
failed: number;
/** Details of each record processed */
records: Array<{
sys_id: string;
name?: string;
type?: string;
status: string;
}>;
/** Details of errors encountered */
errors: Array<{
sys_id: string;
error: string;
}>;
}Result of cloning an update set.
interface CloneUpdateSetResult {
/** sys_id of the newly created update set */
newUpdateSetId: string;
/** Name of the newly created update set */
newUpdateSetName: string;
/** sys_id of the source update set */
sourceUpdateSetId: string;
/** Name of the source update set */
sourceUpdateSetName: string;
/** Number of records cloned */
recordsCloned: number;
/** Total number of records in the source update set */
totalSourceRecords: number;
}Result of inspecting an update set.
interface InspectUpdateSetResult {
/** The update set record */
updateSet: {
sys_id: string;
name: string;
state: string;
description?: string;
};
/** Total number of records in the update set */
totalRecords: number;
/** Components grouped by type */
components: Array<{
type: string;
count: number;
items: string[];
}>;
}import { ServiceNowInstance, UpdateSetManager } from '@sonisoft/now-sdk-ext-core';
async function createAndActivateUpdateSet(instance: ServiceNowInstance) {
const usm = new UpdateSetManager(instance);
// Create a new update set
const newSet = await usm.createUpdateSet({
name: 'FEAT-5678 Incident Form Changes',
description: 'Custom fields and UI policies for the incident form',
state: 'in progress'
});
console.log(`Created update set: ${newSet.name} (${newSet.sys_id})`);
// Set it as the current update set
await usm.setCurrentUpdateSet({
name: newSet.name,
sysId: newSet.sys_id
});
console.log('Update set is now active');
// Verify
const current = await usm.getCurrentUpdateSet();
console.log(`Active update set: ${current?.name}`);
}async function reviewUpdateSet(instance: ServiceNowInstance, updateSetId: string) {
const usm = new UpdateSetManager(instance);
const inspection = await usm.inspectUpdateSet(updateSetId);
console.log(`\n=== Update Set Review ===`);
console.log(`Name: ${inspection.updateSet.name}`);
console.log(`State: ${inspection.updateSet.state}`);
console.log(`Description: ${inspection.updateSet.description || 'N/A'}`);
console.log(`Total Records: ${inspection.totalRecords}`);
console.log(`\nComponent Breakdown:`);
inspection.components
.sort((a, b) => b.count - a.count)
.forEach(comp => {
console.log(` ${comp.type}: ${comp.count}`);
comp.items.forEach(item => console.log(` - ${item}`));
});
if (inspection.totalRecords === 0) {
console.warn('\nWarning: Update set is empty -- nothing to promote.');
}
}async function consolidateUpdateSets(
instance: ServiceNowInstance,
sourceId: string,
targetId: string
) {
const usm = new UpdateSetManager(instance);
console.log('Moving all records from source to target update set...');
const result = await usm.moveRecordsToUpdateSet(targetId, {
sourceUpdateSet: sourceId,
onProgress: (msg) => console.log(` ${msg}`)
});
console.log(`\n=== Move Summary ===`);
console.log(`Moved: ${result.moved}`);
console.log(`Failed: ${result.failed}`);
if (result.errors.length > 0) {
console.error('\nErrors:');
result.errors.forEach(e => {
console.error(` ${e.sys_id}: ${e.error}`);
});
}
}async function cloneForTesting(instance: ServiceNowInstance, updateSetId: string) {
const usm = new UpdateSetManager(instance);
const result = await usm.cloneUpdateSet(
updateSetId,
`TEST - ${new Date().toISOString().slice(0, 10)} Clone`,
(msg) => console.log(msg)
);
console.log(`\n=== Clone Complete ===`);
console.log(`Source: ${result.sourceUpdateSetName}`);
console.log(`Clone: ${result.newUpdateSetName} (${result.newUpdateSetId})`);
console.log(`Records: ${result.recordsCloned}/${result.totalSourceRecords}`);
// Optionally set the clone as current
await usm.setCurrentUpdateSet({
name: result.newUpdateSetName,
sysId: result.newUpdateSetId
});
console.log('Clone is now the active update set');
}async function findRecentUpdateSets(instance: ServiceNowInstance) {
const usm = new UpdateSetManager(instance);
// Find in-progress update sets created in the last 7 days
const recentSets = await usm.listUpdateSets({
encodedQuery: 'state=in progress^sys_created_on>=javascript:gs.daysAgoStart(7)',
limit: 25,
fields: 'sys_id,name,state,description,sys_created_on,sys_created_by'
});
console.log(`\n=== Recent Update Sets (${recentSets.length}) ===`);
recentSets.forEach(us => {
console.log(` ${us.name}`);
console.log(` Created: ${us.sys_created_on} by ${us.sys_created_by}`);
console.log(` Description: ${us.description || 'N/A'}`);
});
return recentSets;
}- One Feature Per Update Set: Create a dedicated update set for each feature or fix to keep changes organized and easy to review.
- Inspect Before Promoting: Always use
inspectUpdateSetto review the contents before promoting to higher environments. - Use Descriptive Names: Include ticket numbers or feature names in update set names (e.g.,
"FEAT-1234 Login Redesign") for traceability. - Monitor Move Operations: Use the
onProgresscallback when moving or cloning records to track progress on large update sets. - Check Move Results: Always inspect the
errorsarray inMoveRecordsResult-- partial failures are possible when moving records in bulk. - Clone for Safety: Use
cloneUpdateSetto create a backup before performing destructive operations on an update set. - Verify Current Update Set: After calling
setCurrentUpdateSet, usegetCurrentUpdateSetto confirm the change took effect. - Filter with Encoded Queries: Use ServiceNow encoded query syntax in
listUpdateSetsfor efficient server-side filtering rather than fetching all records and filtering client-side.