From fe6c8a6ef6a17fc2e18b8d8b78bf25b196c8f7e2 Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Mon, 12 Feb 2024 16:02:51 +1100 Subject: [PATCH] chore: update docs regarding dangerous contract modification --- website/docs/docs/on-premises/rename-me.md | 50 -------- ...sabling-dangerous-contract-modification.md | 120 ++++++++++++++++++ website/sidebars.js | 2 +- 3 files changed, 121 insertions(+), 51 deletions(-) delete mode 100644 website/docs/docs/on-premises/rename-me.md create mode 100644 website/docs/docs/troubleshooting/disabling-dangerous-contract-modification.md diff --git a/website/docs/docs/on-premises/rename-me.md b/website/docs/docs/on-premises/rename-me.md deleted file mode 100644 index 2cfcd557..00000000 --- a/website/docs/docs/on-premises/rename-me.md +++ /dev/null @@ -1,50 +0,0 @@ -# Disabling dangerous contract modification - -Please check the start up logs of the PactFlow application to determine the value for the configuration property `allow_dangerous_contract_modification`. The logs will look like this (depending on your log format): - -``` -01:18:30 I -- allow_dangerous_contract_modification=false source=... -``` - -If the value is `true`, then it means that the contract for a particular application version can be modified by a subsequent build. Contract modification can happen when a matcher has been used without an example value and a random value is supplied by the Pact library, or when there is other random data in the contract, or when an application version number is being used that does not have a one-to-one mapping with a git commit (eg. the semantic version is being used for the application version number and multiple contract versions are being published with the same version number). - -Allowing contract modification means that the results of the can-i-deploy command cannot be relied on due to race conditions. New installations of PactFlow should disable dangerous contract modification from the start. Existing installations of PactFlow are recommended to disable contract modification after analysis the current situation. - -If the contract modification is being relied on by existing CI/CD pipelines, disabling the modification will cause builds to fail, as any attempt to modify an existing contract will be rejected, causing the pact publication task to fail. - -For existing installations of PactFlow, you will need to determine whether or not contracts are currently being modified. To do this, login to PactFlow, and click on the API browser button in the top right of the screen. In the Explorer text box, append the path `/metrics` to the URL, and click Go. In the Properties section, identify the `pactRevisionsPerConsumerVersion` object. If the `distribution` object has only property with a key `1`, then you may safely disable contract modification without impacting any CI/CD pipelines. - -``` -# Disabling contract modification will have no impact as contracts are not being modified -"pactRevisionsPerConsumerVersion": { - "distribution": { - "1": 916 - } - }, -``` - -If, however, there is a large distribution of revisions per consumer version, then one or more of your application pipelines is modifying contracts. - -``` -# Disabling contract modification will likely cause builds to fail. One application in particular is likely to be affected -# as can be seen by the one application version which has 78 revisions. -"pactRevisionsPerConsumerVersion": { - "distribution": { - "1": 1039, - "2": 58 - "3": 356, - "6": 25, - ... - "78": 1 - } - }, -``` - -To ensure a pipeline is publishing contracts in the correct way, follow these guidelines: - -* Ensure each contract is published with a deterministic version number that relates to or contains the git sha, as per https://docs.pact.io/getting_started/versioning_in_the_pact_broker -* If the recommended approach to version numbers is being used, then it is likely that random data is being used in a pact. You can identify what has changed between pacts by following [this documentation](https://docs.pactflow.io/docs/how_to#see-what-has-changed-in-a-pact). Random data in a pact is often cause by using matcher without providing an example value (in which case, the Pact library provides a random example value). Ensure all matchers have an example value provided. Otherwise, the random data might be being included directly in the test by using test data generation tools. - -Once all the recommendations have been implemented, disable dangerous contract modification by setting the following environment variable. - -`PACTFLOW_ALLOW_DANGEROUS_CONTRACT_MODIFICATION=false` diff --git a/website/docs/docs/troubleshooting/disabling-dangerous-contract-modification.md b/website/docs/docs/troubleshooting/disabling-dangerous-contract-modification.md new file mode 100644 index 00000000..71be2c63 --- /dev/null +++ b/website/docs/docs/troubleshooting/disabling-dangerous-contract-modification.md @@ -0,0 +1,120 @@ +# Disabling dangerous contract modification + +## Background + +When a contract is published, it is associated with the application version that generated the contract. + +When the Pact Broker (the OSS project on which PactFlow is based) was first created, the contract content for an existing application version was allowed to be modified. When the `can-i-deploy` feature was released however, it became apparent that allowing modification of a contract for a particular consumer version was causing `can-i-deploy` to be unreliable. The result would depend on which branch had last published a contract. + +To prevent this scenario without breaking pipelines that depended on contract modification, the PactFlow configuration setting `allow_dangerous_contract_modification` was introduced. All new SaaS accounts and new on-premises installations from August 2021 were configured to disallow contract modification for a given application version. + +Contract modification is still allowed for accounts and installations created before August 2021, and this can cause problems when the versioning best practice guidelines are not followed. We strongly recommend that contract modification is disabled for all SaaS accounts and on-premises installations. + +You may choose to disable contract modification and fix affected pipelines afterwards, or you may wish to identify which pipelines will be affected by the change, and fix them before making the change. + +Please follow these instructions below to identify and prevent issues. + +## How to identify if dangerous contract modifications are occurring + +### Using the metrics endpoint (SaaS and On-Premesis) + +* For On-Premises installations, ensure you have version 1.29.0 or later. +* Log in to your PactFlow account. +* Click on the API Browser button in the top right. +* In the `Explorer bar` append `/metrics` to the base URL, and click `Go!` +* In the `Properties` section, locate the object for the `pactRevisionsPerConsumerVersion` key. +* If the `distribution` object has only one key, and that key is "1", then no contracts have been modified. + ``` + "pactRevisionsPerConsumerVersion": { + "distribution": { + "1": 916 + } + }, + ``` +* If there are multiple keys inside the `distribution` object, then contract modification is occurring. + ``` + "pactRevisionsPerConsumerVersion": { + "distribution": { + "1": 1039, + "2": 58 + "3": 356, + "6": 25, + ... + "78": 1 + } + }, + ``` + +### Using the output of the contract publication command (SaaS and On-Premesis) + +When modifying a contract for an existing application version, the following text would be shown in the terminal output for a consumer called "Example Consumer" and a provider called "Example Provider": + +``` +Updated Example Consumer version 1.2.26 with branch master +Pact with changed content published over existing content for Example Consumer version 1.2.26 and provider Example Provider. This is not recommended in normal circumstances and may indicate that you have not configured your Pact pipeline correctly. For more information see https://docs.pact.io/go/versioning +``` + +If contract modification is disabled, the following error would be shown: + +``` +Cannot change the content of the pact for Example Consumer version 1.2.26 and provider Example Provider, as race conditions will cause unreliable results for can-i-deploy. Each pact must be published with a unique consumer version number. Some Pact libraries generate random data when a concrete value for a type matcher is not specified, and this can cause the contract to mutate - ensure you have given example values for all type matchers. For more information see https://docs.pact.io/go/versioning + { + "interactions": [ + { +- "description": "a request to list TODOs" ++ "description": "a request to list TODOs 2" + } + ] + } +``` + +### Checking the logs (On-Premesis only) + +Check the start up logs of the PactFlow application to determine the value for the configuration property `allow_dangerous_contract_modification`. The logs will look like this (depending on your log format): + +``` +01:18:30 I -- allow_dangerous_contract_modification=false source=... +``` + +If the value is `false`, then no further action is required. + +## How to identify which applications have contracts which are being modified + +### SaaS + +Please open a [support case](https://support.smartbear.com/pactflow/message) and request the Customer Care team to provide a list of applications with modified contracts. + +### On-premesis + +Run the following SQL query against the Postgres database: + +```sql +select distinct c.name as consumer_name +from pact_publications pp +join (select consumer_version_id + from pact_publications + group by consumer_version_id + having count(*) > 1 ) as mpp + on mpp.consumer_version_id = pp.consumer_version_id +join pacticipants c + on pp.consumer_id = c.id +order by 1 +``` + +## How to avoid contract modification + +To ensure a pipeline is publishing contracts in the correct way, follow these guidelines: + +* Ensure each contract is published with a deterministic version number that *is* or *contains* the git sha, as per https://docs.pact.io/go/versioning +* If the recommended approach to version numbers is already being used, then it is likely that random data is being used in a pact. You can identify what has changed between pacts by following [this documentation](https://docs.pactflow.io/docs/how_to#see-what-has-changed-in-a-pact). Random data in a pact is often cause by using matcher without providing an example value (in which case, the Pact library provides a random example value). Ensure all matchers have an example value provided. Otherwise, the random data might be being included directly in the test by using test data generation tools. + +## Disabling dangerous contract modification + +### SaaS + +Please open a [support case](https://support.smartbear.com/pactflow/message) and specify that you would like the Customer Care team to disable dangerous contract modification for your account. + + +## On-premesis + +Set the environment variable `PACTFLOW_ALLOW_DANGEROUS_CONTRACT_MODIFICATION=false` and restart the server. diff --git a/website/sidebars.js b/website/sidebars.js index 0567f1d9..e3e3f5a7 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -110,7 +110,7 @@ module.exports = { { type: 'category', label: 'Troubleshooting', - items: ['docs/login-help', `docs/authorization-help`, 'docs/webhooks-help', 'docs/powershell-guide'] + items: ['docs/login-help', `docs/authorization-help`, 'docs/webhooks-help', 'docs/powershell-guide', 'docs/troubleshooting/disabling-dangerous-contract-modification'] }, { type: 'link',