<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="generator" content="Asciidoctor 1.5.2"> <meta name="author" content="Tristan Juricek"> <title>Perforce Web Services Guide: Internal Alpha</title> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400"> <style> /* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */ /* Remove the comments around the @import statement below when using this as a custom stylesheet */ /*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400";*/ article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block} audio,canvas,video{display:inline-block} audio:not([controls]){display:none;height:0} [hidden],template{display:none} script{display:none!important} html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} body{margin:0} a{background:transparent} a:focus{outline:thin dotted} a:active,a:hover{outline:0} h1{font-size:2em;margin:.67em 0} abbr[title]{border-bottom:1px dotted} b,strong{font-weight:bold} dfn{font-style:italic} hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0} mark{background:#ff0;color:#000} code,kbd,pre,samp{font-family:monospace;font-size:1em} pre{white-space:pre-wrap} q{quotes:"\201C" "\201D" "\2018" "\2019"} small{font-size:80%} sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} sup{top:-.5em} sub{bottom:-.25em} img{border:0} svg:not(:root){overflow:hidden} figure{margin:0} fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em} legend{border:0;padding:0} button,input,select,textarea{font-family:inherit;font-size:100%;margin:0} button,input{line-height:normal} button,select{text-transform:none} button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} button[disabled],html input[disabled]{cursor:default} input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0} input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box} input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none} button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} textarea{overflow:auto;vertical-align:top} table{border-collapse:collapse;border-spacing:0} *,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box} html,body{font-size:100%} body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto} a:hover{cursor:pointer} img,object,embed{max-width:100%;height:auto} object,embed{height:100%} img{-ms-interpolation-mode:bicubic} #map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none!important} .left{float:left!important} .right{float:right!important} .text-left{text-align:left!important} .text-right{text-align:right!important} .text-center{text-align:center!important} .text-justify{text-align:justify!important} .hide{display:none} .antialiased,body{-webkit-font-smoothing:antialiased} img{display:inline-block;vertical-align:middle} textarea{height:auto;min-height:50px} select{width:100%} p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6} .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em} div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr} a{color:#2156a5;text-decoration:underline;line-height:inherit} a:hover,a:focus{color:#1d4b8f} a img{border:none} p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility} p aside{font-size:.875em;line-height:1.35;font-style:italic} h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em} h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0} h1{font-size:2.125em} h2{font-size:1.6875em} h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em} h4,h5{font-size:1.125em} h6{font-size:1em} hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0} em,i{font-style:italic;line-height:inherit} strong,b{font-weight:bold;line-height:inherit} small{font-size:60%;line-height:inherit} code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em} ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em} ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit} ul.square{list-style-type:square} ul.circle{list-style-type:circle} ul.disc{list-style-type:disc} ul.no-bullet{list-style:none} ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} dl dt{margin-bottom:.3125em;font-weight:bold} dl dd{margin-bottom:1.25em} abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help} abbr{text-transform:none} blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd} blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)} blockquote cite:before{content:"\2014 \0020"} blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)} blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)} @media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2} h1{font-size:2.75em} h2{font-size:2.3125em} h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em} h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede} table thead,table tfoot{background:#f7f8f7;font-weight:bold} table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)} table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7} table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6} h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em} h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400} .clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table} .clearfix:after,.float-group:after{clear:both} *:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed} pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed} .keyseq{color:rgba(51,51,51,.8)} kbd{display:inline-block;color:rgba(0,0,0,.8);font-size:.75em;line-height:1.4;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:-.15em .15em 0 .15em;padding:.2em .6em .2em .5em;vertical-align:middle;white-space:nowrap} .keyseq kbd:first-child{margin-left:0} .keyseq kbd:last-child{margin-right:0} .menuseq,.menu{color:rgba(0,0,0,.8)} b.button:before,b.button:after{position:relative;top:-1px;font-weight:400} b.button:before{content:"[";padding:0 3px 0 2px} b.button:after{content:"]";padding:0 2px 0 3px} p a>code:hover{color:rgba(0,0,0,.9)} #header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em} #header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table} #header:after,#content:after,#footnotes:after,#footer:after{clear:both} #content{margin-top:1.25em} #content:before{content:none} #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8} #header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px} #header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap} #header .details span:first-child{margin-left:-.125em} #header .details span.email a{color:rgba(0,0,0,.85)} #header .details br{display:none} #header .details br+span:before{content:"\00a0\2013\00a0"} #header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)} #header .details br+span#revremark:before{content:"\00a0|\00a0"} #header #revnumber{text-transform:capitalize} #header #revnumber:after{content:"\00a0"} #content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem} #toc{border-bottom:1px solid #efefed;padding-bottom:.5em} #toc>ul{margin-left:.125em} #toc ul.sectlevel0>li>a{font-style:italic} #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0} #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none} #toc a{text-decoration:none} #toc a:active{text-decoration:underline} #toctitle{color:#7a2518;font-size:1.2em} @media only screen and (min-width:768px){#toctitle{font-size:1.375em} body.toc2{padding-left:15em;padding-right:0} #toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} #toc.toc2 #toctitle{margin-top:0;font-size:1.2em} #toc.toc2>ul{font-size:.9em;margin-bottom:0} #toc.toc2 ul ul{margin-left:0;padding-left:1em} #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em} body.toc2.toc-right{padding-left:0;padding-right:15em} body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0} #toc.toc2{width:20em} #toc.toc2 #toctitle{font-size:1.375em} #toc.toc2>ul{font-size:.95em} #toc.toc2 ul ul{padding-left:1.25em} body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} #content #toc>:first-child{margin-top:0} #content #toc>:last-child{margin-bottom:0} #footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em} #footer-text{color:rgba(255,255,255,.8);line-height:1.44} .sect1{padding-bottom:.625em} @media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed} #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400} #content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em} #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible} #content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none} #content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221} .audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em} .admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic} table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0} .paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)} table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit} .admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%} .admonitionblock>table td.icon{text-align:center;width:80px} .admonitionblock>table td.icon img{max-width:none} .admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase} .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)} .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} .exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px} .exampleblock>.content>:first-child{margin-top:0} .exampleblock>.content>:last-child{margin-bottom:0} .sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} .sidebarblock>:first-child{margin-top:0} .sidebarblock>:last-child{margin-bottom:0} .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} .exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} .literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8} .sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1} .literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em} .literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal} @media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)} .listingblock pre.highlightjs{padding:0} .listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px} .listingblock pre.prettyprint{border-width:0} .listingblock>.content{position:relative} .listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999} .listingblock:hover code[data-lang]:before{display:block} .listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999} .listingblock.terminal pre .command:not([data-prompt]):before{content:"$"} table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none} table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0} table.pyhltable td.code{padding-left:.75em;padding-right:0} pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8} pre.pygments .lineno{display:inline-block;margin-right:.25em} table.pyhltable .linenodiv{background:none!important;padding-right:0!important} .quoteblock{margin:0 1em 1.25em 1.5em;display:table} .quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em} .quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify} .quoteblock blockquote{margin:0;padding:0;border:0} .quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)} .quoteblock blockquote>.paragraph:last-child p{margin-bottom:0} .quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right} .quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)} .quoteblock .quoteblock blockquote{padding:0 0 0 .75em} .quoteblock .quoteblock blockquote:before{display:none} .verseblock{margin:0 1em 1.25em 1em} .verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} .verseblock pre strong{font-weight:400} .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex} .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic} .quoteblock .attribution br,.verseblock .attribution br{display:none} .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.05em;color:rgba(0,0,0,.6)} .quoteblock.abstract{margin:0 0 1.25em 0;display:block} .quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0} .quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none} table.tableblock{max-width:100%;border-collapse:separate} table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0} table.spread{width:100%} table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0} table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0} table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0} table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0} table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0} table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0} table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0} table.frame-all{border-width:1px} table.frame-sides{border-width:0 1px} table.frame-topbot{border-width:1px 0} th.halign-left,td.halign-left{text-align:left} th.halign-right,td.halign-right{text-align:right} th.halign-center,td.halign-center{text-align:center} th.valign-top,td.valign-top{vertical-align:top} th.valign-bottom,td.valign-bottom{vertical-align:bottom} th.valign-middle,td.valign-middle{vertical-align:middle} table thead th,table tfoot th{font-weight:bold} tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7} tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold} p.tableblock>code:only-child{background:none;padding:0} p.tableblock{font-size:1em} td>div.verse{white-space:pre} ol{margin-left:1.75em} ul li ol{margin-left:1.5em} dl dd{margin-left:1.125em} dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0} ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em} ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none} ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em} ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em} ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px} ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden} ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block} ul.inline>li>*{display:block} .unstyled dl dt{font-weight:400;font-style:normal} ol.arabic{list-style-type:decimal} ol.decimal{list-style-type:decimal-leading-zero} ol.loweralpha{list-style-type:lower-alpha} ol.upperalpha{list-style-type:upper-alpha} ol.lowerroman{list-style-type:lower-roman} ol.upperroman{list-style-type:upper-roman} ol.lowergreek{list-style-type:lower-greek} .hdlist>table,.colist>table{border:0;background:none} .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none} td.hdlist1{padding-right:.75em;font-weight:bold} td.hdlist1,td.hdlist2{vertical-align:top} .literalblock+.colist,.listingblock+.colist{margin-top:-.5em} .colist>table tr>td:first-of-type{padding:0 .75em;line-height:1} .colist>table tr>td:last-of-type{padding:.25em 0} .thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd} .imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0} .imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em} .imageblock>.title{margin-bottom:0} .imageblock.thumb,.imageblock.th{border-width:6px} .imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em} .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0} .image.left{margin-right:.625em} .image.right{margin-left:.625em} a.image{text-decoration:none} span.footnote,span.footnoteref{vertical-align:super;font-size:.875em} span.footnote a,span.footnoteref a{text-decoration:none} span.footnote a:active,span.footnoteref a:active{text-decoration:underline} #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0} #footnotes .footnote{padding:0 .375em;line-height:1.3;font-size:.875em;margin-left:1.2em;text-indent:-1.2em;margin-bottom:.2em} #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none} #footnotes .footnote:last-of-type{margin-bottom:0} #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0} .gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0} .gist .file-data>table td.line-data{width:99%} div.unbreakable{page-break-inside:avoid} .big{font-size:larger} .small{font-size:smaller} .underline{text-decoration:underline} .overline{text-decoration:overline} .line-through{text-decoration:line-through} .aqua{color:#00bfbf} .aqua-background{background-color:#00fafa} .black{color:#000} .black-background{background-color:#000} .blue{color:#0000bf} .blue-background{background-color:#0000fa} .fuchsia{color:#bf00bf} .fuchsia-background{background-color:#fa00fa} .gray{color:#606060} .gray-background{background-color:#7d7d7d} .green{color:#006000} .green-background{background-color:#007d00} .lime{color:#00bf00} .lime-background{background-color:#00fa00} .maroon{color:#600000} .maroon-background{background-color:#7d0000} .navy{color:#000060} .navy-background{background-color:#00007d} .olive{color:#606000} .olive-background{background-color:#7d7d00} .purple{color:#600060} .purple-background{background-color:#7d007d} .red{color:#bf0000} .red-background{background-color:#fa0000} .silver{color:#909090} .silver-background{background-color:#bcbcbc} .teal{color:#006060} .teal-background{background-color:#007d7d} .white{color:#bfbfbf} .white-background{background-color:#fafafa} .yellow{color:#bfbf00} .yellow-background{background-color:#fafa00} span.icon>.fa{cursor:default} .admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default} .admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c} .admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111} .admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900} .admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400} .admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000} .conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold} .conum[data-value] *{color:#fff!important} .conum[data-value]+b{display:none} .conum[data-value]:after{content:attr(data-value)} pre .conum[data-value]{position:relative;top:-.125em} b.conum *{color:inherit!important} .conum:not([data-value]):empty{display:none} h1,h2{letter-spacing:-.01em} dt,th.tableblock,td.content{text-rendering:optimizeLegibility} p,td.content{letter-spacing:-.01em} p strong,td.content strong{letter-spacing:-.005em} p,blockquote,dt,td.content{font-size:1.0625rem} p{margin-bottom:1.25rem} .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} .exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc} .print-only{display:none!important} @media print{@page{margin:1.25cm .75cm} *{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important} a{color:inherit!important;text-decoration:underline!important} a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important} a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em} abbr[title]:after{content:" (" attr(title) ")"} pre,blockquote,tr,img{page-break-inside:avoid} thead{display:table-header-group} img{max-width:100%!important} p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3} h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid} #toc,.sidebarblock,.exampleblock>.content{background:none!important} #toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important} .sect1{padding-bottom:0!important} .sect1+.sect1{border:0!important} #header>h1:first-child{margin-top:1.25rem} body.book #header{text-align:center} body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0} body.book #header .details{border:0!important;display:block;padding:0!important} body.book #header .details span:first-child{margin-left:0!important} body.book #header .details br{display:block} body.book #header .details br+span:before{content:none!important} body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important} body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always} .listingblock code[data-lang]:before{display:block} #footer{background:none!important;padding:0 .9375em} #footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em} .hide-on-print{display:none!important} .print-only{display:block!important} .hide-for-print{display:none!important} .show-for-print{display:inherit!important}} </style> </head> <body class="article toc2 toc-right"> <div id="header"> <h1>Perforce Web Services Guide: Internal Alpha</h1> <div class="details"> <span id="author" class="author">Tristan Juricek</span><br> <span id="email" class="email"><a href="mailto:tjuricek@perforce.com">tjuricek@perforce.com</a></span><br> <span id="revnumber">version 2015.1.alpha,</span> <span id="revdate">May 2015</span> </div> <div id="toc" class="toc2"> <div id="toctitle">Table of Contents</div> <ul class="sectlevel1"> <li><a href="#_about_this_manual">About This Manual</a> <ul class="sectlevel2"> <li><a href="#_please_give_us_feedback">Please give us feedback</a></li> </ul> </li> <li><a href="#_overview">Overview</a> <ul class="sectlevel2"> <li><a href="#_knowledge_required">Knowledge Required</a></li> <li><a href="#_release_compatibility_of_the_api">Release compatibility of the API</a></li> <li><a href="#_architecture_of_the_api">Architecture of the API</a></li> </ul> </li> <li><a href="#_deploying_helix_web_services">Deploying Helix Web Services</a> <ul class="sectlevel2"> <li><a href="#_deploying_from_a_source_tarball">Deploying from a source tarball</a></li> <li><a href="#_deploying_from_packages">Deploying from Packages</a></li> <li><a href="#_configuration">Configuration</a></li> </ul> </li> <li><a href="#_client_application_development">Client Application Development</a> <ul class="sectlevel2"> <li><a href="#_authentication">Authentication</a></li> <li><a href="#per_request_configuration">Per-Request Configuration</a></li> <li><a href="#_client_sdks">Client SDKs</a></li> </ul> </li> <li><a href="#_http_protocol_reference">HTTP Protocol Reference</a> <ul class="sectlevel2"> <li><a href="#_authentication_methods">Authentication Methods</a></li> <li><a href="#_helix_versioning_service_methods">Helix Versioning Service Methods</a></li> <li><a href="#_project_service_methods">Project Service Methods</a></li> </ul> </li> <li><a href="#_client_sdk_reference">Client SDK Reference</a></li> <li><a href="#_server_programming">Server Programming</a> <ul class="sectlevel2"> <li><a href="#_including_new_rack_middleware">Including New Rack Middleware</a></li> <li><a href="#_registering_configuration_variables">Registering Configuration Variables</a></li> </ul> </li> <li><a href="#_server_api_reference">Server API Reference</a></li> </ul> </div> </div> <div id="content"> <div class="sect1"> <h2 id="_about_this_manual"><a class="link" href="#_about_this_manual">About This Manual</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>This guide covers administering and developing against the Helix Web Services. Helix Web Services provide common services and APIs that interact with the Helix Versioning Engine.</p> </div> <div class="paragraph"> <p>A Helix Web Services server is a web server, and it’s APIs are fundamentally based on the HTTP protocol. Not all aspects of the Helix Versioning Engine are provided by Helix Web Services, vice versa. Some services provided by Helix Web Services are not available in the Helix Versioning Engine.</p> </div> <div class="sect2"> <h3 id="_please_give_us_feedback"><a class="link" href="#_please_give_us_feedback">Please give us feedback</a></h3> <div class="paragraph"> <p>If you have any feedback for us, or detect any errors in this guide, please email details to <a href="mailto:manual@perforce.com">manual@perforce.com</a>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_overview"><a class="link" href="#_overview">Overview</a></h2> <div class="sectionbody"> <div class="sect2"> <h3 id="_knowledge_required"><a class="link" href="#_knowledge_required">Knowledge Required</a></h3> <div class="paragraph"> <p>For deployment and configuration tasks, this guide assumes that you are experienced with administering web applications. You should be conceptually comfortable with Nginx and Unicorn. It is not necessary to have expert knowledge of these systems, but you should understand what their roles are without further clarification. If you require more knowledge, please consult online guides for both of these application frameworks.</p> </div> <div class="ulist"> <ul> <li> <p>Nginx: <a href="http://nginx.org/" class="bare">http://nginx.org/</a></p> </li> <li> <p>Unicorn: <a href="http://unicorn.bogomips.org/" class="bare">http://unicorn.bogomips.org/</a></p> </li> </ul> </div> <div class="paragraph"> <p>Additionally, while this guide interfaces with the Helix Versioning Engine, we assume you are familiar with it. For more information about the Helix Versioning Engine, please become familiar with the following online guides:</p> </div> <div class="ulist"> <ul> <li> <p>Product overview: <a href="http://www.perforce.com/versioning-engine" class="bare">http://www.perforce.com/versioning-engine</a></p> </li> <li> <p>P4 Command Reference: <a href="http://www.perforce.com/perforce/doc.current/manuals/cmdref/index.html" class="bare">http://www.perforce.com/perforce/doc.current/manuals/cmdref/index.html</a></p> </li> <li> <p>Admin fundamentals: <a href="http://www.perforce.com/perforce/doc.current/manuals/p4sag/index.html" class="bare">http://www.perforce.com/perforce/doc.current/manuals/p4sag/index.html</a></p> </li> </ul> </div> <div class="paragraph"> <p>For client development tasks, this guide assumes you are comfortable with the HTTP protocol. While it is not required to know Ruby, we provide a client SDK for Ruby, which may be easier to understand initially. If you do not use our Ruby client SDK, you will need to create an SDK for your platform, likely combined with a JSON parser.</p> </div> </div> <div class="sect2"> <h3 id="_release_compatibility_of_the_api"><a class="link" href="#_release_compatibility_of_the_api">Release compatibility of the API</a></h3> <div class="paragraph"> <p>Helix Web Services are intended to be executed against a corresponding major release of the Helix Versioning Engine. For example, the '2015.1' release of Helix Web Services, is intended to interact with the '2015.1' of the Helix Versioning Engine. Using Helix Web Services against a non-corresponding Helix Versioning Engine instance will likely work, with some caveats.</p> </div> <div class="paragraph"> <p>The client SDK provided for Helix Web Services contains several 'model' objects that help assist in normalizing data from the Helix Versioning Engine. When you use a different version of Helix Web Services than your Helix Versioning Engine, it is likely that some data may not exist. You may not want to use the model instances when using mismatching versions, and focus more on the more generic hash-based methods.</p> </div> </div> <div class="sect2"> <h3 id="_architecture_of_the_api"><a class="link" href="#_architecture_of_the_api">Architecture of the API</a></h3> <div class="paragraph"> <p>Helix Web Services is a Ruby web application, that is intended to sit behind a reverse proxy server, such as nginx. The reverse proxy server should handle the configuration of SSL for the web services, and can host other web applications from the Helix suite. Helix Web Services currently deploys into a single unicorn instance, on Linux machines.</p> </div> <div class="paragraph"> <p>Each Helix Web Services instance should not maintain significant state. You should be able to launch more than one Helix Web Services instance, and configure your reverse proxy to handle load balancing. You can also architect your system using services such as haproxy for load balancing. Using haproxy and nginx is beyond the scope of this documentation guide; we assume you are an experienced systems administrator when it comes to clustered web application deployment.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_deploying_helix_web_services"><a class="link" href="#_deploying_helix_web_services">Deploying Helix Web Services</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>Helix Web Services can be deployed from a source tarball distribution or from installed packages. Starting up web services from a source tarball is similar to working with code checked out from our source distribution.</p> </div> <div class="paragraph"> <p>To be clear, Helix Web Services will be set up to run a single application server instance. This application server will run on an unprivileged port, like 9000. It’s expected that Helix Web Services would be a part of a greater ecosystem of web applications, likely proxied by a web server such as Nginx. Our package installation includes a post-install configuration script that configures other services on the local machine to make it easy.</p> </div> <div class="sect2"> <h3 id="_deploying_from_a_source_tarball"><a class="link" href="#_deploying_from_a_source_tarball">Deploying from a source tarball</a></h3> <div class="paragraph"> <p>The following steps will launch a Helix Web Services instance in the current terminal session. This is not intended for a production installation, but may be valid for evaluating the product or experimenting with customizing Helix Web Services from source.</p> </div> <div class="paragraph"> <p>Prerequisites to working with our source tarball:</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Ruby 2.2</p> </li> <li> <p>An installed Perforce server</p> </li> </ol> </div> <div class="paragraph"> <p>Other Ruby variations will likely work, we do not test them.</p> </div> <div class="paragraph"> <p>Installation steps:</p> </div> <div class="olist arabic"> <ol class="arabic"> <li> <p>Run: <code>tar xzf helix-web-services-[VERSION].tar.gz</code></p> </li> <li> <p>Run: <code>cd helix-web-services-[VERSION]/helix_web_services</code></p> </li> <li> <p>Run: <code>bundle install</code></p> </li> <li> <p>Run: <code>bundle exec rake db:init db:migrate</code></p> </li> <li> <p>Setup environment configuration (see <a href="#_environment_configuration">[_environment_configuration]</a>)</p> </li> <li> <p>Run: <code>bundle exec foreman start</code></p> </li> </ol> </div> </div> <div class="sect2"> <h3 id="_deploying_from_packages"><a class="link" href="#_deploying_from_packages">Deploying from Packages</a></h3> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <div class="title">Note</div> </td> <td class="content"> Right now you can only obtain packages from an internal build instance of Perforce. This assumes you have obtained the appropriate tarball, and unpacked it. </td> </tr> </table> </div> <div class="paragraph"> <p>Install the package using the appropriate platform tool:</p> </div> <div class="ulist"> <ul> <li> <p>On Debian or Ubuntu systems, run <code>dpkg -i helix-web-services-[VERSION].deb</code></p> </li> <li> <p>On Redhat or CentOS systems, run <code>rpm -i helix-web-services-[VERSION].rpm</code></p> </li> </ul> </div> <div class="paragraph"> <p>After installation, run the configuration script:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlight"><code>sudo /opt/perforce/helix-web-services/bin/hws_configure</code></pre> </div> </div> <div class="paragraph"> <p>If this machine already has an existing nginx or perforce server configuration, you will have to manually configure /etc/nginx/nginx.conf or adjust the environment in the <code>/opt/perforce/helix-web-services/bin/helix_web_services</code> wrapper script.</p> </div> </div> <div class="sect2"> <h3 id="_configuration"><a class="link" href="#_configuration">Configuration</a></h3> <div class="paragraph"> <p>System default settings for Helix Web Services can be set by creating a YAML file at <code>/etc/perforce/helix_web_services.conf</code>. If you’re unfamiliar with YAML, you simply use the variables below in simple key-value pairs. Pay attention, however, to the type of the variable. In many cases we use strings when you might have thought it were a number.</p> </div> <div class="paragraph"> <p>For example:</p> </div> <div class="paragraph"> <p>/etc/perforce/helix_web_services.conf</p> </div> <div class="listingblock"> <div class="content"> <pre>P4HOST: 'perforce.mycompany.com' P4PORT: '1999'</pre> </div> </div> <div class="paragraph"> <p>Many settings in Helix Web Services are overridable by HTTP headers on a per-request basis. The "Overridable" column in the table below means you can specify this header. If it is not available, you can <em>only</em> specify the configuration in the system config file. For more information on specifying the system header, see <a href="#per_request_configuration">Per-Request Configuration</a>.</p> </div> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Variable</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Overridable</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Default</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">P4HOST</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The hostname for the perforce server, e.g., <code>perforce.example.com</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>localhost</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">P4PORT</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The port number (or port and hostname combination) that indicates our Perforce connection</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>1666</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">P4URL</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">A <code>p4:</code> URL that indicates hostname and port, e.g., <code>p4://perforce.example.com:1666</code></p></td> <td class="tableblock halign-left valign-top"></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">P4CHARSET</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The charset value for P4 connections. Set to <code>none</code> if you are connecting to a non-unicode server.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>auto</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">WORKSPACE_PATH</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The local directory used for generating temporary Perforce Client Workspaces to do some basic operations.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/var/lib/perforce/helix_web_services/workspaces</code></p></td> </tr> </tbody> </table> </div> </div> </div> <div class="sect1"> <h2 id="_client_application_development"><a class="link" href="#_client_application_development">Client Application Development</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>Working with Helix Web Services…​.</p> </div> <div class="sect2"> <h3 id="_authentication"><a class="link" href="#_authentication">Authentication</a></h3> </div> <div class="sect2"> <h3 id="per_request_configuration"><a class="link" href="#per_request_configuration">Per-Request Configuration</a></h3> </div> <div class="sect2"> <h3 id="_client_sdks"><a class="link" href="#_client_sdks">Client SDKs</a></h3> </div> </div> </div> <div class="sect1"> <h2 id="_http_protocol_reference"><a class="link" href="#_http_protocol_reference">HTTP Protocol Reference</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>Each section includes methods related to a particular topic or resource.</p> </div> <div class="sect2"> <h3 id="_authentication_methods"><a class="link" href="#_authentication_methods">Authentication Methods</a></h3> </div> <div class="sect2"> <h3 id="_helix_versioning_service_methods"><a class="link" href="#_helix_versioning_service_methods">Helix Versioning Service Methods</a></h3> <div class="paragraph"> <p>These methods are an HTTP protocol to commands available from the core Helix Versioning Service client API.</p> </div> <div class="sect3"> <h4 id="_branches"><a class="link" href="#_branches">Branches</a></h4> <div class="paragraph"> <p><a href="#get_perforce_v1_branches"><code>GET /perforce/v1/branches</code></a></p> </div> </div> <div class="sect3"> <h4 id="_changes"><a class="link" href="#_changes">Changes</a></h4> </div> </div> <div class="sect2"> <h3 id="_project_service_methods"><a class="link" href="#_project_service_methods">Project Service Methods</a></h3> <div class="sect3"> <h4 id="get_perforce_v1_branches"><a class="link" href="#get_perforce_v1_branches"><code>GET /perforce/v1/branches</code></a></h4> <div class="paragraph"> <p>Lists available branches in the system.</p> </div> <div class="paragraph"> <p>The resources of this list are summaries of branches in the system. For more details of each branch, append the <code>branch</code> property the end of this URL.</p> </div> <div class="paragraph"> <p>There are no other parameters to this method.</p> </div> <div class="paragraph"> <p>This method requires authentication. See <a href="#_perforce_web_api_authentication">[_perforce_web_api_authentication]</a></p> </div> <div class="sect4"> <h5 id="_response_json_object"><a class="link" href="#_response_json_object">Response JSON Object</a></h5> <div class="paragraph"> <p>Returns the result of the <code>p4 -ztag branches</code> command. For more field information refer to the command reference.</p> </div> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The branch name and primary ID</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Owner</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The Perforce login of the user that owns this branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Options</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The options of the branch specification</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The branch description</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Update</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The date the branch mapping was last changed.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">number</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Access</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The date the branch mapping was last accessed.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">number</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> </tbody> </table> <div class="sect5"> <h6 id="_example"><a class="link" href="#_example">Example</a></h6> <div class="paragraph"> <p>Our standard authenticated request format for listing branches:</p> </div> <div class="literalblock"> <div class="content"> <pre>GET /v1/branches HTTP/1.1 Authorization: Basic c3VwZXI6NzcxMmJkMTAtOGQxMi00ZmUwLTgxM2MtZmM2OTExODQ3Yjdj</pre> </div> </div> <div class="paragraph"> <p>Here’s an example of a list with two branches in the response:</p> </div> <div class="literalblock"> <div class="content"> <pre>HTTP/1.1 200 OK Content-Type: application/json</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>[{ "Branch": "yagg-main", "Update": 1410907712, "Access": 1410907712, "Owner": "super", "Options": "unlocked", "Description": "Maintains a path from a development area to a main area.\n" }, { "Branch": "secondary-dev", "Update": 1410907541, "Access": 1410907111, "Owner": "jdoe", "Options": "unlocked", "Description": "Updates project Secondary's development area.\n" }]</pre> </div> </div> </div> </div> <div class="sect4"> <h5 id="__code_post_v1_branches_code"><a class="link" href="#__code_post_v1_branches_code"><code>POST /v1/branches</code></a></h5> <div class="paragraph"> <p>Creates a new branch specification.</p> </div> <div class="paragraph"> <p>Upon success, this will return a 303 redirect to the new branch specification resource that has been created.</p> </div> <div class="paragraph"> <p>If the branch already exists, this method will replace the existing branch completely.</p> </div> <div class="paragraph"> <p>This method requires authentication. See <a href="#_perforce_web_api_authentication">[_perforce_web_api_authentication]</a>.</p> </div> <div class="sect5"> <h6 id="_parameters"><a class="link" href="#_parameters">Parameters</a></h6> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Parameter Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The name of the branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Owner</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The Perforce login of the user that owns the branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">A textual description of this branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">View</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">How different paths in the depot should relate to each other. Each string in the array contains a source and target end of the mapping. See the user guide for more information.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">array</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> </tbody> </table> </div> <div class="sect5"> <h6 id="_example_2"><a class="link" href="#_example_2">Example</a></h6> <div class="paragraph"> <p>We’ll create a simple branch my-project-main that maps <code>//depot/main/my-project/…​</code> to <code>//depot/dev/my-project/…​</code>.</p> </div> <div class="literalblock"> <div class="content"> <pre>POST /v1/branches HTTP/1.1 Authorization: Basic c3VwZXI6NzcxMmJkMTAtOGQxMi00ZmUwLTgxM2MtZmM2OTExODQ3Yjdj Content-Type: application/json</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>{ "Branch": "my-project-main", "Description": "Branch my project from main to dev.\n", "View": ["//depot/main/my-project/... //depot/dev/my-project/..."] }</pre> </div> </div> <div class="paragraph"> <p>The return value should be a redirect to the details page of the new branch.</p> </div> <div class="literalblock"> <div class="content"> <pre>HTTP/1.1 303 Found Location: http://example.com/p4/v1/branches/my-project-main</pre> </div> </div> <div class="paragraph"> <p>You may need to recall that the URL returned by a 303 response should be accessed via GET, and not via POST.</p> </div> </div> </div> <div class="sect4"> <h5 id="__code_get_v1_branches_branch_code"><a class="link" href="#__code_get_v1_branches_branch_code"><code>GET /v1/branches/[branch]</code></a></h5> <div class="paragraph"> <p>Return branch details.</p> </div> <div class="paragraph"> <p>This method requires authentication. See <a href="#_perforce_web_api_authentication">[_perforce_web_api_authentication]</a>.</p> </div> <div class="sect5"> <h6 id="_parameters_2"><a class="link" href="#_parameters_2">Parameters</a></h6> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Parameter Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The branch name.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">path</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> </tbody> </table> </div> <div class="sect5"> <h6 id="_response_data"><a class="link" href="#_response_data">Response Data</a></h6> <div class="paragraph"> <p>Returns the result of <code>p4 -ztag branch [branch name].</code> For more information, see the command reference. The main difference between the details and list view is the inclusion of the View field.</p> </div> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The name of the branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Owner</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The Perforce login of the user that owns the branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">A textual description of this branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">View</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">How different paths in the depot should relate to each other. Each string in the array contains a source and target end of the mapping. See the user guide for more information.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">array</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Update</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The date the branch mapping was last changed.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">number</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Access</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The date the branch mapping was last accessed.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">number</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> </tbody> </table> </div> <div class="sect5"> <h6 id="_example_3"><a class="link" href="#_example_3">Example</a></h6> <div class="paragraph"> <p>Here is an example request for the branch yagg-main. This is a fairly simple branch, containing only one view mapping.</p> </div> <div class="literalblock"> <div class="content"> <pre>GET /v1/branches/yagg-main HTTP/1.1 Authorization: Basic c3VwZXI6NzcxMmJkMTAtOGQxMi00ZmUwLTgxM2MtZmM2OTExODQ3Yjdj</pre> </div> </div> <div class="paragraph"> <p>And the typical JSON response:</p> </div> <div class="literalblock"> <div class="content"> <pre>HTTP/1.1 200 OK Content-Type: application/json</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>{ "Branch": "yagg-main", "Update": 1410907712, "Access": 1410907712, "Owner": "super", "Description": "Maintains a path from a development area to a main area.\n", "Options": "unlocked", "View": ["//depot/yagg/... //depot/main/yagg/..."] }</pre> </div> </div> </div> </div> <div class="sect4"> <h5 id="__code_patch_v1_branches_branch_code"><a class="link" href="#__code_patch_v1_branches_branch_code"><code>PATCH /v1/branches/[branch]</code></a></h5> <div class="paragraph"> <p>Update branch specifications. Only the specified parameters in the body will be changed.</p> </div> <div class="paragraph"> <p>This method requires authentication. See <a href="#_perforce_web_api_authentication">[_perforce_web_api_authentication]</a>.</p> </div> <div class="sect5"> <h6 id="_parameters_3"><a class="link" href="#_parameters_3">Parameters</a></h6> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Parameter Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The name of the branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">path</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Owner</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The Perforce login of the user that owns the branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">A textual description of this branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">View</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">How different paths in the depot should relate to each other. Each string in the array contains a source and target end of the mapping. See the user guide for more information.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">array</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> </tbody> </table> </div> <div class="sect5"> <h6 id="_example_4"><a class="link" href="#_example_4">Example</a></h6> <div class="paragraph"> <p>Here we’ll update the description of the existing branch my-project-main.</p> </div> <div class="literalblock"> <div class="content"> <pre>PATCH /v1/branches/my-project-main HTTP/1.1 Authorization: Basic c3VwZXI6NzcxMmJkMTAtOGQxMi00ZmUwLTgxM2MtZmM2OTExODQ3Yjdj Content-Type: application/json</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>{ "Description": "The updated my-project-main description.\n" }</pre> </div> </div> <div class="paragraph"> <p>The response will only contain the normal HTTP status information.</p> </div> <div class="literalblock"> <div class="content"> <pre>HTTP/1.1 200 OK</pre> </div> </div> </div> </div> <div class="sect4"> <h5 id="__code_delete_v1_branches_branch_code"><a class="link" href="#__code_delete_v1_branches_branch_code"><code>DELETE /v1/branches/[branch]</code></a></h5> <div class="paragraph"> <p>Removes the branch specification.</p> </div> <div class="paragraph"> <p>This method requires authentication. See <a href="#_perforce_web_api_authentication">[_perforce_web_api_authentication]</a>.</p> </div> <div class="sect5"> <h6 id="_parameters_4"><a class="link" href="#_parameters_4">Parameters</a></h6> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Parameter Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">branch</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The branch name.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">path</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> </tbody> </table> </div> <div class="sect5"> <h6 id="_example_5"><a class="link" href="#_example_5">Example</a></h6> <div class="paragraph"> <p>Delete the branch <code>my-project-main</code>:</p> </div> <div class="literalblock"> <div class="content"> <pre>DELETE /v1/branches/my-project-main HTTP/1.1 Authorization: Basic c3VwZXI6NzcxMmJkMTAtOGQxMi00ZmUwLTgxM2MtZmM2OTExODQ3Yjdj</pre> </div> </div> <div class="paragraph"> <p>The response will only contain the normal HTTP status information.</p> </div> <div class="literalblock"> <div class="content"> <pre>HTTP/1.1 200 OK</pre> </div> </div> </div> </div> </div> <div class="sect3"> <h4 id="_p4_web_api_changes_http_protocol"><a class="link" href="#_p4_web_api_changes_http_protocol">P4 Web API Changes HTTP Protocol</a></h4> <div class="paragraph"> <p>The method here allows for summarizing history with some common filters.</p> </div> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 50%;"> <col style="width: 50%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Path</th> <th class="tableblock halign-left valign-top">Description</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#__code_get_v1_changes_code"><code>GET /v1/changes</code></a></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">List changelist summaries</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#__code_get_v1_changes_change_code"><code>GET /v1/changes/[change]</code></a></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Describe a single changelist</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#__code_post_v1_changes_code"><code>POST /v1/changes</code></a></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Create a new change with multiple file operations.</p></td> </tr> </tbody> </table> <div class="sect4"> <h5 id="__code_get_v1_changes_code"><a class="link" href="#__code_get_v1_changes_code"><code>GET /v1/changes</code></a></h5> <div class="paragraph"> <p>List changelist summaries, with some common filtering options.</p> </div> <div class="paragraph"> <p>This method requires authentication. See <a href="#_perforce_web_api_authentication">[_perforce_web_api_authentication]</a></p> </div> <div class="sect5"> <h6 id="_parameters_5"><a class="link" href="#_parameters_5">Parameters</a></h6> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Parameter Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">max</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Limit the number of results</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">number</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">URL parameter</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">status</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>pending</code>, <code>submitted</code>, or <code>shelved</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">URL parameter</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">user</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The Perforce login of the user who owns the change</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">URL parameter</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">files</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">A file pattern that should match files affected by the changelist</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">URL parameter</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> </tbody> </table> </div> <div class="sect5"> <h6 id="_response_data_2"><a class="link" href="#_response_data_2">Response Data</a></h6> <div class="paragraph"> <p>Most of the information here is based off of the <code>p4 -ztag changes</code> output. For more information please refer to the <code>p4 changes</code> command reference.</p> </div> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Change</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The changelist number</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The changelist summary description</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Status</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>pending</code>, <code>submitted</code>, or <code>shelved</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Type</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>restricted</code>, or <code>public</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Path</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Region of the depot affected by the changelist</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Client</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The Perforce client workspace name that created the change</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">User</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The Perforce login who created the changelist</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Date</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The timestamp of when the change was created</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">number</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> </tbody> </table> </div> <div class="sect5"> <h6 id="_example_6"><a class="link" href="#_example_6">Example</a></h6> <div class="paragraph"> <p>List the changes made underneath <code>//depot/swarm-development-kit/…​</code> by user jdoe.</p> </div> <div class="literalblock"> <div class="content"> <pre>GET /v1/changes?user=jdoe&amp;files=//depot/swarm-development-kit/... HTTP/1.1 Authorization: Basic c3VwZXI6NzcxMmJkMTAtOGQxMi00ZmUwLTgxM2MtZmM2OTExODQ3Yjdj</pre> </div> </div> <div class="paragraph"> <p>Here’s a response with one changelist:</p> </div> <div class="literalblock"> <div class="content"> <pre>HTTP/1.1 200 OK Content-Type: application/json</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>[ { "Change": "3", "Date": 1412976404, "User": "jdoe", "Client": "jdoe_client", "Status": "submitted", "Type": "public", "Path": "//depot/swarm-development-kit/...", "Description": "first pass\n" } ]</pre> </div> </div> </div> </div> <div class="sect4"> <h5 id="__code_get_v1_changes_change_code"><a class="link" href="#__code_get_v1_changes_change_code"><code>GET /v1/changes/[change]</code></a></h5> <div class="paragraph"> <p>Read details of a single changelist in the system.</p> </div> <div class="paragraph"> <p>Unlike the p4 describe command, this method does not list the diffs of files in a particular changelist.</p> </div> <div class="paragraph"> <p>This method requires authentication. See <a href="#_perforce_web_api_authentication">[_perforce_web_api_authentication]</a></p> </div> <div class="sect5"> <h6 id="_parameters_6"><a class="link" href="#_parameters_6">Parameters</a></h6> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Parameter Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">change</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The Perforce changelist number</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">URL path</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> </tbody> </table> </div> <div class="sect5"> <h6 id="_response_data_3"><a class="link" href="#_response_data_3">Response Data</a></h6> <div class="paragraph"> <p>The responses return fields available from <code>p4 -ztag describe</code> command. You can review the the <code>p4 describe</code> command reference, however, please be aware that the tagged output differs from the console command.</p> </div> <div class="paragraph"> <p>The main set of fields for changelists are:</p> </div> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Change</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The changelist ID</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">A textual description of the change</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Date</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The timestamp the change was created</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">number</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Client</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The client ID used to submit the change</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">User</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The Perforce login of who created the change</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Type</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The type of changelist, probably public, or, restricted</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Status</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The changelist status, probably pending, shelved, submitted, or new.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Path</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The part of the depot affected by this changelist</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Files</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Array of file changes (see below)</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">array</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> </tbody> </table> <div class="paragraph"> <p>Description of each entry in the Files array for changes.</p> </div> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">DepotFile</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The depot path to the file</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Action</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The kind of action taken on the file. For example, branch, add, edit, delete, move/delete, move/add.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Revision</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The file revision created by this entry</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Digest</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">A digest string for submitted changes.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">FileSize</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The file size, in bytes, for submitted changes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> </tbody> </table> </div> <div class="sect5"> <h6 id="_example_7"><a class="link" href="#_example_7">Example</a></h6> <div class="paragraph"> <p>Fetch the description of change 5.</p> </div> <div class="literalblock"> <div class="content"> <pre>GET /v1/changes/5 HTTP/1.1 Authorization: Basic c3VwZXI6NzcxMmJkMTAtOGQxMi00ZmUwLTgxM2MtZmM2OTExODQ3Yjdj</pre> </div> </div> <div class="paragraph"> <p>Typical JSON response:</p> </div> <div class="literalblock"> <div class="content"> <pre>HTTP/1.1 200 OK Content-Type: application/json</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>[{ "Path": "//depot/dev/Experimental/*", "Change": "5", "Date": 1418922083, "Client": "BADFJRZI", "User": "jdoe", "Status": "submitted", "Type": "public", "Description": "Uploaded files\n", "Files": [ { "DepotFile": "//depot/dev/Experimental/new_file", "Action": "add", "Revision": "1", "Digest": "3D65EFC8CA18C21F7BEB78E47AE94206", "FileSize": "16" }, { "DepotFile": "//depot/dev/Experimental/README", "Action": "edit", "Revision": "3", "Digest": "79D26F4E7F23D662E51F45896891D7C1", "FileSize": "22" } ] }]</pre> </div> </div> </div> </div> <div class="sect4"> <h5 id="__code_post_v1_changes_code"><a class="link" href="#__code_post_v1_changes_code"><code>POST /v1/changes</code></a></h5> <div class="paragraph"> <p>Create a new changelist that can affect multiple files using different kinds of actions. If you require the ability to integrate or move, for example, you will use this method.</p> </div> <div class="paragraph"> <p>This method requires authentication. See <a href="#_perforce_web_api_authentication">[_perforce_web_api_authentication]</a></p> </div> <div class="sect5"> <h6 id="_request_body"><a class="link" href="#_request_body">Request Body</a></h6> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Parameter Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Textual description of the change</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Files</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Array of file change actions to take (See below)</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">array</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> </tbody> </table> <div class="paragraph"> <p>Each object in the Files array consists of the following fields:</p> </div> <table class="tableblock frame-all grid-all spread"> <colgroup> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> <col style="width: 20%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Parameter</th> <th class="tableblock halign-left valign-top">Description</th> <th class="tableblock halign-left valign-top">Type</th> <th class="tableblock halign-left valign-top">Parameter Type</th> <th class="tableblock halign-left valign-top">Required</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">DepotFile</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">The depot path specifier for the action</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">FromDepotFile</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">When the Action is a branch or move, this indicates the source of the operation.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Action</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">One of upload, branch, or move.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Content</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">If the Action is upload, this is the base-64 encoded file content.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">body</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td> </tr> </tbody> </table> </div> <div class="sect5"> <h6 id="_example_8"><a class="link" href="#_example_8">Example</a></h6> <div class="paragraph"> <p>Create a new change with one file branched and the other moved.</p> </div> <div class="literalblock"> <div class="content"> <pre>POST /v1/users HTTP/1.1 Authorization: Basic c3VwZXI6NzcxMmJkMTAtOGQxMi00ZmUwLTgxM2MtZmM2OTExODQ3Yjdj Content-Type: application/json</pre> </div> </div> <div class="literalblock"> <div class="content"> <pre>{ 'Description' =&gt; 'An integ and a move', 'Files' =&gt; [ { 'DepotFile' =&gt; '//depot/main/README', 'FromDepotFile' =&gt; '//depot/dev/README', 'Action' =&gt; 'branch' }, { 'DepotFile' =&gt; '//depot/main/to', 'FromDepotFile' =&gt; '//depot/main/from', 'Action' =&gt; 'move' } ] }</pre> </div> </div> <div class="paragraph"> <p>The response should indicate 200 on success.</p> </div> <div class="literalblock"> <div class="content"> <pre>HTTP/1.1 200 OK</pre> </div> </div> </div> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_client_sdk_reference"><a class="link" href="#_client_sdk_reference">Client SDK Reference</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>The most complete Client SDK is provided by Ruby.</p> </div> <div class="ulist"> <ul> <li> <p><a href="./helix_web_services_client_ruby/index.html">Open Ruby Client API</a></p> </li> </ul> </div> <div class="paragraph"> <p>Other SDKs are available that provide a less complete implementation to Helix Web SErvices</p> </div> <div class="ulist"> <ul> <li> <p><a href="./helix_web_services_client_js/index.html">Open JavaScript API</a></p> </li> <li> <p><a href="./helix_web_services_client_qt/html/index.html">Open Qt API</a></p> </li> </ul> </div> </div> </div> <div class="sect1"> <h2 id="_server_programming"><a class="link" href="#_server_programming">Server Programming</a></h2> <div class="sectionbody"> <div class="sect2"> <h3 id="_including_new_rack_middleware"><a class="link" href="#_including_new_rack_middleware">Including New Rack Middleware</a></h3> </div> <div class="sect2"> <h3 id="_registering_configuration_variables"><a class="link" href="#_registering_configuration_variables">Registering Configuration Variables</a></h3> </div> </div> </div> <div class="sect1"> <h2 id="_server_api_reference"><a class="link" href="#_server_api_reference">Server API Reference</a></h2> <div class="sectionbody"> <div class="paragraph"> <p>The Ruby-based server API reference should help you when generating custom services to be deployed into your own environment.</p> </div> <div class="ulist"> <ul> <li> <p><a href="./helix_web_services/index.html">Open Server API</a></p> </li> </ul> </div> </div> </div> </div> <div id="footer"> <div id="footer-text"> Version 2015.1.alpha<br> Last updated 2015-07-14 13:19:42 PDT </div> </div> </body> </html>
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#69 | 16346 | tjuricek | Removing build directory prior to migration | ||
#68 | 16334 | tjuricek |
HWS/NOARCH/2015.1.main/201510211937 Documentation updates for new system configuration options. |
||
#67 | 16331 | tjuricek |
HWS/NOARCH/2015.1.main/201510211755 This is a large revision to the deployment: - nginx is now part of the system - perforce-server is *not* installed during post-install configuration The only change for migration should be to uninstall (and purge) your current nginx setup. |
||
#66 | 16161 | tjuricek |
HWS/NOARCH/2015.1.main/201510082242 - Ability for custom middleware to filter P4PORT agressively - If p4d deems login not necessary, return an empty string for the valid ticket value. |
||
#65 | 16144 | tjuricek |
HWS/NOARCH/2015.1.main/201510081946 Major revision to URL structure. This is a breaking change to the API. |
||
#64 | 16093 | tjuricek |
HWS/NOARCH/2015.1.main/201510061647 Rename of trust setting, and adjustments to Helix Sync logic for selecting pending changelists |
||
#63 | 16077 | tjuricek |
HWS/NOARCH/2015.1.main/201510051630 Includes changes to trust behavior |
||
#62 | 16007 | tjuricek |
HWS/NOARCH/2015.1.main/201510011648 Documentation updates for the new default parameter to getting the latest helix sync client |
||
#61 | 15975 | tjuricek |
HWS/NOARCH/2015.1.main/201509291925 Add support for repo creation/update and deletion, same for SSH keys. Add util module for supporting methods, modify temp client to dissapear. (Modified submit of review 15549 by @ptomiak) |
||
#60 | 15783 | tjuricek | HWS/NOARCH/2015.1.main/201509180120 | ||
#59 | 15769 | tjuricek | HWS/NOARCH/2015.1.main/201509170120 | ||
#58 | 15758 | tjuricek | HWS/NOARCH/2015.1.main/201509161743 | ||
#57 | 15737 | tjuricek | HWS/NOARCH/2015.1.main/201509150120 | ||
#56 | 15708 | tjuricek | HWS/NOARCH/2015.1.main/201509140120 | ||
#55 | 15699 | tjuricek | HWS/NOARCH/2015.1.main/201509111845 | ||
#54 | 15690 | tjuricek | HWS/NOARCH/2015.1.main/201509110141 | ||
#53 | 15676 | tjuricek | HWS/NOARCH/2015.1.main/201509092205 | ||
#52 | 15545 | tjuricek | Place in config and hooks for Helix Cloud authentication. | ||
#51 | 15530 | tjuricek | Add basic development guide | ||
#50 | 15517 | tjuricek | Do not require changelist ID for submitting Helix Sync pending changelists. | ||
#49 | 15499 | tjuricek | Naive implementation of helix sync project submit for "helix versioning engine projects". | ||
#48 | 15496 | tjuricek |
Revise GET /helix_sync/v1/changes/[project] to /helix_sync/v1/changes/[project]/pending The base method is really intended for the latest changelist number. Meh. |
||
#47 | 15487 | tjuricek | Add basic ability to create pending changelists for helix sync projects. | ||
#46 | 15483 | tjuricek |
Add a new 'hws_console` application to the deployment. This should give users the ability to use the Ruby client for quick and dirty debugging of issues with HWS. Since it's so easy, I've added it to the deployment guide. |
||
#45 | 15479 | tjuricek | Added a basic "HVE project" implementation for creating clients. | ||
#44 | 15460 | tjuricek | Add notes on service startup in deployment | ||
#43 | 15447 | tjuricek |
Add simple Example application to list "projects" in a HVE instance. Qt's a little weird to follow, so I may have to find a different kind of example to write. It does work, however. |
||
#42 | 15435 | tjuricek |
Add proposed HTTP methods for Helix Sync. It's a little unclear to me why you would need a local root directory to create the shared shelving changelist for a particular project (and user). So I didn't add that. |
||
#41 | 15423 | tjuricek |
Revised HWS Qt API. This is a major revision of the API, which removes most of the "typed" data, replacing it with a more generic "executeMethodDone" callback. The main benefit here is to allow the API to interop with different versions of p4d, and not restrict the methods it can call. We may add more helpers in the future. |
||
#40 | 15299 | tjuricek | Revise documentation of our new 'list available services' method. | ||
#39 | 15297 | tjuricek |
Implement of 'cluster services' configuration. The configuration will be stored in a local JSON file, which is expected to be maintained by the systems admin. Eventually, it's expected to have this sort of thing implemented via Helix Admin. |
||
#38 | 15260 | tjuricek |
Fix truncation of content when listing a single file's details. Added message warning people about timeouts. This does work, and doesn't bring the system down, but you'll probably hit timeouts if you're trying to download files using this system. |
||
#37 | 15257 | tjuricek |
Added stress test, corrected per-request header config. Apparently using underscores is a "special" mechanism for HTTP headers, and requires adjusting nginx to allow such things. Might as well just recommend using hyphens, which get converted to underscores anyway. The current test just hits a listing of 20000 files against p4play. Returns a 2.5 MB response, which doesn't seem to cause problems (yay). |
||
#36 | 15242 | tjuricek | Add Helix Sync stubs and documentation | ||
#35 | 15241 | tjuricek | Add Git Fusion stubs and documentation. | ||
#34 | 15240 | tjuricek |
Set api level via request path on all Helix Versioning Engine methods. This will allow migration of applications to different P4D versions. Our internal methods (like project API) should attempt to handle backward compatibility similarly. P4WEBAPI-118 |
||
#33 | 15229 | tjuricek | Remove incorrect default setting for P4HOST | ||
#32 | 15228 | tjuricek | Revise triggers implementation, tests, and documentation. | ||
#31 | 15227 | tjuricek |
Revise implementation, tests, and documentation for protections management. Remove some specs I will not be revising from the helix_web_services project. |
||
#30 | 15225 | tjuricek |
Revise counter implementation, tests, and documentation Wasn't available in the Ruby client before, so, it's now available. |
||
#29 | 15222 | tjuricek |
Revise server specs testing and documentation. Note: also fixed issues with setting P4PORT via headers. For whatever reason, the host setting doesn't seem to work like I expect it to, though P4PORT works just fine. |
||
#28 | 15211 | tjuricek | Implement tests and documentation for label spec management. | ||
#27 | 15210 | tjuricek | Implement tests and documentation for job spec management. | ||
#26 | 15209 | tjuricek | Implement tests and documentation for group spec management. | ||
#25 | 15208 | tjuricek |
Revise 'command' implementation, tests, and documentaiton. This includes a change from a command blacklist to a whitelist. See P4WEBAPI-21 |
||
#24 | 15205 | tjuricek | Implemented tests and documentation for depot spec editing. | ||
#23 | 15189 | tjuricek | Update files implementation, testing, and documentation. | ||
#22 | 15188 | tjuricek | Execute user modification commands as the super user in tests. | ||
#21 | 15185 | tjuricek | Update user spec management implementation, tests, and documentation. | ||
#20 | 15144 | tjuricek |
Setup stream spec tests and documentation. Also revised the documentation folder http_p4_web_api -> helix_versioning_engine |
||
#19 | 15132 | tjuricek | Provde a basic submit -e mechanism on classic perforce workspaces. | ||
#18 | 15110 | tjuricek | Revise changes methods for new p4 connection handling, add server specs, remove model references in client, and update asciidoc documentation. | ||
#17 | 15099 | tjuricek | Revise project services to be our simple 'container' for other systems. | ||
#16 | 15098 | tjuricek |
Revised project services to GET-only forms. With Helix Sync revising to integrate purely with Helix Cloud, this is the only thing we can reasonably define. |
||
#15 | 15090 | tjuricek |
Update _proposed_ API for project services. This is *very likely* to change, and will not be implemented until reviewed. |
||
#14 | 15078 | tjuricek |
clients spec method revisions Updated some other documentation. |
||
#13 | 15077 | tjuricek |
Add new 'model' technique, revised branch spec operations, test Auth::Middleware. The Ruby client now does *not* strictly type anything, but extends OpenStruct with helper methods to help deal with inconsistent data formats. See the OpenModel class documentation for more details. The Auth::Middleware class is also *finally* implemented as well. This does not take into account all possible variations of server behavior (yet), but that will happen in follow-up work. |
||
#12 | 15073 | tjuricek | Update Auth::Middleware and add spec | ||
#11 | 15042 | tjuricek | Document error conventions. | ||
#10 | 15038 | tjuricek | Document 'login' auth method and client programming overview. | ||
#9 | 15032 | tjuricek |
Starting config and doc revisions. System is now broken while revisions underway. Configuration of the p4d connection is now done via a single HWSSettings middleware object injected into the Rack env. The HWSP4Cleanup middleware now cleans up any p4 injected into the Rack env. The Auth::App class now mostly just contains one method to generate a p4 ticket. /auth/v1/login. Added yard documentation for the main project. Yard docs have been reconfigured to dump into build/ directories. This should probably be done with each release. Hm... The top level rake file contains a task, 'all:doc', to update our documentation. This should probably be run for each checkin. Hm... Specs are now using Rack::Test on top of a 'live' p4d. I'd suggest you still use the p4util mechanism, which now dumps to a /tmp folder, so we can safely add P4IGNORE rules back into your local .p4config file. Old 'perforce' application now called 'helix_versioning_engine'. Removing cache data. Helix Sync may be slow. It may also get axed. We'll see. |
||
#8 | 14980 | tjuricek |
Starting to make revisions to the Asciidoc guide. These are just revisions to the preable sections. |
||
#7 | 14184 | tjuricek | Revise the CD diagram, update official docs, and change the DB configuration key. | ||
#6 | 14182 | tjuricek | Asciidoc conversion of the changes HTTP guide | ||
#5 | 14049 | tjuricek |
Add methods to generate client workspaces for a user. The Qt SDK was updated based on immediate need. Also, add Ruby client SDK documentation to the docs site. Everything is early, but there's *some* reference available at least. |
||
#4 | 14027 | tjuricek | Move almost all Qt SDK documentation to Doxygen system, and just reference it in the main doc site. | ||
#3 | 14002 | tjuricek | Some preliminary API documentation for the JavaScript SDK. | ||
#2 | 13614 | tjuricek | Update the Qt guide to include the QSettings* constructor. | ||
#1 | 13612 | tjuricek | Update deployment guide, switch built documentation to asciidoc, remove unused packaging script for p4_web_api |