Deploying and Releasing
The PactFlow needs to know which versions of each application are in each environment so it can determine whether a particular application version is safe to deploy.
To notify PactFlow that an application version has been deployed or released, the
pact-broker record-deployment and
pact-broker record-release commands are provided by the Pact Broker CLI.
"Deployed versions" and "released versions" are very similar, but are modelled slightly differently in PactFlow. The difference between
record-release is that:
record-deploymentautomatically marks the previously deployed version as undeployed, and is used for APIs and consumer applications that are deployed to known instances.
record-releasedoes NOT change the status of any previously released version, and is used for mobile applications and libraries that are made publicly available via an application store or repository.
"Deployed versions" and "released versions" are different resource types in PactFlow, and an application version may be both deployed and released. For example, a mobile phone application version may be recorded as deployed to a mobile device for automated testing in a test environment, and then recorded as released to an app store in a production environment.
Before you can record a deployment or a release, you must create the environment in PactFlow. To get you you started quickly, the
production environments are pre-populated.
To create a new environment, you can use the Environments page or use the following command from the Pact Broker CLI.
$ pact-broker create-environment --name NAME --display-name DISPLAY_NAME \
$ pact-broker create-environment --name uat --display-name UAT --no-production
$ pact-broker create-environment --name customer-1-production --display-name "Customer 1 Production" --production
Once the enviroment is created, ensure the team and application are configured correctly.
Handling conflicting views of what an "environment" is
For can-i-deploy to work correctly, every team and PactFlow must have the same shared understanding of what an "environment" is. Defining the bounds of an environment can be a tricky thing. A consumer team may have multiple deployed consumer applications that all share the same instance of the provider. From the consumer team's point of view, there are multiple environments, but from the provider team's point of view, there is one. For PactFlow to operate correctly, in this situation, you have two options:
- Create one environment resource in PactFlow, and use the
--application-instancefeature described below, and give each consumer application instance its own identifier. This would work well if there was only one application in each of the sub environments.
- If there are just too many applications in each of the sub environments to want to use the application instance approach, then you can create an environment resource for each sub environment, and when the shared application is deployed, call
record-deploymentonce for each sub environment. Before deploying the shared application, the
can-i-deploycommand would need to be called for each sub environment, and it should only deploy if all the results were positive.
pact-broker record-deployment command should be called at the very end of the deployment process, when there is no chance that the deployment might fail, and there are no more instances of the previous version running. When
record-deployment is called, the previously deployed version for that application/environment is automatically marked as no longer deployed, so there is no need to make a separate call for this.
record-deployment --pacticipant foo --version 6897aa95e --environment production
record-deployment --pacticipant foo --version 6897aa95e --environment production \
record-deployment --pacticipant foo --version 6897aa95e --environment test \
Setting the "application instance" attribute is only necessary when there are multiple instances of an application permanently deployed to the same environment at the same time (ie. not just temporarily during a rolling migration). An example of this might be when you are maintaining on-premises consumer applications for multiple customers that all share the same backend API instance, or when you have more than one mobile device running the same application in a test environment, all pointing to the same test API instance.
The "application instance" field is used to distinguish between deployed versions of an application within the same environment, and most importantly, to identify which previously deployed version has been replaced by the current deployment. PactFlow only allows one unique combination of pacticipant/environment/application instance to be considered the "currently deployed" one, and any call to record a deployment will cause the previously deployed version with the same pacticipant/environment/application instance to be automatically marked as undeployed (mimicking the real world process of "deploying over" a previous version). Note that a "null" (anonymous) application instance is considered to be a distinct value, so if you record a deployment with no application instance set, then record a deployment with an application instance set, you will have two different deployed versions in that environment.
The application instance should not be used to model blue/green or other forms of no-downtime deployments where there are two different application versions deployed temporarily at once during the deployment phase. See the next section for more information.
Why the application instance should not be used for long running deployments
When executing a rolling deployment (an approach for deploying with no downtime where there are multiple application instances that are deployed to sequentially), there will be a period of time when there are 2 different versions of an application in the environment at the same time. Even if there is a long running deployment, the
record-deployment should still be called at the end of the deployment, and there is no need to let the Broker know of newer application version until the deployment process is complete.
Why is this so?
Imagine an application, Consumer, which depends on application, Provider. Each of them has version 1 deployed to production. Consumer version 2 is waiting for a new feature to be supported in Provider version 2.
Provider deploys version 2 using a rolling deployment, during which time the response to Consumer's request might come from Provider version 1 or it might come from version 2. Technically, both versions of Provider could be said to be in production at this point in time. However, Consumer v2 cannot be deployed safely to production until Provider v1 is no longer in production. This is why there is no advantage to recording Provider v2 as being in production during the time period of the deployment. It's not just that Consumer v2 requires Provider v2 to be in production, it also requires Provider v1 to NOT be in production, and that can't be guaranteed until the deployment is complete.
If you need to rollback to a previous version, call
record-deployment again with the version that you are rolling back to.
Recording undeployments is not usually necessary, because the
record-deployment command automatically marks any application version that was deployed to the same application instance as undeployed.
If however, an application instance is being permanently removed from an environment, rather than just being deployed over, you can use
record-undeployment --pacticipant my-retired-service --environment test
record-undeployment --pacticipant foo --environment test \
pact-broker record-release command should be called once an application version has been successfully made available in a production environment (eg. via a Github release, made available on an app store, or released to a Maven repository etc.). Unlike recording a deployment, recording a release does not change the status of any previously released application versions, and there is no concept of a release "application instance".
record-release is generally only used for production environments.
record-release --pacticipant foo-mobile-app --version 6897aa95e --environment production
Recording support ended for a release
When a released application is deemed to be no longer supported, call
pact-broker record-support-ended. This will remove it from consideration when checking if an integrated application is safe to deploy.
record-support-ended --pacticipant foo-mobile-app --version 6897aa95e --environment production
Using deployed and released versions
The use for the deployed and released versions is when using can-i-deploy. This is the command that is used to check if the version you are about to deploy into an environment has a successful verification result with each of the application versions that is already in the environment.
pact-broker can-i-deploy --pacticipant Foo \
--version 617c76e8bf05e1a480aed86a0946357c042c533c \
Can I Deploy Results
When a new Pact or OAS contract is published some comparisons between the published Pact/OAS and the contracts of integrated applications will be automatically pre-generated. This is to speed up the response time of the
can-i-deploy command for application versions that are most critical to the user (those that are likely to be deployed). Other comparisons are generated as needed when viewing the matrix page in the Pactflow UI or via using the
can-i-deploy command with versions that do not yet have a comparison.
Currently comparisons are pre-generated in the following cases:
- Between the newly published pact or contract and the contracts belonging to the deployed versions of each the integrated applications.
- The main branch of each of the integrated applications
- Recently published feature branches for each of the integrated applications.
Note pre-generating the comparisons relies on the use of application branches and deployment environments to select which comparisons are likely to be needed.
When a comparison is missing at the time the
can-i-deploy command executes there will be an "unknown" result. This can happen when:
- The comparison takes longer to execute than the time between the contract publication and the call to can-i-deploy.
- Pre-generation of the comparison did not occur because tags where used for publishing the contract and recording deployment, rather than branches and environments. It is recommended to switch to using branches and environments to help streamline this process.
can-i-deploy returns results with an "unknown" comparison status it is recommended to enable polling for the command, so that your CI/CD pipeline will not be blocked. This causes the can-i-deploy check to wait a short time and then retry, allowing any long running Bi-Directional contract comparisons to be completed. The wait time and number of retries are customizable and can be set to appropriate durations based on the user's needs. The arguments to specify are
--retry-while-unknown TIMES and
pact-broker can-i-deploy --pacticipant Foo \
--version 617c76e8bf05e1a480aed86a0946357c042c533c \