{"id":5480,"date":"2018-10-14T00:36:20","date_gmt":"2018-10-14T00:36:20","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=5480"},"modified":"2019-12-05T06:18:53","modified_gmt":"2019-12-05T06:18:53","slug":"helix-core-trigger-script-type-reference-guide","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/helix-core-trigger-script-type-reference-guide\/","title":{"rendered":"Helix Core Trigger script type Reference Guide"},"content":{"rendered":"<div><a name=\"1057442\"><\/a>Each line in the trigger table has four fields.<\/div>\n<table cellspacing=\"0\">\n<caption>&nbsp;<\/caption>\n<tbody>\n<tr>\n<td>\n<div><a name=\"1056839\"><\/a>Field<\/div>\n<\/td>\n<td>\n<div><a name=\"1056841\"><\/a>Meaning<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<div><a name=\"1056843\"><\/a>name<\/div>\n<\/td>\n<td>\n<div><a name=\"1056846\"><\/a>The user-defined name of the trigger.<\/div>\n<div><a name=\"1061908\"><\/a>A run of the same trigger name on contiguous lines is treated as a single&nbsp;trigger, so that multiple&nbsp;paths may be specified. In this case, only the&nbsp;command&nbsp;of the first such trigger line is used.<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<div><a name=\"1056849\"><\/a>type<\/div>\n<\/td>\n<td>\n<div><a name=\"1066845\"><\/a>Trigger types are divided into six subtypes: changelist submission triggers,&nbsp;shelve triggers, fix triggers, form triggers, authentication triggers, and archive triggers.<\/div>\n<div><a name=\"1061940\"><\/a>Changelist submission triggers:<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1061941\"><\/a>change-submit: Execute a changelist trigger after changelist creation, but before file transfer. Trigger may not access file contents.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1061942\"><\/a>change-content: Execute a changelist trigger after changelist creation and file transfer, but before file commit.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div><a name=\"1061943\"><\/a>To obtain file contents, use commands such as&nbsp;p4 diff2,&nbsp;p4 files,&nbsp;p4&nbsp;fstat, and&nbsp;p4 print&nbsp;with the revision specifier&nbsp;@=change, where&nbsp;change&nbsp;is the changelist number of the pending changelist as passed to the script in the&nbsp;%changelist%&nbsp;variable.<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1061944\"><\/a>change-commit: Execute a changelist trigger after changelist creation, file transfer, and changelist commit.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<div><a name=\"1066853\"><\/a><\/div>\n<\/td>\n<td>\n<div><a name=\"1066855\"><\/a>Shelve triggers:<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1066856\"><\/a>shelve-submit: Execute a pre-shelve trigger after changelist has been created and files locked, but prior to file transfer.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1066857\"><\/a>shelve-commit: Execute a post-shelve trigger after files are shelved.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1066858\"><\/a>shelve-delete: Execute a shelve trigger prior to discarding shelved files.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<div><a name=\"1061950\"><\/a><\/div>\n<\/td>\n<td>\n<div><a name=\"1061952\"><\/a>Fix triggers:<\/div>\n<div><a name=\"1061953\"><\/a>The special variable&nbsp;%jobs%&nbsp;is available for expansion; it expands to one argument for every job listed on the&nbsp;p4 fix&nbsp;command line (or in the&nbsp;Jobs:&nbsp;field of a&nbsp;p4 change&nbsp;or&nbsp;p4 submit&nbsp;form), and must therefore be the last argument supplied to the trigger script.<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1061957\"><\/a>fix-add: Execute fix trigger prior to adding a fix.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1061958\"><\/a>fix-delete: Execute fix trigger prior to deleting a fix.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<div><a name=\"1059635\"><\/a><\/div>\n<\/td>\n<td>\n<div><a name=\"1059637\"><\/a>Form triggers:<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1059638\"><\/a>form-save: Execute a form trigger after the form contents are parsed, but before the contents are stored in the Perforce database. The trigger cannot modify the form specified in&nbsp;%formfile%&nbsp;variable.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1059639\"><\/a>form-out: Execute form trigger upon generation of form to end user. The trigger can modify the form.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1062073\"><\/a>form-in: Execute form trigger on edited form before contents are parsed and validated by the Perforce server. The trigger can modify the form.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1059641\"><\/a>form-delete: Execute form trigger after the form contents are parsed, but before the form is deleted from the Perforce database. The trigger cannot modify the form.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1062079\"><\/a>form-commit: Execute form trigger after the form has been committed for access to automatically-generated fields such as jobname, dates, etc.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div><a name=\"1063586\"><\/a>For job forms, this trigger is run by&nbsp;p4 job&nbsp;as well as&nbsp;p4 fix&nbsp;(after the status is updated). The&nbsp;form-commit&nbsp;trigger has access to the new job name created by&nbsp;p4 job; any&nbsp;form-in&nbsp;and&nbsp;form-save&nbsp;triggers are run before the job name is created.<\/div>\n<div><a name=\"1063592\"><\/a>For job forms, this trigger is also run by&nbsp;p4 change&nbsp;(if a job is added or deleted by editing the&nbsp;Jobs:&nbsp;field of the changelist), and&nbsp;p4 submit&nbsp;(for any jobs present in the&nbsp;Jobs:field of the changelist). In these cases, the special variable&nbsp;%action%&nbsp;is available for expansion on the job&nbsp;form-commit&nbsp;trigger command line. The trigger cannot modify the form.<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<div><a name=\"1059643\"><\/a><\/div>\n<\/td>\n<td>\n<div><a name=\"1059645\"><\/a>Authentication triggers:<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1062133\"><\/a>auth-check: Execute an authentication check trigger to verify a user&#8217;s password against an external password manager during login, or when setting a new password If an&nbsp;auth-check&nbsp;trigger is present, the Perforce&nbsp;security&nbsp;configurable (and any associated password strength require\u00adment) is ignored, as authentication is now controlled by the trigger script.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1062134\"><\/a>auth-set: Execute an authentication set trigger to send a new password to an external password manager.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1067532\"><\/a>service-check: Execute a trigger to verify the password of a service user, rather than a standard user. Service check triggers work in the same way that&nbsp;auth-checktriggers do.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div><a name=\"1062123\"><\/a>You must restart the Perforce server after adding an&nbsp;auth-check&nbsp;or&nbsp;service-check&nbsp;trigger.<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<div><a name=\"1064992\"><\/a><\/div>\n<\/td>\n<td>\n<div><a name=\"1064994\"><\/a>Archive triggers:<\/div>\n<div>\n<table border=\"0\" summary=\"\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td>\n<div>\u2022<\/div>\n<\/td>\n<td width=\"100%\">\n<div><a name=\"1064995\"><\/a>archive: Execute the script when a user accesses any file with a filetype containing the&nbsp;+X&nbsp;filetype modifier.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div><a name=\"1065961\"><\/a>The script is run once per file requested.<\/div>\n<div><a name=\"1065952\"><\/a>For&nbsp;read&nbsp;operations, scripts should deliver the file to the user on standard output. For&nbsp;write&nbsp;operations, scripts receive the file on standard input.<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<div><a name=\"1056862\"><\/a>path<\/div>\n<\/td>\n<td>\n<div><a name=\"1066892\"><\/a>For changelist and shelve triggers (change-submit,&nbsp;change-content,&nbsp;change-commit,&nbsp;shelve-submit,&nbsp;shelve-commit, and&nbsp;shelve-delete), a file pattern in depot syntax. When a user submits a changelist that contains any files that match this file pattern, the script linked to this trigger is run. Use exclusionary mappings to prevent triggers from running on specified files.<\/div>\n<div><a name=\"1062143\"><\/a>For fix triggers (fix-add&nbsp;or&nbsp;fix-delete), use&nbsp;fix&nbsp;as the path value.<\/div>\n<div><a name=\"1062144\"><\/a>For form triggers (form-save,&nbsp;form-out,&nbsp;form-in,&nbsp;form-commit, or&nbsp;form-delete), the name of the type of form, (one of&nbsp;branch,&nbsp;change,&nbsp;client,&nbsp;depot,&nbsp;group,&nbsp;job,&nbsp;label,&nbsp;protect,&nbsp;spec,&nbsp;triggers,&nbsp;typemap, or&nbsp;user).<\/div>\n<div><a name=\"1062145\"><\/a>For authentication triggers (auth-check,&nbsp;auth-set, or&nbsp;service-check), use&nbsp;auth&nbsp;as the path value.<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<div><a name=\"1056867\"><\/a>command<\/div>\n<\/td>\n<td>\n<div><a name=\"1062156\"><\/a>The command for the Perforce server to run when a matching&nbsp;path&nbsp;applies for the trigger type. Specify the command in a way that allows the Perforce server account to locate and run the command. The command must be quoted, and can take the variables specified below as arguments.<\/div>\n<div><a name=\"1062158\"><\/a>For&nbsp;change-submit&nbsp;and&nbsp;change-content&nbsp;triggers, changelist submission continues if the trigger script exits with 0, or fails if the script exits with a nonzero value. For&nbsp;change-commit&nbsp;triggers, changelist submission succeeds regardless of the trigger script&#8217;s exit code, but subsequent&nbsp;change-commit&nbsp;triggers do not fire if the script exits with a nonzero value.<\/div>\n<div><a name=\"1062159\"><\/a>For&nbsp;form-in,&nbsp;form-out,&nbsp;form-save, and&nbsp;form-delete&nbsp;triggers, the data in the specification becomes part of the Perforce database if the script exits with 0. Otherwise, the database is not updated.<\/div>\n<div><a name=\"1062160\"><\/a>The&nbsp;form-commit&nbsp;trigger type never rejects a change; it exists primarily so that scripts can access a job number (from the&nbsp;%formname%&nbsp;variable) during the process of job creation.<\/div>\n<div><a name=\"1062161\"><\/a>For&nbsp;fix-add&nbsp;and&nbsp;fix-delete&nbsp;triggers, fix addition or deletion continues if the trigger script exits with 0, or fails if the script exits with a nonzero value.<\/div>\n<div><a name=\"1062163\"><\/a>For&nbsp;auth-check&nbsp;and&nbsp;service-check&nbsp;triggers (fired by&nbsp;p4 login&nbsp;from standard users and service users respectively), the user&#8217;s typed password is supplied to the trigger command as standard input. If the trigger executes successfully, the Perforce ticket is issued. The user name is available as&nbsp;%user%&nbsp;to be passed on the command line.<\/div>\n<div><a name=\"1062165\"><\/a>For&nbsp;auth-set&nbsp;triggers, (fired by&nbsp;p4 passwd, but only after also passing an&nbsp;auth-check&nbsp;trigger check) the user&#8217;s old password and new password are passed to the trigger as standard input. The user name is available as&nbsp;%user%&nbsp;to be passed on the command line.<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>Each line in the trigger table has four fields. &nbsp; Field Meaning name The user-defined name of the trigger. A run of the same trigger name on contiguous lines is treated as a single&nbsp;trigger, so that multiple&nbsp;paths may be specified. In this case, only the&nbsp;command&nbsp;of the first such trigger line is used. type Trigger types&#8230;<\/p>\n","protected":false},"author":1,"featured_media":7923,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","_joinchat":[],"footnotes":""},"categories":[370],"tags":[5092,5071,278,818,5068],"class_list":["post-5480","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-perforce","tag-core","tag-helix","tag-script","tag-trigger","tag-type"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/5480","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=5480"}],"version-history":[{"count":2,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/5480\/revisions"}],"predecessor-version":[{"id":7924,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/5480\/revisions\/7924"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media\/7923"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=5480"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=5480"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=5480"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}