Hey guys,
We migrated over to Bitbucket Cloud and we are trying to replicate some functionality after losing the plugin Control-Freaks.
We decided to try and use the Forge App to replicate the on-merge check for a pull request. I have a pull request in and when i try to merge it, Forge will run the merge check but it ultimately fails.
I keep getting a “No pull request data in payload” failure error. From forge logs its:
INFO 2024-02-11T01:03:29.796Z 7274eda3-430b-4cef-9d53-954dd70eee3b Received payload: null
INFO 2024-02-11T01:03:29.797Z 7274eda3-430b-4cef-9d53-954dd70eee3b Received context: {
“cloudId”: “a995146f-5d43-4368-2113-4664eaedbb95”,
“moduleKey”: “control-freak-merge-check”
}
ERROR 2024-02-11T01:03:29.797Z 7274eda3-430b-4cef-9d53-954dd70eee3b No pull request data in payload
Here is my manifest.yml:
permissions:
scopes:
- ‘read:repository:bitbucket’
- ‘read:pullrequest:bitbucket’
- ‘read:workspace:bitbucket’
- ‘write:pullrequest:bitbucket’
- ‘write:repository:bitbucket’
modules:
bitbucket:mergeCheck:
- key: control-freak-merge-check
function: checkCommitMessages
name: Control-Freak Merge Check
description: Ensures all commits contain a JIRA issue key
triggers:
- on-merge # This trigger will invoke the check when a merge is attempted
function:
- key: checkCommitMessages
handler: index.checkCommitMessages
***below is the app:
id: ari … … … …
and here is my index.js:
const api = require(‘@forge/api’).default;
const { route } = require(‘@forge/api’);
exports.checkCommitMessages = async ({ payload, context }) => {
// Enhanced logging for debugging
console.log(‘Received payload:’, JSON.stringify(payload, null, 2));
console.log(‘Received context:’, JSON.stringify(context, null, 2));
// Check if the payload contains necessary data
if (!payload || !payload.pullrequest) {
console.error('No pull request data in payload');
return { success: false, message: 'No pull request data in payload' };
}
// Extract necessary IDs from the payload
const workspaceId = payload.workspace.uuid.replace(/[{}]/g, '');
const repositoryId = payload.repository.uuid.replace(/[{}]/g, '');
const pullRequestId = payload.pullrequest.id;
try {
// Fetch commits for the pull request
const commitsResponse = await requestBitbucket(
route`/2.0/repositories/${workspaceId}/${repositoryId}/pullrequests/${pullRequestId}/commits`
);
if (!commitsResponse.ok) {
throw new Error(`Failed to fetch commits: ${commitsResponse.status} ${commitsResponse.statusText}`);
}
const commits = await commitsResponse.json();
// Regex pattern for JIRA ticket validation
const jiraTicketRegex = /^(Revert ")?([A-Z][A-Z_0-9]+-[0-9]+)[:, ]?.*$/;
// Check each commit message
for (const commit of commits.values) {
// Skip merge commits
if (commit.parents && commit.parents.length > 1) continue;
// Validate commit message
if (!jiraTicketRegex.test(commit.message)) {
return {
success: false,
message: `Commit ${commit.hash} does not reference a JIRA ticket correctly.`
};
}
}
// All commit messages passed the check
return { success: true, message: "All commit messages are correctly formatted." };
} catch (error) {
console.error('Error occurred:', error);
return { success: false, message: `Error occurred while processing: ${error.message}` };
}
};
Could you see what the issue is or why I keep getting that error?
Hi @AshotKagramaniants,
At first glance, while checking your function checkCommitMessages
, it seems like you are trying to do some destructuring assignments with the function parameters by doing ({ payload, context })
. However, payload
is technically not an existing payload parameter based on the documentation.
Can you try using event
instead of payload
?
// ({ payload, context }) => { ...
(event, context) => { ...
Also, based on the generated Forge template, the function handler need not be async
.
Do try this out and let us know how it goes.
Cheers,
Ian
1 Like
Yes that seems to have did it.
I made the adjustment. Index.js looks like this now:
> const api = require('@forge/api');
>
> exports.checkCommitMessages = async (event, context) => {
> // Log the entire event and context for debugging
> console.log('Received event:', JSON.stringify(event, null, 2));
> console.log('Received context:', JSON.stringify(context, null, 2));
>
> // Validate the event object
> if (!event || !event.workspace || !event.repository || !event.pullrequest) {
> console.error('Invalid event data:', event);
> return { success: false, message: 'Invalid event data received' };
> }
>
> // Extract necessary IDs from the event
> const workspaceId = event.workspace.uuid;
> const repositoryId = event.repository.uuid;
> const pullRequestId = event.pullrequest.id;
>
> try {
> // Fetch commits for the pull request
> const commitsResponse = await api
> .asApp()
> .requestBitbucket(api.route`/2.0/repositories/${workspaceId}/${repositoryId}/pullrequests/${pullRequestId}/commits`);
>
> if (!commitsResponse.ok) {
> throw new Error(`Failed to fetch commits: ${commitsResponse.status} ${commitsResponse.statusText}`);
> }
>
> const commits = await commitsResponse.json();
>
> // Regex pattern for JIRA ticket validation
> const jiraTicketRegex = /^(Revert ")?([A-Z][A-Z_0-9]+-[0-9]+)[:, ]?.*$/;
>
> // Check each commit message
> for (const commit of commits.values) {
> if (commit.parents && commit.parents.length > 1) continue;
>
> if (!jiraTicketRegex.test(commit.message)) {
> return { success: false, message: `Commit ${commit.hash} does not reference a JIRA ticket correctly.` };
> }
> }
>
> // All commit messages passed the check
> return { success: true, message: "All commit messages are correctly formatted." };
> } catch (error) {
> console.error('Error occurred:', error);
> return { success: false, message: `Error occurred while processing: ${error.message}` };
> }
> };
However, the one issue I have noticed is that if I do a merge on a PR that has the wrong commit message format (no jira issue key), it will block it, which is good, but then if I do a git amend with the correct commit message and make sure the PR is updated with that, the merge check will still be blocked and fail. It seems to be related to how the Bitbucket API is handling the updated commits. When I force-push an amended commit to a pull request, it’s possible that the Bitbucket API’s response for the pull request’s commits is not immediately reflecting these changes. I think it leads to the Forge app checking against an outdated commit list…
That’s great, thanks for the confirmation (this solves the original issue).
As for the new issue that you raised, if the commit amend was successful, then it seems like a bug to me (although I have not replicated this yet). For potential bugs, I recommend that you raise it in the Developer and Marketplace Support portal for further investigation.
To isolate if it is indeed a timing issue, calling the REST API again after some time should result in an updated commit list.
Cheers,
Ian
1 Like