{"id":804,"date":"2016-08-29T12:25:43","date_gmt":"2016-08-29T12:25:43","guid":{"rendered":"http:\/\/blog.stratio.com\/?p=804"},"modified":"2023-09-20T13:45:04","modified_gmt":"2023-09-20T13:45:04","slug":"continuous-delivery-depth-part-one","status":"publish","type":"post","link":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/","title":{"rendered":"Continuous delivery in depth #1"},"content":{"rendered":"<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">Following on from\u00a0a\u00a0previous &#8220;Lunch &amp;\u00a0learn&#8221; about how Jenkins is being used for Stratio&#8217;s Continuous Delivery jobs (watch\u00a0on\u00a0<a href=\"https:\/\/www.youtube.com\/channel\/UCuzJA_GlT3TQaU5DyRwDOVw\" target=\"_blank\" rel=\"noopener\">Stratio&#8217;s youtube channel<\/a>),\u00a0<\/span>it seemed logical to provide more information on our\u00a0<a href=\"https:\/\/jenkins.io\/doc\/pipeline\/\" target=\"_blank\" rel=\"noopener\">Jenkins pipeline<\/a>\u00a0plug-in usage.<\/p>\n<p style=\"text-align: justify;\">In this\u00a0first issue, we will \u00a0follow how pipelines are being used at\u00a0<a href=\"http:\/\/blog.stratio.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Stratio Big Data<\/a>\u00a0to achieve full lifecycle traceability, from the development team to a final productive environment.<\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">Some pitfalls were mentioned during the &#8220;Lunch &amp; Learn&#8221; meeting and will be explained to help you fully comprehend the nature of the underlying bug and the solution achieved. This will follow in a second issue.<\/span><\/p>\n<p style=\"text-align: justify;\"><!--more--><\/p>\n<h2 style=\"text-align: justify;\">Pipelines are code<\/h2>\n<p style=\"text-align: justify;\">Each of our pipelines is kept in a private github project under\u00a0<a href=\"https:\/\/github.com\/Stratio\/\" target=\"_blank\" rel=\"noopener noreferrer\">Stratio&#8217;s organization repo<\/a>,\u00a0where we mantain several\u00a0elements:<\/p>\n<ul style=\"text-align: justify;\">\n<li>l.groovy<\/li>\n<li>libvars.groovy<\/li>\n<li>libpipeline.groovy<\/li>\n<li>dev-project.groovy<\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><strong>l.groovy<\/strong>\u00a0is the main place for shared methods, used for parsing files, checking out code, building, running tests, building docker images. +70 methods, most of them &#8220;private&#8221;. The \u00a0Jenkins pipeline allows us to auto-load it from an internal jenkins repo, but to make it easier, we are skipping that functionality and keeping the file in github.<br \/>\n<strong>libvars.groovy<\/strong>\u00a0is the home for shared variables. Groovy allows untyped vars, but some of them are typed allowing better maintenance. Some of those variables are constants, such as urls (internal nexus, gitolite or docker registry), slack channels, default versions.<br \/>\n<strong>libpipeline.groovy<\/strong>\u00a0is the main method. It will decide what kind of operations will be performed on the current job. We will go back to this file later.<br \/>\n<strong>dev-project.groovy<\/strong>\u00a0is the real pipeline. Real because\u00a0it loads the previous three files, sets variables values and invokes the previous main method. As an example, we can look at\u00a0one of Stratio&#8217;s open source projects (<a href=\"https:\/\/github.com\/Stratio\/crossdata\" target=\"_blank\" rel=\"noopener noreferrer\">Stratio Crossdata<\/a>), with comments about its objective:<\/p>\n<pre class=\"height:1200 lang:default decode:true\" title=\"dev-project.groovy\">import groovy.transform.Field\n\n@Field String lib\n\nnode('master') { \/\/Common element load\n    def cdpwd = pwd().split('\/').reverse()[0].replaceAll('@.*', '')\n    lib = load \"..\/${cdpwd}@script\/l.groovy\"\n    l.vars = load \"..\/${cdpwd}@script\/libvars.groovy\"\n    l.pipeline = load \"..\/${cdpwd}@script\/libpipeline.groovy\"\n}\n\n\/\/ Some metadata for checking out, identifying and messaging abouts warnings\/errors\nl.v.MODULE = 'crossdata' \nl.v.MAIL = 'crossdata@stratio.com'\nl.v.REPO = 'Stratio\/crossdata'\nl.v.ID = 'xd'\nl.v.SLACKTEAM = 'stratiocrossdata'\nl.v.FAILFAST = true \n\n\/\/ Stratio is polyglot, and so are its developments. \n\/\/ We need to know what build tool we have to use\nl.v.BUILDTOOL = 'maven' \n\n\/\/ Should we deploy to sonatype oss repository (so maven artifacts become public)\nl.v.FOSS = true \n\n\/\/ Each PR gets statuses, as soon as each run action passes or fails\nl.v.PRStatuses = ['Compile', 'Unit Tests', 'Integration Tests', 'Code Quality'] \n\nl.v.MERGETIMEOUT = 70  \/\/ Timeous for each kind of operation we could perform\nl.v.PRTIMEOUT = 30\nl.v.RELEASETIMEOUT = 30\nl.v.SQUASHTIMEOUT = 15\n\nl.v.MERGEACTIONS = { \/\/ If our git hook sent a payload related to a PR being merged \n                  l.doBuild()\n\n                  parallel(UT: {\n                     l.doUnitTest()\n                  }, IT: {\n                     l.doIntegrationTest()\n                  }, failFast: l.v.FAILFAST)\n\n                  l.doPackage() \/\/Might be a tgz, deb, jar, war\n                  \/\/ java-scaladocs are published to our s3 bucket \n                  \/\/ (such as http:\/\/stratiodocs.s3-website-us-east-1.amazonaws.com\/cassandra-lucene-index\/3.0.6.1\/)\n                  l.doDoc() \n\n                  parallel(CQ: {\n                     \/\/ Static code analysis with Sonarqube \n                     \/\/ and coveralls.io (for some FOSS projects)\n                     l.doCodeQuality() \n                  }, DEPLOY: {\n                     l.doDeploy()\n                  }, failFast: l.v.FAILFAST)\n\n                  \/\/ And push it to our internal docker registry\n                  \/\/, for a later usage in tests and demos\n                  l.doDockerImage() \n                  \/\/ A Marathon cluster deploys the previously build image\n                  l.doMarathonInstall('mc1') \n                  l.doAcceptanceTests(['basic', 'auth', cassandra', 'elasticsearch', 'mongodb', mesos', 'yarn'])\n                 }\n\nl.v.PRACTIONS = { \/\/ If our git hook sent a payload about a PR being opened or synced\n               l.doBuild()\n\n               parallel(UT: {\n                  l.doUnitTest()\n               }, IT: {\n                  l.doIntegrationTest()\n               }, failFast: l.v.FAILFAST)\n\n               l.doCodeQuality()\n               \/\/ We deploy a subset of our wannabe packages to an staging repo\t\t\t   \n               l.doStagePackage()\n               \/\/ Work as packer, building a temporal docker image, so a container can be used for testing \n               l.doPackerImage() \n               l.doAcceptanceTests(['basic', 'auth', cassandra', 'elasticsearch', 'mongodb', mesos', 'yarn'])\n              }\n\nl.v.BRANCHACTIONS = { \/\/ We could receive a hook signalling a branch to be forged\n                   l.doBranch()\n                  }\n\nl.v.RELEASEACTIONS = { \/\/ So we could release a final version\n                    l.doRelease()\n                    l.doDoc()\n                    l.prepareForNextCycle()\n                    \/\/ This time the image is the real deal\n                    \/\/ It will end @ Docker Hub (https:\/\/hub.docker.com\/r\/stratio\/)\n                    l.doDockerImage() \n\n                    \/\/ Deploying again, to a production Marathon cluster\n                    l.doMarathonInstall('mc2')\n                    \/\/ Let the world know a new version is released, and spread its changelog\n                    l.doReleaseMail() \n                   }\n\nl.v.SQUASHACTIONS = {\n                   \/\/ Currently just checks a PR statuse, rebases it, \n                   \/\/ invokes l.v.PRACTIONS, and merges the PR\n                   l.doSquash() \n                  }\n\nl.pipeline.roll()<\/pre>\n<p><span style=\"font-weight: 400;\">Back to our libpipeline.groovy, we can see how some of the previously set up variables are being used:<\/span><\/p>\n<pre class=\"height:1200 lang:default decode:true\" title=\"libpipeline.groovy\">def roll() {\n    timestamps {\n        try {            \n            l.credentialsHandler()\n            \/\/ The git hook gets parsed, so we can know the committer, \n            \/\/ pusher, ref, commitid, for a later git fetch\n            l.doParseHook() \n            l.signalJobStart()\n\n            if (l.isMerge()) {\n                currentBuild.description = \"${l.v.REF.replaceAll('refs\/heads\/', '')}\"\n                \/\/ Stages limit concurrency until milestone step \n                \/\/ (https:\/\/github.com\/jenkinsci\/pipeline-milestone-step-plugin) gets live\n                stage name: \"${currentBuild.description}\", concurrency: 1 \n                \n                timeout(time: l.v.MERGETIMEOUT, unit: 'MINUTES') {\n                    \/\/ Checkout some git ref, to a previously clean workspace\n                    l.doFetch() \n                    \/\/ http:\/\/slack.com is one ofour preferred notification systems\n                    l.doSlack('started')\n                    \/\/ What is the Crossdata team expecting to be run when merging a PR? See a few lines above\n                    l.v.MERGEACTIONS.call() \n                    \/\/ And we love to know our builds passed\n                    l.doSlack('passed') \n                }                \n\n            } else if (l.isPR()) { \/\/Pull-merge requests\n                currentBuild.description = l.evalPRDescription()\n                stage name: \"PR${PR}\", concurrency: 1\n\n                    timeout(time: l.v.PRTIMEOUT, unit: 'MINUTES') {\n                        l.doFetch()\n                        l.doSlack('started')\n                        l.v.PRACTIONS.call()\n                        l.doSlack('passed')\n                    }\n\n            } else if (l.isTagForReleaseBranching()) {              \n                currentBuild.description = \"Some branch to forge\"\n                stage name: \"${l.v.BASEREF.replaceAll('refs\/heads\/', '')}\", concurrency: 1\n                timeout(time: l.v.BRANCHTIMEOUT, unit: 'MINUTES') {\n                    l.doFetch()\n                    l.doSlack('started')\n                    l.v.BRANCHACTIONS.call()\n                }\n                l.doSlack('passed')\n\n            } else if (l.isRCorRelease()) {                \n                currentBuild.description = \"${l.v.REF.replaceAll('refs\/tags\/', '').replaceAll('-RELEASE', '')} to be released\"\n                stage name: \"${l.v.BASEREF.replaceAll('refs\/heads\/', '')}\", concurrency: 1\n                timeout(time: l.v.RELEASETIMEOUT, unit: 'MINUTES') {\n                    l.doFetch()\n                    l.doSlack('started')\n                    l.v.RELEASEACTIONS.call()\n                }\n                l.doSlack('passed')\n\n            } else if (l.isCommentOnPR()) {\n                currentBuild.description = \"Squashing ${l.evalPRDescription()}\"\n                stage name: \"PR${PR}\", concurrency: 1\n                timeout(time: l.v.SQUASHTIMEOUT, unit: 'MINUTES') {\n                    l.doFetch()\n                    l.doSlack('started')\n                    l.v.SQUASHACTIONS.call()\n                }\n                l.doSlack('passed')\n\n            } else {                \n                currentBuild.result = 'NOT_BUILT'\n                currentBuild.description = 'github operation ommitted'\n            }\n            \n        } catch (e) {\n            l.doSlack('failed') \/\/ DUH!\n            \/\/ mail notifications are not welcomed, buth here they come\n            l.doFlowExceptionCatch(e) \n        } finally {\n            \/\/ Clean up resources, and get ready for a next run\n            l.doFinalize() \n        }\n    }\n}\n\nreturn this;<\/pre>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">Some of the unmentioned functionality is the brightest: Prior to Integration and Acceptance tests, several docker images are pulled, run and configured. With the tests ended, containers get destroyed. This way we can enjoy a clean environment for testing.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">As you can imagine, both private and public repos can be checked out, from different git providers (github, gitlab, bitbucket). We are able to work with maven and make projects.<\/span><\/p>\n<p style=\"text-align: justify;\"><span style=\"font-weight: 400;\">And as most of the elements can be defined from within each development team, some elements can be read from each git repo:<\/span><\/p>\n<blockquote>\n<ul>\n<li><span style=\"font-weight: 400;\">\u00a0A docker entrypoint to be used whilst building each docker image\u00a0<a href=\"https:\/\/github.com\/Stratio\/Crossdata\/blob\/master\/docker\/docker-entrypoint.sh\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/Stratio\/Crossdata\/blob\/master\/docker\/docker-entrypoint.sh<\/a><\/span><\/li>\n<li><span style=\"font-weight: 400;\">\u00a0A file defining most of the pipeline variables\u00a0<a href=\"https:\/\/github.com\/Stratio\/Crossdata\/blob\/master\/.jenkins.yml\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/Stratio\/Crossdata\/blob\/master\/.jenkins.yml<\/a><\/span><\/li>\n<\/ul>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>In this\u00a0first issue, we will \u00a0follow how pipelines are being used at\u00a0Stratio Big Data\u00a0to achieve full lifecycle traceability, from the development team to a final productive environment.<\/p>\n","protected":false},"author":2,"featured_media":849,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[686],"tags":[],"ppma_author":[794],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v22.9 (Yoast SEO v22.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Continuous delivery in depth #1 - Stratio Blog<\/title>\n<meta name=\"description\" content=\"See how pipelines are being used at Stratio Big Data to achieve full lifecycle traceability, from the development team to a final productive environment.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Continuous delivery in depth #1\" \/>\n<meta property=\"og:description\" content=\"See how pipelines are being used at Stratio Big Data to achieve full lifecycle traceability, from the development team to a final productive environment.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/\" \/>\n<meta property=\"og:site_name\" content=\"Stratio\" \/>\n<meta property=\"article:published_time\" content=\"2016-08-29T12:25:43+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-20T13:45:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/08\/Jenkins.gif\" \/>\n\t<meta property=\"og:image:width\" content=\"730\" \/>\n\t<meta property=\"og:image:height\" content=\"312\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/gif\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@stratiobd\" \/>\n<meta name=\"twitter:site\" content=\"@stratiobd\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/af4f5fbbeb95bd7d55f79d9a677e615d\"},\"headline\":\"Continuous delivery in depth #1\",\"datePublished\":\"2016-08-29T12:25:43+00:00\",\"dateModified\":\"2023-09-20T13:45:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/\"},\"wordCount\":458,\"publisher\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/08\/Jenkins.gif\",\"articleSection\":[\"Product\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/\",\"url\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/\",\"name\":\"Continuous delivery in depth #1 - Stratio Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/08\/Jenkins.gif\",\"datePublished\":\"2016-08-29T12:25:43+00:00\",\"dateModified\":\"2023-09-20T13:45:04+00:00\",\"description\":\"See how pipelines are being used at Stratio Big Data to achieve full lifecycle traceability, from the development team to a final productive environment.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#primaryimage\",\"url\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/08\/Jenkins.gif\",\"contentUrl\":\"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/08\/Jenkins.gif\",\"width\":730,\"height\":312},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.stratio.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Continuous delivery in depth #1\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#website\",\"url\":\"https:\/\/www.stratio.com\/blog\/\",\"name\":\"Stratio Blog\",\"description\":\"Corporate blog\",\"publisher\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.stratio.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#organization\",\"name\":\"Stratio\",\"url\":\"https:\/\/www.stratio.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png\",\"contentUrl\":\"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png\",\"width\":260,\"height\":55,\"caption\":\"Stratio\"},\"image\":{\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/stratiobd\",\"https:\/\/es.linkedin.com\/company\/stratiobd\",\"https:\/\/www.youtube.com\/c\/StratioBD\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/af4f5fbbeb95bd7d55f79d9a677e615d\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/image\/589aaf4b404b1fe099b09564062c4563\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/9b181ae4395243dccaf1c3e3a4749d81?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/9b181ae4395243dccaf1c3e3a4749d81?s=96&d=mm&r=g\",\"caption\":\"admin\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Continuous delivery in depth #1 - Stratio Blog","description":"See how pipelines are being used at Stratio Big Data to achieve full lifecycle traceability, from the development team to a final productive environment.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/","og_locale":"en_US","og_type":"article","og_title":"Continuous delivery in depth #1","og_description":"See how pipelines are being used at Stratio Big Data to achieve full lifecycle traceability, from the development team to a final productive environment.","og_url":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/","og_site_name":"Stratio","article_published_time":"2016-08-29T12:25:43+00:00","article_modified_time":"2023-09-20T13:45:04+00:00","og_image":[{"width":730,"height":312,"url":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/08\/Jenkins.gif","type":"image\/gif"}],"author":"admin","twitter_card":"summary_large_image","twitter_creator":"@stratiobd","twitter_site":"@stratiobd","twitter_misc":{"Written by":"admin","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#article","isPartOf":{"@id":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/"},"author":{"name":"admin","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/af4f5fbbeb95bd7d55f79d9a677e615d"},"headline":"Continuous delivery in depth #1","datePublished":"2016-08-29T12:25:43+00:00","dateModified":"2023-09-20T13:45:04+00:00","mainEntityOfPage":{"@id":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/"},"wordCount":458,"publisher":{"@id":"https:\/\/www.stratio.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#primaryimage"},"thumbnailUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/08\/Jenkins.gif","articleSection":["Product"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/","url":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/","name":"Continuous delivery in depth #1 - Stratio Blog","isPartOf":{"@id":"https:\/\/www.stratio.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#primaryimage"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#primaryimage"},"thumbnailUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/08\/Jenkins.gif","datePublished":"2016-08-29T12:25:43+00:00","dateModified":"2023-09-20T13:45:04+00:00","description":"See how pipelines are being used at Stratio Big Data to achieve full lifecycle traceability, from the development team to a final productive environment.","breadcrumb":{"@id":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#primaryimage","url":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/08\/Jenkins.gif","contentUrl":"https:\/\/www.stratio.com\/blog\/wp-content\/uploads\/2016\/08\/Jenkins.gif","width":730,"height":312},{"@type":"BreadcrumbList","@id":"https:\/\/www.stratio.com\/blog\/continuous-delivery-depth-part-one\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.stratio.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Continuous delivery in depth #1"}]},{"@type":"WebSite","@id":"https:\/\/www.stratio.com\/blog\/#website","url":"https:\/\/www.stratio.com\/blog\/","name":"Stratio Blog","description":"Corporate blog","publisher":{"@id":"https:\/\/www.stratio.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.stratio.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.stratio.com\/blog\/#organization","name":"Stratio","url":"https:\/\/www.stratio.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png","contentUrl":"https:\/\/stratio.com\/blog\/wp-content\/uploads\/2020\/06\/stratio-web-logo-1.png","width":260,"height":55,"caption":"Stratio"},"image":{"@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/stratiobd","https:\/\/es.linkedin.com\/company\/stratiobd","https:\/\/www.youtube.com\/c\/StratioBD"]},{"@type":"Person","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/af4f5fbbeb95bd7d55f79d9a677e615d","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stratio.com\/blog\/#\/schema\/person\/image\/589aaf4b404b1fe099b09564062c4563","url":"https:\/\/secure.gravatar.com\/avatar\/9b181ae4395243dccaf1c3e3a4749d81?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9b181ae4395243dccaf1c3e3a4749d81?s=96&d=mm&r=g","caption":"admin"}}]}},"authors":[{"term_id":794,"user_id":2,"is_guest":0,"slug":"admin","display_name":"admin","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/9b181ae4395243dccaf1c3e3a4749d81?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/804"}],"collection":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/comments?post=804"}],"version-history":[{"count":9,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/804\/revisions"}],"predecessor-version":[{"id":13936,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/posts\/804\/revisions\/13936"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/media\/849"}],"wp:attachment":[{"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/media?parent=804"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/categories?post=804"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/tags?post=804"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.stratio.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=804"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}