PageSourceSearch

https://docs-pactflow-preview.netlify.app/assets/js/9f2a5c9f.cb7763c0.js

js docs-pactflow-preview.netlify.app collected 2026-10-03 10:41:50 UTC 10,578 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkpartners=self.webpackChunkpartners||[]).push([[22724],{15680:(e,t,n)=>{n.d(t,{xA:()=>c,yg:()=>g});var a=n(96540);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 o(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 p(e,t){if(null==e)return{};var n,a,i=function(e,t){if(null==e)return{};var n,a,i={},r=Object.keys(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=a.createContext({}),l=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(s.Provider,{value:t},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),d=l(n),u=i,g=d["".concat(s,".").concat(u)]||d[u]||h[u]||r;return n?a.createElement(g,o(o({ref:t},c),{},{components:n})):a.createElement(g,o({ref:t},c))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=u;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[d]="string"==typeof e?e:i,o[1]=p;for(var l=2;l<r;l++)o[l]=n[l];return a.createElement.apply(null,o)}return a.createElement.apply(null,n)}u.displayName="MDXCreateElement"},21613:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>p,toc:()=>l});var a=n(58168),i=(n(96540),n(15680));const r={id:"protecting-the-provider",title:"Protecting provider builds from changed pacts"},o=void 0,p={unversionedId:"docs/workshops/ci-cd-legacy/workshop/protecting-the-provider",id:"docs/workshops/ci-cd-legacy/workshop/protecting-the-provider",title:"Protecting provider builds from changed pacts",description:'Those familiar with automated testing frameworks have probably come across the term "pending tests". These are tests that have a particular flag on them that causes them (depending on the framework) to either be skipped, or if executed, to not fail the test suite.',source:"@site/docs/docs/workshops/ci-cd-legacy/workshop/03_protecting_the_provider.md",sourceDirName:"docs/workshops/ci-cd-legacy/workshop",slug:"/docs/workshops/ci-cd-legacy/workshop/protecting-the-provider",permalink:"/docs/workshops/ci-cd-legacy/workshop/protecting-the-provider",draft:!1,editUrl:"https://github.com/pactflow/docs.pactflow.io/edit/master/website/docs/docs/workshops/ci-cd-legacy/workshop/03_protecting_the_provider.md",tags:[],version:"current",lastUpdatedBy:"Yousaf Nabi",lastUpdatedAt:1674493712,formattedLastUpdatedAt:"Jan 23, 2023",sidebarPosition:3,frontMatter:{id:"protecting-the-provider",title:"Protecting provider builds from changed pacts"},sidebar:"university",previous:{title:"How to break everything",permalink:"/docs/workshops/ci-cd-legacy/workshop/how-to-break-everything"},next:{title:"How not to break everything",permalink:"/docs/workshops/ci-cd-legacy/workshop/how-not-to-break-everything"}},s={},l=[{value:"Enable &#39;pending pacts&#39; for the provider",id:"enable-pending-pacts-for-the-provider",level:2},{value:"Make a breaking change to the provider",id:"make-a-breaking-change-to-the-provider",level:2},{value:"Expected state by the end of this step",id:"expected-state-by-the-end-of-this-step",level:2},{value:"Conclusion",id:"conclusion",level:2}],c={toc:l},d="wrapper";
1function h(e){let{components:t,...n}=e;return(0,i.yg)(d,(0,a.A)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.yg)("p",null,'Those familiar with automated testing frameworks have probably come across the term "pending tests". These are tests that have a particular flag on them that causes them (depending on the framework) to either be skipped, or if executed, to not fail the test suite.'),(0,i.yg)("p",null,'When using Pact with PactFlow, we have a similar concept of a "pending pact". A pending pact is one which does not yet have a successful verification result published. Pending pacts can fail verification without causing the overall verification task (and hence, the overall provider build) to fail.'),(0,i.yg)("p",null,"Once a pact has a successful verification result published, it is now considered to be an accepted/supported contract, and any subsequent failure can only be as a result of the provider itself changing. Once a pact has left pending state, verification failures ",(0,i.yg)("em",{parentName:"p"},"will")," cause the provider build to fail."),(0,i.yg)("p",null,"Something important to note about the pending calculation is that ",(0,i.yg)("em",{parentName:"p"},"it is based on the branch for the provider version"),". For example, once a pact has a successful verification from a provider version with branch ",(0,i.yg)("inlineCode",{parentName:"p"},"master"),", it will cease to be pending for subsequent ",(0,i.yg)("inlineCode",{parentName:"p"},"master")," versions, but would still be pending for a ",(0,i.yg)("inlineCode",{parentName:"p"},"feat/x")," branch of the provider (until the first successful ",(0,i.yg)("inlineCode",{parentName:"p"},"feat/x")," verification was published, etc.)"),(0,i.yg)("p",null,"For further reading: ",(0,i.yg)("a",{parentName:"p",href:"https://docs.pact.io/pending"},"https://docs.pact.io/pending")),(0,i.yg)("h2",{id:"enable-pending-pacts-for-the-provider"},"Enable 'pending pacts' for the provider"),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"In ",(0,i.yg)("inlineCode",{parentName:"p"},"product/product.pact.test.js"),", set ",(0,i.yg)("inlineCode",{parentName:"p"},"enablePending: true")," in the options for the dynamically fetched pacts.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Run ",(0,i.yg)("inlineCode",{parentName:"p"},"GIT_BRANCH=master make test")," - note that this now passes \u2705"),(0,i.yg)("p",{parentName:"li"},"\ud83d\udc49 Whenever we run the verification step with the pending feature enabled, we have to make sure we've set the branch correctly (which we do in this codebase by providing the environment variable ",(0,i.yg)("inlineCode",{parentName:"p"},"GIT_BRANCH")," to ",(0,i.yg)("inlineCode",{parentName:"p"},"providerVersionBranch")," in our test ",(0,i.yg)("inlineCode",{parentName:"p"},"product/product.pact.test.js"),"), because the pending status for each pact depends on it.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Commit and push, and open up the build in Github Actions."),(0,i.yg)("p",{parentName:"li"},"\ud83d\udc49 The test output indicates that the ",(0,i.yg)("inlineCode",{parentName:"p"},"master")," pact is in pending mode, so even though its verification fails, the overall build still passes."),(0,i.yg)("p",{parentName:"li"},"\ud83d\udc49 The provider is still compatible with pact deployed to the ",(0,i.yg)("inlineCode",{parentName:"p"},"prod")," environment , so the deploy step is able to proceed without issue.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"In PactFlow, refresh the pact page."),(0,i.yg)("p",{parentName:"li"},"\ud83d\udc49 Even though the provider build is passing, the ",(0,i.yg)("inlineCode",{parentName:"p"},"master")," pact has a (correctly) failed verification result, which tells the consumer team that they cannot deploy the code associated with this pact yet."))),(0,i.yg)("h2",{id:"make-a-breaking-change-to-the-provider"},"Make a breaking change to the provider"),(0,i.yg)("p",null,"Let's see what happens if the provider makes a change that would break its contract with the production version of the consumer. The pact deployed to the ",(0,i.yg)("inlineCode",{parentName:"p"},"prod")," environment is not in pending mode, as it already has a successful verification result published. This means that a failure for the ",(0,i.yg)("inlineCode",{parentName:"p"},"prod")," pact verification ",(0,i.yg)("em",{parentName:"p"},"will")," fail the overall verification task."),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Make a change to the provider that would cause the production pact to fail."),(0,i.yg)("ul",{parentName:"li"},(0,i.yg)("li",{parentName:"ul"},"An easy way to do this is to open up ",(0,i.yg)("inlineCode",{parentName:"li"},"product/product.js")," and change ",(0,i.yg)("inlineCode",{parentName:"li"},"this.id")," to ",(0,i.yg)("inlineCode",{parentName:"li"},"this.uuid"),"."))),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Run ",(0,i.yg)("inlineCode",{parentName:"p"},"GIT_BRANCH=master make test")," - note that this now fails \u274c"),(0,i.yg)("p",{parentName:"li"},"A developer would typically run all the tests before pushing, so this change would most likely never even make it into the codebase. However, even if they did push this change, the build would fail and stop before it got to the deployment stage, ensuring that the production consumer could not be broken by an unintentional deployment of this version of the provider.")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Discard your changes."))),(0,i.yg)("h2",{id:"expected-state-by-the-end-of-this-step"},"Expected state by the end of this step"),(0,i.yg)("p",null,"A provider build that is passing and still deploying to production, with a failing ",(0,i.yg)("inlineCode",{parentName:"p"},"master")," pact in pending state."),(0,i.yg)("h2",{id:"conclusion"},"Conclusion"),(0,i.yg)("p",null,"Enabling the pending pacts feature for verifications stops changed pacts from breaking provider builds, allowing the provider to deploy to production if it is still compatible with the prod pact, while ensuring that the provider cannot make changes that break existing consumers."))}h.isMDXComponent=!0}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.