From 5476b69388c84839d72526e2ebaaa8bed8fbdab4 Mon Sep 17 00:00:00 2001 From: Max Edwards Date: Wed, 3 Sep 2025 14:37:18 +0100 Subject: [PATCH 1/7] ci: added silent merge check --- .github/workflows/silent-merge-check.yml | 95 ++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 .github/workflows/silent-merge-check.yml diff --git a/.github/workflows/silent-merge-check.yml b/.github/workflows/silent-merge-check.yml new file mode 100644 index 000000000000..1dd3fa49a9e9 --- /dev/null +++ b/.github/workflows/silent-merge-check.yml @@ -0,0 +1,95 @@ +name: Periodic Silent Merge Check + +on: + schedule: + - cron: "0 0 * * 0" # Sunday 00:00 UTC + workflow_dispatch: + +jobs: + verify-prs: + runs-on: ubuntu-latest + permissions: + checks: write + pull-requests: read + contents: read + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake build-essential + + - name: List open PRs + id: prs + run: | + prs=$(gh pr list --state open --json number --jq '.[].number') + echo "prs=$prs" >> $GITHUB_ENV + + - name: Process PRs + run: | + for pr in $prs; do + echo "Checking PR #$pr" + + # Fetch PR metadata + pr_json=$(gh api repos/${GITHUB_REPOSITORY}/pulls/$pr) + draft=$(echo "$pr_json" | jq -r '.draft') + mergeable_state=$(echo "$pr_json" | jq -r '.mergeable_state') + head_sha=$(echo "$pr_json" | jq -r '.head.sha') + + if [ "$draft" = "true" ]; then + echo "PR #$pr is draft, skipping." + continue + fi + + if [ "$mergeable_state" = "dirty" ]; then + echo "PR #$pr has merge conflicts, reporting failed check." + gh api repos/${GITHUB_REPOSITORY}/check-runs \ + -X POST \ + -F "name=Conflict Check" \ + -F "head_sha=$head_sha" \ + -F "status=completed" \ + -F "conclusion=failure" \ + -F "output[title]=Merge conflicts detected" \ + -F "output[summary]=This PR cannot be merged due to conflicts." + continue + fi + + # --- Check existing check runs --- + failed_checks=$(gh api repos/${GITHUB_REPOSITORY}/commits/$head_sha/check-runs \ + --jq '.check_runs[] | select(.conclusion=="failure") | .name' || true) + + if [ -n "$failed_checks" ]; then + echo "PR #$pr already has failing check runs: $failed_checks. Skipping." + continue + fi + + # --- Run build/tests --- + git fetch origin pull/$pr/head:pr-$pr + git checkout pr-$pr + + mkdir -p build && cd build + cmake .. + if make -j$(nproc) && ctest --output-on-failure; then + conclusion=success + summary="CMake build and tests passed." + else + conclusion=failure + summary="CMake build or tests failed." + fi + + # --- Report result as a new check run --- + gh api repos/${GITHUB_REPOSITORY}/check-runs \ + -X POST \ + -F "name=CMake Build & Test" \ + -F "head_sha=$head_sha" \ + -F "status=completed" \ + -F "conclusion=$conclusion" \ + -F "output[title]=CMake Build & Test" \ + -F "output[summary]=$summary" + + done From 85b37cb936ebfdd863e7c01f44f4542cfae277e4 Mon Sep 17 00:00:00 2001 From: Max Edwards Date: Wed, 3 Sep 2025 16:17:27 +0100 Subject: [PATCH 2/7] try logging the gh tool in --- .github/workflows/silent-merge-check.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/silent-merge-check.yml b/.github/workflows/silent-merge-check.yml index 1dd3fa49a9e9..7cd5a9b30f21 100644 --- a/.github/workflows/silent-merge-check.yml +++ b/.github/workflows/silent-merge-check.yml @@ -24,6 +24,9 @@ jobs: sudo apt-get update sudo apt-get install -y cmake build-essential + - name: Set up GitHub CLI + run: gh auth login --with-token <<< "${{ secrets.GITHUB_TOKEN }}" + - name: List open PRs id: prs run: | From 14a41633051c4211af2f02b3316e89f40fc7b7fc Mon Sep 17 00:00:00 2001 From: Max Edwards Date: Thu, 4 Sep 2025 16:33:26 +0100 Subject: [PATCH 3/7] wip on silent merge check --- .github/workflows/silent-merge-check.yml | 105 ++++++++++++++++++++--- 1 file changed, 94 insertions(+), 11 deletions(-) diff --git a/.github/workflows/silent-merge-check.yml b/.github/workflows/silent-merge-check.yml index 7cd5a9b30f21..1307cb655bf4 100644 --- a/.github/workflows/silent-merge-check.yml +++ b/.github/workflows/silent-merge-check.yml @@ -1,4 +1,8 @@ -name: Periodic Silent Merge Check +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://opensource.org/license/mit. + +name: Silent Merge Periodic Check on: schedule: @@ -7,11 +11,15 @@ on: jobs: verify-prs: + name: 'Verify open PRs for silent merge conflicts' runs-on: ubuntu-latest permissions: checks: write pull-requests: read contents: read + env: + FILE_ENV: './ci/test/00_setup_env_native_previous_releases.sh' + DANGER_CI_ON_HOST_FOLDERS: 1 steps: - name: Checkout repo @@ -19,10 +27,17 @@ jobs: with: fetch-depth: 0 - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y cmake build-essential + - name: Configure environment + uses: ./.github/actions/configure-environment + + - name: Restore caches + id: restore-cache + uses: ./.github/actions/restore-caches + + - name: Configure Docker + uses: ./.github/actions/configure-docker + with: + use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }} - name: Set up GitHub CLI run: gh auth login --with-token <<< "${{ secrets.GITHUB_TOKEN }}" @@ -75,14 +90,17 @@ jobs: git fetch origin pull/$pr/head:pr-$pr git checkout pr-$pr - mkdir -p build && cd build - cmake .. - if make -j$(nproc) && ctest --output-on-failure; then - conclusion=success - summary="CMake build and tests passed." - else + ci_failed=false + ./ci/test_run_all.sh || { + echo "PR #$pr CI script failed." + ci_failed=true + } + if [ "$ci_failed" = true ]; then conclusion=failure summary="CMake build or tests failed." + else + conclusion=success + summary="CMake build and tests passed." fi # --- Report result as a new check run --- @@ -96,3 +114,68 @@ jobs: -F "output[summary]=$summary" done + + - name: Save caches + uses: ./.github/actions/save-caches + with: + depends-sources-cache-hit: ${{ steps.restore-cache.depends-sources-cache-hit }} + depends-built-cache-hit: ${{ steps.restore-cache.depends-built-cache-hit }} + + previous-releases: + name: 'Previous releases, depends DEBUG' + if: contains(github.event.label.name, 'PeriodicMergeCICheck') + needs: runners + runs-on: ${{ needs.runners.outputs.use-cirrus-runners == 'true' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' || 'ubuntu-24.04' }} + + env: + FILE_ENV: './ci/test/00_setup_env_native_previous_releases.sh' + DANGER_CI_ON_HOST_FOLDERS: 1 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure environment + uses: ./.github/actions/configure-environment + + - name: Restore caches + id: restore-cache + uses: ./.github/actions/restore-caches + + - name: Configure Docker + uses: ./.github/actions/configure-docker + with: + use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }} + + - name: CI script + run: ./ci/test_run_all.sh + + + lint: + name: 'Lint' + if: contains(github.event.label.name, 'PeriodicMergeCICheck') + needs: runners + runs-on: ${{ needs.runners.outputs.use-cirrus-runners == 'true' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' || 'ubuntu-24.04' }} + timeout-minutes: 20 + env: + CONTAINER_NAME: "bitcoin-linter" + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Configure Docker + uses: ./.github/actions/configure-docker + with: + use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }} + + - name: CI script + run: | + set -o xtrace + docker buildx build -t "$CONTAINER_NAME" $DOCKER_BUILD_CACHE_ARG --file "./ci/lint_imagefile" . + CIRRUS_PR_FLAG="" + if [ "${{ github.event_name }}" = "pull_request" ]; then + CIRRUS_PR_FLAG="-e CIRRUS_PR=1" + fi + docker run --rm $CIRRUS_PR_FLAG -v "$(pwd)":/bitcoin "$CONTAINER_NAME" From 21b0901756660cc6cb4691fd70eedfa2c18b8492 Mon Sep 17 00:00:00 2001 From: Max Edwards Date: Mon, 8 Sep 2025 19:16:23 +0100 Subject: [PATCH 4/7] cleanup silent merge check yml --- .github/workflows/silent-merge-check.yml | 66 +++--------------------- 1 file changed, 8 insertions(+), 58 deletions(-) diff --git a/.github/workflows/silent-merge-check.yml b/.github/workflows/silent-merge-check.yml index 1307cb655bf4..de41e9dd62c3 100644 --- a/.github/workflows/silent-merge-check.yml +++ b/.github/workflows/silent-merge-check.yml @@ -103,6 +103,14 @@ jobs: summary="CMake build and tests passed." fi + # set -o xtrace + # docker buildx build -t "$CONTAINER_NAME" $DOCKER_BUILD_CACHE_ARG --file "./ci/lint_imagefile" . + # CIRRUS_PR_FLAG="" + # if [ "${{ github.event_name }}" = "pull_request" ]; then + # CIRRUS_PR_FLAG="-e CIRRUS_PR=1" + # fi + # docker run --rm $CIRRUS_PR_FLAG -v "$(pwd)":/bitcoin "$CONTAINER_NAME" + # --- Report result as a new check run --- gh api repos/${GITHUB_REPOSITORY}/check-runs \ -X POST \ @@ -121,61 +129,3 @@ jobs: depends-sources-cache-hit: ${{ steps.restore-cache.depends-sources-cache-hit }} depends-built-cache-hit: ${{ steps.restore-cache.depends-built-cache-hit }} - previous-releases: - name: 'Previous releases, depends DEBUG' - if: contains(github.event.label.name, 'PeriodicMergeCICheck') - needs: runners - runs-on: ${{ needs.runners.outputs.use-cirrus-runners == 'true' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' || 'ubuntu-24.04' }} - - env: - FILE_ENV: './ci/test/00_setup_env_native_previous_releases.sh' - DANGER_CI_ON_HOST_FOLDERS: 1 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Configure environment - uses: ./.github/actions/configure-environment - - - name: Restore caches - id: restore-cache - uses: ./.github/actions/restore-caches - - - name: Configure Docker - uses: ./.github/actions/configure-docker - with: - use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }} - - - name: CI script - run: ./ci/test_run_all.sh - - - lint: - name: 'Lint' - if: contains(github.event.label.name, 'PeriodicMergeCICheck') - needs: runners - runs-on: ${{ needs.runners.outputs.use-cirrus-runners == 'true' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' || 'ubuntu-24.04' }} - timeout-minutes: 20 - env: - CONTAINER_NAME: "bitcoin-linter" - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Configure Docker - uses: ./.github/actions/configure-docker - with: - use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }} - - - name: CI script - run: | - set -o xtrace - docker buildx build -t "$CONTAINER_NAME" $DOCKER_BUILD_CACHE_ARG --file "./ci/lint_imagefile" . - CIRRUS_PR_FLAG="" - if [ "${{ github.event_name }}" = "pull_request" ]; then - CIRRUS_PR_FLAG="-e CIRRUS_PR=1" - fi - docker run --rm $CIRRUS_PR_FLAG -v "$(pwd)":/bitcoin "$CONTAINER_NAME" From bdc643e7692da327256869e5ef4900222b1e176f Mon Sep 17 00:00:00 2001 From: Max Edwards Date: Mon, 8 Sep 2025 19:19:30 +0100 Subject: [PATCH 5/7] do not save caches on silent merge check --- .github/workflows/silent-merge-check.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/silent-merge-check.yml b/.github/workflows/silent-merge-check.yml index de41e9dd62c3..8d9c4f4e8820 100644 --- a/.github/workflows/silent-merge-check.yml +++ b/.github/workflows/silent-merge-check.yml @@ -123,9 +123,3 @@ jobs: done - - name: Save caches - uses: ./.github/actions/save-caches - with: - depends-sources-cache-hit: ${{ steps.restore-cache.depends-sources-cache-hit }} - depends-built-cache-hit: ${{ steps.restore-cache.depends-built-cache-hit }} - From b9406f0fadd56fb5bc267aaa4c627c3da72b8f9e Mon Sep 17 00:00:00 2001 From: Max Edwards Date: Mon, 8 Sep 2025 19:20:56 +0100 Subject: [PATCH 6/7] do not configure docker with cirrus cache --- .github/workflows/silent-merge-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/silent-merge-check.yml b/.github/workflows/silent-merge-check.yml index 8d9c4f4e8820..a165dc77b298 100644 --- a/.github/workflows/silent-merge-check.yml +++ b/.github/workflows/silent-merge-check.yml @@ -37,7 +37,7 @@ jobs: - name: Configure Docker uses: ./.github/actions/configure-docker with: - use-cirrus: ${{ needs.runners.outputs.use-cirrus-runners }} + use-cirrus: 'false' - name: Set up GitHub CLI run: gh auth login --with-token <<< "${{ secrets.GITHUB_TOKEN }}" From ae0cf16369765050a0b534d5ca8127a8957306d1 Mon Sep 17 00:00:00 2001 From: Max Edwards Date: Wed, 10 Sep 2025 17:48:57 +0100 Subject: [PATCH 7/7] this test should always pass --- src/test/util_tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index f9038c4fc977..0b45e59165c4 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -315,6 +315,7 @@ BOOST_AUTO_TEST_CASE(util_TrimString) BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n "), "foo \n\tbar"); BOOST_CHECK_EQUAL(TrimStringView("\t \n foo \n\tbar\t \n ", "fobar"), "\t \n foo \n\tbar\t \n "); BOOST_CHECK_EQUAL(TrimString("foo bar"), "foo bar"); + BOOST_CHECK_EQUAL(TrimString("silent_merge9"), "silent_merge9"); BOOST_CHECK_EQUAL(TrimStringView("foo bar", "fobar"), " "); BOOST_CHECK_EQUAL(TrimString(std::string("\0 foo \0 ", 8)), std::string("\0 foo \0", 7)); BOOST_CHECK_EQUAL(TrimStringView(std::string(" foo ", 5)), std::string("foo", 3));