The CreatorCon Call for Content is officially open! Get started here.

Sandaru1
Tera Expert

Background

Often in DevOps-minded organizations, promoting update sets from lower instances to the Production Environment is considered as something to be automated. As there is no such OOB facility available in ServiceNow, the following script is built to fulfill this requirement.

Recommended Algorithm

find_real_file.png

Supportive Scripts

1.  Get Completed Updatesets from Remote instance

//get completed updatesets from a remote instance
function getCompletedUpdateSetsFromRemote(instance_name){
    //get data source
    var id, gr   = new GlideRecord('sys_update_set_source');
    gr.addQuery('name',instance_name);//name of the target environment
    gr.query();
    if(gr.next()){
        id= gr.getUniqueValue();
    }
    //define worker and required paras
    var worker = new GlideUpdateSetWorker();
    var sys_id = id;
    //initiate worker
    worker.setUpdateSourceSysId(sys_id);
    worker.setBackground(true);
    worker.start();
    //start an one time schedule
    var progress_id = worker.getProgressID();
}

2. Auto Preview UpdateSets

//OPTIONAL if you have auto preview enabled
//Auto preview loaded update sets which has a specific prefix
function AutoPreviewUpdateSets(update_set_prefix){
   //Query the remote update sets
   var remote_updateset = new GlideRecord('sys_remote_update_set');
   remote_updateset.addQuery('sys_class_name=sys_remote_update_set^nameSTARTSWITH'+update_set_prefix);
   remote_updateset.query();
    while(remote_updateset.next()){
        if(!remote_updateset.sys_id.nil()) {
            //update state of selected update sets to preview
            if(remote_updateset.state == 'loaded'){ //eliminate invalid status
                remote_updateset.state = "previewed";
                remote_updateset.update();
                // run previwer job
                var t = new UpdateSetPreviewer();
                t.removePreviewRecords(remote_updateset.sys_id);
                t.generatePreviewRecords(remote_updateset.sys_id);
            }
        }
    }
   
}

3.  Commit Remote UpdateSets

//Commit previewed updates which has a specific prefix
function commitRemoteUpdateSets(update_set_prefix){
    var remote_updateset = new GlideRecord('sys_remote_update_set');
    remote_updateset.addQuery('sys_class_name=sys_remote_update_set^nameSTARTSWITH'+update_set_prefix);
    remote_updateset.query();
     while(remote_updateset.next()){
        if(!remote_updateset.sys_id.nil() && remote_updateset.state == 'previewed') {
            //check updateset issues are fixed
            if(!GlidePreviewProblemHandler.hasUnresolvedProblems(remote_updateset.sys_id)) 
            {
            var sys_up_set = new GlideRecord('sys_update_set');
            var worker = new GlideUpdateSetWorker();
            var local_sys_id = worker.remoteUpdateSetCommit(sys_up_set, remote_updateset, remote_updateset.update_source.url);
            var xml_gr = new GlideRecord("sys_update_xml");
            xml_gr.addQuery("remote_update_set", remote_updateset.sys_id);
            xml_gr.query();
            //execute commit and XML installtion
            while(xml_gr.next()) 
            {
                    var local_xml_gr = new GlideRecord("sys_update_xml");
                    local_xml_gr.initialize();
                    local_xml_gr.name = xml_gr.name;
                    local_xml_gr.payload = xml_gr.payload;
                    local_xml_gr.action = xml_gr.action;
                    local_xml_gr.type = xml_gr.type;
                    local_xml_gr.target_name = xml_gr.target_name;
                    local_xml_gr.view = xml_gr.view;
                    local_xml_gr.update_domain = xml_gr.update_domain;
                    local_xml_gr.table = xml_gr.table;
                    local_xml_gr.category = xml_gr.category;
                    local_xml_gr.application = xml_gr.application;
                    local_xml_gr.update_set = local_sys_id;
                    if (local_xml_gr.isValidField('replace_on_upgrade'))
                    local_xml_gr.replace_on_upgrade = xml_gr.replace_on_upgrade;
                    local_xml_gr.insert();
            }
            remote_updateset.update();
            }

        }
     }
}

 

4. Create New Updateset

The credit of creating this script goes to @Keminda 

//Create updateset and make it current
function createUpdateSetAndMakeCurrent(update_set_name)
{
    var up= new GlideRecord("sys_update_set");
    up.initialize();
    up.application ='global';
    up.name = update_set_name;
    up.description = 'Onboarding Catalog Item';
    var updateset_sys_id= up.insert();
    //Make updateset current
    var upset= new GlideUpdateSet();
    upset.set(updateset_sys_id);
}

 

Comments
Himavamshi K
Tera Contributor

Hi Sandaru1,

Thanks for the article!

The 1st script in this article is pulling all the committed updated sets which are not loaded to my TEST instance. Is there a way to get particular update set from dev instance. 

 

Thanks

Rohit Ladda
Tera Contributor

This is very helpful, the only part which is not working is the 3.  Commit Remote UpdateSets
It sets the state to Committed but the underlying updates are not actually committed. Any idea how to fix this?

Nikhil65
Mega Guru

As Rohit mentioned, retrieve, preview would work perfectly fine.
But commit wont work, it would simply change the status of the update set to committed.

For moving the customer updates along with update set you would have to include the below 3 lines after remote_updateset.update();

<--- code to be added --->
worker.setUpdateSetSysId(local_sys_id);
worker.setBackground(false);
worker.start();

SrikanthReddy60
ServiceNow Employee
ServiceNow Employee

how to handle if there are any preview errors while committing the update sets.

I am looking for "Accept remote" options for all the conflicts/errors

Nikhil65
Mega Guru

@SrikanthReddy60 There is a table called - Update Set Preview Problems(sys_update_preview_problem), when you preview the update set, the errors are stored in that table. And when you, accept or skip the remote update - the action is stored in the status field as Ignored or Skipped.

Try to play around the table you will understand how to utilize the table for your need.

Version history
Last update:
‎11-11-2021 10:40 PM
Updated by: