pact-js icon indicating copy to clipboard operation
pact-js copied to clipboard

publish with multiple Consumers appends Tags to last Consumer's pacts only

Open FilipSwiatczak opened this issue 5 years ago • 10 comments

Software versions

  • OS: Windows 10 Pro, v1803, build: 17134.590
  • Consumer Pact library: "@pact-foundation/pact": "^8.0.5",
  • Node Version: 8.12.0
  • DiUS pact broker docker: 2.29.0-1

Expected behaviour

When publishing an array of Pacts given set of tags is expected to be appended to all pact files

Actual behaviour

Only last item in the Pacts array gets the Tags. Result? Without tags attached, running tagged test against provider is not possible.

Steps to reproduce

Here is my publish.js file. Please note the readdirSync which populates array from local pacts dir with absolute paths, since you don't support wildcards (desirable improvement). In log snippet in log files you can see the three pact files expected to be appended with "prod" and "test" tags.

publish.js:

const pact = require("@pact-foundation/pact-node")
const path = require("path")
const data = require("../data/pactConfig.json")
const fs = require("fs")
const pactPath = path.join(__dirname, '../pacts');
const pacts = [];
fs.readdirSync(pactPath).forEach(file => {
  pacts.push(path.join(pactPath, file));
});
console.log(pacts);
const opts = Object.assign(data, {
  pactFilesOrDirs: pacts,
  tags: ["prod", "test"],
  consumerVersion:
    "1.0." +
    (process.env.TRAVIS_BUILD_NUMBER
      ? process.env.TRAVIS_BUILD_NUMBER
      : Math.floor(new Date() / 1000)),
});

pact
  .publishPacts(opts)
  .then(() => {
    console.log("Pact contract publishing complete!")
    console.log("")
    console.log("Head over to " + data.pactBrokerUrl + " and login with")
    console.log("=> Username: " + data.pactBrokerUsername)
    console.log("=> Password: " + data.pactBrokerPassword)
    console.log("to see your published contracts.")
  })
  .catch(e => {
    console.log("Pact contract publishing failed: ", e)
  })

Relevant log files

Please note that only "Half consumer" is tagged, "Double" and "Greeting" are missed. There is a workaround of running this several times for each file but this is so basic I believe it should work out of the box, unless I'm missing something obvious.

> node utility/publish.js

[ 'C:\\p\\pacts\\double_consumer-multi_provider.json',
  'C:\\p\\pacts\\greeting_consumer-multi_provider.json',
  'C:\\p\\pacts\\half_consumer-multi_provider.json' ]
[2019-03-29T10:49:21.860Z]  INFO: [email protected]/13884 on UKMANLT-0007136: Publishing Pacts to Broker
[2019-03-29T10:49:21.863Z]  INFO: [email protected]/13884 on UKMANLT-0007136: Publishing pacts to broker at: http://XXXXXX:
8008/
[2019-03-29T10:49:21.872Z]  INFO: [email protected]/13884 on UKMANLT-0007136: Created 'standalone\win32-1.63.0\bin\pact-broker.bat
publish 'C:\p\pacts\half_consumer-multi_provider.json' 'C:\p\pacts\greeting_consumer-multi_provider.json' 'C:\p\pacts\double_consu
mer-multi_provider.json' --broker-base-url 'http://XXXXXXX:8008/' --broker-username 'pactbroker' --broker-password 'Passwor
d10' --tag 'prod' --tag 'test' --consumer-app-version '1.0.1553856561'' process with PID: 10040
[2019-03-29T10:49:23.915Z]  INFO: [email protected]/13884 on UKMANLT-0007136:
    
    Tagging version 1.0.1553856561 of Half consumer as "prod"
    Tagging version 1.0.1553856561 of Half consumer as "test"
    Publishing Half consumer/Multi Provider pact to pact broker at http://XXXXXX:8008/
    The latest version of this pact can be accessed at the following URL (use this to configure the provider verification):
    http://XXXXXX:8008/pacts/provider/Multi%20Provider/consumer/Half%20consumer/latest
    Publishing Greeting consumer/Multi Provider pact to pact broker at http://XXXXXX:8008/
    The latest version of this pact can be accessed at the following URL (use this to configure the provider verification):
    http://XXXXXX:8008/pacts/provider/Multi%20Provider/consumer/Greeting%20consumer/latest
    Publishing Double consumer/Multi Provider pact to pact broker at http://XXXXXX:8008/
    The latest version of this pact can be accessed at the following URL (use this to configure the provider verification):
    http://XXXXX:8008/pacts/provider/Multi%20Provider/consumer/Double%20consumer/latest


Pact contract publishing complete!

Head over to http://XXXXX:8008/ and login with
=> Username: pactbroker
=> Password: Password10
to see your published contracts.

Debug log file is perfectly clean, so a non-factor: mockserver-integration.log

FilipSwiatczak avatar Mar 29 '19 11:03 FilipSwiatczak

Hi mate, not a member of the pact-js team, but have been looking at this area with the work I am doing

Just moving away from using curl requests to the pact-js implementation for publishing pacts.

I have just tested being able to add multiple tags, against multiple consumers ( 1 consumers 3 provider). I see in your example, you have multiple consumers but a single provider.


let publisher = require("@pact-foundation/pact-node")
let path = require("path")

revision = require('child_process')
  .execSync('git rev-parse --short HEAD')
  .toString().trim()

branch = require('child_process')
  .execSync("git rev-parse --abbrev-ref HEAD")
  .toString().trim()

consumer_version=process.env.CIRCLE_BUILD_NUM + '-' + revision

let opts = {
  pactFilesOrDirs: [path.resolve(process.cwd(), "src/pact/pacts")],
  pactBroker: process.env.PACT_BROKER_URL,
  pactBrokerUsername: process.env.PACT_BROKER_BASIC_AUTH_USERNAME,
  pactBrokerPassword: process.env.PACT_BROKER_BASIC_AUTH_PASSWORD,
  consumerVersion: consumer_version,
  tags: [branch,"test"]
}

publisher.publishPacts(opts).then(() => done())

Here is a screenshot of the matrix entry for 1 consumer-provider pair, but all three 3 have them.

Screenshot 2019-04-01 at 13 08 02

YOU54F avatar Apr 01 '19 12:04 YOU54F

Hi @YOU54F, thank you for the pointer. I have double checked with a single consumer having a pact against 3 different providers and it works correctly, with the publishing log looking very much the same

Tagging version 1.0.1554390404 of Tri consumer as "prod"
    Tagging version 1.0.1554390404 of Tri consumer as "test"

and all three pacts updated with correct tags. So while 1 C => 3 P succeeds, 3 C => 1 P fails to tag all pacts

It appears tagging only one Consumer is supported per publish action. @mefellows could you please confirm if this is an issue or design decision? Thank you

With multiple Consumers in uploaded pacts only the last Consumer is updated, as per my earlier observation. In my use-case I would:

  1. call all the various Consumer mocha tests
  2. publish all Pacts in one call
  3. call all the various Provider mocha tests

Thanks again

FilipSwiatczak avatar Apr 04 '19 15:04 FilipSwiatczak

No thats certainly not intended. And sounds like a bug

mefellows avatar Apr 04 '19 19:04 mefellows

Apologies, this has very much slipped any attention. I've just confirmed that behaviour locally myself.

It's a bit strange having multiple consumers publish at once, but I don't see why we shouldn't supported. It's definitely confusing that the tag isn't applied, whilst the rest of the operation is successful.

@bethesque if you're happy, I'll move this over to the appropriate repo.

Please note the readdirSync which populates array from local pacts dir with absolute paths, since you don't support wildcards (desirable improvement).

@FilipSwiatczak actually this is not entirely true. It doesn't support wildcard, but you can just pass it a directory. The property is pactFilesOrDirs - it can just take a dir, and will publish whatever is in it. So you can simplify this way:

const pact = require("@pact-foundation/pact-node")
const path = require("path")
const data = require("../data/pactConfig.json")
const opts = Object.assign(data, {
  pactFilesOrDirs: path.join(__dirname, '../pacts'),
  tags: ["prod", "test"],
  consumerVersion:
    "1.0." +
    (process.env.TRAVIS_BUILD_NUMBER
      ? process.env.TRAVIS_BUILD_NUMBER
      : Math.floor(new Date() / 1000)),
});

pact
  .publishPacts(opts)
  .then(() => {
    console.log("Pact contract publishing complete!")
    console.log("")
    console.log("Head over to " + data.pactBrokerUrl + " and login with")
    console.log("=> Username: " + data.pactBrokerUsername)
    console.log("=> Password: " + data.pactBrokerPassword)
    console.log("to see your published contracts.")
  })
  .catch(e => {
    console.log("Pact contract publishing failed: ", e)
  })

mefellows avatar Jul 29 '20 12:07 mefellows

It's not a bug. The command was only ever intended to support publishing for one consumer.

If you need to publish for multiple consumers, create two different configs and call the publish twice.

bethesque avatar Jul 31 '20 00:07 bethesque

The reason the tag isn't applied to the other consumers is that the tagging is only called once, because it's not expecting there to be more than one consumer.

bethesque avatar Jul 31 '20 00:07 bethesque

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Aug 30 '20 23:08 stale[bot]

Closing as discussed above.

mefellows avatar Aug 30 '20 23:08 mefellows

Ah, that's where the issue was. I updated the publishing code to support multiple consumers (though I still think it's cray-cray!). I just couldn't find the original issue to update it.

https://github.com/pact-foundation/pact_broker-client/commit/573e97c9933743bb82634566b1796742370e5c43

bethesque avatar Aug 31 '20 23:08 bethesque

Cool, we may already support it then if we're on the latest standalone binary. Marking for review.

mefellows avatar Sep 01 '20 04:09 mefellows

What should we do with this issue @bethesque move to the client repo?

mefellows avatar Aug 18 '23 07:08 mefellows

If the pb client already supports it, then can't we close this?

bethesque avatar Aug 18 '23 08:08 bethesque

Oh I misunderstood your comment above. Closing!

mefellows avatar Aug 18 '23 10:08 mefellows