(window.webpackJsonp=window.webpackJsonp||[]).push([[570],{1091:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return s})),n.d(t,"metadata",(function(){return c})),n.d(t,"rightToc",(function(){return u})),n.d(t,"default",(function(){return p}));var a=n(2),o=n(6),i=(n(0),n(1629)),r=n(1632),s={id:"setting-up-ci-cd",sidebar_label:"Setting up CI/CD",title:"Setting up CI/CD",description:"Set up a CI/CD pipeline to ensure that iterative improvements to your assistant are tested and deployed with minimum manual effort",abstract:"Even though developing a contextual assistant is different from developing traditional software, you should still follow software development best practices. Setting up a Continuous Integration (CI) and Continuous Deployment (CD) pipeline ensures that incremental updates to your bot are improving it, not harming it."},c={unversionedId:"setting-up-ci-cd",id:"version-2.x/setting-up-ci-cd",isDocsHomePage:!1,title:"Setting up CI/CD",description:"Set up a CI/CD pipeline to ensure that iterative improvements to your assistant are tested and deployed with minimum manual effort",source:"@site/versioned_docs/version-2.x/setting-up-ci-cd.mdx",slug:"/setting-up-ci-cd",permalink:"/docs/rasa/2.x/setting-up-ci-cd",editUrl:"https://github.com/rasahq/rasa/edit/main/docs/versioned_docs/version-2.x/setting-up-ci-cd.mdx",version:"2.x",lastUpdatedBy:"Maksim Moiseikin",lastUpdatedAt:1726488183,sidebar_label:"Setting up CI/CD",sidebar:"version-2.x/default",previous:{title:"Testing Your Assistant",permalink:"/docs/rasa/2.x/testing-your-assistant"},next:{title:"Deploying Your Rasa Assistant",permalink:"/docs/rasa/2.x/how-to-deploy"}},u=[{value:"Overview",id:"overview",children:[]},{value:"Continuous Integration (CI)",id:"continuous-integration-ci",children:[{value:"CI Pipeline Overview",id:"ci-pipeline-overview",children:[]},{value:"GitHub Actions CI Pipeline",id:"github-actions-ci-pipeline",children:[]}]},{value:"Continuous Deployment (CD)",id:"continuous-deployment-cd",children:[{value:"Deploying Your Rasa Model",id:"deploying-your-rasa-model",children:[]},{value:"Deploying Your Action Server",id:"deploying-your-action-server",children:[]}]},{value:"Example CI/CD pipelines",id:"example-cicd-pipelines",children:[]}],l={rightToc:u};function p(e){var t=e.components,n=Object(o.a)(e,["components"]);return Object(i.b)("wrapper",Object(a.a)({},l,n,{components:t,mdxType:"MDXLayout"}),Object(i.b)("h2",{id:"overview"},"Overview"),Object(i.b)("p",null,"Continous Integration (CI) is the practice of merging in code changes\nfrequently and automatically testing changes as they are committed. Continuous\nDeployment (CD) means automatically deploying integrated changes to a staging\nor production environment. Together, they allow you to make more frequent improvements\nto your assistant and efficiently test and deploy those changes."),Object(i.b)("p",null,"This guide will cover what should go in a CI/CD pipeline, specific to a\nRasa project. How you implement that pipeline is up to you.\nThere are many CI/CD tools out there, such as ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/features/actions"}),"GitHub Actions"),",\n",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://docs.gitlab.com/ee/ci/"}),"GitLab CI/CD"),", ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://www.jenkins.io/doc/"}),"Jenkins"),", and\n",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://circleci.com/docs/2.0/"}),"CircleCI"),". We recommend choosing a tool that integrates with\nwhatever Git repository you use."),Object(i.b)("h2",{id:"continuous-integration-ci"},"Continuous Integration (CI)"),Object(i.b)("p",null,"The best way to improve an assistant is with frequent ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://rasa.com/docs/rasa-x/user-guide/fix-problems"}),"incremental updates"),".\nNo matter how small a change is, you want to be sure that it doesn't introduce\nnew problems or negatively impact the performance of your assistant."),Object(i.b)("p",null,"It is usually best to run CI checks on merge / pull requests or on commit. Most tests are\nquick enough to run on every change. However, you can choose to run more\nresource-intensive tests only when certain files have been changed or when some\nother indicator is present. For example, if your code is hosted on Github,\nyou can make a test run only if the pull request has a certain label (e.g. \u201cNLU testing required\u201d)."),Object(i.b)("h3",{id:"ci-pipeline-overview"},"CI Pipeline Overview"),Object(i.b)("p",null,"Your CI pipeline should include model training and testing as steps to streamline the deployment process.\nThe first step after saving new training data is to kick off the pipeline. This can be initiated manually\nor when you create or update a pull request."),Object(i.b)("p",null,"Next, you need to run various sets of test to see the impact of your changes. This includes running\ntests for data validation, NLU cross validation, and story testing. For\nmore information about testing, see ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/rasa/2.x/testing-your-assistant"}),"Testing Your Assistant"),"."),Object(i.b)("p",null,"The last step is to review the results of your test and push the changes if the tests are successful.\nOnce the new model is trained and tested, it can be deployed automatically using a Continuous\nDeployment pipeline."),Object(i.b)("h3",{id:"github-actions-ci-pipeline"},"GitHub Actions CI Pipeline"),Object(i.b)("p",null,"You can use the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/RasaHQ/rasa-train-test-gha"}),"Rasa Train-Test Github Action"),"\nin your CI pipeline to automatically perform data validation, training, and testing."),Object(i.b)("p",null,"An example CI pipeline using the Github Action is shown below:"),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-yaml"}),"jobs:\n  training-testing:\n    name: Training and Testing\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v1\n      - name: Rasa Train and Test GitHub Action\n        uses: RasaHQ/rasa-train-test-gha@main\n        with:\n          requirements_file: requirements.txt\n          data_validate: true\n          rasa_train: true\n          cross_validation: true\n          rasa_test: true\n          test_type: all\n          publish_summary: true\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n      - name: Upload model\n        if: github.ref == 'refs/heads/main'\n        uses: actions/upload-artifact@master\n        with:\n          name: model\n          path: models\n")),Object(i.b)("p",null,"In this pipeline, the Rasa Train-Test Github Action is performing data validation, model training, and story testing\nin the first step and the model file is uploaded as an artifact in the second step."),Object(i.b)("p",null,"The complete list of configurable parameters for the Rasa Train-Test Github Action is available in the repository's\n",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/RasaHQ/rasa-train-test-gha#input-arguments"}),"README"),"."),Object(i.b)("p",null,"When ",Object(i.b)("inlineCode",{parentName:"p"},"publish_summary")," is set to ",Object(i.b)("inlineCode",{parentName:"p"},"true"),", this action will automatically publish the model's test results to the associated\nPull Request as a comment:"),Object(i.b)("img",{alt:"image",src:Object(r.a)("/img/train-test-github-action.png")}),Object(i.b)("p",null,"The pull request can be approved or denied based on the evaluation results and, in many cases, you will want to automate the model's deployment if all CI checks pass. You can continue to the next section to learn more about Continuous Deployment."),Object(i.b)("h2",{id:"continuous-deployment-cd"},"Continuous Deployment (CD)"),Object(i.b)("p",null,"To get improvements out to your users frequently, you will want to automate as\nmuch of the deployment process as possible."),Object(i.b)("p",null,"CD steps usually run on push or merge to a certain branch, once CI checks have\nsucceeded."),Object(i.b)("h3",{id:"deploying-your-rasa-model"},"Deploying Your Rasa Model"),Object(i.b)("p",null,"If you ran ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/rasa/2.x/testing-your-assistant"}),"test stories")," in your CI pipeline,\nyou'll already have a trained model. You can set up your CD pipeline to upload the trained model to your\nRasa server if the CI results are satisfactory. For example, to upload a model to Rasa X:"),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-bash"}),'curl -k -F "model=@models/my_model.tar.gz" "https://example.rasa.com/api/projects/default/models?api_token={your_api_token}"\n')),Object(i.b)("p",null,"If you are using Rasa X, you can also ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://rasa.com/docs/rasa-x/pages/http-api/#tag/Models/paths/~1projects~1%7Bproject_id%7D~1models~1%7Bmodel%7D~1tags~1%7Btag%7D/put"}),"tag the uploaded model"),"\nas production (or whichever deployment you want to tag if using multiple ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://rasa.com/docs/rasa-x/enterprise/deployment-environments/#"}),"deployment environments"),"):"),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-bash"}),'curl -X PUT "https://example.rasa.com/api/projects/default/models/my_model/tags/production"\n')),Object(i.b)("div",{className:"admonition admonition-caution alert alert--warning"},Object(i.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-heading"}),Object(i.b)("h5",{parentName:"div"},Object(i.b)("span",Object(a.a)({parentName:"h5"},{className:"admonition-icon"}),Object(i.b)("svg",Object(a.a)({parentName:"span"},{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 16 16"}),Object(i.b)("path",Object(a.a)({parentName:"svg"},{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})))),"updates to action code")),Object(i.b)("div",Object(a.a)({parentName:"div"},{className:"admonition-content"}),Object(i.b)("p",{parentName:"div"},"If your update includes changes to both your model and your action\ncode, and these changes depend on each other in any way, you should ",Object(i.b)("strong",{parentName:"p"},"not"),"\nautomatically tag the model as ",Object(i.b)("inlineCode",{parentName:"p"},"production"),". You will first need to build and\ndeploy your updated action server, so that the new model won't e.g. call\nactions that don't exist in the pre-update action server."))),Object(i.b)("h3",{id:"deploying-your-action-server"},"Deploying Your Action Server"),Object(i.b)("p",null,"You can automate\n",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"/docs/rasa/2.x/how-to-deploy#building-an-action-server-image"}),"building and uploading a new image for your action server"),"\nto an image repository for each\nupdate to your action code. As noted above, be careful with\nautomatically deploying a new image tag to production if the action server\nwould be incompatible with the current production model."),Object(i.b)("h2",{id:"example-cicd-pipelines"},"Example CI/CD pipelines"),Object(i.b)("p",null,"As examples, see the CI/CD pipelines for\n",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/RasaHQ/rasa-demo/blob/main/.github/workflows/continuous_integration.yml"}),"Sara"),",\nthe Rasa assistant that you can talk to in the Rasa Docs, and\n",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/RasaHQ/carbon-bot/blob/master/.github/workflows/model_ci.yml"}),"Carbon Bot"),".\nBoth use ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/features/actions"}),"Github Actions")," as a CI/CD tool."),Object(i.b)("p",null,"These examples are just two of many possibilities. If you have a CI/CD setup you like, please\nshare it with the Rasa community on the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://forum.rasa.com"}),"forum"),"."))}p.isMDXComponent=!0},1629:function(e,t,n){"use strict";n.d(t,"a",(function(){return p})),n.d(t,"b",(function(){return m}));var a=n(0),o=n.n(a);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,a,o=function(e,t){if(null==e)return{};var n,a,o={},i=Object.keys(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=o.a.createContext({}),l=function(e){var t=o.a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=l(e.components);return o.a.createElement(u.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.a.createElement(o.a.Fragment,{},t)}},b=o.a.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,r=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=l(n),b=a,m=p["".concat(r,".").concat(b)]||p[b]||d[b]||i;return n?o.a.createElement(m,s(s({ref:t},u),{},{components:n})):o.a.createElement(m,s({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,r=new Array(i);r[0]=b;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s.mdxType="string"==typeof e?e:a,r[1]=s;for(var u=2;u<i;u++)r[u]=n[u];return o.a.createElement.apply(null,r)}return o.a.createElement.apply(null,n)}b.displayName="MDXCreateElement"},1631:function(e,t,n){"use strict";var a=n(0),o=n(19);t.a=function(){var e=Object(a.useContext)(o.a);if(null===e)throw new Error("Docusaurus context not provided");return e}},1632:function(e,t,n){"use strict";n.d(t,"b",(function(){return i})),n.d(t,"a",(function(){return r}));var a=n(1631),o=n(1633);function i(){var e=Object(a.a)().siteConfig,t=(e=void 0===e?{}:e).baseUrl,n=void 0===t?"/":t,i=e.url;return{withBaseUrl:function(e,t){return function(e,t,n,a){var i=void 0===a?{}:a,r=i.forcePrependBaseUrl,s=void 0!==r&&r,c=i.absolute,u=void 0!==c&&c;if(!n)return n;if(n.startsWith("#"))return n;if(Object(o.b)(n))return n;if(s)return t+n;var l=!n.startsWith(t)?t+n.replace(/^\//,""):n;return u?e+l:l}(i,n,e,t)}}}function r(e,t){return void 0===t&&(t={}),(0,i().withBaseUrl)(e,t)}},1633:function(e,t,n){"use strict";function a(e){return!0===/^(\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!a(e)}n.d(t,"b",(function(){return a})),n.d(t,"a",(function(){return o}))}}]);