From 9391218395e4beafe4a35b4a0592d7516fb6b2e3 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 01:23:25 +0530 Subject: [PATCH 01/17] Create merge_conflict_helpers.js Signed-off-by: cheese-cakee --- .github/scripts/merge_conflict_helpers.js | 92 +++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 .github/scripts/merge_conflict_helpers.js diff --git a/.github/scripts/merge_conflict_helpers.js b/.github/scripts/merge_conflict_helpers.js new file mode 100644 index 000000000..43b18bba3 --- /dev/null +++ b/.github/scripts/merge_conflict_helpers.js @@ -0,0 +1,92 @@ +// scripts/merge_conflict_helpers.js + +const BOT_SIGNATURE = ''; + +module.exports = async ({ github, context, core }) => { + const { owner, repo } = context.repo; + + // fetch PR with retry logic for unknown state + async function getPrWithRetry(prNumber) { + for (let i = 0; i < 10; i++) { + const { data: pr } = await github.rest.pulls.get({ + owner, repo, pull_number: prNumber + }); + + if (pr.mergeable_state !== 'unknown') return pr; + + console.log(`PR #${prNumber} state is 'unknown'. Retrying (${i+1}/10)...`); + await new Promise(r => setTimeout(r, 2000)); + } + const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber }); + return pr; + } + + // post comment + async function notifyUser(prNumber) { + const { data: comments } = await github.rest.issues.listComments({ + owner, repo, issue_number: prNumber, + }); + + if (comments.some(c => c.body.includes(BOT_SIGNATURE))) { + console.log(`Already commented on PR #${prNumber}. Skipping.`); + return; + } + + const body = `Hi, this is MergeConflictBot.\nYour pull request cannot be merged because it contains **merge conflicts**.\n\nPlease resolve these conflicts locally and push the changes.\n\nTo assist you, please read:\n- [Resolving Merge Conflicts](docs/sdk_developers/merge_conflicts.md)\n- [Rebasing Guide](docs/sdk_developers/rebasing.md)\n\nThank you for contributing!\nFrom the Hiero Python SDK Team\n\n${BOT_SIGNATURE}`; + + await github.rest.issues.createComment({ + owner, repo, issue_number: prNumber, body: body + }); + } + + //set commit status + async function setCommitStatus(sha, state, description) { + await github.rest.repos.createCommitStatus({ + owner, repo, sha: sha, state: state, + context: 'Merge Conflict Detector', + description: description, + target_url: `${process.env.GITHUB_SERVER_URL}/${owner}/${repo}/actions/runs/${context.runId}` + }); + } + + //main + let prsToCheck = []; + + //push to main + if (context.eventName === 'push') { + console.log("Triggered by Push to Main. Fetching all open PRs..."); + const { data: openPrs } = await github.rest.pulls.list({ + owner, repo, state: 'open', base: 'main' + }); + prsToCheck = openPrs.map(pr => pr.number); + } + //PR update + else { + console.log("Triggered by PR update."); + prsToCheck.push(context.payload.pull_request.number); + } + + let hasFailure = false; + + for (const prNumber of prsToCheck) { + console.log(`Checking PR #${prNumber}...`); + const pr = await getPrWithRetry(prNumber); + + if (pr.mergeable_state === 'dirty') { + console.log(`Conflict detected in PR #${prNumber}`); + await notifyUser(prNumber); + + if (context.eventName === 'push') { + await setCommitStatus(pr.head.sha, 'failure', 'Conflicts detected with main'); + } else { + core.setFailed(`Merge conflicts detected in PR #${prNumber}.`); + hasFailure = true; + } + } else { + console.log(`PR #${prNumber} is clean.`); + if (context.eventName === 'push') { + await setCommitStatus(pr.head.sha, 'success', 'No conflicts detected'); + } + } + } +}; From dedd8c10fd9700af9b9bde35ed18572ad4b70c3a Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 01:24:33 +0530 Subject: [PATCH 02/17] Update merge-conflict-bot.yml Signed-off-by: cheese-cakee --- .github/workflows/bot-merge-conflict.yml | 63 ++++++------------------ 1 file changed, 15 insertions(+), 48 deletions(-) diff --git a/.github/workflows/bot-merge-conflict.yml b/.github/workflows/bot-merge-conflict.yml index 3fead7a7d..704101405 100644 --- a/.github/workflows/bot-merge-conflict.yml +++ b/.github/workflows/bot-merge-conflict.yml @@ -1,71 +1,38 @@ -name: PythonBot - Check Merge Conflicts +name: Merge Conflict Bot on: pull_request_target: types: [opened, synchronize, reopened] + push: + branches: + - main permissions: contents: read pull-requests: write + issues: write + statuses: write concurrency: - group: "check-conflicts-${{ github.event.pull_request.number }}" + group: "check-conflicts-${{ github.event.pull_request.number || github.sha }}" cancel-in-progress: true jobs: check-conflicts: runs-on: ubuntu-latest - steps: - name: Harden the runner (Audit all outbound calls) uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 with: egress-policy: audit - - - name: Check for merge conflicts - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - PR_NUMBER=${{ github.event.pull_request.number }} - REPO="${{ github.repository }}" - - echo "Checking merge status for PR #$PR_NUMBER in repository $REPO..." - - for i in {1..10}; do - PR_JSON=$(gh api repos/$REPO/pulls/$PR_NUMBER) - MERGEABLE_STATE=$(echo "$PR_JSON" | jq -r '.mergeable_state') - - echo "Attempt $i: Current mergeable state: $MERGEABLE_STATE" - - if [ "$MERGEABLE_STATE" != "unknown" ]; then - break - fi - echo "State is 'unknown', waiting 2 seconds..." - sleep 2 - done + - name: Checkout code + uses: actions/checkout@v4 - if [ "$MERGEABLE_STATE" = "dirty" ]; then - COMMENT=$(cat </dev/null || \ - (gh pr comment $PR_NUMBER --repo $REPO --body "$COMMENT" && echo "Comment added to PR #$PR_NUMBER") - - exit 1 - else - echo "No merge conflicts detected (State: $MERGEABLE_STATE)." - fi + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd + with: + script: | + const script = require('./scripts/merge_conflict_helpers.js') + await script({github, context, core}) From 3cf5d830691c4e7fa55af16f80c19326122d0eaf Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 01:35:53 +0530 Subject: [PATCH 03/17] Update merge-conflict-bot.yml Signed-off-by: cheese-cakee --- .github/workflows/bot-merge-conflict.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/bot-merge-conflict.yml b/.github/workflows/bot-merge-conflict.yml index 704101405..bb7f37f33 100644 --- a/.github/workflows/bot-merge-conflict.yml +++ b/.github/workflows/bot-merge-conflict.yml @@ -6,6 +6,7 @@ on: push: branches: - main + - merge-conflict-bot-main-trigger permissions: contents: read From 29cfb80d006bd5bfc1d599b61a2a3fad3e98dea4 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 01:39:28 +0530 Subject: [PATCH 04/17] Update README.md Signed-off-by: cheese-cakee --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a2b9de148..8f2ad84c2 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![License](https://img.shields.io/badge/license-apache2-blue.svg)](LICENSE) A Python SDK for interacting with the Hedera Hashgraph platform. +This is the BASE branch version ## Quick Start From 467422fc820b41c90e8ba35e1ccaf17435e40cfa Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 02:04:02 +0530 Subject: [PATCH 05/17] Create clean.txt Signed-off-by: cheese-cakee --- clean.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 clean.txt diff --git a/clean.txt b/clean.txt new file mode 100644 index 000000000..53e5f1738 --- /dev/null +++ b/clean.txt @@ -0,0 +1 @@ +This is the MAIN branch version that causes a crash From 52c3c985d8faaa0b60dee7241f24ab467a392d25 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 02:15:26 +0530 Subject: [PATCH 06/17] Delete clean.txt Signed-off-by: cheese-cakee --- clean.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 clean.txt diff --git a/clean.txt b/clean.txt deleted file mode 100644 index 53e5f1738..000000000 --- a/clean.txt +++ /dev/null @@ -1 +0,0 @@ -This is the MAIN branch version that causes a crash From 43f5307f7eee84eedc11e083ff651bf55fe98a90 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 02:18:10 +0530 Subject: [PATCH 07/17] Update merge-conflict-bot.yml Signed-off-by: cheese-cakee --- .github/workflows/bot-merge-conflict.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/bot-merge-conflict.yml b/.github/workflows/bot-merge-conflict.yml index bb7f37f33..989e52e24 100644 --- a/.github/workflows/bot-merge-conflict.yml +++ b/.github/workflows/bot-merge-conflict.yml @@ -35,5 +35,10 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd with: script: | - const script = require('./scripts/merge_conflict_helpers.js') + const path = require('path') + // Fix: Use the workspace path to reliably find the script + const scriptPath = path.join(process.env.GITHUB_WORKSPACE, 'scripts/merge_conflict_helpers.js') + + console.log(`Loading script from: ${scriptPath}`) + const script = require(scriptPath) await script({github, context, core}) From fea7ab8e6705737fce1b6088dbe8c3a8e6894724 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 02:21:56 +0530 Subject: [PATCH 08/17] Create clean.txt Signed-off-by: cheese-cakee --- clean.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 clean.txt diff --git a/clean.txt b/clean.txt new file mode 100644 index 000000000..22725d52e --- /dev/null +++ b/clean.txt @@ -0,0 +1 @@ +will this break things hope it does, hope it does, oh i hope it does From de4ff204d4ed4cf93b5102fb7e2328359349adc1 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 15:04:01 +0530 Subject: [PATCH 09/17] Update merge-conflict-bot.yml Signed-off-by: cheese-cakee --- .github/workflows/bot-merge-conflict.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/bot-merge-conflict.yml b/.github/workflows/bot-merge-conflict.yml index 989e52e24..c6a8cba38 100644 --- a/.github/workflows/bot-merge-conflict.yml +++ b/.github/workflows/bot-merge-conflict.yml @@ -36,9 +36,7 @@ jobs: with: script: | const path = require('path') - // Fix: Use the workspace path to reliably find the script - const scriptPath = path.join(process.env.GITHUB_WORKSPACE, 'scripts/merge_conflict_helpers.js') - + const scriptPath = path.join(process.env.GITHUB_WORKSPACE, '.github/scripts/merge_conflict_helpers.js') console.log(`Loading script from: ${scriptPath}`) const script = require(scriptPath) await script({github, context, core}) From 28b9401e33e63cd03d102447f65eebaff140e94e Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 15:04:48 +0530 Subject: [PATCH 10/17] Delete clean.txt Signed-off-by: cheese-cakee --- clean.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 clean.txt diff --git a/clean.txt b/clean.txt deleted file mode 100644 index 22725d52e..000000000 --- a/clean.txt +++ /dev/null @@ -1 +0,0 @@ -will this break things hope it does, hope it does, oh i hope it does From 928dcea12d01c03b47d5823be968486d440837a9 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 15:07:44 +0530 Subject: [PATCH 11/17] Create clean.txt Signed-off-by: cheese-cakee --- clean.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 clean.txt diff --git a/clean.txt b/clean.txt new file mode 100644 index 000000000..02102dc9f --- /dev/null +++ b/clean.txt @@ -0,0 +1 @@ +hoping this will break stuff and stimulate the error i want to see From 6600cfaa4c544d98839ce6b42432c210f743a88e Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 15:40:38 +0530 Subject: [PATCH 12/17] Delete clean.txt Signed-off-by: cheese-cakee --- clean.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 clean.txt diff --git a/clean.txt b/clean.txt deleted file mode 100644 index 02102dc9f..000000000 --- a/clean.txt +++ /dev/null @@ -1 +0,0 @@ -hoping this will break stuff and stimulate the error i want to see From 474fb4c0c04cc0599db1ddca4308fb80388e3d90 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 15:41:34 +0530 Subject: [PATCH 13/17] cleanup after test Signed-off-by: cheese-cakee --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 8f2ad84c2..a2b9de148 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ [![License](https://img.shields.io/badge/license-apache2-blue.svg)](LICENSE) A Python SDK for interacting with the Hedera Hashgraph platform. -This is the BASE branch version ## Quick Start From 5129b8ad9de276d28647398f1c6b28fa40e7a1d9 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Tue, 9 Dec 2025 15:42:28 +0530 Subject: [PATCH 14/17] cleanup after test Signed-off-by: cheese-cakee --- .github/workflows/bot-merge-conflict.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/bot-merge-conflict.yml b/.github/workflows/bot-merge-conflict.yml index c6a8cba38..ad0cebd53 100644 --- a/.github/workflows/bot-merge-conflict.yml +++ b/.github/workflows/bot-merge-conflict.yml @@ -6,7 +6,6 @@ on: push: branches: - main - - merge-conflict-bot-main-trigger permissions: contents: read From 4c79bb10d519773ded1d775ed0c94cae97093ea6 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Thu, 11 Dec 2025 16:16:59 +0530 Subject: [PATCH 15/17] Update merge_conflict_helpers.js Signed-off-by: cheese-cakee From a796d8558460e097f14adb9d7b05776fd5a459dd Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Thu, 11 Dec 2025 19:12:45 +0530 Subject: [PATCH 16/17] Update merge-conflict-bot.yml Signed-off-by: cheese-cakee --- .github/workflows/bot-merge-conflict.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bot-merge-conflict.yml b/.github/workflows/bot-merge-conflict.yml index ad0cebd53..08d212d70 100644 --- a/.github/workflows/bot-merge-conflict.yml +++ b/.github/workflows/bot-merge-conflict.yml @@ -27,7 +27,7 @@ jobs: egress-policy: audit - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Check for merge conflicts From 55122e00e02b3ed43bd650bd5a51ca7a13dbed60 Mon Sep 17 00:00:00 2001 From: cheese-cakee Date: Thu, 11 Dec 2025 19:25:26 +0530 Subject: [PATCH 17/17] Update merge_conflict_helpers.js Signed-off-by: cheese-cakee --- .github/scripts/merge_conflict_helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/merge_conflict_helpers.js b/.github/scripts/merge_conflict_helpers.js index 43b18bba3..4a0485f88 100644 --- a/.github/scripts/merge_conflict_helpers.js +++ b/.github/scripts/merge_conflict_helpers.js @@ -1,6 +1,6 @@ // scripts/merge_conflict_helpers.js -const BOT_SIGNATURE = ''; +const BOT_SIGNATURE = '[merge-conflict bot]'; module.exports = async ({ github, context, core }) => { const { owner, repo } = context.repo;