Hello everyone! I'm reaching out to seek some gui...
# pact-js
r
Hello everyone! I'm reaching out to seek some guidance on an issue I've encountered with the Pact Broker in relation to our contract tests. Here's what's happening: I've noticed that when running contract tests for my provider microservice, the branch responsible for executing the test isn't displayed in the Pact Broker as expected. Instead of showing the branch name, only the generated UUID is listed, as seen in the screenshot I've attached. Curiously, if I run a single test with Jest, the provider's branch is displayed correctly. However, when executing a full suite of tests, this doesn't seem to work. Could someone assist me in figuring out what might be causing this issue? Is there a parameter I might be missing or incorrectly specifying, or could this be a bug? I'm providing my "pact-provider-setup.ts" file below for reference:
Copy code
import { PactProviderModule, PactProviderOptions } from 'nestjs-pact';
import * as dotenv from 'dotenv';
import {
    generateRandomValue,
    getCurrentBranch,
    getGitDirectoryName
} from '../helper/utils';

export enum ConsumerName {
    KK_SHOPPINGCART_SERVICE = 'KK-SHOPPINGCART-SERVICE',
    KK_PURCHASE_SERVICE = 'KK-PURCHASE-SERVICE'
}

const DEFAULT_BRANCH = 'master';
const MASTER_WEBHOOK = 'master-webhook';

export const configurePactProvider = (consumer: ConsumerName) => {
    dotenv.config({ path: './.env.test' });

    const GET_PROVIDER_NAME = getGitDirectoryName();
    const GET_RANDOM_VALUE = generateRandomValue();

    const consumerWebhookBranch = process.env.CONSUMER_VERSION_TAGS;

    const [GET_CURRENT_BRANCH, GET_PROVIDER_BRANCH] = consumerWebhookBranch
        ? [consumerWebhookBranch, MASTER_WEBHOOK]
        : [getCurrentBranch(), getCurrentBranch()];

    if (!consumer?.length) {
        throw new Error(
            'Error: PACT_BROKER_BASE_URL environment variable is not set.'
        );
    }

    const options: PactProviderOptions = {
        pactBrokerUrl: String(process.env.PACT_BROKER_BASE_URL),
        provider: GET_PROVIDER_NAME,
        providerVersion: GET_RANDOM_VALUE,
        providerVersionBranch: GET_PROVIDER_BRANCH,
        providerVersionTags: [GET_PROVIDER_BRANCH],
        logLevel: 'error',
        consumerVersionSelectors: [
            {
                fallbackTag: DEFAULT_BRANCH,
                tag: GET_CURRENT_BRANCH,
                latest: true,
                consumer: consumer
            }
        ],
        publishVerificationResult: true
    };

    return PactProviderModule.register(options);
};
I'm currently using the following versions and dependencies: • Node: 16.14.0 • pact-foundation/pact: 12.1.0 • nestjs-pact: 2.3.1 • jest: 28.1.3 • @types/jest: 29.0.0 • ts-jest: 28.0.8 Any guidance or suggestions would be greatly appreciated!
Here is one of my contract test files:
Copy code
describe('Verification', () => {
    let verifierService: PactVerifierService;
    let app: INestApplication;

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            imports: [
                CacheModule.register(),
                configurePactProvider(ConsumerName.KK_PURCHASE_SERVICE)
            ],
            controllers: [OfferController],
            providers: [
                {
                    provide: OfferService,
                    useValue: {
                        readManyOffers: jest
                            .fn()
                            .mockResolvedValue([cartOfferDtoMock]),
                        lockStock: jest
                            .fn()
                            .mockResolvedValue([offerLockStockMock]),
                        unlockStock: jest.fn()
                    }
                }
            ]
        }).compile();

        verifierService = module.get(PactVerifierService);
        app = module.createNestApplication<NestFastifyApplication>(
            new FastifyAdapter()
        );
        app.useGlobalPipes(new BodyValidationPipe());
        await app.init();
    });

    afterEach(async () => {
        await app.close();
    });

    it('Shall validate the expectations', async () => {
        await verifierService.verify(app);
    });
});
y
just first look, why are you using random uuids for the application version? that will surely change every time you run the test, even if the provider codebase hasn’t changed
providerVersionBranch is the correct value to use but it might not be mapped through in nestjs-pact which isn’t particularly up to date. if you run with debug what do you see sent to the broker for the providers parameters ( branch / version / consumer version selectors )
r
Hello, good morning! So, regarding why I used the 'providerVersion', it's because sending it to the broker is mandatory
And I've also noticed that when I execute the tests (test suite), one of these tests always sends the current branch, but only for a single test, when executing all 8 tests together. And I've also noticed that if I access "The Matrix" part of these 8 microservices, the branch and tag appear as usual, but in the "dashboard/provider/KK-PRODUCT-SERVICE/consumer/KK-PURCHASE-SERVICE" section they don't appear, as shown in the previous screenshot.
y
I am aware providerVersion is mandatory, but it should only change, when your code changes, using a randomly generated number, isn’t going to give you consistent results at all. https://docs.pact.io/getting_started/versioning_in_the_pact_broker#rules
r
I've adjusted my code by creating the
getGitCommitSha()
function, and I passed this function's result to the "providerVersion" property, and everything started working properly. Now, the provider's branch is showing up. 🙌 @Yousaf Nabi (pactflow.io) Thank you so much for your help and quick response!!
🙌 1
y
Happy days! I assume you were getting a different random number for each test and you were only seeing the latest on the matrix (perhaps). I would hope that with our change, our provider version is now deterministic for each test, and will only change when your provider code changes (given that the codebase would publish pacts or verify pacts in CI, when publishing results, and be associated with a commit) versus running on your machine, where you may make a change but your codebase is dirty because the change isn’t committed.
r
I probably should apply the same logic to the command that publishes the pacts for the consumers. Therefore, I would replace this "uuidgen" in the command below with "git rev-parse HEAD," right?
"publish:contract": "pact-broker publish $(sed -n 's/^PACTS_PATH=//p' .env.test) --consumer-app-version=$(uuidgen) --tag-with-git-branch --broker-base-url=$(sed -n 's/^PACT_BROKER_BASE_URL=//p' .env.test)"
y
oh yeah 110% so, you won’t be able to trace that uuid back to the point in time it was generated from and it will change every time you publish a pact, even if you just re-run your ci build against the same commit on the same branch
did you get that info from a guide or docs somewhere for using a uuid/random number there? just wondering if we need to mop something up
r
No, the documentation is correct. I think I initially took the uuid/random approach when I was learning how to use the system, and for some reason (which I don’t recall now), it ended up requiring me to update the 'consumer-app-version' every time I published a pact, because it wouldn't allow me to publish saying that the same hash ('consumer-app-version') was already published. But with the way my command is set up now, everything is working fine after I added '--consumer-app-version=$(git rev-parse HEAD)'. It allows me to run the same command with the same hash ('consumer-app-version'), and everything is correct with the change here; I've already tested it.
🙌 1