CINXE.COM
<!doctype html><html lang="en"><head><title data-rh="true">Developing fast & reliable iOS builds at Pinterest | by Pinterest Engineering | Pinterest Engineering Blog | Medium</title><meta data-rh="true" charset="utf-8"/><meta data-rh="true" name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,maximum-scale=1"/><meta data-rh="true" name="theme-color" content="#000000"/><meta data-rh="true" name="twitter:app:name:iphone" content="Medium"/><meta data-rh="true" name="twitter:app:id:iphone" content="828256236"/><meta data-rh="true" property="al:ios:app_name" content="Medium"/><meta data-rh="true" property="al:ios:app_store_id" content="828256236"/><meta data-rh="true" property="al:android:package" content="com.medium.reader"/><meta data-rh="true" property="fb:app_id" content="542599432471018"/><meta data-rh="true" property="og:site_name" content="Medium"/><meta data-rh="true" property="og:type" content="article"/><meta data-rh="true" property="article:published_time" content="2021-06-11T16:51:59.725Z"/><meta data-rh="true" name="title" content="Developing fast & reliable iOS builds at Pinterest | by Pinterest Engineering | Pinterest Engineering Blog | Medium"/><meta data-rh="true" property="og:title" content="Developing fast & reliable iOS builds at Pinterest (Part one)"/><meta data-rh="true" property="al:android:url" content="medium://p/cb1810407b92"/><meta data-rh="true" property="al:ios:url" content="medium://p/cb1810407b92"/><meta data-rh="true" property="al:android:app_name" content="Medium"/><meta data-rh="true" name="description" content="At Pinterest we’re focused on helping people discover inspiring ideas, from dinner recipes to try, home and style products to buy, to places to travel. Building the best products for mobile is a…"/><meta data-rh="true" property="og:description" content="By Rahul Malik | iOS Platform Tech Lead"/><meta data-rh="true" property="og:url" content="https://medium.com/pinterest-engineering/developing-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92"/><meta data-rh="true" property="al:web:url" content="https://medium.com/pinterest-engineering/developing-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92"/><meta data-rh="true" property="og:image" content="https://miro.medium.com/v2/resize:fit:512/1*zDbDRMKBXoSjywY_vmbrzA.jpeg"/><meta data-rh="true" property="article:author" content="https://medium.com/@Pinterest_Engineering"/><meta data-rh="true" name="author" content="Pinterest Engineering"/><meta data-rh="true" name="robots" content="index,noarchive,follow,max-image-preview:large"/><meta data-rh="true" name="referrer" content="unsafe-url"/><meta data-rh="true" property="twitter:title" content="Developing fast & reliable iOS builds at Pinterest (Part one)"/><meta data-rh="true" name="twitter:site" content="@PinterestEng"/><meta data-rh="true" name="twitter:app:url:iphone" content="medium://p/cb1810407b92"/><meta data-rh="true" property="twitter:description" content="By Rahul Malik | iOS Platform Tech Lead"/><meta data-rh="true" name="twitter:image:src" content="https://miro.medium.com/v2/resize:fit:512/1*zDbDRMKBXoSjywY_vmbrzA.jpeg"/><meta data-rh="true" name="twitter:card" content="summary_large_image"/><meta data-rh="true" name="twitter:creator" content="@PinterestEng"/><meta data-rh="true" name="twitter:label1" content="Reading time"/><meta data-rh="true" name="twitter:data1" content="7 min read"/><link data-rh="true" rel="icon" href="https://miro.medium.com/v2/5d8de952517e8160e40ef9841c781cdc14a5db313057fa3c3de41c6f5b494b19"/><link data-rh="true" rel="search" type="application/opensearchdescription+xml" title="Medium" href="/osd.xml"/><link data-rh="true" rel="apple-touch-icon" sizes="152x152" href="https://miro.medium.com/v2/resize:fill:304:304/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="120x120" href="https://miro.medium.com/v2/resize:fill:240:240/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="76x76" href="https://miro.medium.com/v2/resize:fill:152:152/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="60x60" href="https://miro.medium.com/v2/resize:fill:120:120/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="mask-icon" href="https://miro.medium.com/v2/resize:fill:1000:1000/7*GAOKVe--MXbEJmV9230oOQ.png" color="#171717"/><link data-rh="true" rel="preconnect" href="https://glyph.medium.com" crossOrigin=""/><link data-rh="true" id="glyph_preload_link" rel="preload" as="style" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" id="glyph_link" rel="stylesheet" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" rel="author" href="https://medium.com/@Pinterest_Engineering"/><link data-rh="true" rel="canonical" href="https://medium.com/pinterest-engineering/developing-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92"/><link data-rh="true" rel="alternate" href="android-app://com.medium.reader/https/medium.com/p/cb1810407b92"/><script data-rh="true" type="application/ld+json">{"@context":"http:\u002F\u002Fschema.org","@type":"NewsArticle","image":["https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1200\u002F1*zDbDRMKBXoSjywY_vmbrzA.jpeg"],"url":"https:\u002F\u002Fmedium.com\u002Fpinterest-engineering\u002Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92","dateCreated":"2019-02-13T23:25:37.528Z","datePublished":"2019-02-13T23:25:37.528Z","dateModified":"2021-12-07T12:25:32.823Z","headline":"Developing fast & reliable iOS builds at Pinterest - Pinterest Engineering Blog - Medium","name":"Developing fast & reliable iOS builds at Pinterest - Pinterest Engineering Blog - Medium","description":"At Pinterest we’re focused on helping people discover inspiring ideas, from dinner recipes to try, home and style products to buy, to places to travel. Building the best products for mobile is a…","identifier":"cb1810407b92","author":{"@type":"Person","name":"Pinterest Engineering","url":"https:\u002F\u002Fmedium.com\u002F@Pinterest_Engineering"},"creator":["Pinterest Engineering"],"publisher":{"@type":"Organization","name":"Pinterest Engineering Blog","url":"https:\u002F\u002Fmedium.com\u002Fpinterest-engineering","logo":{"@type":"ImageObject","width":272,"height":60,"url":"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:544\u002F7*V1_7XP4snlmqrc_0Njontw.png"}},"mainEntityOfPage":"https:\u002F\u002Fmedium.com\u002Fpinterest-engineering\u002Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92"}</script><style type="text/css" data-fela-rehydration="541" data-fela-type="STATIC">html{box-sizing:border-box;-webkit-text-size-adjust:100%}*, *:before, *:after{box-sizing:inherit}body{margin:0;padding:0;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:rgba(0,0,0,0.8);position:relative;min-height:100vh}h1, h2, h3, h4, h5, h6, dl, dd, ol, ul, menu, figure, blockquote, p, pre, form{margin:0}menu, ol, ul{padding:0;list-style:none;list-style-image:none}main{display:block}a{color:inherit;text-decoration:none}a, button, input{-webkit-tap-highlight-color:transparent}img, svg{vertical-align:middle}button{background:transparent;overflow:visible}button, input, optgroup, select, textarea{margin:0}:root{--reach-tabs:1;--reach-menu-button:1}#speechify-root{font-family:Sohne, sans-serif}div[data-popper-reference-hidden="true"]{visibility:hidden;pointer-events:none}.grecaptcha-badge{visibility:hidden} /*XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com>*/.hljs {background: #fff;color: black; }/* Gray DOCTYPE selectors like WebKit */ .xml .hljs-meta {color: #c0c0c0; }.hljs-comment, .hljs-quote {color: #007400; }.hljs-tag, .hljs-attribute, .hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-name {color: #aa0d91; }.hljs-variable, .hljs-template-variable {color: #3F6E74; }.hljs-code, .hljs-string, .hljs-meta .hljs-string {color: #c41a16; }.hljs-regexp, .hljs-link {color: #0E0EFF; }.hljs-title, .hljs-symbol, .hljs-bullet, .hljs-number {color: #1c00cf; }.hljs-section, .hljs-meta {color: #643820; }.hljs-title.class_, .hljs-class .hljs-title, .hljs-type, .hljs-built_in, .hljs-params {color: #5c2699; }.hljs-attr {color: #836C28; }.hljs-subst {color: #000; }.hljs-formula {background-color: #eee;font-style: italic; }.hljs-addition {background-color: #baeeba; }.hljs-deletion {background-color: #ffc8bd; }.hljs-selector-id, .hljs-selector-class {color: #9b703f; }.hljs-doctag, .hljs-strong {font-weight: bold; }.hljs-emphasis {font-style: italic; } </style><style type="text/css" data-fela-rehydration="541" data-fela-type="KEYFRAME">@-webkit-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@-moz-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE">.a{font-family:medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}.b{font-weight:400}.c{background-color:rgba(255, 255, 255, 1)}.l{display:block}.m{position:sticky}.n{top:0}.o{z-index:500}.p{padding:0 24px}.q{align-items:center}.r{border-bottom:solid 1px #F2F2F2}.y{height:41px}.z{line-height:20px}.ab{display:flex}.ac{height:57px}.ae{flex:1 0 auto}.af{color:inherit}.ag{fill:inherit}.ah{font-size:inherit}.ai{border:inherit}.aj{font-family:inherit}.ak{letter-spacing:inherit}.al{font-weight:inherit}.am{padding:0}.an{margin:0}.ao{cursor:pointer}.ap:disabled{cursor:not-allowed}.aq:disabled{color:#6B6B6B}.ar:disabled{fill:#6B6B6B}.au{width:auto}.av path{fill:#242424}.aw{height:25px}.ax{margin-left:16px}.ay{border:none}.az{border-radius:20px}.ba{width:240px}.bb{background:#F9F9F9}.bc path{fill:#6B6B6B}.be{outline:none}.bf{font-family:sohne, "Helvetica Neue", Helvetica, Arial, sans-serif}.bg{font-size:14px}.bh{width:100%}.bi{padding:10px 20px 10px 0}.bj{background-color:transparent}.bk{color:#242424}.bl::placeholder{color:#6B6B6B}.bm{display:inline-block}.bn{margin-left:12px}.bo{margin-right:12px}.bp{border-radius:4px}.bq{margin-left:24px}.br{height:24px}.bx{background-color:#F9F9F9}.by{border-radius:50%}.bz{height:32px}.ca{width:32px}.cb{justify-content:center}.ch{max-width:680px}.ci{min-width:0}.cj{animation:k1 1.2s ease-in-out infinite}.ck{height:100vh}.cl{margin-bottom:16px}.cm{margin-top:48px}.cn{align-items:flex-start}.co{flex-direction:column}.cp{justify-content:space-between}.cq{margin-bottom:24px}.cw{width:80%}.cx{background-color:#F2F2F2}.dd{height:44px}.de{width:44px}.df{margin:auto 0}.dg{margin-bottom:4px}.dh{height:16px}.di{width:120px}.dj{width:80px}.dp{margin-bottom:8px}.dq{width:96%}.dr{width:98%}.ds{width:81%}.dt{margin-left:8px}.du{color:#6B6B6B}.dv{font-size:13px}.dw{height:100%}.ep{color:#FFFFFF}.eq{fill:#FFFFFF}.er{background:rgba(233, 51, 53, 1)}.es{border-color:rgba(233, 51, 53, 1)}.ew:disabled{cursor:inherit !important}.ex:disabled{opacity:0.3}.ey:disabled:hover{background:rgba(233, 51, 53, 1)}.ez:disabled:hover{border-color:rgba(233, 51, 53, 1)}.fa{border-radius:99em}.fb{border-width:1px}.fc{border-style:solid}.fd{box-sizing:border-box}.fe{text-decoration:none}.ff{text-align:center}.fi{margin-right:32px}.fj{position:relative}.fk{fill:#6B6B6B}.fn{background:transparent}.fo svg{margin-left:4px}.fp svg{fill:#6B6B6B}.fr{box-shadow:inset 0 0 0 1px rgba(0, 0, 0, 0.05)}.fs{position:absolute}.fz{margin:0 24px}.gd{background:rgba(255, 255, 255, 1)}.ge{border:1px solid #F2F2F2}.gf{box-shadow:0 1px 4px #F2F2F2}.gg{max-height:100vh}.gh{overflow-y:auto}.gi{left:0}.gj{top:calc(100vh + 100px)}.gk{bottom:calc(100vh + 100px)}.gl{width:10px}.gm{pointer-events:none}.gn{word-break:break-word}.go{word-wrap:break-word}.gp:after{display:block}.gq:after{content:""}.gr:after{clear:both}.gs{line-height:1.23}.gt{letter-spacing:0}.gu{font-style:normal}.gv{font-weight:700}.ia{align-items:baseline}.ib{width:48px}.ic{height:48px}.id{border:2px solid rgba(255, 255, 255, 1)}.ie{z-index:0}.if{box-shadow:none}.ig{border:1px solid rgba(0, 0, 0, 0.05)}.ih{margin-left:-12px}.ii{width:28px}.ij{height:28px}.ik{z-index:1}.il{width:24px}.im{margin-bottom:2px}.in{flex-wrap:nowrap}.io{font-size:16px}.ip{line-height:24px}.ir{margin:0 8px}.is{display:inline}.it{color:rgba(233, 51, 53, 1)}.iu{fill:rgba(233, 51, 53, 1)}.ix{flex:0 0 auto}.ja{flex-wrap:wrap}.jb{white-space:pre-wrap}.jc{margin-right:4px}.jd{overflow:hidden}.je{max-height:20px}.jf{text-overflow:ellipsis}.jg{display:-webkit-box}.jh{-webkit-line-clamp:1}.ji{-webkit-box-orient:vertical}.jj{word-break:break-all}.jl{padding-left:8px}.jm{padding-right:8px}.kn> *{flex-shrink:0}.ko{overflow-x:scroll}.kp::-webkit-scrollbar{display:none}.kq{scrollbar-width:none}.kr{-ms-overflow-style:none}.ks{width:74px}.kt{flex-direction:row}.ku{z-index:2}.kx{-webkit-user-select:none}.ky{border:0}.kz{fill:rgba(117, 117, 117, 1)}.lc{outline:0}.ld{user-select:none}.le> svg{pointer-events:none}.ln{cursor:progress}.lo{margin-left:4px}.lp{margin-top:0px}.lq{opacity:1}.lr{padding:4px 0}.lu{width:16px}.lw{display:inline-flex}.mc{max-width:100%}.md{padding:8px 2px}.me svg{color:#6B6B6B}.mv{line-height:1.58}.mw{letter-spacing:-0.004em}.mx{font-family:source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif}.ns{margin-bottom:-0.46em}.nt{margin-left:auto}.nu{margin-right:auto}.nv{max-width:512px}.ob{clear:both}.oc{height:auto}.od{list-style-type:disc}.oe{margin-left:30px}.of{padding-left:0px}.ol{line-height:1.12}.om{letter-spacing:-0.022em}.on{font-weight:600}.pi{margin-bottom:-0.28em}.po{text-decoration:underline}.pp{margin-bottom:26px}.pq{margin-top:6px}.pr{margin-top:8px}.ps{margin-right:8px}.pt{padding:8px 16px}.pu{border-radius:100px}.pv{transition:background 300ms ease}.px{white-space:nowrap}.py{border-top:none}.pz{margin-bottom:50px}.qa{height:52px}.qb{max-height:52px}.qc{box-sizing:content-box}.qd{position:static}.qf{max-width:155px}.ql{margin-right:20px}.qm{margin-bottom:64px}.qn{margin-bottom:48px}.rb{border-radius:2px}.rd{height:64px}.re{width:64px}.rf{align-self:flex-end}.rg{flex:1 1 auto}.rm{padding-right:4px}.rn{font-weight:500}.sa{margin-top:16px}.sb{color:rgba(255, 255, 255, 1)}.sc{fill:rgba(255, 255, 255, 1)}.sd{background:rgba(25, 25, 25, 1)}.se{border-color:rgba(25, 25, 25, 1)}.sh:disabled{opacity:0.1}.si:disabled:hover{background:rgba(25, 25, 25, 1)}.sj:disabled:hover{border-color:rgba(25, 25, 25, 1)}.sp{height:0px}.sq{gap:18px}.sr{fill:rgba(61, 61, 61, 1)}.st{padding-bottom:6px}.su{border-bottom:1px solid #F2F2F2}.ta{margin-top:32px}.tb{fill:#242424}.tc{background:0}.td{border-color:#242424}.te:disabled:hover{color:#242424}.tf:disabled:hover{fill:#242424}.tg:disabled:hover{border-color:#242424}.tr{border-bottom:solid 1px #E5E5E5}.ts{margin-top:72px}.tt{padding:24px 0}.tu{margin-bottom:0px}.tv{margin-right:16px}.as:hover:not(:disabled){color:rgba(25, 25, 25, 1)}.at:hover:not(:disabled){fill:rgba(25, 25, 25, 1)}.et:hover{background:rgba(197, 51, 49, 1)}.eu:hover{border-color:rgba(197, 51, 49, 1)}.ev:hover{cursor:pointer}.fl:hover{color:#242424}.fm:hover{fill:#242424}.fq:hover svg{fill:#242424}.ft:hover{background-color:rgba(0, 0, 0, 0.1)}.iq:hover{text-decoration:underline}.iv:hover:not(:disabled){color:rgba(197, 51, 49, 1)}.iw:hover:not(:disabled){fill:rgba(197, 51, 49, 1)}.lb:hover{fill:rgba(8, 8, 8, 1)}.ls:hover{fill:#000000}.lt:hover p{color:#000000}.lv:hover{color:#000000}.mf:hover svg{color:#000000}.pw:hover{background-color:#F2F2F2}.rc:hover{background-color:none}.sf:hover{background:#000000}.sg:hover{border-color:#242424}.ss:hover{fill:rgba(25, 25, 25, 1)}.bd:focus-within path{fill:#242424}.la:focus{fill:rgba(8, 8, 8, 1)}.mg:focus svg{color:#000000}.lf:active{border-style:none}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE" media="all and (min-width: 1080px)">.d{display:none}.bw{width:64px}.cg{margin:0 64px}.cv{height:48px}.dc{margin-bottom:52px}.do{margin-bottom:48px}.ef{font-size:14px}.eg{line-height:20px}.em{font-size:13px}.eo{padding:5px 12px}.fh{display:flex}.fy{margin-bottom:50px}.gc{max-width:680px}.hq{font-size:42px}.hr{margin-top:1.19em}.hs{margin-bottom:32px}.ht{line-height:52px}.hu{letter-spacing:-0.011em}.hz{align-items:center}.jz{border-top:solid 1px #F2F2F2}.ka{border-bottom:solid 1px #F2F2F2}.kb{margin:32px 0 0}.kc{padding:3px 8px}.kl> *{margin-right:24px}.km> :last-child{margin-right:0}.lm{margin-top:0px}.mb{margin:0}.no{font-size:20px}.np{margin-top:2.14em}.nq{line-height:32px}.nr{letter-spacing:-0.003em}.oa{margin-top:56px}.ok{margin-top:1.14em}.pe{font-size:24px}.pf{margin-top:1.95em}.pg{line-height:30px}.ph{letter-spacing:-0.016em}.pn{margin-top:0.94em}.qk{display:inline-block}.qo{flex-direction:row}.qr{margin-bottom:0}.qs{margin-right:20px}.rh{max-width:500px}.ry{line-height:24px}.rz{letter-spacing:0}.so{margin-bottom:88px}.sz{margin:40px 0 16px}.tl{width:min-width}.tq{padding-top:72px}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE" media="all and (max-width: 1079.98px)">.e{display:none}.ll{margin-top:0px}.qj{display:inline-block}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE" media="all and (max-width: 903.98px)">.f{display:none}.lk{margin-top:0px}.qi{display:inline-block}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE" media="all and (max-width: 727.98px)">.g{display:none}.li{margin-top:0px}.lj{margin-right:0px}.qh{display:inline-block}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE" media="all and (max-width: 551.98px)">.h{display:none}.s{display:flex}.t{justify-content:space-between}.bs{width:24px}.cc{margin:0 24px}.cr{height:40px}.cy{margin-bottom:44px}.dk{margin-bottom:32px}.dx{font-size:13px}.dy{line-height:20px}.eh{padding:0px 8px 1px}.fu{margin-bottom:2px}.gw{font-size:32px}.gx{margin-top:1.01em}.gy{margin-bottom:24px}.gz{line-height:38px}.ha{letter-spacing:-0.014em}.hv{align-items:flex-start}.iy{flex-direction:column}.jn{margin:24px -24px 0}.jo{padding:0}.kd> *{margin-right:8px}.ke> :last-child{margin-right:24px}.kv{margin-left:0px}.lg{margin-top:0px}.lh{margin-right:0px}.lx{margin:0}.mh{border:1px solid #F2F2F2}.mi{border-radius:99em}.mj{padding:0px 16px 0px 12px}.mk{height:38px}.ml{align-items:center}.mn svg{margin-right:8px}.my{font-size:18px}.mz{margin-top:1.56em}.na{line-height:28px}.nb{letter-spacing:-0.003em}.nw{margin-top:40px}.og{margin-top:1.34em}.oo{font-size:20px}.op{margin-top:1.2em}.oq{line-height:24px}.or{letter-spacing:0}.pj{margin-top:0.67em}.qg{display:inline-block}.qz{margin-bottom:20px}.ra{margin-right:0}.rl{max-width:100%}.ro{font-size:24px}.rp{line-height:30px}.rq{letter-spacing:-0.016em}.sk{margin-bottom:64px}.sv{margin:32px 0 16px}.th{width:100%}.tm{padding-top:48px}.mm:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE" media="all and (min-width: 904px) and (max-width: 1079.98px)">.i{display:none}.bv{width:64px}.cf{margin:0 64px}.cu{height:48px}.db{margin-bottom:52px}.dn{margin-bottom:48px}.ed{font-size:14px}.ee{line-height:20px}.ek{font-size:13px}.el{padding:5px 12px}.fg{display:flex}.fx{margin-bottom:50px}.gb{max-width:680px}.hl{font-size:42px}.hm{margin-top:1.19em}.hn{margin-bottom:32px}.ho{line-height:52px}.hp{letter-spacing:-0.011em}.hy{align-items:center}.jv{border-top:solid 1px #F2F2F2}.jw{border-bottom:solid 1px #F2F2F2}.jx{margin:32px 0 0}.jy{padding:3px 8px}.kj> *{margin-right:24px}.kk> :last-child{margin-right:0}.ma{margin:0}.nk{font-size:20px}.nl{margin-top:2.14em}.nm{line-height:32px}.nn{letter-spacing:-0.003em}.nz{margin-top:56px}.oj{margin-top:1.14em}.pa{font-size:24px}.pb{margin-top:1.95em}.pc{line-height:30px}.pd{letter-spacing:-0.016em}.pm{margin-top:0.94em}.qp{flex-direction:row}.qt{margin-bottom:0}.qu{margin-right:20px}.ri{max-width:500px}.rw{line-height:24px}.rx{letter-spacing:0}.sn{margin-bottom:88px}.sy{margin:40px 0 16px}.tk{width:min-width}.tp{padding-top:72px}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE" media="all and (min-width: 728px) and (max-width: 903.98px)">.j{display:none}.w{display:flex}.x{justify-content:space-between}.bu{width:64px}.ce{margin:0 48px}.ct{height:48px}.da{margin-bottom:52px}.dm{margin-bottom:48px}.eb{font-size:13px}.ec{line-height:20px}.ej{padding:0px 8px 1px}.fw{margin-bottom:50px}.ga{max-width:680px}.hg{font-size:42px}.hh{margin-top:1.19em}.hi{margin-bottom:32px}.hj{line-height:52px}.hk{letter-spacing:-0.011em}.hx{align-items:center}.jr{border-top:solid 1px #F2F2F2}.js{border-bottom:solid 1px #F2F2F2}.jt{margin:32px 0 0}.ju{padding:3px 8px}.kh> *{margin-right:24px}.ki> :last-child{margin-right:0}.lz{margin:0}.ng{font-size:20px}.nh{margin-top:2.14em}.ni{line-height:32px}.nj{letter-spacing:-0.003em}.ny{margin-top:56px}.oi{margin-top:1.14em}.ow{font-size:24px}.ox{margin-top:1.95em}.oy{line-height:30px}.oz{letter-spacing:-0.016em}.pl{margin-top:0.94em}.qq{flex-direction:row}.qv{margin-bottom:0}.qw{margin-right:20px}.rj{max-width:500px}.ru{line-height:24px}.rv{letter-spacing:0}.sm{margin-bottom:88px}.sx{margin:40px 0 16px}.tj{width:min-width}.to{padding-top:72px}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE" media="all and (min-width: 552px) and (max-width: 727.98px)">.k{display:none}.u{display:flex}.v{justify-content:space-between}.bt{width:24px}.cd{margin:0 24px}.cs{height:40px}.cz{margin-bottom:44px}.dl{margin-bottom:32px}.dz{font-size:13px}.ea{line-height:20px}.ei{padding:0px 8px 1px}.fv{margin-bottom:2px}.hb{font-size:32px}.hc{margin-top:1.01em}.hd{margin-bottom:24px}.he{line-height:38px}.hf{letter-spacing:-0.014em}.hw{align-items:flex-start}.iz{flex-direction:column}.jp{margin:24px 0 0}.jq{padding:0}.kf> *{margin-right:8px}.kg> :last-child{margin-right:8px}.kw{margin-left:0px}.ly{margin:0}.mo{border:1px solid #F2F2F2}.mp{border-radius:99em}.mq{padding:0px 16px 0px 12px}.mr{height:38px}.ms{align-items:center}.mu svg{margin-right:8px}.nc{font-size:18px}.nd{margin-top:1.56em}.ne{line-height:28px}.nf{letter-spacing:-0.003em}.nx{margin-top:40px}.oh{margin-top:1.34em}.os{font-size:20px}.ot{margin-top:1.2em}.ou{line-height:24px}.ov{letter-spacing:0}.pk{margin-top:0.67em}.qx{margin-bottom:20px}.qy{margin-right:0}.rk{max-width:100%}.rr{font-size:24px}.rs{line-height:30px}.rt{letter-spacing:-0.016em}.sl{margin-bottom:64px}.sw{margin:32px 0 16px}.ti{width:100%}.tn{padding-top:48px}.mt:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE" media="print">.qe{display:none}</style><style type="text/css" data-fela-rehydration="541" data-fela-type="RULE" media="(orientation: landscape) and (max-width: 903.98px)">.jk{max-height:none}</style></head><body><div id="root"><div class="a b c"><div class="d e f g h i j k"></div><script>document.domain = document.domain;</script><div class="l c"><div class="l m n o c"><div class="p q r s t u v w x i d y z"><a class="du ag dv bf ak b am an ao ap aq ar as at s u w i d q dw z" href="https://rsci.app.link/?%24canonical_url=https%3A%2F%2Fmedium.com%2Fp%2Fcb1810407b92&%7Efeature=LoOpenInAppButton&%7Echannel=ShowPostUnderCollection&source=---top_nav_layout_nav-----------------------------------------" rel="noopener follow">Open in app<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="none" viewBox="0 0 10 10" class="dt"><path fill="currentColor" d="M.985 8.485a.375.375 0 1 0 .53.53zM8.75 1.25h.375A.375.375 0 0 0 8.75.875zM8.375 6.5a.375.375 0 1 0 .75 0zM3.5.875a.375.375 0 1 0 0 .75zm-1.985 8.14 7.5-7.5-.53-.53-7.5 7.5zm6.86-7.765V6.5h.75V1.25zM3.5 1.625h5.25v-.75H3.5z"></path></svg></a><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><button class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton">Sign up</button></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" rel="noopener follow" href="/m/signin?operation=login&redirect=https%3A%2F%2Fmedium.com%2Fpinterest-engineering%2Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92&source=post_page---top_nav_layout_nav-----------------------global_nav------------------">Sign in</a></span></p></div></div></div><div class="p q r ab ac"><div class="ab q ae"><a class="af ag ah ai aj ak al am an ao ap aq ar as at ab" aria-label="Homepage" data-testid="headerMediumLogo" rel="noopener follow" href="/?source=---top_nav_layout_nav-----------------------------------------"><svg xmlns="http://www.w3.org/2000/svg" width="719" height="160" fill="none" viewBox="0 0 719 160" class="au av aw"><path fill="#242424" d="m174.104 9.734.215-.047V8.02H130.39L89.6 103.89 48.81 8.021H1.472v1.666l.212.047c8.018 1.81 12.09 4.509 12.09 14.242V137.93c0 9.734-4.087 12.433-12.106 14.243l-.212.047v1.671h32.118v-1.665l-.213-.048c-8.018-1.809-12.089-4.509-12.089-14.242V30.586l52.399 123.305h2.972l53.925-126.743V140.75c-.687 7.688-4.721 10.062-11.982 11.701l-.215.05v1.652h55.948v-1.652l-.215-.05c-7.269-1.639-11.4-4.013-12.087-11.701l-.037-116.774h.037c0-9.733 4.071-12.432 12.087-14.242m25.555 75.488c.915-20.474 8.268-35.252 20.606-35.507 3.806.063 6.998 1.312 9.479 3.714 5.272 5.118 7.751 15.812 7.368 31.793zm-.553 5.77h65.573v-.275c-.186-15.656-4.721-27.834-13.466-36.196-7.559-7.227-18.751-11.203-30.507-11.203h-.263c-6.101 0-13.584 1.48-18.909 4.16-6.061 2.807-11.407 7.003-15.855 12.511-7.161 8.874-11.499 20.866-12.554 34.343q-.05.606-.092 1.212a50 50 0 0 0-.065 1.151 85.807 85.807 0 0 0-.094 5.689c.71 30.524 17.198 54.917 46.483 54.917 25.705 0 40.675-18.791 44.407-44.013l-1.886-.664c-6.557 13.556-18.334 21.771-31.738 20.769-18.297-1.369-32.314-19.922-31.042-42.395m139.722 41.359c-2.151 5.101-6.639 7.908-12.653 7.908s-11.513-4.129-15.418-11.63c-4.197-8.053-6.405-19.436-6.405-32.92 0-28.067 8.729-46.22 22.24-46.22 5.657 0 10.111 2.807 12.236 7.704zm43.499 20.008c-8.019-1.897-12.089-4.722-12.089-14.951V1.309l-48.716 14.353v1.757l.299-.024c6.72-.543 11.278.386 13.925 2.83 2.072 1.915 3.082 4.853 3.082 8.987v18.66c-4.803-3.067-10.516-4.56-17.448-4.56-14.059 0-26.909 5.92-36.176 16.672-9.66 11.205-14.767 26.518-14.767 44.278-.003 31.72 15.612 53.039 38.851 53.039 13.595 0 24.533-7.449 29.54-20.013v16.865h43.711v-1.746zM424.1 19.819c0-9.904-7.468-17.374-17.375-17.374-9.859 0-17.573 7.632-17.573 17.374s7.721 17.374 17.573 17.374c9.907 0 17.375-7.47 17.375-17.374m11.499 132.546c-8.019-1.897-12.089-4.722-12.089-14.951h-.035V43.635l-43.714 12.551v1.705l.263.024c9.458.842 12.047 4.1 12.047 15.152v81.086h43.751v-1.746zm112.013 0c-8.018-1.897-12.089-4.722-12.089-14.951V43.635l-41.621 12.137v1.71l.246.026c7.733.813 9.967 4.257 9.967 15.36v59.279c-2.578 5.102-7.415 8.131-13.274 8.336-9.503 0-14.736-6.419-14.736-18.073V43.638l-43.714 12.55v1.703l.262.024c9.459.84 12.05 4.097 12.05 15.152v50.17a56.3 56.3 0 0 0 .91 10.444l.787 3.423c3.701 13.262 13.398 20.197 28.59 20.197 12.868 0 24.147-7.966 29.115-20.43v17.311h43.714v-1.747zm169.818 1.788v-1.749l-.213-.05c-8.7-2.006-12.089-5.789-12.089-13.49v-63.79c0-19.89-11.171-31.761-29.883-31.761-13.64 0-25.141 7.882-29.569 20.16-3.517-13.01-13.639-20.16-28.606-20.16-13.146 0-23.449 6.938-27.869 18.657V43.643L545.487 55.68v1.715l.263.024c9.345.829 12.047 4.181 12.047 14.95v81.784h40.787v-1.746l-.215-.053c-6.941-1.631-9.181-4.606-9.181-12.239V66.998c1.836-4.289 5.537-9.37 12.853-9.37 9.086 0 13.692 6.296 13.692 18.697v77.828h40.797v-1.746l-.215-.053c-6.94-1.631-9.18-4.606-9.18-12.239V75.066a42 42 0 0 0-.578-7.26c1.947-4.661 5.86-10.177 13.475-10.177 9.214 0 13.691 6.114 13.691 18.696v77.828z"></path></svg></a><div class="ax h"><div class="ab ay az ba bb q bc bd"><div class="bm" aria-hidden="false" aria-describedby="searchResults" aria-labelledby="searchResults"></div><div class="bn bo ab"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div><input role="combobox" aria-controls="searchResults" aria-expanded="false" aria-label="search" data-testid="headerSearchInput" tabindex="0" class="ay be bf bg z bh bi bj bk bl" placeholder="Search" value=""/></div></div></div><div class="h k w fg fh"><div class="fi ab"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerWriteButton" rel="noopener follow" href="/m/signin?operation=register&redirect=https%3A%2F%2Fmedium.com%2Fnew-story&source=---top_nav_layout_nav-----------------------new_post_topnav------------------"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Write"><path fill="currentColor" d="M14 4a.5.5 0 0 0 0-1zm7 6a.5.5 0 0 0-1 0zm-7-7H4v1h10zM3 4v16h1V4zm1 17h16v-1H4zm17-1V10h-1v10zm-1 1a1 1 0 0 0 1-1h-1zM3 20a1 1 0 0 0 1 1v-1zM4 3a1 1 0 0 0-1 1h1z"></path><path stroke="currentColor" d="m17.5 4.5-8.458 8.458a.25.25 0 0 0-.06.098l-.824 2.47a.25.25 0 0 0 .316.316l2.47-.823a.25.25 0 0 0 .098-.06L19.5 6.5m-2-2 2.323-2.323a.25.25 0 0 1 .354 0l1.646 1.646a.25.25 0 0 1 0 .354L19.5 6.5m-2-2 2 2"></path></svg><div class="dt l">Write</div></div></a></span></div></div><div class="k j i d"><div class="fi ab"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSearchButton" rel="noopener follow" href="/search?source=---top_nav_layout_nav-----------------------------------------"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Search"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div></a></div></div><div class="fi h k j"><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><button class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton">Sign up</button></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" rel="noopener follow" href="/m/signin?operation=login&redirect=https%3A%2F%2Fmedium.com%2Fpinterest-engineering%2Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92&source=post_page---top_nav_layout_nav-----------------------global_nav------------------">Sign in</a></span></p></div></div></div><div class="l" aria-hidden="false"><button class="ay fn am ab q ao fo fp fq" aria-label="user options menu" data-testid="headerUserIcon"><div class="l fj"><img alt="" class="l fd by bz ca cx" src="https://miro.medium.com/v2/resize:fill:64:64/1*dmbNkD5D-u45r44go_cf0g.png" width="32" height="32" loading="lazy" role="presentation"/><div class="fr by l bz ca fs n ay ft"></div></div></button></div></div></div><div class="l"><div class="fu fv fw fx fy l"><div class="ab cb"><div class="ci bh fz ga gb gc"></div></div><article><div class="l"><div class="l"><span class="l"></span><section><div><div class="fs gi gj gk gl gm"></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><div><h1 id="e96c" class="pw-post-title gs gt gu bf gv gw gx gy gz ha hb hc hd he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu bk" data-testid="storyTitle">Developing fast & reliable iOS builds at Pinterest</h1><div><div class="speechify-ignore ab cp"><div class="speechify-ignore bh l"><div class="hv hw hx hy hz ab"><div><div class="ab ia"><div><div class="bm" aria-hidden="false"><a rel="noopener follow" href="/@Pinterest_Engineering?source=post_page---byline--cb1810407b92---------------------------------------"><div class="l ib ic by id ie"><div class="l fj"><img alt="Pinterest Engineering" class="l fd by dd de cx" src="https://miro.medium.com/v2/resize:fill:88:88/1*iAV-apeVpCJ1h6Znt1AzCg.jpeg" width="44" height="44" loading="lazy" data-testid="authorPhoto"/><div class="if by l dd de fs n ig ft"></div></div></div></a></div></div><div class="ih ab fj"><div><div class="bm" aria-hidden="false"><a href="https://medium.com/pinterest-engineering?source=post_page---byline--cb1810407b92---------------------------------------" rel="noopener follow"><div class="l ii ij by id ik"><div class="l fj"><img alt="Pinterest Engineering Blog" class="l fd by br il cx" src="https://miro.medium.com/v2/resize:fill:48:48/1*XiUFDZgSFl6n-MM2yXFifQ.png" width="24" height="24" loading="lazy" data-testid="publicationPhoto"/><div class="if by l br il fs n ig ft"></div></div></div></a></div></div></div></div></div><div class="bn bh l"><div class="ab"><div style="flex:1"><span class="bf b bg z bk"><div class="im ab q"><div class="ab q in"><div class="ab q"><div><div class="bm" aria-hidden="false"><p class="bf b io ip bk"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" data-testid="authorName" rel="noopener follow" href="/@Pinterest_Engineering?source=post_page---byline--cb1810407b92---------------------------------------">Pinterest Engineering</a></p></div></div></div><span class="ir is" aria-hidden="true"><span class="bf b bg z du">·</span></span><p class="bf b io ip du"><span><a class="it iu ah ai aj ak al am an ao ap aq ar ex iv iw" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2Fef81ef829bcb&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fpinterest-engineering%2Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92&user=Pinterest+Engineering&userId=ef81ef829bcb&source=post_page-ef81ef829bcb--byline--cb1810407b92---------------------post_header------------------">Follow</a></span></p></div></div></span></div></div><div class="l ix"><span class="bf b bg z du"><div class="ab cn iy iz ja"><div class="fu fv ab"><div class="bf b bg z du ab jb"><span class="jc l ix">Published in</span><div><div class="l" aria-hidden="false"><a class="af ag ah ai aj ak al am an ao ap aq ar iq ab q" data-testid="publicationName" href="https://medium.com/pinterest-engineering?source=post_page---byline--cb1810407b92---------------------------------------" rel="noopener follow"><p class="bf b bg z jd je jf jg jh ji jj jk bk">Pinterest Engineering Blog</p></a></div></div></div><div class="h k"><span class="ir is" aria-hidden="true"><span class="bf b bg z du">·</span></span></div></div><span class="bf b bg z du"><div class="ab ae"><span data-testid="storyReadTime">7 min read</span><div class="jl jm l" aria-hidden="true"><span class="l" aria-hidden="true"><span class="bf b bg z du">·</span></span></div><span data-testid="storyPublishDate">Feb 13, 2019</span></div></span></div></span></div></div></div><div class="ab cp jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc"><div class="h k w fg fh q"><div class="ks l"><div class="ab q kt ku"><div class="pw-multi-vote-icon fj jc kv kw kx"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fpinterest-engineering%2Fcb1810407b92&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fpinterest-engineering%2Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92&user=Pinterest+Engineering&userId=ef81ef829bcb&source=---header_actions--cb1810407b92---------------------clap_footer------------------"><div><div class="bm" aria-hidden="false"><div class="ky ao kz la lb lc am ld le lf kx"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l lg lh li lj lk ll lm"><p class="bf b dv z du"><span class="ln">--</span></p></div></div></div><div><div class="bm" aria-hidden="false"><button class="ao ky lq lr ab q fk ls lt" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="lp"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg><p class="bf b dv z du"><span class="pw-responses-count lo lp">6</span></p></button></div></div></div><div class="ab q kd ke kf kg kh ki kj kk kl km kn ko kp kq kr"><div class="lu k j i d"></div><div class="h k"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerBookmarkButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2Fcb1810407b92&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fpinterest-engineering%2Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92&source=---header_actions--cb1810407b92---------------------bookmark_footer------------------"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du lv" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="fd lw cn"><div class="l ae"><div class="ab cb"><div class="lx ly lz ma mb mc ci bh"><div class="ab"><div class="bm" aria-hidden="false"><div><div class="bm" aria-hidden="false"><button aria-label="Listen" data-testid="audioPlayButton" class="af fk ah ai aj ak al md an ao ap ex me mf lt mg mh mi mj mk s ml mm mn mo mp mq mr u ms mt mu"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M3 12a9 9 0 1 1 18 0 9 9 0 0 1-18 0m9-10C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2m3.376 10.416-4.599 3.066a.5.5 0 0 1-.777-.416V8.934a.5.5 0 0 1 .777-.416l4.599 3.066a.5.5 0 0 1 0 .832" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Listen</p></div></button></div></div></div></div></div></div></div></div><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="headerSocialShareButton" class="af fk ah ai aj ak al md an ao ap ex me mf lt mg mh mi mj mk s ml mm mn mo mp mq mr u ms mt mu"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Share</p></div></button></div></div></div></div></div></div></div></div></div><p id="8e56" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk">By Rahul Malik | iOS Platform Tech Lead</p><p id="ada4" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk">At Pinterest we’re focused on helping people discover inspiring ideas, from dinner recipes to try, home and style products to buy, to places to travel. Building the best products for mobile is a critical part of that, with 80% of all Pinners access Pinterest via mobile apps. On the iOS team specifically, we’re constantly working to improve that experience as efficiently and quickly as we can, and giving our team the best development and testing environment is a key step in that.</p><p id="55aa" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk">We recently looked into ways to streamline that process, and set out to improve the speed and reliability of our iOS builds on local and continuous integration environments. In addition, we began modularizing our application into standalone frameworks and needed a system to support that migration. We reviewed multiple tools, including Xcode, Cocoapods, Buck, and Bazel. We wanted to introduce a more stable foundation for the future, which is central to our ability to rapidly iterate and release new features to Pinners.</p><figure class="nw nx ny nz oa ob nt nu paragraph-image"><div class="nt nu nv"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 1100w, https://miro.medium.com/v2/resize:fit:1024/format:webp/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 1024w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 512px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 640w, https://miro.medium.com/v2/resize:fit:720/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 720w, https://miro.medium.com/v2/resize:fit:750/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 750w, https://miro.medium.com/v2/resize:fit:786/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 786w, https://miro.medium.com/v2/resize:fit:828/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 828w, https://miro.medium.com/v2/resize:fit:1100/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 1100w, https://miro.medium.com/v2/resize:fit:1024/1*zDbDRMKBXoSjywY_vmbrzA.jpeg 1024w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 512px"/><img alt="" class="bh mc oc c" width="512" height="768" loading="eager" role="presentation"/></picture></div></figure><p id="b7b1" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk">After comparing Xcode, Cocoapods, Buck and Bazel, we identified Bazel was the best fit for our goals to build a foundation for an order of magnitude improvement in performance, eliminate variability in build environments and adopt incrementally. As a result, we’re now shipping all our iOS releases using Bazel which has already resulted in wins, including:</p><p id="2910" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk"><strong class="mx gv">Local Development</strong></p><ul class=""><li id="81c6" class="mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns od oe of bk">Faster builds: Reduced clean build time from 4m 38s to 3m 38s, a 21% improvement.</li><li id="cbe1" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Local disk caches allow for instant rebuilds for anything you’ve built before (other branches, commits, etc).</li><li id="be6d" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Environments are identical between CI and local environments, so build issues are easy to reproduce.</li><li id="b882" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Increased automation: Tasks like code generation are included as part of the build graph.</li></ul><p id="27fc" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk"><strong class="mx gv">Continuous Integration</strong></p><ul class=""><li id="cb81" class="mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns od oe of bk">Every build is an incremental build: Since Bazel is reproducible, we haven’t performed a single clean build on CI in over a year.</li><li id="ae8d" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Build once, reuse everywhere: After introducing remote build caching, build times dropped under a minute and as low as 30 seconds since we don’t need to rebuild anything that has been built on any machine</li><li id="dd11" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Reduced time to land code: Reduced build time from 10m 24s to 7m 34s, a 27% improvement.</li><li id="256c" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Reduced time to get changes to beta testers: Beta build time went from 14m 32s to 7m 52s, a 45% improvement.</li><li id="a8da" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Faster test execution: Test runs are instant if the modified code does not affect the test.</li><li id="e5ca" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Higher build success rate: Success rate of builds improved from around 80% to 97%-100% when running build tasks with Bazel.</li></ul><h1 id="b1a7" class="ol om gu bf on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph pi bk">Moving to a future of fast and reliable builds</h1><p id="7c07" class="pw-post-body-paragraph mv mw gu mx b my pj na nb nc pk ne nf ng pl ni nj nk pm nm nn no pn nq nr ns gn bk">Build speed is a constant bottleneck for developers since we’re using compiled languages (Objective-C/C++). But build speed is hard to quantify. It includes of builds in different environments, like continuous integration or local development. We also work with a variety of workflow scenarios, like clean builds, incremental builds, branch switching, rebasing, reverting changes, and others. You can’t improve what you don’t measure, so improving build speed requires tracking a variety of scenarios to allow us to pinpoint regressions and focus our performance efforts.</p><p id="baf4" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk">We can make builds faster by a combination of doing less work or performing work more efficiently. This might involve using different tools, improving parallelization, or updating the architecture of the project to require fewer source files. Having strong practices around maintaining a modular architecture and cleaning up dead code that is unreferenced or related to completed experiments will help maintain / improve build speeds. We use a variety of in-house tools and scripts to identify dead code. For experiments, we utilize automation that adds clang annotations to deprecate methods and constants that are related to the experiment which allows the compiler to warn developers that the experiment is ended and code should be removed. Identifying unreferenced code is performed adhoc by developers by periodically running tools that inspect the header include graph of our build and look for files that are have zero references recursively.</p><p id="171c" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk">Our build process needs to be both fast and reliable. Builds are reliable if they are reproducible. Reproducible builds are important not just for reproducing bugs, but also for ensuring we ship the exact version of the app that we’ve developed and tested against. We can only achieve that if the build environment — the inputs and outputs — are consistent.</p><p id="ce76" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk">Changes to the environment can greatly affect the end product and introduce variability. A consistent environment guarantees the application behaves the same regardless of if it was built on a developer’s machine or via continuous integration, and it eliminates time spent figuring out why a build succeeds in one environment but fails elsewhere.</p><p id="6dcc" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk">While the ideas and explorations are focused around iOS, the goals of fast and reproducible builds are one that we all share and will allow us to scale client engineering.</p><h1 id="5974" class="ol om gu bf on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph pi bk">Challenges</h1><p id="9118" class="pw-post-body-paragraph mv mw gu mx b my pj na nb nc pk ne nf ng pl ni nj nk pm nm nn no pn nq nr ns gn bk">The decision to focus on improving our build process was rooted in the impact it was having on developer productivity. As we grow our team and product, it’s paramount that we invest in our developers’ ability to work with a consistent and fast build system.</p><ul class=""><li id="888d" class="mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns od oe of bk">Scale: As we scale client engineering, the amount of time spent supporting developers, maintaining or reducing build times and improving reliability scale as well. The number of engineers that support developers does not necessarily scale proportionally with the number of developers, and Xcode doesn’t contain tools to profile builds when performance degrades.</li><li id="7fe2" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Modular architecture: We’ve begun refactoring the core frameworks that compose our platform from our app in order to improve our overall architecture, documentation and quality. This adds complexity because it requires a build system that can manage a dependency graph of build targets which need to be configured and compiled in a specific order. While not impossible in Xcode, the configuration and maintenance of such a graph would be prohibitively difficult to maintain over time due to a lack of a expressive configuration API.</li><li id="b032" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Build instability: Outside of our codebase, there are a number of tools written in different languages (Ruby, Python, Bash, etc.) that require specific versions and toolchains that must be identical to create consistent builds. These variations can result in errors that are hard to reliably reproduce. It was not uncommon for developers to have a build pass locally but fail on continuous integration, and vice versa. Only certain machines had the requirements necessary to create a release candidate. Local state can become corrupted, which required performing clean builds. That wastes time.</li><li id="edf5" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Task automation & code generation: We rely on code generation to create our immutable models (via Plank) and logging infrastructure (via Thrift). While it has support for run script phases, Xcode can’t introduce dynamic workflows like code generation or general task automation to be a part of the build process, and instead requires manually integrating generated sources, putting more work on developers and onboarding education. This also requires adding generated artifacts to version control, which increases our repository size and git clone performance.</li><li id="7474" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Shared resources: The integration path for external repositories has not been clear and has historically resulted in periodically copying resources from other repositories. We have explored options like git subtree or git submodule, but this required an increased investment in employee education and a change to developer workflows. That introduced confusion and, again, wastes time. Xcode does not have any support for declaring external build dependencies, so we would have to rely on external tooling to provide this integration.</li></ul><h1 id="47fa" class="ol om gu bf on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph pi bk">Solutions</h1><p id="60e7" class="pw-post-body-paragraph mv mw gu mx b my pj na nb nc pk ne nf ng pl ni nj nk pm nm nn no pn nq nr ns gn bk">We wanted solutions that would allow us to overcome these challenges with tooling and automation instead of increased load on developer education and process — and waste less time. We primarily optimize for:</p><ul class=""><li id="f744" class="mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns od oe of bk">Rapid iteration: Our solution should provide functionality to greatly improve and maintain build speed and developer velocity over time, likely achieved through better parallelism and advanced tooling features.</li><li id="6c62" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Sandboxed development: A consistent environment that allows us to have reliable builds and minimizes variability and impact on developer productivity.</li><li id="f10c" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Monorepo-like development: All sources should still remain in one repository. This minimizes the amount of work and context switching required to make changes across the application.</li><li id="0b5f" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Profiling, Monitoring, Analysis: We need tools that give us insight into our build system to identify issues. Our solution needs to allow us to visualize the actions performed throughout the build and their respective durations. Assuming we have this, we will be able to track detailed changes on a frequent basis.</li><li id="b5b2" class="mv mw gu mx b my og na nb nc oh ne nf ng oi ni nj nk oj nm nn no ok nq nr ns od oe of bk">Incremental Compilation: Once we build the client once, we should be able to safely incrementally build through all workflows. That should include switching branches, reverting changes, or other parts of the workflow. Clean builds are by far the most expensive builds and are usually performed when local state is corrupted or the developer is trying to diagnose an unknown build issues.</li></ul><h1 id="1ced" class="ol om gu bf on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph pi bk">Extensible for the future</h1><p id="caca" class="pw-post-body-paragraph mv mw gu mx b my pj na nb nc pk ne nf ng pl ni nj nk pm nm nn no pn nq nr ns gn bk">As our application grows in complexity and our needs evolve we must ensure that we have enough extensibility in our build system to allow for change to be develop. But it must not be so specific in that it hinders further dynamic automation in our build process. This may range from being able to automate tasks to integrate third-party static analysis,<a class="af po" rel="noopener" href="/@Pinterest_Engineering/ios-linting-at-pinterest-3108d8764390"> custom toolchains</a> and<a class="af po" href="https://pinterest.github.io/plank/" rel="noopener ugc nofollow" target="_blank"> the in-house tools</a> we develop at Pinterest.</p><p id="e783" class="pw-post-body-paragraph mv mw gu mx b my mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns gn bk">Changing a build system is a significant change, and we cannot support an approach that isn’t possible to introduce incrementally. An all-or-nothing solution would require potentially pausing development or maintaining a long-lived fork and performing a risky migration atomically across developer environments and CI systems.</p></div></div></div></div></section></div></div></article></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="pp pq ab ja"><div class="pr ab"><a class="ps ay am ao" rel="noopener follow" href="/tag/continuous-integration?source=post_page-----cb1810407b92---------------------------------------"><div class="pt fj cx pu ge pv pw bf b bg z bk px">Continuous Integration</div></a></div><div class="pr ab"><a class="ps ay am ao" rel="noopener follow" href="/tag/ios?source=post_page-----cb1810407b92---------------------------------------"><div class="pt fj cx pu ge pv pw bf b bg z bk px">IOS</div></a></div><div class="pr ab"><a class="ps ay am ao" rel="noopener follow" href="/tag/ios-app-development?source=post_page-----cb1810407b92---------------------------------------"><div class="pt fj cx pu ge pv pw bf b bg z bk px">IOS App Development</div></a></div><div class="pr ab"><a class="ps ay am ao" rel="noopener follow" href="/tag/xcode?source=post_page-----cb1810407b92---------------------------------------"><div class="pt fj cx pu ge pv pw bf b bg z bk px">Xcode</div></a></div><div class="pr ab"><a class="ps ay am ao" rel="noopener follow" href="/tag/mobile?source=post_page-----cb1810407b92---------------------------------------"><div class="pt fj cx pu ge pv pw bf b bg z bk px">Mobile</div></a></div></div></div></div><div class="l"></div><footer class="py pz qa qb qc ab q qd ik c"><div class="l ae"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="ab cp qe"><div class="ab q kt"><div class="qf l"><span class="l qg qh qi e d"><div class="ab q kt ku"><div class="pw-multi-vote-icon fj jc kv kw kx"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fpinterest-engineering%2Fcb1810407b92&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fpinterest-engineering%2Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92&user=Pinterest+Engineering&userId=ef81ef829bcb&source=---footer_actions--cb1810407b92---------------------clap_footer------------------"><div><div class="bm" aria-hidden="false"><div class="ky ao kz la lb lc am ld le lf kx"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l lg lh li lj lk ll lm"><p class="bf b dv z du"><span class="ln">--</span></p></div></div></span><span class="l h g f qj qk"><div class="ab q kt ku"><div class="pw-multi-vote-icon fj jc kv kw kx"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fpinterest-engineering%2Fcb1810407b92&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fpinterest-engineering%2Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92&user=Pinterest+Engineering&userId=ef81ef829bcb&source=---footer_actions--cb1810407b92---------------------clap_footer------------------"><div><div class="bm" aria-hidden="false"><div class="ky ao kz la lb lc am ld le lf kx"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l lg lh li lj lk ll lm"><p class="bf b dv z du"><span class="ln">--</span></p></div></div></span></div><div class="bq ab"><div><div class="bm" aria-hidden="false"><button class="ao ky lq lr ab q fk ls lt" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="lp"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg><p class="bf b bg z du"><span class="pw-responses-count lo lp">6</span></p></button></div></div></div></div><div class="ab q"><div class="ql l ix"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerBookmarkButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2Fcb1810407b92&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fpinterest-engineering%2Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92&source=---footer_actions--cb1810407b92---------------------bookmark_footer------------------"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du lv" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="ql l ix"><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="footerSocialShareButton" class="af fk ah ai aj ak al md an ao ap ex me mf lt mg"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg></button></div></div></div></div></div></div></div></div></div></footer><div class="qm l"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="qn l"><div class="ab qo qp qq iz iy"><div class="qr qs qt qu qv qw qx qy qz ra ab cp"><div class="h k"><a href="https://medium.com/pinterest-engineering?source=post_page---post_publication_info--cb1810407b92---------------------------------------" rel="noopener follow"><div class="fj ab"><img alt="Pinterest Engineering Blog" class="rb ib ic cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*XiUFDZgSFl6n-MM2yXFifQ.png" width="48" height="48" loading="lazy"/><div class="rb l ic ib fs n fr rc"></div></div></a></div><div class="j i d"><a href="https://medium.com/pinterest-engineering?source=post_page---post_publication_info--cb1810407b92---------------------------------------" rel="noopener follow"><div class="fj ab"><img alt="Pinterest Engineering Blog" class="rb re rd cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*XiUFDZgSFl6n-MM2yXFifQ.png" width="64" height="64" loading="lazy"/><div class="rb l rd re fs n fr rc"></div></div></a></div><div class="j i d rf ix"><div class="ab"></div></div></div><div class="ab co rg"><div class="rh ri rj rk rl l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" href="https://medium.com/pinterest-engineering?source=post_page---post_publication_info--cb1810407b92---------------------------------------" rel="noopener follow"><h2 class="pw-author-name bf rn ro rp rq rr rs rt ng ru rv nk rw rx no ry rz bk"><span class="gn rm">Published in <!-- -->Pinterest Engineering Blog</span></h2></a><div class="pr ab ia"><div class="l ix"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/pinterest-engineering/followers?source=post_page---post_publication_info--cb1810407b92---------------------------------------">15.5K Followers</a></span></div><div class="bf b bg z du ab jb"><span class="ir l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/pinterest-engineering/infrastructure-advancements-at-aws-reinvent-2024-3670363c467d?source=post_page---post_publication_info--cb1810407b92---------------------------------------">Last published <!-- -->6 days ago</a></div></div><div class="sa l"><p class="bf b bg z bk"><span class="gn">Inventive engineers building the first visual discovery engine, 300 billion ideas and counting.</span></p></div></div></div><div class="h k"><div class="ab"></div></div></div></div><div class="ab qo qp qq iz iy"><div class="qr qs qt qu qv qw qx qy qz ra ab cp"><div class="h k"><a tabindex="0" rel="noopener follow" href="/@Pinterest_Engineering?source=post_page---post_author_info--cb1810407b92---------------------------------------"><div class="l fj"><img alt="Pinterest Engineering" class="l fd by ic ib cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*iAV-apeVpCJ1h6Znt1AzCg.jpeg" width="48" height="48" loading="lazy"/><div class="fr by l ic ib fs n ay rc"></div></div></a></div><div class="j i d"><a tabindex="0" rel="noopener follow" href="/@Pinterest_Engineering?source=post_page---post_author_info--cb1810407b92---------------------------------------"><div class="l fj"><img alt="Pinterest Engineering" class="l fd by rd re cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*iAV-apeVpCJ1h6Znt1AzCg.jpeg" width="64" height="64" loading="lazy"/><div class="fr by l rd re fs n ay rc"></div></div></a></div><div class="j i d rf ix"><div class="ab"><span><button class="bf b bg z sb pt sc sd se sf sg ev ew sh si sj fa fb fc fd bm fe ff">Follow</button></span></div></div></div><div class="ab co rg"><div class="rh ri rj rk rl l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" rel="noopener follow" href="/@Pinterest_Engineering?source=post_page---post_author_info--cb1810407b92---------------------------------------"><h2 class="pw-author-name bf rn ro rp rq rr rs rt ng ru rv nk rw rx no ry rz bk"><span class="gn rm">Written by <!-- -->Pinterest Engineering</span></h2></a><div class="pr ab ia"><div class="l ix"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/@Pinterest_Engineering/followers?source=post_page---post_author_info--cb1810407b92---------------------------------------">58K Followers</a></span></div><div class="bf b bg z du ab jb"><span class="ir l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/@Pinterest_Engineering/following?source=post_page---post_author_info--cb1810407b92---------------------------------------">329 Following</a></div></div><div class="sa l"><p class="bf b bg z bk"><a class="af ag ah ai aj ak al am an ao ap aq ar po go" href="https://medium.com/pinterest-engineering" rel="noopener follow">https://medium.com/pinterest-engineering</a> | Inventive engineers building the first visual discovery engine <a class="af ag ah ai aj ak al am an ao ap aq ar po go" href="https://careers.pinterest.com/" rel="noopener ugc nofollow">https://careers.pinterest.com/</a></p></div></div></div><div class="h k"><div class="ab"><span><button class="bf b bg z sb pt sc sd se sf sg ev ew sh si sj fa fb fc fd bm fe ff">Follow</button></span></div></div></div></div></div></div><div class="sk sl sm sn so l"><div class="sp bh r qm"></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="ab q cp"><h2 class="bf rn oo oq or os ou ov ow oy oz pa pc pd pe pg ph bk">Responses (<!-- -->6<!-- -->)</h2><div class="ab sq"><div><div class="bm" aria-hidden="false"><a class="sr ss" href="https://policy.medium.com/medium-rules-30e5502c4eb4?source=post_page---post_responses--cb1810407b92---------------------------------------" rel="noopener follow" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 25 25"><path fill-rule="evenodd" d="M11.987 5.036a.754.754 0 0 1 .914-.01c.972.721 1.767 1.218 2.6 1.543.828.322 1.719.485 2.887.505a.755.755 0 0 1 .741.757c-.018 3.623-.43 6.256-1.449 8.21-1.034 1.984-2.662 3.209-4.966 4.083a.75.75 0 0 1-.537-.003c-2.243-.874-3.858-2.095-4.897-4.074-1.024-1.951-1.457-4.583-1.476-8.216a.755.755 0 0 1 .741-.757c1.195-.02 2.1-.182 2.923-.503.827-.322 1.6-.815 2.519-1.535m.468.903c-.897.69-1.717 1.21-2.623 1.564-.898.35-1.856.527-3.026.565.037 3.45.469 5.817 1.36 7.515.884 1.684 2.25 2.762 4.284 3.571 2.092-.81 3.465-1.89 4.344-3.575.886-1.698 1.299-4.065 1.334-7.512-1.149-.039-2.091-.217-2.99-.567-.906-.353-1.745-.873-2.683-1.561m-.009 9.155a2.672 2.672 0 1 0 0-5.344 2.672 2.672 0 0 0 0 5.344m0 1a3.672 3.672 0 1 0 0-7.344 3.672 3.672 0 0 0 0 7.344m-1.813-3.777.525-.526.916.917 1.623-1.625.526.526-2.149 2.152z" clip-rule="evenodd"></path></svg></a></div></div></div></div><div class="st su sv sw sx sy sz l"></div><div class="ta l"><button class="bf b bg z bk pt tb tc td lv ls sg ev ew ex te tf tg fa th ti tj tk tl fb fc fd bm fe ff">See all responses</button></div></div></div></div><div class="tm tn to tp tq l bx"><div class="h k j"><div class="sp bh tr ts"></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="tt ab kt ja"><div class="tu tv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://help.medium.com/hc/en-us?source=post_page-----cb1810407b92---------------------------------------" rel="noopener follow"><p class="bf b dv z du">Help</p></a></div><div class="tu tv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.statuspage.io/?source=post_page-----cb1810407b92---------------------------------------" rel="noopener follow"><p class="bf b dv z du">Status</p></a></div><div class="tu tv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/about?autoplay=1&source=post_page-----cb1810407b92---------------------------------------"><p class="bf b dv z du">About</p></a></div><div class="tu tv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/jobs-at-medium/work-at-medium-959d1a85284e?source=post_page-----cb1810407b92---------------------------------------"><p class="bf b dv z du">Careers</p></a></div><div class="tu tv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="mailto:pressinquiries@medium.com" rel="noopener follow"><p class="bf b dv z du">Press</p></a></div><div class="tu tv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://blog.medium.com/?source=post_page-----cb1810407b92---------------------------------------" rel="noopener follow"><p class="bf b dv z du">Blog</p></a></div><div class="tu tv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-privacy-policy-f03bf92035c9?source=post_page-----cb1810407b92---------------------------------------" rel="noopener follow"><p class="bf b dv z du">Privacy</p></a></div><div class="tu tv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-terms-of-service-9db0094a1e0f?source=post_page-----cb1810407b92---------------------------------------" rel="noopener follow"><p class="bf b dv z du">Terms</p></a></div><div class="tu tv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://speechify.com/medium?source=post_page-----cb1810407b92---------------------------------------" rel="noopener follow"><p class="bf b dv z du">Text to speech</p></a></div><div class="tu l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/business?source=post_page-----cb1810407b92---------------------------------------"><p class="bf b dv z du">Teams</p></a></div></div></div></div></div></div></div></div></div></div><script>window.__BUILD_ID__="main-20250225-184414-4ed2460310"</script><script>window.__GRAPHQL_URI__ = "https://medium.com/_/graphql"</script><script>window.__PRELOADED_STATE__ = {"algolia":{"queries":{}},"cache":{"experimentGroupSet":true,"reason":"","group":"enabled","tags":["group-edgeCachePosts","post-cb1810407b92","user-ef81ef829bcb","collection-4c5a5f6279b6"],"serverVariantState":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","middlewareEnabled":true,"cacheStatus":"DYNAMIC","shouldUseCache":true,"vary":[],"pubFeaturingPostPageLabelEnabled":false,"pubHierarchyFlagGroup":"control"},"client":{"hydrated":false,"isUs":false,"isNativeMedium":false,"isSafariMobile":false,"isSafari":false,"isFirefox":false,"routingEntity":{"type":"DEFAULT","explicit":false},"viewerIsBot":false},"debug":{"requestId":"99fccaa6-a457-4f6b-a678-c5ac752c7ff0","requestTag":"","hybridDevServices":[],"originalSpanCarrier":{"traceparent":"00-6929652d7106cbab16ce245eac64767d-a2c53f0e74e40ed8-01"}},"multiVote":{"clapsPerPost":{}},"navigation":{"branch":{"show":null,"hasRendered":null,"blockedByCTA":false},"hideGoogleOneTap":false,"hasRenderedAlternateUserBanner":null,"currentLocation":"https:\u002F\u002Fmedium.com\u002Fpinterest-engineering\u002Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92","host":"medium.com","hostname":"medium.com","referrer":"","hasSetReferrer":false,"susiModal":{"step":null,"operation":"register"},"postRead":false,"partnerProgram":{"selectedCountryCode":null},"queryString":"","currentHash":""},"config":{"nodeEnv":"production","version":"main-20250225-184414-4ed2460310","target":"production","productName":"Medium","publicUrl":"https:\u002F\u002Fcdn-client.medium.com\u002Flite","authDomain":"medium.com","authGoogleClientId":"216296035834-k1k6qe060s2tp2a2jam4ljdcms00sttg.apps.googleusercontent.com","favicon":"production","glyphUrl":"https:\u002F\u002Fglyph.medium.com","branchKey":"key_live_ofxXr2qTrrU9NqURK8ZwEhknBxiI6KBm","algolia":{"appId":"MQ57UUUQZ2","apiKeySearch":"394474ced050e3911ae2249ecc774921","indexPrefix":"medium_","host":"-dsn.algolia.net"},"recaptchaKey":"6Lfc37IUAAAAAKGGtC6rLS13R1Hrw_BqADfS1LRk","recaptcha3Key":"6Lf8R9wUAAAAABMI_85Wb8melS7Zj6ziuf99Yot5","recaptchaEnterpriseKeyId":"6Le-uGgpAAAAAPprRaokM8AKthQ9KNGdoxaGUvVp","datadog":{"applicationId":"6702d87d-a7e0-42fe-bbcb-95b469547ea0","clientToken":"pub853ea8d17ad6821d9f8f11861d23dfed","rumToken":"pubf9cc52896502b9413b68ba36fc0c7162","context":{"deployment":{"target":"production","tag":"main-20250225-184414-4ed2460310","commit":"4ed24603101d3704bd30a09999b05695c364bfa8"}},"datacenter":"us"},"googleAnalyticsCode":"G-7JY7T788PK","googlePay":{"apiVersion":"2","apiVersionMinor":"0","merchantId":"BCR2DN6TV7EMTGBM","merchantName":"Medium","instanceMerchantId":"13685562959212738550"},"applePay":{"version":3},"signInWallCustomDomainCollectionIds":["3a8144eabfe3","336d898217ee","61061eb0c96b","138adf9c44c","819cc2aaeee0"],"mediumMastodonDomainName":"me.dm","mediumOwnedAndOperatedCollectionIds":["8a9336e5bb4","b7e45b22fec3","193b68bd4fba","8d6b8a439e32","54c98c43354d","3f6ecf56618","d944778ce714","92d2092dc598","ae2a65f35510","1285ba81cada","544c7006046e","fc8964313712","40187e704f1c","88d9857e584e","7b6769f2748b","bcc38c8f6edf","cef6983b292","cb8577c9149e","444d13b52878","713d7dbc99b0","ef8e90590e66","191186aaafa0","55760f21cdc5","9dc80918cc93","bdc4052bbdba","8ccfed20cbb2"],"tierOneDomains":["medium.com","thebolditalic.com","arcdigital.media","towardsdatascience.com","uxdesign.cc","codeburst.io","psiloveyou.xyz","writingcooperative.com","entrepreneurshandbook.co","prototypr.io","betterhumans.coach.me","theascent.pub"],"topicsToFollow":["d61cf867d93f","8a146bc21b28","1eca0103fff3","4d562ee63426","aef1078a3ef5","e15e46793f8d","6158eb913466","55f1c20aba7a","3d18b94f6858","4861fee224fd","63c6f1f93ee","1d98b3a9a871","decb52b64abf","ae5d4995e225","830cded25262"],"topicToTagMappings":{"accessibility":"accessibility","addiction":"addiction","android-development":"android-development","art":"art","artificial-intelligence":"artificial-intelligence","astrology":"astrology","basic-income":"basic-income","beauty":"beauty","biotech":"biotech","blockchain":"blockchain","books":"books","business":"business","cannabis":"cannabis","cities":"cities","climate-change":"climate-change","comics":"comics","coronavirus":"coronavirus","creativity":"creativity","cryptocurrency":"cryptocurrency","culture":"culture","cybersecurity":"cybersecurity","data-science":"data-science","design":"design","digital-life":"digital-life","disability":"disability","economy":"economy","education":"education","equality":"equality","family":"family","feminism":"feminism","fiction":"fiction","film":"film","fitness":"fitness","food":"food","freelancing":"freelancing","future":"future","gadgets":"gadgets","gaming":"gaming","gun-control":"gun-control","health":"health","history":"history","humor":"humor","immigration":"immigration","ios-development":"ios-development","javascript":"javascript","justice":"justice","language":"language","leadership":"leadership","lgbtqia":"lgbtqia","lifestyle":"lifestyle","machine-learning":"machine-learning","makers":"makers","marketing":"marketing","math":"math","media":"media","mental-health":"mental-health","mindfulness":"mindfulness","money":"money","music":"music","neuroscience":"neuroscience","nonfiction":"nonfiction","outdoors":"outdoors","parenting":"parenting","pets":"pets","philosophy":"philosophy","photography":"photography","podcasts":"podcast","poetry":"poetry","politics":"politics","privacy":"privacy","product-management":"product-management","productivity":"productivity","programming":"programming","psychedelics":"psychedelics","psychology":"psychology","race":"race","relationships":"relationships","religion":"religion","remote-work":"remote-work","san-francisco":"san-francisco","science":"science","self":"self","self-driving-cars":"self-driving-cars","sexuality":"sexuality","social-media":"social-media","society":"society","software-engineering":"software-engineering","space":"space","spirituality":"spirituality","sports":"sports","startups":"startup","style":"style","technology":"technology","transportation":"transportation","travel":"travel","true-crime":"true-crime","tv":"tv","ux":"ux","venture-capital":"venture-capital","visual-design":"visual-design","work":"work","world":"world","writing":"writing"},"defaultImages":{"avatar":{"imageId":"1*dmbNkD5D-u45r44go_cf0g.png","height":150,"width":150},"orgLogo":{"imageId":"7*V1_7XP4snlmqrc_0Njontw.png","height":110,"width":500},"postLogo":{"imageId":"bd978bb536350a710e8efb012513429cabdc4c28700604261aeda246d0f980b7","height":810,"width":1440},"postPreviewImage":{"imageId":"1*hn4v1tCaJy7cWMyb0bpNpQ.png","height":386,"width":579}},"collectionStructuredData":{"8d6b8a439e32":{"name":"Elemental","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F980\u002F1*9ygdqoKprhwuTVKUM0DLPA@2x.png","width":980,"height":159}}},"3f6ecf56618":{"name":"Forge","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F596\u002F1*uULpIlImcO5TDuBZ6lm7Lg@2x.png","width":596,"height":183}}},"ae2a65f35510":{"name":"GEN","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F264\u002F1*RdVZMdvfV3YiZTw6mX7yWA.png","width":264,"height":140}}},"88d9857e584e":{"name":"LEVEL","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*JqYMhNX6KNNb2UlqGqO2WQ.png","width":540,"height":108}}},"7b6769f2748b":{"name":"Marker","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F383\u002F1*haCUs0wF6TgOOvfoY-jEoQ@2x.png","width":383,"height":92}}},"444d13b52878":{"name":"OneZero","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*cw32fIqCbRWzwJaoQw6BUg.png","width":540,"height":123}}},"8ccfed20cbb2":{"name":"Zora","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*tZUQqRcCCZDXjjiZ4bDvgQ.png","width":540,"height":106}}}},"embeddedPostIds":{"coronavirus":"cd3010f9d81f"},"sharedCdcMessaging":{"COVID_APPLICABLE_TAG_SLUGS":[],"COVID_APPLICABLE_TOPIC_NAMES":[],"COVID_APPLICABLE_TOPIC_NAMES_FOR_TOPIC_PAGE":[],"COVID_MESSAGES":{"tierA":{"text":"For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":66,"end":73,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"tierB":{"text":"Anyone can publish on Medium per our Policies, but we don’t fact-check every story. For more info about the coronavirus, see cdc.gov.","markups":[{"start":37,"end":45,"href":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Fcategories\u002F201931128-Policies-Safety"},{"start":125,"end":132,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"paywall":{"text":"This article has been made free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":56,"end":70,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":138,"end":145,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"unbound":{"text":"This article is free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":45,"end":59,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":127,"end":134,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]}},"COVID_BANNER_POST_ID_OVERRIDE_WHITELIST":["3b31a67bff4a"]},"sharedVoteMessaging":{"TAGS":["politics","election-2020","government","us-politics","election","2020-presidential-race","trump","donald-trump","democrats","republicans","congress","republican-party","democratic-party","biden","joe-biden","maga"],"TOPICS":["politics","election"],"MESSAGE":{"text":"Find out more about the U.S. election results here.","markups":[{"start":46,"end":50,"href":"https:\u002F\u002Fcookpolitical.com\u002F2020-national-popular-vote-tracker"}]},"EXCLUDE_POSTS":["397ef29e3ca5"]},"embedPostRules":[],"recircOptions":{"v1":{"limit":3},"v2":{"limit":8}},"braintreeClientKey":"production_zjkj96jm_m56f8fqpf7ngnrd4","braintree":{"enabled":true,"merchantId":"m56f8fqpf7ngnrd4","merchantAccountId":{"usd":"AMediumCorporation_instant","eur":"amediumcorporation_EUR","cad":"amediumcorporation_CAD"},"publicKey":"ds2nn34bg2z7j5gd","braintreeEnvironment":"production","dashboardUrl":"https:\u002F\u002Fwww.braintreegateway.com\u002Fmerchants","gracePeriodDurationInDays":14,"mediumMembershipPlanId":{"monthly":"ce105f8c57a3","monthlyV2":"e8a5e126-792b-4ee6-8fba-d574c1b02fc5","monthlyWithTrial":"d5ee3dbe3db8","monthlyPremium":"fa741a9b47a2","yearly":"a40ad4a43185","yearlyV2":"3815d7d6-b8ca-4224-9b8c-182f9047866e","yearlyStaff":"d74fb811198a","yearlyWithTrial":"b3bc7350e5c7","yearlyPremium":"e21bd2c12166","monthlyOneYearFree":"e6c0637a-2bad-4171-ab4f-3c268633d83c","monthly25PercentOffFirstYear":"235ecc62-0cdb-49ae-9378-726cd21c504b","monthly20PercentOffFirstYear":"ba518864-9c13-4a99-91ca-411bf0cac756","monthly15PercentOffFirstYear":"594c029b-9f89-43d5-88f8-8173af4e070e","monthly10PercentOffFirstYear":"c6c7bc9a-40f2-4b51-8126-e28511d5bdb0","monthlyForStudents":"629ebe51-da7d-41fd-8293-34cd2f2030a8","yearlyOneYearFree":"78ba7be9-0d9f-4ece-aa3e-b54b826f2bf1","yearly25PercentOffFirstYear":"2dbb010d-bb8f-4eeb-ad5c-a08509f42d34","yearly20PercentOffFirstYear":"47565488-435b-47f8-bf93-40d5fbe0ebc8","yearly15PercentOffFirstYear":"8259809b-0881-47d9-acf7-6c001c7f720f","yearly10PercentOffFirstYear":"9dd694fb-96e1-472c-8d9e-3c868d5c1506","yearlyForStudents":"e29345ef-ab1c-4234-95c5-70e50fe6bc23","monthlyCad":"p52orjkaceei","yearlyCad":"h4q9g2up9ktt"},"braintreeDiscountId":{"oneMonthFree":"MONTHS_FREE_01","threeMonthsFree":"MONTHS_FREE_03","sixMonthsFree":"MONTHS_FREE_06","fiftyPercentOffOneYear":"FIFTY_PERCENT_OFF_ONE_YEAR"},"3DSecureVersion":"2","defaultCurrency":"usd","providerPlanIdCurrency":{"4ycw":"usd","rz3b":"usd","3kqm":"usd","jzw6":"usd","c2q2":"usd","nnsw":"usd","q8qw":"usd","d9y6":"usd","fx7w":"cad","nwf2":"cad"}},"paypalClientId":"AXj1G4fotC2GE8KzWX9mSxCH1wmPE3nJglf4Z2ig_amnhvlMVX87otaq58niAg9iuLktVNF_1WCMnN7v","paypal":{"host":"https:\u002F\u002Fapi.paypal.com:443","clientMode":"production","serverMode":"live","webhookId":"4G466076A0294510S","monthlyPlan":{"planId":"P-9WR0658853113943TMU5FDQA","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlan":{"planId":"P-7N8963881P8875835MU5JOPQ","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oneYearGift":{"name":"Medium Membership (1 Year, Digital Gift Code)","description":"Unlimited access to the best and brightest stories on Medium. Gift codes can be redeemed at medium.com\u002Fredeem.","price":"50.00","currency":"USD","sku":"membership-gift-1-yr"},"oldMonthlyPlan":{"planId":"P-96U02458LM656772MJZUVH2Y","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlan":{"planId":"P-59P80963JF186412JJZU3SMI","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"monthlyPlanWithTrial":{"planId":"P-66C21969LR178604GJPVKUKY","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlanWithTrial":{"planId":"P-6XW32684EX226940VKCT2MFA","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oldMonthlyPlanNoSetupFee":{"planId":"P-4N046520HR188054PCJC7LJI","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlanNoSetupFee":{"planId":"P-7A4913502Y5181304CJEJMXQ","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"sdkUrl":"https:\u002F\u002Fwww.paypal.com\u002Fsdk\u002Fjs"},"stripePublishableKey":"pk_live_7FReX44VnNIInZwrIIx6ghjl","log":{"json":true,"level":"info"},"imageUploadMaxSizeMb":25,"staffPicks":{"title":"Staff Picks","catalogId":"c7bc6e1ee00f"}},"session":{"xsrf":""}}</script><script>window.__APOLLO_STATE__ = {"ROOT_QUERY":{"__typename":"Query","viewer":null,"collectionByDomainOrSlug({\"domainOrSlug\":\"pinterest-engineering\"})":{"__ref":"Collection:4c5a5f6279b6"},"postResult({\"id\":\"cb1810407b92\"})":{"__ref":"Post:cb1810407b92"}},"ImageMetadata:":{"__typename":"ImageMetadata","id":"","originalWidth":0,"originalHeight":0},"Collection:4c5a5f6279b6":{"__typename":"Collection","id":"4c5a5f6279b6","favicon":{"__ref":"ImageMetadata:"},"customStyleSheet":null,"colorPalette":{"__typename":"ColorPalette","highlightSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FFFFDED6","point":0},{"__typename":"ColorPoint","color":"#FFFFD8CF","point":0.1},{"__typename":"ColorPoint","color":"#FFFFD2C8","point":0.2},{"__typename":"ColorPoint","color":"#FFFFCDC1","point":0.3},{"__typename":"ColorPoint","color":"#FFFFC7BB","point":0.4},{"__typename":"ColorPoint","color":"#FFFFC1B4","point":0.5},{"__typename":"ColorPoint","color":"#FFFFBBAD","point":0.6},{"__typename":"ColorPoint","color":"#FFFFB4A7","point":0.7},{"__typename":"ColorPoint","color":"#FFFFAEA0","point":0.8},{"__typename":"ColorPoint","color":"#FFFFA89A","point":0.9},{"__typename":"ColorPoint","color":"#FFFFA193","point":1}]},"defaultBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FFE93335","point":0},{"__typename":"ColorPoint","color":"#FFD73433","point":0.1},{"__typename":"ColorPoint","color":"#FFC53331","point":0.2},{"__typename":"ColorPoint","color":"#FFB3322E","point":0.3},{"__typename":"ColorPoint","color":"#FFA12F2B","point":0.4},{"__typename":"ColorPoint","color":"#FF8F2C28","point":0.5},{"__typename":"ColorPoint","color":"#FF7C2924","point":0.6},{"__typename":"ColorPoint","color":"#FF692420","point":0.7},{"__typename":"ColorPoint","color":"#FF561E1A","point":0.8},{"__typename":"ColorPoint","color":"#FF421714","point":0.9},{"__typename":"ColorPoint","color":"#FF2D0F0C","point":1}]},"tintBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFBD081C","colorPoints":[{"__typename":"ColorPoint","color":"#FFBD081C","point":0},{"__typename":"ColorPoint","color":"#FFD12F30","point":0.1},{"__typename":"ColorPoint","color":"#FFE34943","point":0.2},{"__typename":"ColorPoint","color":"#FFF26057","point":0.3},{"__typename":"ColorPoint","color":"#FFFF766B","point":0.4},{"__typename":"ColorPoint","color":"#FFFF8B7F","point":0.5},{"__typename":"ColorPoint","color":"#FFFF9F94","point":0.6},{"__typename":"ColorPoint","color":"#FFFFB3A8","point":0.7},{"__typename":"ColorPoint","color":"#FFFFC7BD","point":0.8},{"__typename":"ColorPoint","color":"#FFFFDAD2","point":0.9},{"__typename":"ColorPoint","color":"#FFFFEEE7","point":1}]}},"domain":null,"slug":"pinterest-engineering","googleAnalyticsId":null,"name":"Pinterest Engineering Blog","avatar":{"__ref":"ImageMetadata:1*XiUFDZgSFl6n-MM2yXFifQ.png"},"description":"Inventive engineers building the first visual discovery engine, 300 billion ideas and counting.","subscriberCount":15507,"latestPostsConnection({\"paging\":{\"limit\":1}})":{"__typename":"PostConnection","posts":[{"__ref":"Post:3670363c467d"}]},"isAuroraVisible":false,"tintColor":"#FFBD081C","newsletterV3":null,"viewerEdge":{"__ref":"CollectionViewerEdge:collectionId:4c5a5f6279b6-viewerId:lo_548445cd662b"},"twitterUsername":"PinterestEng","facebookPageId":null,"logo":{"__ref":"ImageMetadata:"}},"ImageMetadata:1*XiUFDZgSFl6n-MM2yXFifQ.png":{"__typename":"ImageMetadata","id":"1*XiUFDZgSFl6n-MM2yXFifQ.png"},"User:ef81ef829bcb":{"__typename":"User","id":"ef81ef829bcb","customDomainState":null,"hasSubdomain":false,"username":"Pinterest_Engineering","linkedAccounts":{"__ref":"LinkedAccounts:ef81ef829bcb"},"isSuspended":false,"name":"Pinterest Engineering","imageId":"1*iAV-apeVpCJ1h6Znt1AzCg.jpeg","verifications":{"__typename":"VerifiedInfo","isBookAuthor":false},"socialStats":{"__typename":"SocialStats","followerCount":58549,"followingCount":323,"collectionFollowingCount":6},"bio":"https:\u002F\u002Fmedium.com\u002Fpinterest-engineering | Inventive engineers building the first visual discovery engine https:\u002F\u002Fcareers.pinterest.com\u002F","membership":null,"allowNotes":true,"viewerEdge":{"__ref":"UserViewerEdge:userId:ef81ef829bcb-viewerId:lo_548445cd662b"},"twitterScreenName":"PinterestEng"},"Post:3670363c467d":{"__typename":"Post","id":"3670363c467d","firstPublishedAt":1740002249241,"creator":{"__ref":"User:ef81ef829bcb"},"collection":{"__ref":"Collection:4c5a5f6279b6"},"isSeries":false,"mediumUrl":"https:\u002F\u002Fmedium.com\u002Fpinterest-engineering\u002Finfrastructure-advancements-at-aws-reinvent-2024-3670363c467d","sequence":null,"uniqueSlug":"infrastructure-advancements-at-aws-reinvent-2024-3670363c467d"},"LinkedAccounts:ef81ef829bcb":{"__typename":"LinkedAccounts","mastodon":null,"id":"ef81ef829bcb"},"Paragraph:b6bbc5cdaf5f_0":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_0","name":"e96c","type":"H3","href":null,"layout":null,"metadata":null,"text":"Developing fast & reliable iOS builds at Pinterest","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_1":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_1","name":"8e56","type":"P","href":null,"layout":null,"metadata":null,"text":"By Rahul Malik | iOS Platform Tech Lead","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_2":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_2","name":"ada4","type":"P","href":null,"layout":null,"metadata":null,"text":"At Pinterest we’re focused on helping people discover inspiring ideas, from dinner recipes to try, home and style products to buy, to places to travel. Building the best products for mobile is a critical part of that, with 80% of all Pinners access Pinterest via mobile apps. On the iOS team specifically, we’re constantly working to improve that experience as efficiently and quickly as we can, and giving our team the best development and testing environment is a key step in that.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_3":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_3","name":"55aa","type":"P","href":null,"layout":null,"metadata":null,"text":"We recently looked into ways to streamline that process, and set out to improve the speed and reliability of our iOS builds on local and continuous integration environments. In addition, we began modularizing our application into standalone frameworks and needed a system to support that migration. We reviewed multiple tools, including Xcode, Cocoapods, Buck, and Bazel. We wanted to introduce a more stable foundation for the future, which is central to our ability to rapidly iterate and release new features to Pinners.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*zDbDRMKBXoSjywY_vmbrzA.jpeg":{"__typename":"ImageMetadata","id":"1*zDbDRMKBXoSjywY_vmbrzA.jpeg","originalHeight":768,"originalWidth":512,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:b6bbc5cdaf5f_4":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_4","name":"77a4","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*zDbDRMKBXoSjywY_vmbrzA.jpeg"},"text":"","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_5":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_5","name":"b7b1","type":"P","href":null,"layout":null,"metadata":null,"text":"After comparing Xcode, Cocoapods, Buck and Bazel, we identified Bazel was the best fit for our goals to build a foundation for an order of magnitude improvement in performance, eliminate variability in build environments and adopt incrementally. As a result, we’re now shipping all our iOS releases using Bazel which has already resulted in wins, including:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_6":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_6","name":"2910","type":"P","href":null,"layout":null,"metadata":null,"text":"Local Development","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":0,"end":17,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_7":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_7","name":"81c6","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Faster builds: Reduced clean build time from 4m 38s to 3m 38s, a 21% improvement.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_8":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_8","name":"cbe1","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Local disk caches allow for instant rebuilds for anything you’ve built before (other branches, commits, etc).","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_9":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_9","name":"be6d","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Environments are identical between CI and local environments, so build issues are easy to reproduce.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_10":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_10","name":"b882","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Increased automation: Tasks like code generation are included as part of the build graph.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_11":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_11","name":"27fc","type":"P","href":null,"layout":null,"metadata":null,"text":"Continuous Integration","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":0,"end":22,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_12":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_12","name":"cb81","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Every build is an incremental build: Since Bazel is reproducible, we haven’t performed a single clean build on CI in over a year.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_13":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_13","name":"ae8d","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Build once, reuse everywhere: After introducing remote build caching, build times dropped under a minute and as low as 30 seconds since we don’t need to rebuild anything that has been built on any machine","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_14":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_14","name":"dd11","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Reduced time to land code: Reduced build time from 10m 24s to 7m 34s, a 27% improvement.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_15":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_15","name":"256c","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Reduced time to get changes to beta testers: Beta build time went from 14m 32s to 7m 52s, a 45% improvement.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_16":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_16","name":"a8da","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Faster test execution: Test runs are instant if the modified code does not affect the test.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_17":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_17","name":"e5ca","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Higher build success rate: Success rate of builds improved from around 80% to 97%-100% when running build tasks with Bazel.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_18":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_18","name":"b1a7","type":"H3","href":null,"layout":null,"metadata":null,"text":"Moving to a future of fast and reliable builds","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_19":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_19","name":"7c07","type":"P","href":null,"layout":null,"metadata":null,"text":"Build speed is a constant bottleneck for developers since we’re using compiled languages (Objective-C\u002FC++). But build speed is hard to quantify. It includes of builds in different environments, like continuous integration or local development. We also work with a variety of workflow scenarios, like clean builds, incremental builds, branch switching, rebasing, reverting changes, and others. You can’t improve what you don’t measure, so improving build speed requires tracking a variety of scenarios to allow us to pinpoint regressions and focus our performance efforts.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_20":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_20","name":"baf4","type":"P","href":null,"layout":null,"metadata":null,"text":"We can make builds faster by a combination of doing less work or performing work more efficiently. This might involve using different tools, improving parallelization, or updating the architecture of the project to require fewer source files. Having strong practices around maintaining a modular architecture and cleaning up dead code that is unreferenced or related to completed experiments will help maintain \u002F improve build speeds. We use a variety of in-house tools and scripts to identify dead code. For experiments, we utilize automation that adds clang annotations to deprecate methods and constants that are related to the experiment which allows the compiler to warn developers that the experiment is ended and code should be removed. Identifying unreferenced code is performed adhoc by developers by periodically running tools that inspect the header include graph of our build and look for files that are have zero references recursively.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_21":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_21","name":"171c","type":"P","href":null,"layout":null,"metadata":null,"text":"Our build process needs to be both fast and reliable. Builds are reliable if they are reproducible. Reproducible builds are important not just for reproducing bugs, but also for ensuring we ship the exact version of the app that we’ve developed and tested against. We can only achieve that if the build environment — the inputs and outputs — are consistent.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_22":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_22","name":"ce76","type":"P","href":null,"layout":null,"metadata":null,"text":"Changes to the environment can greatly affect the end product and introduce variability. A consistent environment guarantees the application behaves the same regardless of if it was built on a developer’s machine or via continuous integration, and it eliminates time spent figuring out why a build succeeds in one environment but fails elsewhere.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_23":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_23","name":"6dcc","type":"P","href":null,"layout":null,"metadata":null,"text":"While the ideas and explorations are focused around iOS, the goals of fast and reproducible builds are one that we all share and will allow us to scale client engineering.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_24":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_24","name":"5974","type":"H3","href":null,"layout":null,"metadata":null,"text":"Challenges","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_25":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_25","name":"9118","type":"P","href":null,"layout":null,"metadata":null,"text":"The decision to focus on improving our build process was rooted in the impact it was having on developer productivity. As we grow our team and product, it’s paramount that we invest in our developers’ ability to work with a consistent and fast build system.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_26":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_26","name":"888d","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Scale: As we scale client engineering, the amount of time spent supporting developers, maintaining or reducing build times and improving reliability scale as well. The number of engineers that support developers does not necessarily scale proportionally with the number of developers, and Xcode doesn’t contain tools to profile builds when performance degrades.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_27":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_27","name":"7fe2","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Modular architecture: We’ve begun refactoring the core frameworks that compose our platform from our app in order to improve our overall architecture, documentation and quality. This adds complexity because it requires a build system that can manage a dependency graph of build targets which need to be configured and compiled in a specific order. While not impossible in Xcode, the configuration and maintenance of such a graph would be prohibitively difficult to maintain over time due to a lack of a expressive configuration API.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_28":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_28","name":"b032","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Build instability: Outside of our codebase, there are a number of tools written in different languages (Ruby, Python, Bash, etc.) that require specific versions and toolchains that must be identical to create consistent builds. These variations can result in errors that are hard to reliably reproduce. It was not uncommon for developers to have a build pass locally but fail on continuous integration, and vice versa. Only certain machines had the requirements necessary to create a release candidate. Local state can become corrupted, which required performing clean builds. That wastes time.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_29":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_29","name":"edf5","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Task automation & code generation: We rely on code generation to create our immutable models (via Plank) and logging infrastructure (via Thrift). While it has support for run script phases, Xcode can’t introduce dynamic workflows like code generation or general task automation to be a part of the build process, and instead requires manually integrating generated sources, putting more work on developers and onboarding education. This also requires adding generated artifacts to version control, which increases our repository size and git clone performance.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_30":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_30","name":"7474","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Shared resources: The integration path for external repositories has not been clear and has historically resulted in periodically copying resources from other repositories. We have explored options like git subtree or git submodule, but this required an increased investment in employee education and a change to developer workflows. That introduced confusion and, again, wastes time. Xcode does not have any support for declaring external build dependencies, so we would have to rely on external tooling to provide this integration.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_31":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_31","name":"47fa","type":"H3","href":null,"layout":null,"metadata":null,"text":"Solutions","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_32":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_32","name":"60e7","type":"P","href":null,"layout":null,"metadata":null,"text":"We wanted solutions that would allow us to overcome these challenges with tooling and automation instead of increased load on developer education and process — and waste less time. We primarily optimize for:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_33":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_33","name":"f744","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Rapid iteration: Our solution should provide functionality to greatly improve and maintain build speed and developer velocity over time, likely achieved through better parallelism and advanced tooling features.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_34":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_34","name":"6c62","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Sandboxed development: A consistent environment that allows us to have reliable builds and minimizes variability and impact on developer productivity.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_35":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_35","name":"f10c","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Monorepo-like development: All sources should still remain in one repository. This minimizes the amount of work and context switching required to make changes across the application.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_36":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_36","name":"0b5f","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Profiling, Monitoring, Analysis: We need tools that give us insight into our build system to identify issues. Our solution needs to allow us to visualize the actions performed throughout the build and their respective durations. Assuming we have this, we will be able to track detailed changes on a frequent basis.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_37":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_37","name":"b5b2","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Incremental Compilation: Once we build the client once, we should be able to safely incrementally build through all workflows. That should include switching branches, reverting changes, or other parts of the workflow. Clean builds are by far the most expensive builds and are usually performed when local state is corrupted or the developer is trying to diagnose an unknown build issues.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_38":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_38","name":"1ced","type":"H3","href":null,"layout":null,"metadata":null,"text":"Extensible for the future","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_39":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_39","name":"caca","type":"P","href":null,"layout":null,"metadata":null,"text":"As our application grows in complexity and our needs evolve we must ensure that we have enough extensibility in our build system to allow for change to be develop. But it must not be so specific in that it hinders further dynamic automation in our build process. This may range from being able to automate tasks to integrate third-party static analysis, custom toolchains and the in-house tools we develop at Pinterest.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":353,"end":371,"href":"https:\u002F\u002Fmedium.com\u002F@Pinterest_Engineering\u002Fios-linting-at-pinterest-3108d8764390","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":375,"end":394,"href":"https:\u002F\u002Fpinterest.github.io\u002Fplank\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:b6bbc5cdaf5f_40":{"__typename":"Paragraph","id":"b6bbc5cdaf5f_40","name":"e783","type":"P","href":null,"layout":null,"metadata":null,"text":"Changing a build system is a significant change, and we cannot support an approach that isn’t possible to introduce incrementally. An all-or-nothing solution would require potentially pausing development or maintaining a long-lived fork and performing a risky migration atomically across developer environments and CI systems.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"CollectionViewerEdge:collectionId:4c5a5f6279b6-viewerId:lo_548445cd662b":{"__typename":"CollectionViewerEdge","id":"collectionId:4c5a5f6279b6-viewerId:lo_548445cd662b","isEditor":false,"isMuting":false},"UserViewerEdge:userId:ef81ef829bcb-viewerId:lo_548445cd662b":{"__typename":"UserViewerEdge","id":"userId:ef81ef829bcb-viewerId:lo_548445cd662b","isMuting":false},"PostViewerEdge:postId:cb1810407b92-viewerId:lo_548445cd662b":{"__typename":"PostViewerEdge","shouldIndexPostForExternalSearch":true,"id":"postId:cb1810407b92-viewerId:lo_548445cd662b"},"Tag:continuous-integration":{"__typename":"Tag","id":"continuous-integration","displayTitle":"Continuous Integration","normalizedTagSlug":"continuous-integration"},"Tag:ios":{"__typename":"Tag","id":"ios","displayTitle":"iOS","normalizedTagSlug":"ios"},"Tag:ios-app-development":{"__typename":"Tag","id":"ios-app-development","displayTitle":"iOS App Development","normalizedTagSlug":"ios-app-development"},"Tag:xcode":{"__typename":"Tag","id":"xcode","displayTitle":"Xcode","normalizedTagSlug":"xcode"},"Tag:mobile":{"__typename":"Tag","id":"mobile","displayTitle":"Mobile","normalizedTagSlug":"mobile"},"Post:cb1810407b92":{"__typename":"Post","id":"cb1810407b92","collection":{"__ref":"Collection:4c5a5f6279b6"},"content({\"postMeteringOptions\":{\"referrer\":\"\"}})":{"__typename":"PostContent","isLockedPreviewOnly":false,"bodyModel":{"__typename":"RichText","sections":[{"__typename":"Section","name":"624f","startIndex":0,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null}],"paragraphs":[{"__ref":"Paragraph:b6bbc5cdaf5f_0"},{"__ref":"Paragraph:b6bbc5cdaf5f_1"},{"__ref":"Paragraph:b6bbc5cdaf5f_2"},{"__ref":"Paragraph:b6bbc5cdaf5f_3"},{"__ref":"Paragraph:b6bbc5cdaf5f_4"},{"__ref":"Paragraph:b6bbc5cdaf5f_5"},{"__ref":"Paragraph:b6bbc5cdaf5f_6"},{"__ref":"Paragraph:b6bbc5cdaf5f_7"},{"__ref":"Paragraph:b6bbc5cdaf5f_8"},{"__ref":"Paragraph:b6bbc5cdaf5f_9"},{"__ref":"Paragraph:b6bbc5cdaf5f_10"},{"__ref":"Paragraph:b6bbc5cdaf5f_11"},{"__ref":"Paragraph:b6bbc5cdaf5f_12"},{"__ref":"Paragraph:b6bbc5cdaf5f_13"},{"__ref":"Paragraph:b6bbc5cdaf5f_14"},{"__ref":"Paragraph:b6bbc5cdaf5f_15"},{"__ref":"Paragraph:b6bbc5cdaf5f_16"},{"__ref":"Paragraph:b6bbc5cdaf5f_17"},{"__ref":"Paragraph:b6bbc5cdaf5f_18"},{"__ref":"Paragraph:b6bbc5cdaf5f_19"},{"__ref":"Paragraph:b6bbc5cdaf5f_20"},{"__ref":"Paragraph:b6bbc5cdaf5f_21"},{"__ref":"Paragraph:b6bbc5cdaf5f_22"},{"__ref":"Paragraph:b6bbc5cdaf5f_23"},{"__ref":"Paragraph:b6bbc5cdaf5f_24"},{"__ref":"Paragraph:b6bbc5cdaf5f_25"},{"__ref":"Paragraph:b6bbc5cdaf5f_26"},{"__ref":"Paragraph:b6bbc5cdaf5f_27"},{"__ref":"Paragraph:b6bbc5cdaf5f_28"},{"__ref":"Paragraph:b6bbc5cdaf5f_29"},{"__ref":"Paragraph:b6bbc5cdaf5f_30"},{"__ref":"Paragraph:b6bbc5cdaf5f_31"},{"__ref":"Paragraph:b6bbc5cdaf5f_32"},{"__ref":"Paragraph:b6bbc5cdaf5f_33"},{"__ref":"Paragraph:b6bbc5cdaf5f_34"},{"__ref":"Paragraph:b6bbc5cdaf5f_35"},{"__ref":"Paragraph:b6bbc5cdaf5f_36"},{"__ref":"Paragraph:b6bbc5cdaf5f_37"},{"__ref":"Paragraph:b6bbc5cdaf5f_38"},{"__ref":"Paragraph:b6bbc5cdaf5f_39"},{"__ref":"Paragraph:b6bbc5cdaf5f_40"}]},"validatedShareKey":"","shareKeyCreator":null},"creator":{"__ref":"User:ef81ef829bcb"},"inResponseToEntityType":null,"isLocked":false,"isMarkedPaywallOnly":false,"lockedSource":"LOCKED_POST_SOURCE_NONE","mediumUrl":"https:\u002F\u002Fmedium.com\u002Fpinterest-engineering\u002Fdeveloping-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92","primaryTopic":null,"topics":[{"__typename":"Topic","slug":"programming"}],"isLimitedState":false,"isPublished":true,"allowResponses":true,"latestPublishedVersion":"b6bbc5cdaf5f","visibility":"PUBLIC","responsesLocked":false,"postResponses":{"__typename":"PostResponses","count":6},"responseDistribution":"NOT_DISTRIBUTED","clapCount":452,"title":"Developing fast & reliable iOS builds at Pinterest (Part one)","isSeries":false,"sequence":null,"uniqueSlug":"developing-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92","socialTitle":"","socialDek":"","canonicalUrl":"","metaDescription":"","latestPublishedAt":1623430319725,"readingTime":6.230188679245283,"previewContent":{"__typename":"PreviewContent","subtitle":"By Rahul Malik | iOS Platform Tech Lead"},"previewImage":{"__ref":"ImageMetadata:1*zDbDRMKBXoSjywY_vmbrzA.jpeg"},"isShortform":false,"seoTitle":"","firstPublishedAt":1550100337528,"updatedAt":1638879932823,"shortformType":"SHORTFORM_TYPE_LINK","seoDescription":"","viewerEdge":{"__ref":"PostViewerEdge:postId:cb1810407b92-viewerId:lo_548445cd662b"},"isSuspended":false,"license":"ALL_RIGHTS_RESERVED","tags":[{"__ref":"Tag:continuous-integration"},{"__ref":"Tag:ios"},{"__ref":"Tag:ios-app-development"},{"__ref":"Tag:xcode"},{"__ref":"Tag:mobile"}],"isFeaturedInPublishedPublication":false,"isNewsletter":false,"statusForCollection":"APPROVED","pendingCollection":null,"detectedLanguage":"en","wordCount":1598,"layerCake":0}}</script><script>window.__MIDDLEWARE_STATE__={"session":{"xsrf":""},"cache":{"cacheStatus":"EXPIRED"}}</script><script src="https://cdn-client.medium.com/lite/static/js/manifest.8648ce46.js"></script><script src="https://cdn-client.medium.com/lite/static/js/9865.1496d74a.js"></script><script src="https://cdn-client.medium.com/lite/static/js/main.557bd252.js"></script><script src="https://cdn-client.medium.com/lite/static/js/instrumentation.5bef8967.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/reporting.ff22a7a5.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9120.5df29668.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5049.d1ead72d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4505.6dfaf853.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6618.db187378.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9380.fb176dee.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2707.2278ed76.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9977.933c1c9a.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8599.68bc318b.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/3045.1cc3d8cb.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6349.3329b100.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2648.26563adf.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8393.67b7130d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6428.7d30b23c.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6199.c727247b.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5642.7d9f7f3d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6546.e46b7f66.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6834.8aa8d357.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4492.0c3e1a1d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2571.6814b962.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/839.1c286b32.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6128.f8800a13.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2135.aeee1c45.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7975.60bcefe8.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/144.72d76bca.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5240.6281357f.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8819.c627c2bf.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8204.d0637ed0.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/PostPage.MainContent.8692827c.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8414.0d800846.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/3974.8d3e0217.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2527.18a8996d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/PostResponsesContent.e1e580cb.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/responses.editor.e89462cb.chunk.js"></script><script>window.main();</script><script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'917bece2eaa74957',t:'MTc0MDUzMDg2My4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body></html>