Tags
The Golden Rule for tagging is:
Tag with the branch name when you publish pacts or verification results, and tag with the environment name when you deploy.
To find out what this means, read below!
Tags are simple String values that that belong to "pacticipant" version (that is, application version) resources in the Pact Broker. They are typically used to provide metadata about a version - the most common use cases being to indicate the git branch of a version (eg. master
) or a stage (eg test
, prod
).
Pacticipant version tags can be used for multiple purposes.
- Tags can be used to enable you to test consumer and provider
head
andprod
versions against each other. This allows you to decouple the release cycles of your consumer and provider. Read more about this here. - Tags can be used to enable you to add new interactions without breaking all the builds. Read more about this here.
Note that the tag is actually placed on the pacticipant version
resource, not the pact
itself (conceptually, you are indicating that that particular version of the application is a "prod" version, or a "feature-x" version). The URL structures, however, then allow you to retrieve pacts by the tags on their associated versions.
As an example, to tag Foo
application version b5236e772
as the production version, do a PUT
to the resource /pacticipants/Foo/versions/b5236e772/tags/prod
. All the pacts and verifications associated with Foo
version b5236e772
are now considered to be the production pacts/verifications. The pact for provider Bar
and the latest production version of consumer Foo
can be retrieved from /pacts/provider/Bar/consumer/Foo/latest/prod
.
You may have noticed that the URL for a pacticipant version tag starts with /pacticipants
, not /consumers
or /providers
. That is because consumer
and provider
are roles that a pacticipant takes in a pact, not identities in themselves. An application may be both a consumer and a provider.
When you are using tags, you need to ensure that the version numbering scheme you use to identify a "version" cannot give you version that exists on more than one repository branch - don't hard code it. It should either be the git sha (or equivalent for your repository), or it should include the git sha as metadata if you are using semantic versioning eg. 1.2.456+405b31ec6
. See Versioning in the Pact Broker for more information.
"Latest" pacts
Please note that in the Pact Broker (unlike Docker) the term "latest" is not a tag name itself - it's a dynamic reference to the most recently created resource, like "HEAD" in git. The URL /pacts/provider/{provider}/consumer/{consumer}/latest
refers to pact for the most recently created pacticipant version. The same URL with /{tag}
appended refers to the pact for the most recently created pacticipant version that has the specified tag. Some Pact-JVM implementations require you to put the key word "latest" in the list of tags for verification when you want the overall latest pact. This is just an implementation choice of that particular client, and does not mean that there is or should be a tag called "latest". Please do not use the tag "latest" or you will get very confused when talking about the "latest latest pact", which would have a URL of /pacts/provider/Bar/consumer/Foo/latest/latest
!
When are tags created?
When publishing pacts
Your Pact consumer library will allow you to set the "consumer version tags" that will be set for the relevant consumer version when you publish your pacts. The recommended tag value to use is the name of your git branch, if applicable, or something like dev
, if not.
When publishing verification results
Your Pact provider library will allow you to set the "provider version tags" that will be set for the relevant provider version when you publish your verification results. The recommended tag value to use is the name of your git branch, if applicable, or something like dev
, if not.
After deploying to an environment
Note: this tag is required for the use of can-i-deploy, however, if you are just starting with Pact, you can skip it for now.
When you deploy an application that uses Pact to a given environment (eg test
, prod
) then you should tag the relevant pacticipant version with the name of the stage using the create version tag command from the Pact Broker client. This allows other applications to use can-i-deploy to ensure that they're compatible with the version you just deployed before they deploy their own version.
Remember the Golden Rule for tagging is:
Tag with the branch name when you publish pacts or verification results, and tag with the environment name when you deploy.
When are tags used?
When retrieving pacts to verify
Providers should be configured to retrieve pacts by tag name (usually the "latest pact" for a given tag eg. the latest master
and latest prod
pacts).
Before deploying to an environment
The can-i-deploy
tool queries the Pact Broker to determine if the version of the application you are about to deploy is compatible with the versions of the other applications that are already in that environment, and it uses tags to determine this. For example can-i-deploy --pacticipant Foo --version ad72df2 --to prod
will tell the Pact Broker to look up the latest version with the tag prod
for each of Foo's integrations partners, and see if there is a successfully verified pact between that version and version ad72df2 of Foo.
Retrieving pacts
/pacts/provider/PROVIDER/consumer/CONSUMER/latest/TAG
will return the pact associated with the latest pacticipant version that has the specified tag./pacts/provider/PROVIDER/consumer/CONSUMER/latest-untagged
will return the pact for the latest pacticipant version that doesn't have any tags./pacts/provider/PROVIDER/consumer/CONSUMER/latest
will return the pact for the latest pacticipant version, regardless of tags.
Creating tags
Most of the Pact libraries will provide configuration options to create tags automatically when publishing pacts or verification results.
If you need to create a tag manually, then you can use the Pact Broker Client CLI, or send a PUT
request to the tag resource path.
When publishing pacts
This is a Javascript example, assuming that the build is running on Travis CI. Please consult the documentation for your chosen Pact language for the relevant syntax for your codebase.
Once you have your Pact CI/CD implementation running properly, you would only publish your pacts and verification results from your CI, and not your local development machines. However, if you are in the experimentation stage and wish to publish from your local machine, you can set the version and tags from your local git repository like so:
When publishing verification results
Using tags
When verifying pacts
If you have reached the stage of Pact CI/CD maturity where you are tagging with the environment name and using can-i-deploy
, then you should verify the pact from each environment to ensure that can-i-deploy
returns a yes
result when promoting a version through the environments.
If you are just starting out with Pact, then we recommend you just start by verifying the master
pact (or whatever you have called the tag for your main line of development.)
When deploying
See the can-i-deploy documentation.
Deleting tags
At the moment, there is no CLI to delete a tag, but you can delete it via the API by sending a DELETE
request to the tag resource URL. eg curl -X DELETE https://broker/pacticipants/PACTICIPANT/versions/VERSION/tags/TAG
.
The most common reason for deleting tags is if you are rolling back to a previously deployed application version.
Adding new interactions
In summary: keep the CI running against a stable version of the pact, while simultaneously providing a new version for the provider team so they can update their code and provider states. Once both the stable and the new versions of the pact are green, the new version can be published as the stable version.
Remember: just because you're doing consumer driven contracts doesn't meant that the consumer team gets to tell the provider team what to do. Please remember that the best results will be achieved by a collaborative approach between the two teams. Communicate with your nice human words folks.
Ensuring backwards compatibility
If you want to ensure your provider is compatible with both the head version of your consumer, and the production version, you can use pact tagging to achieve this. To read more about this idea, check out this blog post on decoupling the release cycles of your services.
Step 1. Tag the production version of the pact
Use the create-version-tag command from the Pact Broker Client CLI.
Step 2. Configure the provider to verify the production pact
Add the production
tag to the list of tags to verify in your provider's verification configuration.
Handling rollbacks
When the Pact Broker is determining "the latest production
application version" or "the latest production
pact" the logic it uses is "find all the pacticipant versions that have the production
tag, and return the most recently created one", NOT "find the most recently created production
tag, and then return the associated pacticipant version".
This means that if you are rolling back to a previously deployed (and hence, previously tagged) application version, you need to remove the production
tag from the version you are undeploying. See the Deleting tags section.