From 7b890b48ec2a48de4860070b66d99784bd386a3d Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Thu, 14 May 2026 19:23:28 -0400 Subject: [PATCH 01/13] chore(maru): remove maru/.github MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Workflows will be re-added at the monorepo root as .github/workflows/maru-*.yml with paths filters in a later commit (mirrors the tracer import pattern from PR #1852). Maru's dependabot.yml, pull_request_template.md, and ISSUE_TEMPLATE/ are dropped — the monorepo has its own equivalents. --- maru/.github/ISSUE_TEMPLATE/bug-report.md | 32 ---- maru/.github/ISSUE_TEMPLATE/config.yml | 1 - maru/.github/ISSUE_TEMPLATE/epic.md | 30 ---- .../.github/ISSUE_TEMPLATE/feature_request.md | 27 --- maru/.github/dependabot.yml | 31 ---- maru/.github/pull_request_template.md | 2 - maru/.github/workflows/chaos-testing.yml | 153 ---------------- maru/.github/workflows/e2e-tests.yml | 98 ---------- maru/.github/workflows/main.yml | 135 -------------- .../workflows/maru-build-and-publish.yml | 167 ------------------ maru/.github/workflows/release.yml | 116 ------------ .../workflows/security-code-scanner.yml | 53 ------ maru/.github/workflows/smoke-tests.yml | 67 ------- maru/.github/workflows/testing.yml | 84 --------- 14 files changed, 996 deletions(-) delete mode 100644 maru/.github/ISSUE_TEMPLATE/bug-report.md delete mode 100644 maru/.github/ISSUE_TEMPLATE/config.yml delete mode 100644 maru/.github/ISSUE_TEMPLATE/epic.md delete mode 100644 maru/.github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 maru/.github/dependabot.yml delete mode 100644 maru/.github/pull_request_template.md delete mode 100644 maru/.github/workflows/chaos-testing.yml delete mode 100644 maru/.github/workflows/e2e-tests.yml delete mode 100644 maru/.github/workflows/main.yml delete mode 100644 maru/.github/workflows/maru-build-and-publish.yml delete mode 100644 maru/.github/workflows/release.yml delete mode 100644 maru/.github/workflows/security-code-scanner.yml delete mode 100644 maru/.github/workflows/smoke-tests.yml delete mode 100644 maru/.github/workflows/testing.yml diff --git a/maru/.github/ISSUE_TEMPLATE/bug-report.md b/maru/.github/ISSUE_TEMPLATE/bug-report.md deleted file mode 100644 index da26b408b69..00000000000 --- a/maru/.github/ISSUE_TEMPLATE/bug-report.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Bug report -about: File a bug report -title: 'Short and factual title summarizing the bug.' -labels: Bug -assignees: '' ---- - -_Remenber not to put too much unhelpful information or too little important information, be specific._ - -## Impact -__environment [Testnet/Mainnet]__ - -__an user is impacted [Y/N], if yes type of user: [External/Internal]__ - -## Describe the bug -### Steps to Reproduce -_A bug that we can't reproduce is hard to resolve, to ensure the bug is fixed in a timely manner, it is crucial to indicate how to reproduce it. If the bug can't be reproduced, give specific details on how it happened._ - -Steps to reproduce the bug: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -### Actual result -Evidence of the bug including log extracts, screen shot, wallet addresses, Tx hash, ... - -### Expected result -A clear and concise description of what you expected to happen. - -_Remember that an issue without proper labels and without assignee is unlikely to get prioritized -> contact the team or the product owner to get it included in the plan._ diff --git a/maru/.github/ISSUE_TEMPLATE/config.yml b/maru/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 3ba13e0cec6..00000000000 --- a/maru/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1 +0,0 @@ -blank_issues_enabled: false diff --git a/maru/.github/ISSUE_TEMPLATE/epic.md b/maru/.github/ISSUE_TEMPLATE/epic.md deleted file mode 100644 index efed8557891..00000000000 --- a/maru/.github/ISSUE_TEMPLATE/epic.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: Epic/Major Feature -about: File an Epic -assignees: 'dfox-consensys,julien-marchand' ---- - -## Description -Write a clear and concise description of what you want to happen. Add any considered drawbacks. - -## Motivation -This section should indicate what value we are receiving from it. - -## Architecture -- [ ] Link to an architecture document - -## Implementation guidelines -- [ ] List implementation steps to complete the epic/feature - -## Metrics/monitoring -- [ ] What needs to be monitored once this epic has been shipped? - -## Rollout -- [ ] Describe rollout plan for this epic - -## Infrastructure & Node operators -- [ ] What is the impact and migration steps required for the infrastructure and node operators - -## Documentation & communication -- [ ] What needs to be documented for this feature? - diff --git a/maru/.github/ISSUE_TEMPLATE/feature_request.md b/maru/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index cd7c494871f..00000000000 --- a/maru/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Feature request -about: File a feature request -title: '' -assignees: '' - ---- - -## Description -Write a clear and concise description of what you want to happen. Add any considered drawbacks. - -## Motivation -This section should indicate what value we are receiving from it. - -## Tasks -- [ ] Medium-level task that needs to be implemented for this feature request to be considered complete. - -## Acceptance criteria -- [ ] List tests that need to be implemented or checks to consider this task completed. - -## Risks -- [ ] These are risks that may prevent completion of the task as well as areas to pay special attention to - -## Remember to - - [ ] Add the `documentation` label in case there is an impact on the documentation - - [ ] Add `priority` and `team` labels - - [ ] Add Task for updating the Runbook or adding/updating existing metrics and alerts. diff --git a/maru/.github/dependabot.yml b/maru/.github/dependabot.yml deleted file mode 100644 index 2c921824465..00000000000 --- a/maru/.github/dependabot.yml +++ /dev/null @@ -1,31 +0,0 @@ -version: 2 - -updates: - # 1) GitHub Actions - - package-ecosystem: github-actions - directory: / # GitHub scans .github/workflows from here - schedule: - interval: weekly - day: monday - time: "03:00" - open-pull-requests-limit: 5 - assignees: ["Filter94"] - labels: ["dependencies", "github-actions"] - commit-message: - prefix: "deps(actions)" - include: "scope" - groups: - core-actions-minor-patch: - update-types: ["minor", "patch"] - patterns: - - "actions/*" - - "github/*" - third-party-actions-minor-patch: - update-types: ["minor", "patch"] - patterns: - - "*" - exclude-patterns: - - "actions/*" - - "github/*" - cooldown: - default-days: 7 diff --git a/maru/.github/pull_request_template.md b/maru/.github/pull_request_template.md deleted file mode 100644 index ea7e056922a..00000000000 --- a/maru/.github/pull_request_template.md +++ /dev/null @@ -1,2 +0,0 @@ -⚠️ Please make sure PR Title conforms to https://www.conventionalcommits.org/en/v1.0.0/#specification. -During the merge squash please be mindful to stick to conventional commits as well ⚠️ diff --git a/maru/.github/workflows/chaos-testing.yml b/maru/.github/workflows/chaos-testing.yml deleted file mode 100644 index 16d06fa4888..00000000000 --- a/maru/.github/workflows/chaos-testing.yml +++ /dev/null @@ -1,153 +0,0 @@ -name: Chaos Testing - -on: - workflow_dispatch: - inputs: - consensus-client-changed: - required: true - type: string - default: 'true' - description: 'when false, skips the job' - enable_ssh_debug: - description: 'Enable SSH debugging before tests start' - required: false - type: boolean - default: false - ssh_debug_on_failure: - required: false - type: boolean - default: false - description: 'Enable SSH debugging on test failure' - workflow_call: - inputs: - consensus-client-changed: - required: true - type: string - enable_ssh_debug: - required: false - type: boolean - default: false - ssh_debug_on_failure: - required: false - type: boolean - default: false - -permissions: {} # lock everything by default (least-privilege) - -concurrency: - group: maru-chaos-testing-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} - -jobs: - run-chaos-tests: - permissions: - contents: read # for actions/checkout - if: ${{ inputs.consensus-client-changed == 'true' }} - env: - COMMIT_TAG: ${{ inputs.commit_tag }} - DOCKER_ORG_NAME: ${{ secrets.DOCKER_ORG_NAME }} - DOCKER_REPO_TOKEN: ${{ secrets.DOCKER_REPO_TOKEN }} - runs-on: [ gha-runner-scale-set-ubuntu-24-amd64-large ] - name: chaos tests - # useful for debugging flaky tests. - # strategy: - # matrix: - # iterations: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Login to Docker Hub - if: ${{ env.DOCKER_ORG_NAME != '' && env.DOCKER_REPO_TOKEN != '' }} - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_ORG_NAME }} - password: ${{ secrets.DOCKER_REPO_TOKEN }} - - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 25 - - name: Setup Gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # 4.4.0 - - name: Install helm - uses: azure/setup-helm@v4.3.1 - with: - version: 'v3.18.3' - id: install - - # SSH debugging session - before tests (if explicitly requested) - - name: Setup upterm session (pre-test) - if: ${{ inputs.enable_ssh_debug }} - uses: lhotari/action-upterm@v1 - with: - ## If no one connects shut down ssh server after timeout. - wait-timeout-minutes: 20 - - - name: Run chaos tests - id: chaos-tests - timeout-minutes: 30 - run: | - cd chaos-testing - mkdir -p ~/.kube - export KUBECONFIG=~/.kube/k3s-server - make k3s-reload # installs k3s K8S implementation - kubectl config set-context --current --namespace=default - make chaos-redeploy-chaos-mesh-and-linea maru_image=consensys/maru:local - make chaos-health-check # just make sure that the cluster is healthy before starting the chaos tests - make chaos-experiment-workflow-and-health-check - - - name: Collect pod logs - if: failure() - run: | - export KUBECONFIG=~/.kube/k3s-server - mkdir -p chaos-testing/tmp/pod-logs - echo "Collecting logs from all pods..." - for pod in $(kubectl get pods -n default -o jsonpath='{.items[*].metadata.name}' 2>/dev/null); do - echo "Collecting logs for $pod" - kubectl logs "$pod" -n default --tail=5000 > "chaos-testing/tmp/pod-logs/${pod}.log" 2>&1 || true - # Also collect previous container logs (if pod restarted) - kubectl logs "$pod" -n default --previous --tail=5000 > "chaos-testing/tmp/pod-logs/${pod}-previous.log" 2>&1 || true - done - # Collect pod status/describe for context - kubectl get pods -n default -o wide > "chaos-testing/tmp/pod-logs/pod-status.txt" 2>&1 || true - kubectl describe pods -n default > "chaos-testing/tmp/pod-logs/pod-describe.txt" 2>&1 || true - echo "Log collection complete" - ls -la chaos-testing/tmp/pod-logs/ - - - name: Collect port-forward logs - if: failure() - run: | - echo "Collecting port-forward logs..." - if [ -d chaos-testing/tmp/pf ]; then - ls -la chaos-testing/tmp/pf/ - else - echo "No port-forward log directory found" - fi - # Also collect port-forward summary files - for f in chaos-testing/tmp/port-forward-*.txt; do - if [ -f "$f" ]; then - echo "=== $f ===" - cat "$f" - fi - done - # Check for any surviving port-forward processes - ps -o pid=,command= -ax | grep 'kubectl port-forward' | grep -v grep > chaos-testing/tmp/pod-logs/port-forward-processes.txt 2>&1 || true - echo "Port-forward process collection complete" - - - name: Store reports and pod logs - if: failure() - uses: actions/upload-artifact@v4 - with: - name: chaos-test-reports-and-logs - path: | - **/build/reports/tests/ - chaos-testing/tmp/pod-logs/ - chaos-testing/tmp/pf/ - chaos-testing/tmp/port-forward-*.txt - - # SSH debugging session - on failure (if requested) - - name: Setup upterm session after failure - if: ${{ (failure() || steps.chaos-tests.outcome == 'failure') && inputs.ssh_debug_on_failure == true }} - uses: lhotari/action-upterm@v1 - with: - ## If no one connects shut down ssh server after timeout. - wait-timeout-minutes: 20 diff --git a/maru/.github/workflows/e2e-tests.yml b/maru/.github/workflows/e2e-tests.yml deleted file mode 100644 index 63b8450223a..00000000000 --- a/maru/.github/workflows/e2e-tests.yml +++ /dev/null @@ -1,98 +0,0 @@ -name: Reusable run e2e tests -on: - workflow_dispatch: - inputs: -# commit-tag: -# description: 'The commit tag to use' -# required: true -# type: string - e2e-tests-with-ssh: - description: Run end to end tests with ability to ssh into environment - required: false - type: boolean - default: false - e2e-tests-logs-dump: - description: Dump logs after running end to end tests - required: false - type: boolean - default: false - workflow_call: - inputs: -# commit-tag: -# required: true -# type: string - e2e-tests-with-ssh: - description: Run end to end tests with ability to ssh into environment - required: false - type: boolean - default: false - e2e-tests-logs-dump: - description: Dump logs after running end to end tests - required: false - type: boolean - default: false - has-changes-requiring-build: - type: string - outputs: - tests_outcome: - value: ${{ jobs.run-e2e-tests.outputs.tests_outcome }} - -permissions: {} # lock everything by default (least-privilege) - -concurrency: - group: maru-e2e-tests-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} - -jobs: - # Required job - run-e2e-tests: - permissions: - contents: read # for actions/checkout - # We can only use conditionals, and not path filters to 'successfully' skip a required job - https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks - if: ${{ inputs.has-changes-requiring-build == 'true' }} - env: - DOCKER_ORG_NAME: ${{ secrets.DOCKER_ORG_NAME }} - DOCKER_REPO_TOKEN: ${{ secrets.DOCKER_REPO_TOKEN }} - outputs: - tests_outcome: ${{ steps.run_e2e_tests.outcome }} - runs-on: [gha-runner-scale-set-ubuntu-24-amd64-med] - name: e2e tests - steps: - - name: Setup upterm session - if: ${{ inputs.e2e-tests-with-ssh }} - uses: lhotari/action-upterm@v1 - - name: Checkout - uses: actions/checkout@v6 - - name: Login to Docker Hub - if: ${{ env.DOCKER_ORG_NAME != '' && env.DOCKER_REPO_TOKEN != '' }} - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_ORG_NAME }} - password: ${{ secrets.DOCKER_REPO_TOKEN }} - - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 25 - - name: Setup Gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # 4.4.0 - - name: Download images - run: | - make docker-pull - - name: Run e2e tests - id: run_e2e_tests - timeout-minutes: 10 - run: | - make run-e2e-test - - name: Show e2e tests result - if: always() - run: | - echo "E2E_TESTS_RESULT: ${{ steps.run_e2e_tests.outcome }}" - - - name: Archive debug logs - uses: actions/upload-artifact@v4 - if: ${{ failure() && inputs.e2e-tests-logs-dump }} - with: - name: end-2-end-debug-logs - if-no-files-found: error - path: | - e2e/docker_logs/**/* diff --git a/maru/.github/workflows/main.yml b/maru/.github/workflows/main.yml deleted file mode 100644 index 9d1197c2bb1..00000000000 --- a/maru/.github/workflows/main.yml +++ /dev/null @@ -1,135 +0,0 @@ -name: main - -on: - workflow_dispatch: - pull_request: - push: - branches: - - main - -permissions: {} # lock everything by default (least-privilege) - -concurrency: - group: maru-main-workflow-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} - -jobs: - filter-commit-changes: - permissions: - contents: read # for actions/checkout and dorny/paths-filter - runs-on: [gha-runner-scale-set-ubuntu-24-amd64-small] - name: Filter commit changes - outputs: - has-changes-requiring-build: ${{ steps.filter.outputs.has-changes-requiring-build }} - chaos-tests-changes: ${{ steps.filter.outputs.chaos-tests-changes }} - run-chaos-tests: ${{ steps.filter.outputs.has-changes-requiring-build == 'true' || steps.filter.outputs.chaos-tests-changes == 'true' }} - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Filter commit changes - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 #v3.0.2 - id: filter - with: - base: ${{ github.ref }} - list-files: "json" - filters: | - has-changes-requiring-build: - - '.github/**' - - '**/src/**' - - '**/Makefile' - - 'docker/**' - - 'gradle/**' - - 'gradlew' - - 'gradlew.bat' - - '**/*.gradle' - - '**/*.properties' - chaos-tests-changes: - - '.github/**' - - 'chaos-testing/**' - - - name: Debug filter outputs - run: | - echo "has-changes-requiring-build: ${{ steps.filter.outputs.has-changes-requiring-build }}" - echo "chaos-tests-changes: ${{ steps.filter.outputs.chaos-tests-changes }}" - echo "run-chaos-tests: ${{ steps.filter.outputs.run-chaos-tests }}" - echo "Event name: ${{ github.event_name }}" - echo "Ref: ${{ github.ref }}" - echo "All filter outputs: ${{ toJSON(steps.filter.outputs) }}" - - debug: - permissions: {} # no permissions needed - name: Debug Filters outputs - needs: [ filter-commit-changes ] - runs-on: [ gha-runner-scale-set-ubuntu-24-amd64-small ] - steps: - - name: Debug filter outputs - run: | - echo "has-changes-requiring-build: ${{ needs.filter-commit-changes.outputs.has-changes-requiring-build }}" - echo "chaos-tests-changes: ${{ needs.filter-commit-changes.outputs.chaos-tests-changes }}" - echo "run-chaos-tests: ${{ needs.filter-commit-changes.outputs.run-chaos-tests }}" - echo "Event name: ${{ github.event_name }}" - echo "Ref: ${{ github.ref }}" - - testing: - permissions: - contents: read # for actions/checkout in called workflow - needs: [ filter-commit-changes ] - if: ${{ always() && !cancelled() && needs.filter-commit-changes.outputs.has-changes-requiring-build == 'true' }} - uses: ./.github/workflows/testing.yml - with: - consensus-client-changed: ${{ needs.filter-commit-changes.outputs.has-changes-requiring-build }} - secrets: inherit - -# run-e2e-tests: -# needs: [ filter-commit-changes ] -# if: ${{ always() && !cancelled() && needs.filter-commit-changes.outputs.has-changes-requiring-build == 'true' }} -# uses: ./.github/workflows/e2e-tests.yml -# with: -# e2e-tests-logs-dump: true -# has-changes-requiring-build: ${{ needs.filter-commit-changes.outputs.has-changes-requiring-build }} -# secrets: inherit - - chaos-testing: - permissions: - contents: read # for actions/checkout in called workflow - needs: [ filter-commit-changes ] - if: ${{ always() && !cancelled() && needs.filter-commit-changes.outputs.run-chaos-tests == 'true' }} - uses: ./.github/workflows/chaos-testing.yml - with: - consensus-client-changed: ${{ needs.filter-commit-changes.outputs.has-changes-requiring-build }} - secrets: inherit - - build-for-testing: - permissions: - contents: read # for actions/checkout in called workflow - needs: [ filter-commit-changes ] - if: ${{ always() && !cancelled() && needs.filter-commit-changes.outputs.has-changes-requiring-build == 'true' }} - uses: ./.github/workflows/maru-build-and-publish.yml - with: - develop_tag: 'develop' - image_name: 'consensys/maru' - push_image: false - secrets: inherit - - maru-image-smoke-test: - permissions: - contents: read # for actions/checkout in called workflow - needs: [ build-for-testing ] - if: ${{ always() && !cancelled() && needs.filter-commit-changes.outputs.has-changes-requiring-build == 'true' }} - uses: ./.github/workflows/smoke-tests.yml - with: - commit-tag: ${{ needs.build-for-testing.outputs.commit_tag }} - secrets: inherit - - build-and-publish: - permissions: - contents: read # for actions/checkout in called workflow - needs: [ maru-image-smoke-test ] - if: ${{ always() && !cancelled() && needs.maru-image-smoke-test.result == 'success' && (github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/main') }} - uses: ./.github/workflows/maru-build-and-publish.yml - with: - develop_tag: 'develop' - image_name: 'consensys/maru' - push_image: true - secrets: inherit diff --git a/maru/.github/workflows/maru-build-and-publish.yml b/maru/.github/workflows/maru-build-and-publish.yml deleted file mode 100644 index d4295391863..00000000000 --- a/maru/.github/workflows/maru-build-and-publish.yml +++ /dev/null @@ -1,167 +0,0 @@ -name: Build and Publish Maru Image - -on: - workflow_call: - inputs: - commit_tag: - required: false - type: string - default: '' - develop_tag: - required: true - type: string - image_name: - required: true - type: string - push_image: - required: false - type: boolean - default: false - upload_dist_artifact: # Used for release process to reuse the artifact - required: false - type: boolean - default: false - outputs: - commit_tag: - value: ${{ jobs.build-and-publish.outputs.commit_tag }} - secrets: - DOCKER_ORG_NAME: - required: false - DOCKER_REPO_TOKEN: - required: false - workflow_dispatch: - inputs: - commit_tag: - description: 'Image tag, if not given, HEAD commit hash will be used' - required: false - type: string - default: '' - develop_tag: - description: 'Image tag will be "develop" if target branch is main' - required: true - type: choice - options: - - develop - default: 'develop' - image_name: - description: 'Image name' - required: true - type: string - default: 'consensys/maru' - push_image: - description: 'Toggle whether to push image to docker registry' - required: false - type: boolean - default: true - -permissions: {} # lock everything by default (least-privilege) - -concurrency: - group: maru-docker-build-and-publish-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} - -jobs: - build-and-publish: - permissions: - contents: read # for actions/checkout - runs-on: gha-runner-scale-set-ubuntu-24-amd64-large - name: Maru build and publish - env: - COMMIT_TAG: ${{ inputs.commit_tag }} - DEVELOP_TAG: ${{ inputs.develop_tag }} - IMAGE_NAME: ${{ inputs.image_name }} - PUSH_IMAGE: ${{ inputs.push_image }} - TAGS: ${{ inputs.image_name }}:${{ inputs.commit_tag }} - DOCKER_ORG_NAME: ${{ secrets.DOCKER_ORG_NAME }} - DOCKER_REPO_TOKEN: ${{ secrets.DOCKER_REPO_TOKEN }} - outputs: - commit_tag: ${{ env.COMMIT_TAG }} - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Set commit tag if not given - if: ${{ inputs.commit_tag == '' }} - run: | - # For PR, GITHUB_SHA is NOT the last commit pushed onto the PR branch - https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request - if [[ "${{ github.event_name }}" == "pull_request" ]]; then - COMMIT_TAG=$(git rev-parse --short ${{ github.event.pull_request.head.sha }}) - else - COMMIT_TAG=$(git rev-parse --short $GITHUB_SHA) - fi - echo "COMMIT_TAG=$COMMIT_TAG" >> $GITHUB_ENV - echo "TAGS=${{ env.IMAGE_NAME }}:$COMMIT_TAG" >> $GITHUB_ENV - echo "COMMIT_TAG=$COMMIT_TAG" - - name: Set develop tag if main branch - if: ${{ github.ref == 'refs/heads/main' }} - run: | - echo "TAGS=${{ env.IMAGE_NAME }}:${{ env.COMMIT_TAG }},${{ env.IMAGE_NAME }}:${{ env.DEVELOP_TAG }}" >> $GITHUB_ENV - - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b #v4.5.0 - with: - distribution: temurin - java-version: 25 - - name: Setup Gradle - # Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies. - # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # 4.4.0 - - name: Build dist - run: | - ./gradlew :app:installDist - - name: Upload distribution artifact - if: ${{ inputs.upload_dist_artifact }} - uses: actions/upload-artifact@v4 - with: - name: maru-distribution - path: app/build/install/app/ - retention-days: 1 - - name: Login to Docker Hub - if: ${{ env.PUSH_IMAGE == 'true' && env.DOCKER_ORG_NAME != '' && env.DOCKER_REPO_TOKEN != '' }} - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_ORG_NAME }} - password: ${{ secrets.DOCKER_REPO_TOKEN }} - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - local - id: buildx - uses: docker/setup-buildx-action@v3 - - name: Docker meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.IMAGE_NAME }} - - name: Build for testing - uses: docker/build-push-action@v6 - if: ${{ env.PUSH_IMAGE == 'false' }} - with: - context: app - build-contexts: | - libs=./app/build/install/app/lib/ - maru=./app/build/libs/ - platforms: linux/amd64 - load: true - push: false - tags: ${{ env.IMAGE_NAME }}:${{ env.COMMIT_TAG }} - - name: Save Docker image as artifact - if: ${{ env.PUSH_IMAGE == 'false' }} - run: | - docker save ${{ env.IMAGE_NAME }}:${{ env.COMMIT_TAG }} | gzip > linea-maru-docker-image.tar.gz - shell: bash - - name: Upload Docker image artifact - if: ${{ env.PUSH_IMAGE == 'false' }} - uses: actions/upload-artifact@v4 - with: - name: linea-maru - path: linea-maru-docker-image.tar.gz - - name: Build & push - uses: docker/build-push-action@v6 - if: ${{ env.PUSH_IMAGE == 'true' }} - with: - context: app - build-contexts: | - libs=./app/build/install/app/lib/ - maru=./app/build/libs/ - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ env.TAGS }} - cache-from: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache - cache-to: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache,mode=max - diff --git a/maru/.github/workflows/release.yml b/maru/.github/workflows/release.yml deleted file mode 100644 index edd9f30c095..00000000000 --- a/maru/.github/workflows/release.yml +++ /dev/null @@ -1,116 +0,0 @@ -name: Release - -on: - push: - tags: - - 'v*' - -permissions: {} # lock everything by default (least-privilege) - -concurrency: - group: maru-release-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: false - -jobs: - compute-version: - permissions: - contents: read # for actions/checkout with fetch-depth: 0 - runs-on: gha-runner-scale-set-ubuntu-24-amd64-small - name: Compute version - outputs: - tag_name: ${{ steps.version.outputs.tag_name }} - full_version: ${{ steps.version.outputs.full_version }} - date: ${{ steps.version.outputs.date }} - commit_hash: ${{ steps.version.outputs.commit_hash }} - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - name: Validate tag and compute version - id: version - run: | - TAG_NAME=${GITHUB_REF#refs/tags/} - echo "Tag: $TAG_NAME" - - # Validate tag format: v-? - # Examples: v2.0.1-betav4 OR v2.0.1 OR v2.0.1-beta-v4 - if [[ ! $TAG_NAME =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9-]+)?$ ]]; then - echo "Error: Tag format is invalid. Expected format: v-?" - echo "Examples: v2.0.1-betav4 OR v2.0.1 OR v2.0.1-beta-v4" - exit 1 - fi - - # Compute date and commit hash - DATE=$(date -u +%Y%m%d%H%M%S) - COMMIT_HASH=$(git show-ref -s $TAG_NAME | cut -c1-7) - - # Create full version: -?-- - FULL_VERSION="${TAG_NAME}-${DATE}-${COMMIT_HASH}" - - echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT - echo "full_version=$FULL_VERSION" >> $GITHUB_OUTPUT - echo "date=$DATE" >> $GITHUB_OUTPUT - echo "commit_hash=$COMMIT_HASH" >> $GITHUB_OUTPUT - - echo "Release tag: $TAG_NAME" - echo "Full version: $FULL_VERSION" - - build-and-publish-docker: - permissions: - contents: read # for actions/checkout in called workflow - needs: compute-version - uses: ./.github/workflows/maru-build-and-publish.yml - with: - commit_tag: ${{ needs.compute-version.outputs.full_version }} - develop_tag: ${{ needs.compute-version.outputs.tag_name }} - image_name: 'consensys/maru' - push_image: true - upload_dist_artifact: true - secrets: inherit - - create-release: - permissions: - contents: write # for actions/checkout and softprops/action-gh-release - needs: [compute-version, build-and-publish-docker] - runs-on: gha-runner-scale-set-ubuntu-24-amd64-large - name: Create GitHub Release - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - name: Download distribution artifact - uses: actions/download-artifact@v4 - with: - name: maru-distribution - path: app/build/install/app/ - - - name: Create distribution archive - run: | - tar -czf maru-${{ needs.compute-version.outputs.full_version }}.tar.gz -C app/build/install/app . - - - name: Prepare release body - run: | - cat << 'EOF' > release-body.md - ## Docker Image - - 🐳 **Docker Hub:** https://hub.docker.com/r/consensys/maru/tags?name=${{ needs.compute-version.outputs.full_version }} - - ```bash - docker pull consensys/maru:${{ needs.compute-version.outputs.full_version }} - ``` - - EOF - cat CHANGELOG.md >> release-body.md - - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 - with: - draft: true - body_path: release-body.md - files: maru-${{ needs.compute-version.outputs.full_version }}.tar.gz - fail_on_unmatched_files: true - make_latest: true diff --git a/maru/.github/workflows/security-code-scanner.yml b/maru/.github/workflows/security-code-scanner.yml deleted file mode 100644 index 84adf29e16e..00000000000 --- a/maru/.github/workflows/security-code-scanner.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: MetaMask Security Code Scanner - -on: - push: - branches: - - main - pull_request: - branches: - - main - workflow_call: - secrets: - SECURITY_SCAN_METRICS_TOKEN: - required: false - APPSEC_BOT_SLACK_WEBHOOK: - required: false - workflow_dispatch: - -permissions: {} # lock everything by default (least-privilege) - -jobs: - security-scan: - uses: MetaMask/action-security-code-scanner/.github/workflows/security-scan.yml@v2 - permissions: - actions: read - contents: read - security-events: write - with: - repo: ${{ github.repository }} - scanner-ref: 'v2' - paths-ignored: | - **/build/** - **/target/** - **/*.class - **/gradle/** - **/test/** - **/tests/** - **/*Test.java - **/*Tests.java - **/*Test.kt - **/*Tests.kt - languages-config: | - [ - { - "language": "java-kotlin", - "build_mode": "manual", - "build_command": "./gradlew :app:installDist", - "version": "25", - "distribution": "temurin" - } - ] - secrets: - project-metrics-token: ${{ secrets.SECURITY_SCAN_METRICS_TOKEN }} - slack-webhook: ${{ secrets.APPSEC_BOT_SLACK_WEBHOOK }} diff --git a/maru/.github/workflows/smoke-tests.yml b/maru/.github/workflows/smoke-tests.yml deleted file mode 100644 index a04e1fd5d26..00000000000 --- a/maru/.github/workflows/smoke-tests.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Smoke Tests CI - -on: - workflow_call: - inputs: - commit-tag: - required: true - type: string - -permissions: {} # lock everything by default (least-privilege) - -concurrency: - group: maru-smoke-tests-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} - -jobs: - run-smoke-tests: - permissions: - contents: read - env: - DOCKER_ORG_NAME: ${{ secrets.DOCKER_ORG_NAME }} - DOCKER_REPO_TOKEN: ${{ secrets.DOCKER_REPO_TOKEN }} - runs-on: [gha-runner-scale-set-ubuntu-24-amd64-med] - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Download local docker image artifacts - uses: actions/download-artifact@v4 - with: - pattern: linea-maru - - name: Login to Docker Hub - if: ${{ env.DOCKER_ORG_NAME != '' && env.DOCKER_REPO_TOKEN != '' }} - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_ORG_NAME }} - password: ${{ secrets.DOCKER_REPO_TOKEN }} - - name: Load Docker images - run: | - pwd && ls -la && echo "GITHUB_WORKSPACE=$GITHUB_WORKSPACE" && - gunzip -c $GITHUB_WORKSPACE/linea-maru/linea-maru-docker-image.tar.gz | docker load - - name: Run Docker with maru container - run: | - MARU_TAG=${{ inputs.commit-tag }} make docker-run-stack-partial - - name: List docker containers/images - continue-on-error: true - run: | - docker ps -la && docker images - docker container ls -a - - name: Check Maru Docker logs - run: | - SEARCH_STRING="Maru is up" - TIMEOUT_SECONDS=30 - INTERVAL_SECONDS=2 - END_TIME=$((SECONDS + TIMEOUT_SECONDS)) - while [ $SECONDS -lt $END_TIME ]; do - echo $(docker logs maru | grep -q "Maru is up") - LOGS=$(docker logs maru 2>&1) - if echo "$LOGS" | grep -q "$SEARCH_STRING"; then - echo "Found '$SEARCH_STRING' in logs. Marking job as successful." - exit 0 - fi - echo "String '$SEARCH_STRING' not found yet. Retrying in $INTERVAL_SECONDS seconds..." - sleep $INTERVAL_SECONDS - done - echo "Timeout of $TIMEOUT_SECONDS seconds reached. String '$SEARCH_STRING' not found in logs." - echo $LOGS - exit 1 diff --git a/maru/.github/workflows/testing.yml b/maru/.github/workflows/testing.yml deleted file mode 100644 index b802ed68817..00000000000 --- a/maru/.github/workflows/testing.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: Testing CI - -on: - workflow_dispatch: - inputs: - consensus-client-changed: - required: true - type: string - default: 'true' - description: 'when false, skips the job' - workflow_call: - inputs: - # commit-tag: - # required: true - # type: string - consensus-client-changed: - required: true - type: string - -permissions: {} # lock everything by default (least-privilege) - -concurrency: - group: maru-tests-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} - -jobs: - run-tests: - permissions: - contents: read - if: ${{ inputs.consensus-client-changed == 'true' }} - env: - COMMIT_TAG: ${{ inputs.commit_tag }} - runs-on: [ gha-runner-scale-set-ubuntu-24-amd64-med ] - name: maru tests - # useful for debugging flaky tests. Comment out Jacoco and Codecov steps because they override the test results. -# strategy: -# matrix: -# iterations: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - steps: - - name: Checkout - uses: actions/checkout@v6 - - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 25 - - name: Setup Gradle - uses: gradle/actions/setup-gradle@8379f6a1328ee0e06e2bb424dadb7b159856a326 # 4.4.0 - - name: Build consensus and Unit tests - run: | - # force tests to run even if the code is not changed - # this is to debug flaky tests - ./gradlew build --rerun-tasks - - name: Store reports - if: failure() - uses: actions/upload-artifact@v4 - with: - name: test reports - path: | - **/build/reports/tests/ - - name: Run Jacoco - run: | - ./gradlew jacocoAggregatedReport - - name: Upload Jacoco test coverage report - uses: actions/upload-artifact@v4 - with: - name: jacocoRootReport-${{ env.COMMIT_TAG }}.xml - if-no-files-found: error - path: | - ${{ github.workspace }}/build/reports/jacoco/jacocoAggregatedReport/jacocoAggregatedReport.xml - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5 - with: - fail_ci_if_error: true - files: ${{ github.workspace }}/build/reports/jacoco/jacocoAggregatedReport/jacocoAggregatedReport.xml - flags: kotlin - os: linux - name: codecov - verbose: true - token: ${{ secrets.CODECOV_TOKEN }} - - name: Upload test results to Codecov - if: ${{ !cancelled() }} - uses: codecov/test-results-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} From 2472696ddeafffcfdc7bf09b645364a6c2829a33 Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Thu, 14 May 2026 19:24:14 -0400 Subject: [PATCH 02/13] chore(maru): remove maru/settings.gradle The maru subprojects will be wired directly into zkevm/settings.gradle as :maru:* includes in a later commit. There is only one Gradle settings.gradle per build, so maru's own settings.gradle must go. --- maru/settings.gradle | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 maru/settings.gradle diff --git a/maru/settings.gradle b/maru/settings.gradle deleted file mode 100644 index a8c362ba04e..00000000000 --- a/maru/settings.gradle +++ /dev/null @@ -1,26 +0,0 @@ -plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.9.0' -} -rootProject.name = 'maru' - -include ':app' -include ':core' -include ':consensus' -include ':executionlayer' -include ':e2e' -include 'jvm-libs' -include 'jvm-libs:extensions' -include 'storage' -include 'serialization' -include 'p2p' -include 'config' -include 'jvm-libs:test-utils' -include 'jvm-libs:mappers' -include 'jvm-libs:utils' -include 'jvm-libs:teku-web3j' -include 'crypto' -include 'linea-finalization-provider' -include 'api' -include 'observability' -include 'syncing' -include 'chaos-testing:health-checker' From a00fad50ae8a748ae460633711d15032e9732aa5 Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Thu, 14 May 2026 19:24:16 -0400 Subject: [PATCH 03/13] chore(maru): drop maru/buildSrc (migrate to zkevm conventions) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A Gradle build supports only one buildSrc. Maru's five convention plugins (maru.kotlin-{common-minimal,common,library,library-minimal,application}-conventions) are functionally equivalent to zkevm's existing net.consensys.zkevm.kotlin-* family — same five conventions, with zkevm's being slightly richer (catalog-driven versions, --enable-native-access JVM arg, consistent dependency resolution, annotation-default-target). Maru subprojects' 'apply plugin: maru.kotlin-X-conventions' lines will be switched to 'apply plugin: net.consensys.zkevm.kotlin-X-conventions' in a later commit. --- maru/buildSrc/build.gradle | 13 ---- maru/buildSrc/settings.gradle | 15 ---- ...maru.kotlin-application-conventions.gradle | 18 ----- .../maru.kotlin-common-conventions.gradle | 22 ------ ...u.kotlin-common-minimal-conventions.gradle | 75 ------------------- .../maru.kotlin-library-conventions.gradle | 4 - ....kotlin-library-minimal-conventions.gradle | 5 -- 7 files changed, 152 deletions(-) delete mode 100644 maru/buildSrc/build.gradle delete mode 100644 maru/buildSrc/settings.gradle delete mode 100644 maru/buildSrc/src/main/groovy/maru.kotlin-application-conventions.gradle delete mode 100644 maru/buildSrc/src/main/groovy/maru.kotlin-common-conventions.gradle delete mode 100644 maru/buildSrc/src/main/groovy/maru.kotlin-common-minimal-conventions.gradle delete mode 100644 maru/buildSrc/src/main/groovy/maru.kotlin-library-conventions.gradle delete mode 100644 maru/buildSrc/src/main/groovy/maru.kotlin-library-minimal-conventions.gradle diff --git a/maru/buildSrc/build.gradle b/maru/buildSrc/build.gradle deleted file mode 100644 index 22b903be297..00000000000 --- a/maru/buildSrc/build.gradle +++ /dev/null @@ -1,13 +0,0 @@ -plugins { - id("groovy-gradle-plugin") -} - -repositories { - mavenLocal() - mavenCentral() - gradlePluginPortal() -} - -dependencies { - implementation(libs.kotlin.plugin) -} diff --git a/maru/buildSrc/settings.gradle b/maru/buildSrc/settings.gradle deleted file mode 100644 index cdf7e50034c..00000000000 --- a/maru/buildSrc/settings.gradle +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * This settings file is used to specify which projects to include in your build-logic build. - */ - -rootProject.name = 'buildSrc' - -dependencyResolutionManagement { - versionCatalogs { - libs { - from(files("../gradle/libs.versions.toml")) - } - } -} diff --git a/maru/buildSrc/src/main/groovy/maru.kotlin-application-conventions.gradle b/maru/buildSrc/src/main/groovy/maru.kotlin-application-conventions.gradle deleted file mode 100644 index bba969bb7d8..00000000000 --- a/maru/buildSrc/src/main/groovy/maru.kotlin-application-conventions.gradle +++ /dev/null @@ -1,18 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - */ - -plugins { - // Apply the common convention plugin for shared build configuration between library and application projects. - id 'maru.kotlin-common-conventions' - - // Apply the application plugin to add support for building a CLI application in Java. - id 'application' -} - -dependencies { - implementation "build.linea.internal:metrics" - implementation "io.vertx:vertx-micrometer-metrics" - implementation "build.linea.internal:micrometer" - implementation "build.linea.internal:vertx-helper" -} diff --git a/maru/buildSrc/src/main/groovy/maru.kotlin-common-conventions.gradle b/maru/buildSrc/src/main/groovy/maru.kotlin-common-conventions.gradle deleted file mode 100644 index e17cbca0647..00000000000 --- a/maru/buildSrc/src/main/groovy/maru.kotlin-common-conventions.gradle +++ /dev/null @@ -1,22 +0,0 @@ -plugins { - id 'maru.kotlin-common-minimal-conventions' -} - -dependencies { - // - implementation("tech.pegasys.teku.internal:async") { - exclude group: 'org.slf4j' - exclude group: 'com.github.jnr' - exclude group: 'com.squareup.okhttp3' - exclude group: 'org.apache.logging.log4j' - exclude group: 'tech.pegasys.teku.internal', module: 'metrics' - exclude group: 'tech.pegasys.teku.internal', module: 'time' - } because("We are using Teku's SafeFuture, an improved/extension of CompletableFuture.") - - implementation "com.michael-bull.kotlin-result:kotlin-result" - - // - implementation "org.apache.logging.log4j:log4j-api" - implementation "org.apache.logging.log4j:log4j-core" - // -} diff --git a/maru/buildSrc/src/main/groovy/maru.kotlin-common-minimal-conventions.gradle b/maru/buildSrc/src/main/groovy/maru.kotlin-common-minimal-conventions.gradle deleted file mode 100644 index 6f8bb35b2c1..00000000000 --- a/maru/buildSrc/src/main/groovy/maru.kotlin-common-minimal-conventions.gradle +++ /dev/null @@ -1,75 +0,0 @@ -plugins { - // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. - id 'org.jetbrains.kotlin.jvm' - id 'idea' -} - -java { - toolchain { - languageVersion = JavaLanguageVersion.of(25) - } -} - -kotlin { - compilerOptions { - sourceSets.configureEach { - languageSettings.optIn("kotlin.time.ExperimentalTime") - } - } -} - -repositories { - mavenCentral() - maven { - url 'https://artifacts.consensys.net/public/teku/maven/' - content { includeGroupAndSubgroups('tech.pegasys') } - } - maven { - url 'https://hyperledger.jfrog.io/hyperledger/besu-maven' - content { includeGroupByRegex('org\\.hyperledger\\..*') } - } - maven { - url "https://artifacts.consensys.net/public/linea-besu/maven/" - content { - includeGroupByRegex('io\\.consensys\\..*') - includeGroupByRegex('org\\.hyperledger\\..*') - } - } - maven { - url 'https://artifacts.consensys.net/public/maven/maven/' - content { includeGroupByRegex('tech\\.pegasys(\\..*)?') } - } - maven { - url 'https://splunk.jfrog.io/splunk/ext-releases-local' - content { includeGroupByRegex('com\\.splunk\\..*') } - } - maven { - url 'https://dl.cloudsmith.io/public/libp2p/jvm-libp2p/maven/' - content { includeGroup('io.libp2p') } - } - maven { - url "https://jitpack.io" - content { includeGroup('com.github.multiformats')} - } - mavenLocal() -} - -dependencies { - // - testImplementation platform("org.junit:junit-bom") - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - testImplementation 'org.junit.jupiter:junit-jupiter' - testImplementation 'org.assertj:assertj-core' - testImplementation 'org.mockito:mockito-core' - // TODO: org.mockito.kotlin:mockito-kotlin uses org.mockito:mockito-core:4.5.1, - // check later on if this may raise incompatibilities - testImplementation 'org.mockito.kotlin:mockito-kotlin' - testImplementation 'org.awaitility:awaitility-kotlin' - // -} - -tasks.named('test') { - // Use JUnit Platform for unit tests. - useJUnitPlatform() -} diff --git a/maru/buildSrc/src/main/groovy/maru.kotlin-library-conventions.gradle b/maru/buildSrc/src/main/groovy/maru.kotlin-library-conventions.gradle deleted file mode 100644 index 84e12d2fd0b..00000000000 --- a/maru/buildSrc/src/main/groovy/maru.kotlin-library-conventions.gradle +++ /dev/null @@ -1,4 +0,0 @@ -plugins { - id 'maru.kotlin-common-conventions' - id 'java-library' -} diff --git a/maru/buildSrc/src/main/groovy/maru.kotlin-library-minimal-conventions.gradle b/maru/buildSrc/src/main/groovy/maru.kotlin-library-minimal-conventions.gradle deleted file mode 100644 index 9fab3c82b64..00000000000 --- a/maru/buildSrc/src/main/groovy/maru.kotlin-library-minimal-conventions.gradle +++ /dev/null @@ -1,5 +0,0 @@ -// Could be useful for consolidating a set of dependencies without any actual classes -plugins { - id 'maru.kotlin-common-minimal-conventions' - id 'java-library' -} From 3f8a98cf844918ecd2ad912f0f58aa44ac44d355 Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Thu, 14 May 2026 19:25:53 -0400 Subject: [PATCH 04/13] build(maru): add libp2p, JitPack, Splunk repos to common-minimal conventions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Required for the imported maru subprojects which depend on: - io.libp2p:jvm-libp2p (cloudsmith) — used by maru's p2p, crypto, utils - com.github.multiformats:* (jitpack) — libp2p transitive - com.splunk.* — parity with maru's previous build setup Each repository is content-filtered to the specific group(s) it serves so resolution doesn't unnecessarily query these endpoints for unrelated artifacts. --- ...kevm.kotlin-common-minimal-conventions.gradle | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/buildSrc/src/main/groovy/net.consensys.zkevm.kotlin-common-minimal-conventions.gradle b/buildSrc/src/main/groovy/net.consensys.zkevm.kotlin-common-minimal-conventions.gradle index 06430f099e7..d5cc96c6fe5 100644 --- a/buildSrc/src/main/groovy/net.consensys.zkevm.kotlin-common-minimal-conventions.gradle +++ b/buildSrc/src/main/groovy/net.consensys.zkevm.kotlin-common-minimal-conventions.gradle @@ -41,6 +41,22 @@ repositories { maven { url "https://artifacts.consensys.net/public/maven/maven/" } + // Repositories required for the imported maru subprojects: + // - io.libp2p:jvm-libp2p (used by maru's p2p / crypto / utils modules) + // - com.github.multiformats:* (libp2p transitive) + // - com.splunk.* (parity with maru's previous build setup) + maven { + url "https://dl.cloudsmith.io/public/libp2p/jvm-libp2p/maven/" + content { includeGroup('io.libp2p') } + } + maven { + url "https://jitpack.io" + content { includeGroup('com.github.multiformats') } + } + maven { + url 'https://splunk.jfrog.io/splunk/ext-releases-local' + content { includeGroupByRegex('com\\.splunk\\..*') } + } // to allow locally published artifacts to be resolved uncomment enable mavenLocal() below // build.linea:blob-compressor:2.0.0-SNAPSHOT // useful to test WIP development versions From 3cb1fa9a9a153cb0ff200bf503c36e541eff15ab Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Thu, 14 May 2026 19:28:14 -0400 Subject: [PATCH 05/13] build(maru): include :maru:* subprojects in monorepo settings.gradle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds 22 includes mirroring maru's original settings.gradle layout, with paths re-rooted under :maru:* (e.g. ':app' → ':maru:app', 'jvm-libs:extensions' → 'maru:jvm-libs:extensions'). The 'include maru' line ties maru's existing build.gradle to the :maru subproject; the next commit gutts that file to drop dependencies on the removed maru/buildSrc + gradle/versions.gradle. --- settings.gradle | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/settings.gradle b/settings.gradle index 309403f8729..583350e82a4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -79,3 +79,28 @@ include 'tracer:arithmetization' include 'tracer:plugins' include 'tracer:reference-tests' include 'tracer:testing' + +// maru — beacon chain client. Imported from Consensys/maru via +// `git filter-repo --to-subdirectory-filter maru` + merge. +include 'maru' +include 'maru:api' +include 'maru:app' +include 'maru:chaos-testing:health-checker' +include 'maru:config' +include 'maru:consensus' +include 'maru:core' +include 'maru:crypto' +include 'maru:e2e' +include 'maru:executionlayer' +include 'maru:jvm-libs' +include 'maru:jvm-libs:extensions' +include 'maru:jvm-libs:mappers' +include 'maru:jvm-libs:teku-web3j' +include 'maru:jvm-libs:test-utils' +include 'maru:jvm-libs:utils' +include 'maru:linea-finalization-provider' +include 'maru:observability' +include 'maru:p2p' +include 'maru:serialization' +include 'maru:storage' +include 'maru:syncing' From 4f284fd7e99247a647f0fbcbb2ada84d458398aa Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Thu, 14 May 2026 19:29:32 -0400 Subject: [PATCH 06/13] build(maru): expose dependencyManagement plugin to subprojects The io.spring.dependency-management plugin is added with 'apply false' on the root project's plugin classpath so maru subprojects can apply it via 'alias(libs.plugins.dependencyManagement)' in their own plugins{} block. Maru relies on dependencyManagement for BOM-driven version resolution from maru/gradle/versions.gradle (unversioned 'implementation' declarations resolved via the dependencyManagement{} DSL). A follow-up commit folds versions.gradle into the catalog, after which most subprojects can drop the plugin. --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index a9eafe43ac5..063af303050 100644 --- a/build.gradle +++ b/build.gradle @@ -7,6 +7,12 @@ import java.time.Duration plugins { alias(libs.plugins.spotless) alias(libs.plugins.docker) + // Loaded on the root plugin classpath so maru subprojects can apply it + // via `alias(libs.plugins.dependencyManagement)` in their own plugins{} + // block. Maru continues to use io.spring.dependency-management for its + // BOM-driven version resolution until maru/gradle/versions.gradle is + // folded into the catalog (follow-up commit). + alias(libs.plugins.dependencyManagement) apply false } tasks.register("compileAll") { From b10fa941a806ce6642430394a81447dd3217ae99 Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Thu, 14 May 2026 19:37:00 -0400 Subject: [PATCH 07/13] build(maru): apply zkevm convention plugins and rewrite :maru:* project paths - Switch every maru subproject's apply-plugin line from 'maru.kotlin-X-conventions' to 'net.consensys.zkevm.kotlin-X-conventions'. Maru's conventions were removed in an earlier commit; zkevm's same-named conventions are functional equivalents. - Add 'alias(libs.plugins.dependencyManagement)' to each maru subproject's plugins{} block. Maru relies on this for BOM-driven version resolution from maru/gradle/versions.gradle (unversioned 'implementation' declarations resolved via the dependencyManagement{} DSL). - Apply maru/gradle/versions.gradle directly in each subproject (after the plugins{} block). A parent-level subprojects{ apply from } closure doesn't work because the parent's closure evaluates before the subproject's plugins block has applied dependencyManagement. - Rewrite all 'project(":")' refs in maru's subprojects to 'project(":maru:")'. Maru's internal cross-references like 'project(":api")' previously resolved from maru's own rootProject; in the monorepo they need the full :maru:* path. - Gut maru/build.gradle to a minimal parent that only layers the SPDX license-header + Java importOrder Spotless rules on top of the monorepo's base config. All other configuration (errorprone, jacoco, JaCoCo aggregation, test args, all the allprojects/subprojects boilerplate) is now provided by the monorepo's root build.gradle and zkevm/buildSrc conventions. - Add Vert.x + micrometer + linea metrics/micrometer/vertx-helper deps to maru/app/build.gradle. These were previously bundled by maru's kotlin-application-conventions plugin (deleted with maru/buildSrc); zkevm's lighter kotlin-application-conventions doesn't bundle them, so they go explicit in app/build.gradle. Build is not yet green: build.linea.internal:* deps still resolve as remote artifacts via versions.gradle's lineaPackagesVersion default. The next commit folds gradle/versions.gradle into the catalog and substitutes those refs to local zkevm subprojects. --- maru/api/build.gradle | 15 +- maru/app/build.gradle | 54 ++-- maru/build.gradle | 264 ++---------------- maru/chaos-testing/build.gradle | 5 +- .../chaos-testing/health-checker/build.gradle | 11 +- maru/config/build.gradle | 9 +- maru/consensus/build.gradle | 27 +- maru/core/build.gradle | 17 +- maru/crypto/build.gradle | 9 +- maru/e2e/build.gradle | 25 +- maru/executionlayer/build.gradle | 15 +- maru/jvm-libs/build.gradle | 5 +- maru/jvm-libs/extensions/build.gradle | 5 +- maru/jvm-libs/mappers/build.gradle | 9 +- maru/jvm-libs/teku-web3j/build.gradle | 5 +- maru/jvm-libs/test-utils/build.gradle | 19 +- maru/jvm-libs/utils/build.gradle | 7 +- maru/linea-finalization-provider/build.gradle | 9 +- maru/observability/build.gradle | 7 +- maru/p2p/build.gradle | 25 +- maru/serialization/build.gradle | 15 +- maru/storage/build.gradle | 15 +- maru/syncing/build.gradle | 33 ++- 23 files changed, 239 insertions(+), 366 deletions(-) diff --git a/maru/api/build.gradle b/maru/api/build.gradle index 9be5d670f7b..db1423f4dc6 100644 --- a/maru/api/build.gradle +++ b/maru/api/build.gradle @@ -1,17 +1,20 @@ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { implementation "build.linea.internal:metrics" implementation "build.linea.internal:long-running-service" implementation "com.fasterxml.jackson.module:jackson-module-kotlin" implementation "io.javalin:javalin" - implementation project(":core") - implementation project(":p2p") - implementation project(":jvm-libs:extensions") + implementation project(':maru:core') + implementation project(':maru:p2p') + implementation project(':maru:jvm-libs:extensions') - testImplementation(testFixtures(project(":core"))) - testImplementation(project(":syncing")) + testImplementation(testFixtures(project(':maru:core'))) + testImplementation(project(':maru:syncing')) testImplementation("com.squareup.okhttp3:okhttp") } diff --git a/maru/app/build.gradle b/maru/app/build.gradle index 65c667136fc..2c98ac861b4 100644 --- a/maru/app/build.gradle +++ b/maru/app/build.gradle @@ -2,9 +2,12 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { - id 'maru.kotlin-application-conventions' + id 'net.consensys.zkevm.kotlin-application-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + sourceSets { integrationTest { kotlin { @@ -17,31 +20,40 @@ sourceSets { } dependencies { - implementation(project(":api")) - implementation(project(":config")) - implementation(project(":consensus")) - implementation(project(":core")) - implementation(project(":executionlayer")) - implementation(project(":p2p")) - implementation(project(":storage")) - implementation(project(":syncing")) - implementation(project(":crypto")) - implementation(project(":serialization")) - implementation(project(":observability")) - implementation(project(":syncing")) - implementation(project(":jvm-libs:teku-web3j")) - api(project(":linea-finalization-provider")) { + implementation(project(':maru:api')) + implementation(project(':maru:config')) + implementation(project(':maru:consensus')) + implementation(project(':maru:core')) + implementation(project(':maru:executionlayer')) + implementation(project(':maru:p2p')) + implementation(project(':maru:storage')) + implementation(project(':maru:syncing')) + implementation(project(':maru:crypto')) + implementation(project(':maru:serialization')) + implementation(project(':maru:observability')) + implementation(project(':maru:syncing')) + implementation(project(':maru:jvm-libs:teku-web3j')) + api(project(':maru:linea-finalization-provider')) { exclude group: "build.linea", module: "besu-libs" } implementation("build.linea.internal:web3j-extensions") { exclude group: "build.linea", module: "besu-libs" } - implementation(project(":jvm-libs:extensions")) - implementation(project(":jvm-libs:mappers")) + implementation(project(':maru:jvm-libs:extensions')) + implementation(project(':maru:jvm-libs:mappers')) implementation "build.linea.internal:futures" implementation "build.linea.internal:long-running-service" + // Previously inherited from maru's `maru.kotlin-application-conventions` plugin (which the + // import dropped in favor of zkevm's lighter `net.consensys.zkevm.kotlin-application-conventions`). + // Resolved via maru/gradle/versions.gradle until the catalog fold replaces these with project + // references / catalog accessors. + implementation "build.linea.internal:metrics" + implementation "build.linea.internal:micrometer" + implementation "build.linea.internal:vertx-helper" + implementation "io.vertx:vertx-micrometer-metrics" + implementation "info.picocli:picocli" implementation "com.sksamuel.hoplite:hoplite-core" @@ -54,9 +66,9 @@ dependencies { integrationTestRuntimeOnly("org.junit.platform:junit-platform-launcher") integrationTestImplementation 'org.jetbrains.kotlinx:kotlinx-datetime' - integrationTestImplementation(project(":jvm-libs:test-utils")) - integrationTestImplementation(testFixtures(project(":p2p"))) - integrationTestImplementation(testFixtures(project(":crypto"))) + integrationTestImplementation(project(':maru:jvm-libs:test-utils')) + integrationTestImplementation(testFixtures(project(':maru:p2p'))) + integrationTestImplementation(testFixtures(project(':maru:crypto'))) integrationTestImplementation("org.hyperledger.besu.internal:besu-crypto-services") integrationTestImplementation "org.hyperledger.besu.internal:besu-ethereum-api" integrationTestImplementation(group: 'org.hyperledger.besu.internal', name: 'besu-ethereum-core', classifier: 'test-support') @@ -64,7 +76,7 @@ dependencies { integrationTestImplementation("org.hyperledger.besu.internal:besu-consensus-qbft-core") integrationTestImplementation("com.squareup.okhttp3:okhttp") integrationTestImplementation("io.javalin:javalin") - testImplementation(testFixtures(project(":core"))) + testImplementation(testFixtures(project(':maru:core'))) } // Besu and Teku have similar versioning and some modules are also named the same. This creates conflicts when diff --git a/maru/build.gradle b/maru/build.gradle index 265b8ab2644..d499b07afce 100644 --- a/maru/build.gradle +++ b/maru/build.gradle @@ -1,239 +1,37 @@ -import net.ltgt.gradle.errorprone.CheckSeverity -import org.gradle.api.tasks.testing.logging.TestExceptionFormat -import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask - -plugins { - alias(libs.plugins.errorprone) - alias(libs.plugins.spotless) - alias(libs.plugins.spring.dependency.management) - id "jacoco" - id 'maru.kotlin-common-minimal-conventions' -} - -subprojects.each { - - if (!it.project.plugins.hasPlugin("org.jetbrains.kotlin.jvm")) { - it.project.apply plugin: libs.plugins.errorprone.get().getPluginId() - - it.project.dependencies { - errorprone 'com.google.errorprone:error_prone_core' - } - } -} - -allprojects { - apply plugin: libs.plugins.spring.dependency.management.get().getPluginId() - apply from: "${rootDir}/gradle/versions.gradle" - apply plugin: 'java-library' - apply plugin: libs.plugins.spotless.get().getPluginId() - - spotless { - kotlin { - // by default the target is every '.kt' and '.kts` file in the java sourcesets - ktlint(libs.versions.ktlint.get().toString()) - .editorConfigOverride([ - 'ktlint_standard_discouraged-comment-location': 'disabled', - 'ktlint_standard_property-naming': 'disabled', - 'ktlint_standard_function-naming': 'disabled', - 'ktlint_standard_function-signature': 'disabled', - ]) - licenseHeaderFile("${rootDir}/gradle/spotless/java-kotlin.license").onlyIfContentMatches("^(?!/\\*\\r?\\n \\*." + - "*ConsenSys AG\\.)") - } - java { - // This path needs to be relative to each project - target 'src/**/*.java' - removeUnusedImports() - googleJavaFormat() - importOrder 'build.linea', 'java', '' - trimTrailingWhitespace() - endWithNewline() - // apply appropriate license header files. - licenseHeaderFile("${rootDir}/gradle/spotless/java-kotlin.license").onlyIfContentMatches("^(?!/\\*\\r?\\n \\*." + - "*ConsenSys AG\\.)") - } - // spotless check applied to build.gradle (groovy) files - groovyGradle { - target '*.gradle' - greclipse("4.35") - leadingTabsToSpaces(2) - endWithNewline() - } - } - - tasks.withType(KotlinCompilationTask) { - compilerOptions { - freeCompilerArgs.add("-Xannotation-default-target=param-property") - } - } - - tasks.withType(JavaCompile).configureEach { - options.compilerArgs += [ - '-Xlint:unchecked', - '-Xlint:cast', - '-Xlint:rawtypes', - '-Xlint:overloads', - '-Xlint:divzero', - '-Xlint:finally', - '-Xlint:static', - '-Werror', - ] - - options.errorprone { - excludedPaths = '.*/generated/*.*' - disableWarningsInGeneratedCode = true - // Our equals need to be symmetric, this checker doesn't respect that. - check('EqualsGetClass', CheckSeverity.OFF) - // We like to use futures with no return values. - check('FutureReturnValueIgnored', CheckSeverity.OFF) - // We use the JSR-305 annotations instead of the Google annotations. - check('ImmutableEnumChecker', CheckSeverity.OFF) - // This is a style check instead of an error-prone pattern. - check('UnnecessaryParentheses', CheckSeverity.OFF) - - // This check is broken in Java 12. See https://github.com/google/error-prone/issues/1257 - if (JavaVersion.current() == JavaVersion.VERSION_12) { - check('Finally', CheckSeverity.OFF) - } - // This check is broken after Java 12. See https://github.com/google/error-prone/issues/1352 - if (JavaVersion.current() > JavaVersion.VERSION_12) { - check('TypeParameterUnusedInFormals', CheckSeverity.OFF) - } - - check('FieldCanBeFinal', CheckSeverity.WARN) - check('InsecureCryptoUsage', CheckSeverity.WARN) - check('WildcardImport', CheckSeverity.WARN) - } - - options.encoding = 'UTF-8' - } - - // IntelliJ workaround to allow repeated debugging of unchanged code - tasks.withType(JavaExec).configureEach { - if (it.name.contains(".")) { - outputs.upToDateWhen { false } - } - } - - test { - jvmArgs += [ - // JDK 22+: Netty (Vert.x 5) loads native libs from the unnamed module; this opts in so tests do not fail on restricted native access. - '--enable-native-access=ALL-UNNAMED', - '-Xmx4g', - '-XX:-UseGCOverheadLimit', - // Mockito and jackson-databind do some strange reflection during tests. - // This suppresses an illegal access warning. - '--add-opens', - 'java.base/java.util=ALL-UNNAMED', - '--add-opens', - 'java.base/java.util.concurrent=ALL-UNNAMED', - '--add-opens', - 'java.base/java.util.concurrent.atomic=ALL-UNNAMED', - // errorprone tests need access to the javac compiler - '--add-exports', - 'jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED', - '--add-exports', - 'jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED', - '--add-exports', - 'jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED', - '--add-exports', - 'jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED', - '--add-exports', - 'jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED', - '--add-exports', - 'jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED', - '--add-exports', - 'jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED', - '--add-exports', - 'jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED' - ] - Set toImport = [ - 'test.ethereum.include', - 'test.ethereum.state.eip', - 'root.log.level', - 'evm.log.level', - 'acctests.keepLogsOfPassingTests' - ] - for (String name : toImport) { - if (System.getProperty(name) != null) { - systemProperty name, System.getProperty(name) - } - } - useJUnitPlatform {} - testLogging { - exceptionFormat TestExceptionFormat.FULL - events 'skipped', 'failed' - showStandardStreams = false - } - } - - tasks.withType(Test).configureEach { - // Same as test.jvmArgs above: Vert.x / Netty native access on modern JDKs (also applies to other Test task types). - jvmArgs("--enable-native-access=ALL-UNNAMED") - // Java 25: Byte Buddy (pulled in by Mockito inline mocks) may not list 25 as supported yet; - // this flag opts in so tests run until Byte Buddy catches up. - jvmArgs("-Dnet.bytebuddy.experimental=true") - systemProperties["junit.jupiter.execution.parallel.enabled"] = true - systemProperties["junit.jupiter.execution.parallel.mode.default"] = "concurrent" - systemProperties["junit.jupiter.execution.parallel.mode.classes.default"] = "concurrent" - maxParallelForks = 1 - } -} +// :maru is the parent project for the maru beacon-chain client subtree, imported +// from Consensys/maru via `git filter-repo --to-subdirectory-filter maru` + merge +// (see PR that landed the import). Convention plugins (Kotlin/Java setup, base +// Spotless ktlint, JUnit, JaCoCo) come from the monorepo's root build.gradle and +// zkevm/buildSrc conventions. Each maru subproject's plugins{} block also +// applies `libs.plugins.dependencyManagement` and then `apply from: maru/gradle/ +// versions.gradle` directly (the parent's subprojects{} closure cannot reliably +// apply versions.gradle because Gradle evaluates parent's subprojects{} BEFORE +// the subproject's plugins{} block has run, so the dependencyManagement DSL +// isn't yet on the script's classpath at that point). +// +// This file adds the only maru-local concern that isn't part of the monorepo's +// defaults: the SPDX dual MIT/Apache license-header rule + Java importOrder, +// layered on top of the monorepo's base Spotless ktlint / googleJavaFormat +// config. The monorepo doesn't enforce headers; maru retains them so the +// licensing markers stay on every Kotlin and Java file. subprojects { - apply plugin: "jacoco" - - tasks.withType(JavaCompile) { - options.fork = true - options.incremental = true - } - - configurations { - testSupportImplementation.extendsFrom implementation - testSupportArtifacts - } - - // Gradle 9: do not declare `integrationTestImplementation` in the `configurations { }` block above. - // Defining it before `sourceSets { integrationTest { } }` (e.g. in :app) causes a duplicate name error. - // After evaluation, extend the configuration only if the integrationTest source set created it. afterEvaluate { subproject -> - def integrationTestImpl = subproject.configurations.findByName("integrationTestImplementation") - if (integrationTestImpl != null) { - integrationTestImpl.extendsFrom(subproject.configurations.implementation) - } - - // making sure assemble task invokes integration test compile - project.tasks.jacocoTestReport { - if (project.tasks.findByName('acceptanceTest')) { - executionData(tasks.named("acceptanceTest").get()) - sourceSets(sourceSets.named("acceptanceTest").get()) + if (subproject.plugins.hasPlugin('com.diffplug.spotless')) { + subproject.spotless { + kotlin { + licenseHeaderFile( + "${project.rootDir}/maru/gradle/spotless/java-kotlin.license" + ).onlyIfContentMatches("^(?!/\\*\\r?\\n \\*.*ConsenSys AG\\.)") + } + java { + target 'src/**/*.java' + importOrder 'build.linea', 'java', '' + licenseHeaderFile( + "${project.rootDir}/maru/gradle/spotless/java-kotlin.license" + ).onlyIfContentMatches("^(?!/\\*\\r?\\n \\*.*ConsenSys AG\\.)") + } } } - - if (subproject.tasks.findByName('compileIntegrationTestJava')) { - subproject.tasks.assemble.dependsOn compileIntegrationTestJava - } } -} - -task jacocoAggregatedReport(type: JacocoReport) { - group = "verification" - - additionalSourceDirs.from files(subprojects.sourceSets.main.allSource.srcDirs) - sourceDirectories.from files(subprojects.sourceSets.main.allSource.srcDirs) - classDirectories.from files(subprojects.sourceSets.main.output) - - executionData.from fileTree(dir: '.', includes: ['**/jacoco/*.exec']) - reports { - xml.required = true - html.required = true - // Gradle 9: `html.destination` was removed from the reporting API; use `outputLocation` instead. - html.outputLocation.set(layout.buildDirectory.dir("reports/jacocoHtml")) - } -} - -apply plugin: 'application' - -run { - // TODO: Fill -} +} \ No newline at end of file diff --git a/maru/chaos-testing/build.gradle b/maru/chaos-testing/build.gradle index 077675e0ac3..f033c264dc6 100644 --- a/maru/chaos-testing/build.gradle +++ b/maru/chaos-testing/build.gradle @@ -14,5 +14,8 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } + +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" diff --git a/maru/chaos-testing/health-checker/build.gradle b/maru/chaos-testing/health-checker/build.gradle index 8c0451db352..a00a7f1ba66 100644 --- a/maru/chaos-testing/health-checker/build.gradle +++ b/maru/chaos-testing/health-checker/build.gradle @@ -2,13 +2,16 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(project(":jvm-libs:extensions")) - implementation project(":jvm-libs:test-utils") - implementation project(":api") + implementation(project(':maru:jvm-libs:extensions')) + implementation project(':maru:jvm-libs:test-utils') + implementation project(':maru:api') implementation("build.linea.internal:file-system") implementation("build.linea.internal:web3j-extensions") { exclude group: "build.linea", module: "besu-libs" diff --git a/maru/config/build.gradle b/maru/config/build.gradle index 483ec97f07b..262cf326c1a 100644 --- a/maru/config/build.gradle +++ b/maru/config/build.gradle @@ -14,12 +14,15 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(project(":jvm-libs:extensions")) - implementation(project(":core")) + implementation(project(':maru:jvm-libs:extensions')) + implementation(project(':maru:core')) api("build.linea.internal:domain-models") api("build.linea.internal:kotlin") diff --git a/maru/consensus/build.gradle b/maru/consensus/build.gradle index b404a49feda..a85d1088d7d 100644 --- a/maru/consensus/build.gradle +++ b/maru/consensus/build.gradle @@ -14,18 +14,21 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(project(":core")) - implementation(project(":serialization")) - implementation(project(":config")) - implementation(project(":p2p")) - implementation(project(":crypto")) - implementation(project(":jvm-libs:extensions")) - implementation(project(":jvm-libs:mappers")) - implementation(project(":executionlayer")) { + implementation(project(':maru:core')) + implementation(project(':maru:serialization')) + implementation(project(':maru:config')) + implementation(project(':maru:p2p')) + implementation(project(':maru:crypto')) + implementation(project(':maru:jvm-libs:extensions')) + implementation(project(':maru:jvm-libs:mappers')) + implementation(project(':maru:executionlayer')) { because "because of protocol builders" } @@ -52,9 +55,9 @@ dependencies { implementation "build.linea.internal:long-running-service" - testImplementation(testFixtures(project(":core"))) - testImplementation(testFixtures(project(":crypto"))) - testImplementation(project(":jvm-libs:test-utils")) + testImplementation(testFixtures(project(':maru:core'))) + testImplementation(testFixtures(project(':maru:crypto'))) + testImplementation(project(':maru:jvm-libs:test-utils')) testImplementation "org.jetbrains.kotlin:kotlin-test:2.1.0" testImplementation "tech.pegasys.teku.internal:executionclient" testImplementation "tech.pegasys.teku.internal:spec" diff --git a/maru/core/build.gradle b/maru/core/build.gradle index 63b2a954b31..9e242655e38 100644 --- a/maru/core/build.gradle +++ b/maru/core/build.gradle @@ -14,18 +14,21 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) id 'java-test-fixtures' } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(project(":jvm-libs:extensions")) + implementation(project(':maru:jvm-libs:extensions')) implementation "build.linea.internal:kotlin" implementation "build.linea.internal:metrics" implementation "build.linea.internal:long-running-service" implementation "io.consensys.tuweni:tuweni-bytes" implementation "org.jetbrains.kotlin:kotlin-reflect" - testImplementation(project(":serialization")) + testImplementation(project(':maru:serialization')) testFixturesImplementation("org.hyperledger.besu:besu-datatypes") testFixturesImplementation("org.hyperledger.besu:besu-plugin-api") testFixturesImplementation("org.hyperledger.besu.internal:besu-ethereum-core") @@ -33,8 +36,8 @@ dependencies { testFixturesImplementation("build.linea.internal:kotlin") testFixturesImplementation("build.linea.internal:metrics") testFixturesImplementation("build.linea.internal:micrometer") - testFixturesImplementation(project(":serialization")) - testFixturesImplementation(project(":observability")) - testFixturesImplementation(project(":p2p")) - testFixturesImplementation(project(":crypto")) + testFixturesImplementation(project(':maru:serialization')) + testFixturesImplementation(project(':maru:observability')) + testFixturesImplementation(project(':maru:p2p')) + testFixturesImplementation(project(':maru:crypto')) } diff --git a/maru/crypto/build.gradle b/maru/crypto/build.gradle index 0107733592a..fe9e73fa523 100644 --- a/maru/crypto/build.gradle +++ b/maru/crypto/build.gradle @@ -1,11 +1,14 @@ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) id 'java-test-fixtures' } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(project(":core")) - implementation(project(":jvm-libs:extensions")) + implementation(project(':maru:core')) + implementation(project(':maru:jvm-libs:extensions')) implementation("org.hyperledger.besu:besu-datatypes") implementation("org.hyperledger.besu.internal:besu-crypto-algorithms") implementation("org.hyperledger.besu.internal:besu-crypto-services") diff --git a/maru/e2e/build.gradle b/maru/e2e/build.gradle index 53ca086776e..316b0e442bd 100644 --- a/maru/e2e/build.gradle +++ b/maru/e2e/build.gradle @@ -2,21 +2,24 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation project(":core") - implementation project(":app") - implementation project(":consensus") - implementation project(":executionlayer") - implementation project(":config") - implementation project(":p2p") + implementation project(':maru:core') + implementation project(':maru:app') + implementation project(':maru:consensus') + implementation project(':maru:executionlayer') + implementation project(':maru:config') + implementation project(':maru:p2p') // For the syncing logic - implementation project(":jvm-libs:mappers") - implementation(project(":serialization")) - implementation(project(":jvm-libs:extensions")) - implementation project(":jvm-libs:test-utils") + implementation project(':maru:jvm-libs:mappers') + implementation(project(':maru:serialization')) + implementation(project(':maru:jvm-libs:extensions')) + implementation project(':maru:jvm-libs:test-utils') implementation "tech.pegasys.teku.internal:executionclient" implementation "tech.pegasys.teku.internal:time" diff --git a/maru/executionlayer/build.gradle b/maru/executionlayer/build.gradle index d2b1e38a241..d21e71ff9a9 100644 --- a/maru/executionlayer/build.gradle +++ b/maru/executionlayer/build.gradle @@ -14,15 +14,18 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(project(":core")) - implementation(project(":config")) + implementation(project(':maru:core')) + implementation(project(':maru:config')) - implementation(project(":jvm-libs:mappers")) - implementation(project(":jvm-libs:extensions")) + implementation(project(':maru:jvm-libs:mappers')) + implementation(project(':maru:jvm-libs:extensions')) api "tech.pegasys.teku.internal:executionclient" @@ -34,6 +37,6 @@ dependencies { implementation "build.linea.internal:metrics" testImplementation (group: 'tech.pegasys.teku.internal', name: 'spec', classifier: 'test-fixtures') - testImplementation(testFixtures(project(":core"))) + testImplementation(testFixtures(project(':maru:core'))) testImplementation(testFixtures('build.linea.internal:kotlin')) } diff --git a/maru/jvm-libs/build.gradle b/maru/jvm-libs/build.gradle index b3f55342591..1101c018e85 100644 --- a/maru/jvm-libs/build.gradle +++ b/maru/jvm-libs/build.gradle @@ -14,8 +14,11 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { } diff --git a/maru/jvm-libs/extensions/build.gradle b/maru/jvm-libs/extensions/build.gradle index 297f59d3a50..9f618171059 100644 --- a/maru/jvm-libs/extensions/build.gradle +++ b/maru/jvm-libs/extensions/build.gradle @@ -14,9 +14,12 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { implementation "build.linea.internal:metrics" implementation "build.linea.internal:futures" diff --git a/maru/jvm-libs/mappers/build.gradle b/maru/jvm-libs/mappers/build.gradle index e7255f20e60..d771857f0fa 100644 --- a/maru/jvm-libs/mappers/build.gradle +++ b/maru/jvm-libs/mappers/build.gradle @@ -14,12 +14,15 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(project(":core")) - implementation(project(":jvm-libs:extensions")) + implementation(project(':maru:core')) + implementation(project(':maru:jvm-libs:extensions')) implementation "tech.pegasys.teku.internal:unsigned" implementation "tech.pegasys.teku.internal:bytes" diff --git a/maru/jvm-libs/teku-web3j/build.gradle b/maru/jvm-libs/teku-web3j/build.gradle index 26aafed73d9..c64985041b0 100644 --- a/maru/jvm-libs/teku-web3j/build.gradle +++ b/maru/jvm-libs/teku-web3j/build.gradle @@ -14,9 +14,12 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { implementation "tech.pegasys.teku.internal:executionclient" implementation "tech.pegasys.teku.internal:logging" diff --git a/maru/jvm-libs/test-utils/build.gradle b/maru/jvm-libs/test-utils/build.gradle index 64c212634c0..c40e53af9d3 100644 --- a/maru/jvm-libs/test-utils/build.gradle +++ b/maru/jvm-libs/test-utils/build.gradle @@ -1,15 +1,18 @@ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(project(":consensus")) - implementation(project(":app")) - implementation(project(":crypto")) - implementation(testFixtures(project(":crypto"))) - implementation(project(":p2p")) - implementation(project(":config")) - implementation(project(":jvm-libs:extensions")) + implementation(project(':maru:consensus')) + implementation(project(':maru:app')) + implementation(project(':maru:crypto')) + implementation(testFixtures(project(':maru:crypto'))) + implementation(project(':maru:p2p')) + implementation(project(':maru:config')) + implementation(project(':maru:jvm-libs:extensions')) implementation "build.linea.internal:kotlin" implementation "build.linea.internal:long-running-service" diff --git a/maru/jvm-libs/utils/build.gradle b/maru/jvm-libs/utils/build.gradle index 2f13c6f2133..a893a276445 100644 --- a/maru/jvm-libs/utils/build.gradle +++ b/maru/jvm-libs/utils/build.gradle @@ -14,11 +14,14 @@ */ plugins { - id 'maru.kotlin-common-minimal-conventions' + id 'net.consensys.zkevm.kotlin-common-minimal-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(testFixtures(project(":crypto"))) + implementation(testFixtures(project(':maru:crypto'))) implementation "io.libp2p:jvm-libp2p" implementation "tech.pegasys.teku.internal:p2p" implementation "build.linea.internal:kotlin" diff --git a/maru/linea-finalization-provider/build.gradle b/maru/linea-finalization-provider/build.gradle index 7490296a4c2..1883b387318 100644 --- a/maru/linea-finalization-provider/build.gradle +++ b/maru/linea-finalization-provider/build.gradle @@ -14,13 +14,16 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) id 'java-test-fixtures' } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(project(":jvm-libs:extensions")) - api(project(":core")) + implementation(project(':maru:jvm-libs:extensions')) + api(project(':maru:core')) api("build.linea.internal:linea-contract-clients"){ exclude group: "build.linea", module: "besu-libs" } diff --git a/maru/observability/build.gradle b/maru/observability/build.gradle index 49c0bef7e7f..ddfc85122ab 100644 --- a/maru/observability/build.gradle +++ b/maru/observability/build.gradle @@ -1,12 +1,15 @@ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { implementation "build.linea.internal:micrometer" implementation "build.linea.internal:metrics" implementation "org.hyperledger.besu.internal:besu-metrics-core" implementation "org.hyperledger.besu:besu-plugin-api" implementation "com.google.guava:guava" - implementation(project(":core")) + implementation(project(':maru:core')) } diff --git a/maru/p2p/build.gradle b/maru/p2p/build.gradle index 56d8a590748..6df0032a6ec 100644 --- a/maru/p2p/build.gradle +++ b/maru/p2p/build.gradle @@ -14,16 +14,19 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) id 'java-test-fixtures' } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation project(":config") - implementation project(":serialization") - implementation project(":crypto") - implementation project(":core") - implementation project(":observability") + implementation project(':maru:config') + implementation project(':maru:serialization') + implementation project(':maru:crypto') + implementation project(':maru:core') + implementation project(':maru:observability') api "io.libp2p:jvm-libp2p" @@ -50,11 +53,11 @@ dependencies { implementation 'io.consensys.protocols:discovery' implementation 'org.jetbrains.kotlinx:kotlinx-datetime' - implementation(project(":core")) + implementation(project(':maru:core')) - testImplementation(testFixtures(project(":core"))) + testImplementation(testFixtures(project(':maru:core'))) - testFixturesImplementation(project(":serialization")) - testFixturesImplementation(project(":crypto")) - testFixturesImplementation(testFixtures(project(":core"))) + testFixturesImplementation(project(':maru:serialization')) + testFixturesImplementation(project(':maru:crypto')) + testFixturesImplementation(testFixtures(project(':maru:core'))) } diff --git a/maru/serialization/build.gradle b/maru/serialization/build.gradle index 769d9ff6578..cf2bab4f149 100644 --- a/maru/serialization/build.gradle +++ b/maru/serialization/build.gradle @@ -14,19 +14,22 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation(project(":core")) - implementation(project(":config")) - implementation(project(":crypto")) - implementation(project(":jvm-libs:extensions")) + implementation(project(':maru:core')) + implementation(project(':maru:config')) + implementation(project(':maru:crypto')) + implementation(project(':maru:jvm-libs:extensions')) implementation "io.consensys.tuweni:tuweni-bytes" implementation "io.libp2p:jvm-libp2p" implementation "org.hyperledger.besu:besu-datatypes" implementation "org.hyperledger.besu.internal:besu-ethereum-rlp" implementation 'org.xerial.snappy:snappy-java' implementation "tech.pegasys.teku.internal:eth2" - testImplementation(testFixtures(project(":core"))) + testImplementation(testFixtures(project(':maru:core'))) } diff --git a/maru/storage/build.gradle b/maru/storage/build.gradle index 438001416b5..2e25b028ce3 100644 --- a/maru/storage/build.gradle +++ b/maru/storage/build.gradle @@ -14,18 +14,21 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation (project(":core")) - implementation (project(":serialization")) - implementation (project(":jvm-libs:extensions")) + implementation (project(':maru:core')) + implementation (project(':maru:serialization')) + implementation (project(':maru:jvm-libs:extensions')) implementation "org.rocksdb:rocksdbjni" implementation "tech.pegasys.teku.internal:storage" implementation "org.hyperledger.besu.internal:besu-metrics-core" implementation "org.hyperledger.besu:besu-plugin-api" - testImplementation (testFixtures(project(":core"))) - testImplementation (project(":observability")) + testImplementation (testFixtures(project(':maru:core'))) + testImplementation (project(':maru:observability')) testImplementation ("build.linea.internal:metrics") } diff --git a/maru/syncing/build.gradle b/maru/syncing/build.gradle index 1f849f1ff85..e7238525a04 100644 --- a/maru/syncing/build.gradle +++ b/maru/syncing/build.gradle @@ -14,17 +14,20 @@ */ plugins { - id 'maru.kotlin-library-conventions' + id 'net.consensys.zkevm.kotlin-library-conventions' + alias(libs.plugins.dependencyManagement) } +apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" + dependencies { - implementation project(':core') - implementation project(':consensus') - implementation project(':config') - implementation project(':observability') - implementation project(':p2p') - implementation project(':storage') - implementation project(':jvm-libs:extensions') + implementation project(':maru:core') + implementation project(':maru:consensus') + implementation project(':maru:config') + implementation project(':maru:observability') + implementation project(':maru:p2p') + implementation project(':maru:storage') + implementation project(':maru:jvm-libs:extensions') implementation 'build.linea.internal:metrics' implementation 'build.linea.internal:kotlin' implementation 'build.linea.internal:long-running-service' @@ -37,13 +40,13 @@ dependencies { implementation 'tech.pegasys.teku.internal:p2p' implementation "tech.pegasys.teku.internal:eth2" - testImplementation project(':config') - testImplementation project(':crypto') - testImplementation project(':observability') - testImplementation project(':serialization') - testImplementation(testFixtures(project(":core"))) - testImplementation(testFixtures(project(":p2p"))) - testImplementation(project(":jvm-libs:test-utils")) + testImplementation project(':maru:config') + testImplementation project(':maru:crypto') + testImplementation project(':maru:observability') + testImplementation project(':maru:serialization') + testImplementation(testFixtures(project(':maru:core'))) + testImplementation(testFixtures(project(':maru:p2p'))) + testImplementation(project(':maru:jvm-libs:test-utils')) testImplementation 'org.mockito:mockito-core' testImplementation 'org.mockito.kotlin:mockito-kotlin' testImplementation 'org.assertj:assertj-core' From 73580e0fc71b8e30b7a05c5ff57413c0b2e10a56 Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Thu, 14 May 2026 19:45:27 -0400 Subject: [PATCH 08/13] build(maru): substitute build.linea.internal:* with local zkevm subproject refs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maru's subprojects depended on 13 build.linea.internal:* artifacts via versions.gradle's dependencyManagement BOM pins. Those artifacts are products of the zkevm-monorepo build itself, so in the monorepo we wire them as project references instead of remote dependencies. Mapping: build.linea.internal:metrics → :jvm-libs:linea:core:metrics build.linea.internal:micrometer → :jvm-libs:linea:metrics:micrometer build.linea.internal:vertx-helper → :jvm-libs:generic:vertx-helper build.linea.internal:json-rpc → :jvm-libs:generic:json-rpc build.linea.internal:futures → :jvm-libs:generic:extensions:futures build.linea.internal:kotlin → :jvm-libs:generic:extensions:kotlin build.linea.internal:domain-models → :jvm-libs:linea:core:domain-models build.linea.internal:interfaces → :jvm-libs:linea:clients:interfaces build.linea.internal:linea-contract-clients → :jvm-libs:linea:clients:linea-contract-clients build.linea.internal:web3j-extensions → :jvm-libs:linea:web3j-extensions build.linea.internal:file-system → :jvm-libs:linea:testing:file-system build.linea.internal:logging → :jvm-libs:generic:logging build.linea.internal:long-running-service → :jvm-libs:linea:core:long-running-service Two small source fixes were needed for compilation under the monorepo: - QbftFinalStateAdapter.kt:58: '.equals(localAddress)' → '== localAddress' (Kotlin 2.x flags the explicit .equals() call as deprecated; zkevm's -Werror would otherwise fail the build). - ConsensusMetrics.kt:70: drop 'percentileBuckets = [...]' parameter from metricsFacade.createHistogram(). zkevm's :jvm-libs:linea:core:metrics interface does not yet expose that parameter (newer maru-side API). publishPercentileHistogram=true is still set, so histograms still emit percentiles with default buckets. Build is green: './gradlew :maru:app:compileKotlin -x spotlessCheck' succeeds. gradle/versions.gradle is still applied per-subproject and still pins maru-only external deps (Discovery, jvm-libp2p, Javalin, http4k, etc.); the next commit folds those into gradle/libs.versions.toml and removes versions.gradle. --- maru/api/build.gradle | 4 ++-- maru/app/build.gradle | 12 ++++++------ .../app/src/main/kotlin/maru/app/ConsensusMetrics.kt | 6 +++++- maru/chaos-testing/health-checker/build.gradle | 4 ++-- maru/config/build.gradle | 4 ++-- maru/consensus/build.gradle | 4 ++-- .../consensus/qbft/adapters/QbftFinalStateAdapter.kt | 2 +- maru/core/build.gradle | 12 ++++++------ maru/crypto/build.gradle | 4 ++-- maru/e2e/build.gradle | 6 +++--- maru/executionlayer/build.gradle | 4 ++-- maru/jvm-libs/extensions/build.gradle | 4 ++-- maru/jvm-libs/teku-web3j/build.gradle | 4 ++-- maru/jvm-libs/test-utils/build.gradle | 6 +++--- maru/jvm-libs/utils/build.gradle | 2 +- maru/linea-finalization-provider/build.gradle | 6 +++--- maru/observability/build.gradle | 4 ++-- maru/p2p/build.gradle | 6 +++--- maru/storage/build.gradle | 2 +- maru/syncing/build.gradle | 8 ++++---- 20 files changed, 54 insertions(+), 50 deletions(-) diff --git a/maru/api/build.gradle b/maru/api/build.gradle index db1423f4dc6..9a461a9601e 100644 --- a/maru/api/build.gradle +++ b/maru/api/build.gradle @@ -6,8 +6,8 @@ plugins { apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" dependencies { - implementation "build.linea.internal:metrics" - implementation "build.linea.internal:long-running-service" + implementation project(':jvm-libs:linea:core:metrics') + implementation project(':jvm-libs:linea:core:long-running-service') implementation "com.fasterxml.jackson.module:jackson-module-kotlin" implementation "io.javalin:javalin" implementation project(':maru:core') diff --git a/maru/app/build.gradle b/maru/app/build.gradle index 2c98ac861b4..909721c3490 100644 --- a/maru/app/build.gradle +++ b/maru/app/build.gradle @@ -36,22 +36,22 @@ dependencies { api(project(':maru:linea-finalization-provider')) { exclude group: "build.linea", module: "besu-libs" } - implementation("build.linea.internal:web3j-extensions") { + implementation(project(':jvm-libs:linea:web3j-extensions')) { exclude group: "build.linea", module: "besu-libs" } implementation(project(':maru:jvm-libs:extensions')) implementation(project(':maru:jvm-libs:mappers')) - implementation "build.linea.internal:futures" - implementation "build.linea.internal:long-running-service" + implementation project(':jvm-libs:generic:extensions:futures') + implementation project(':jvm-libs:linea:core:long-running-service') // Previously inherited from maru's `maru.kotlin-application-conventions` plugin (which the // import dropped in favor of zkevm's lighter `net.consensys.zkevm.kotlin-application-conventions`). // Resolved via maru/gradle/versions.gradle until the catalog fold replaces these with project // references / catalog accessors. - implementation "build.linea.internal:metrics" - implementation "build.linea.internal:micrometer" - implementation "build.linea.internal:vertx-helper" + implementation project(':jvm-libs:linea:core:metrics') + implementation project(':jvm-libs:linea:metrics:micrometer') + implementation project(':jvm-libs:generic:vertx-helper') implementation "io.vertx:vertx-micrometer-metrics" implementation "info.picocli:picocli" diff --git a/maru/app/src/main/kotlin/maru/app/ConsensusMetrics.kt b/maru/app/src/main/kotlin/maru/app/ConsensusMetrics.kt index 88fa851f085..0d5307c2e52 100644 --- a/maru/app/src/main/kotlin/maru/app/ConsensusMetrics.kt +++ b/maru/app/src/main/kotlin/maru/app/ConsensusMetrics.kt @@ -67,7 +67,11 @@ class ConsensusMetrics( description = description, tags = listOf(Tag("role", role)), publishPercentileHistogram = true, - percentileBuckets = listOf(.5, .8, .95, .99), + // NOTE: zkevm's createHistogram in :jvm-libs:linea:core:metrics does not yet expose + // a `percentileBuckets` parameter (was added in newer maru-side metrics versions). + // Dropping the customized buckets — the publishPercentileHistogram flag still emits + // a percentile histogram with default buckets. Re-add `percentileBuckets` here once + // the zkevm metrics interface gains the parameter. ) // Total consensus latency: timer-fire to block committed (ms). diff --git a/maru/chaos-testing/health-checker/build.gradle b/maru/chaos-testing/health-checker/build.gradle index a00a7f1ba66..d950f187328 100644 --- a/maru/chaos-testing/health-checker/build.gradle +++ b/maru/chaos-testing/health-checker/build.gradle @@ -12,8 +12,8 @@ dependencies { implementation(project(':maru:jvm-libs:extensions')) implementation project(':maru:jvm-libs:test-utils') implementation project(':maru:api') - implementation("build.linea.internal:file-system") - implementation("build.linea.internal:web3j-extensions") { + implementation(project(':jvm-libs:linea:testing:file-system')) + implementation(project(':jvm-libs:linea:web3j-extensions')) { exclude group: "build.linea", module: "besu-libs" } diff --git a/maru/config/build.gradle b/maru/config/build.gradle index 262cf326c1a..5c347bc2af9 100644 --- a/maru/config/build.gradle +++ b/maru/config/build.gradle @@ -23,8 +23,8 @@ apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" dependencies { implementation(project(':maru:jvm-libs:extensions')) implementation(project(':maru:core')) - api("build.linea.internal:domain-models") - api("build.linea.internal:kotlin") + api(project(':jvm-libs:linea:core:domain-models')) + api(project(':jvm-libs:generic:extensions:kotlin')) implementation "com.sksamuel.hoplite:hoplite-toml" implementation "com.sksamuel.hoplite:hoplite-json" diff --git a/maru/consensus/build.gradle b/maru/consensus/build.gradle index a85d1088d7d..490d78e612d 100644 --- a/maru/consensus/build.gradle +++ b/maru/consensus/build.gradle @@ -52,7 +52,7 @@ dependencies { implementation "tech.pegasys.teku.internal:executionclient" implementation "tech.pegasys.teku.internal:spec" - implementation "build.linea.internal:long-running-service" + implementation project(':jvm-libs:linea:core:long-running-service') testImplementation(testFixtures(project(':maru:core'))) @@ -61,5 +61,5 @@ dependencies { testImplementation "org.jetbrains.kotlin:kotlin-test:2.1.0" testImplementation "tech.pegasys.teku.internal:executionclient" testImplementation "tech.pegasys.teku.internal:spec" - testImplementation "build.linea.internal:metrics" + testImplementation project(':jvm-libs:linea:core:metrics') } diff --git a/maru/consensus/src/main/kotlin/maru/consensus/qbft/adapters/QbftFinalStateAdapter.kt b/maru/consensus/src/main/kotlin/maru/consensus/qbft/adapters/QbftFinalStateAdapter.kt index e95c095eecb..ebae8e944ba 100644 --- a/maru/consensus/src/main/kotlin/maru/consensus/qbft/adapters/QbftFinalStateAdapter.kt +++ b/maru/consensus/src/main/kotlin/maru/consensus/qbft/adapters/QbftFinalStateAdapter.kt @@ -55,5 +55,5 @@ class QbftFinalStateAdapter( override fun getBlockTimer(): BlockTimer = blockTimer override fun isLocalNodeProposerForRound(roundIdentifier: ConsensusRoundIdentifier): Boolean = - proposerSelector.selectProposerForRound(roundIdentifier).equals(localAddress) + proposerSelector.selectProposerForRound(roundIdentifier) == localAddress } diff --git a/maru/core/build.gradle b/maru/core/build.gradle index 9e242655e38..aab2a569296 100644 --- a/maru/core/build.gradle +++ b/maru/core/build.gradle @@ -23,9 +23,9 @@ apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" dependencies { implementation(project(':maru:jvm-libs:extensions')) - implementation "build.linea.internal:kotlin" - implementation "build.linea.internal:metrics" - implementation "build.linea.internal:long-running-service" + implementation project(':jvm-libs:generic:extensions:kotlin') + implementation project(':jvm-libs:linea:core:metrics') + implementation project(':jvm-libs:linea:core:long-running-service') implementation "io.consensys.tuweni:tuweni-bytes" implementation "org.jetbrains.kotlin:kotlin-reflect" testImplementation(project(':maru:serialization')) @@ -33,9 +33,9 @@ dependencies { testFixturesImplementation("org.hyperledger.besu:besu-plugin-api") testFixturesImplementation("org.hyperledger.besu.internal:besu-ethereum-core") testFixturesImplementation("org.hyperledger.besu.internal:besu-crypto-algorithms") - testFixturesImplementation("build.linea.internal:kotlin") - testFixturesImplementation("build.linea.internal:metrics") - testFixturesImplementation("build.linea.internal:micrometer") + testFixturesImplementation(project(':jvm-libs:generic:extensions:kotlin')) + testFixturesImplementation(project(':jvm-libs:linea:core:metrics')) + testFixturesImplementation(project(':jvm-libs:linea:metrics:micrometer')) testFixturesImplementation(project(':maru:serialization')) testFixturesImplementation(project(':maru:observability')) testFixturesImplementation(project(':maru:p2p')) diff --git a/maru/crypto/build.gradle b/maru/crypto/build.gradle index fe9e73fa523..2643b7042a5 100644 --- a/maru/crypto/build.gradle +++ b/maru/crypto/build.gradle @@ -17,10 +17,10 @@ dependencies { testFixturesImplementation "io.libp2p:jvm-libp2p" testFixturesImplementation "tech.pegasys.teku.internal:p2p" - testFixturesImplementation "build.linea.internal:kotlin" + testFixturesImplementation project(':jvm-libs:generic:extensions:kotlin') testFixturesImplementation "io.consensys.tuweni:tuweni-bytes" testFixturesImplementation "org.hyperledger.besu.internal:besu-crypto-algorithms" testFixturesImplementation "org.hyperledger.besu.internal:besu-crypto-services" - testImplementation "build.linea.internal:kotlin" + testImplementation project(':jvm-libs:generic:extensions:kotlin') } diff --git a/maru/e2e/build.gradle b/maru/e2e/build.gradle index 316b0e442bd..f20b5e81bb2 100644 --- a/maru/e2e/build.gradle +++ b/maru/e2e/build.gradle @@ -37,9 +37,9 @@ dependencies { implementation('com.palantir.docker.compose:docker-compose-junit-jupiter') implementation "org.hyperledger.besu.internal:besu-acceptance-tests-dsl" - implementation "build.linea.internal:metrics" - implementation "build.linea.internal:micrometer" - implementation "build.linea.internal:long-running-service" + implementation project(':jvm-libs:linea:core:metrics') + implementation project(':jvm-libs:linea:metrics:micrometer') + implementation project(':jvm-libs:linea:core:long-running-service') } sourceSets { diff --git a/maru/executionlayer/build.gradle b/maru/executionlayer/build.gradle index d21e71ff9a9..6c02cc1464e 100644 --- a/maru/executionlayer/build.gradle +++ b/maru/executionlayer/build.gradle @@ -34,9 +34,9 @@ dependencies { implementation "tech.pegasys.teku.internal:unsigned" implementation "tech.pegasys.teku.internal:bytes" implementation "tech.pegasys.teku.internal:spec" - implementation "build.linea.internal:metrics" + implementation project(':jvm-libs:linea:core:metrics') testImplementation (group: 'tech.pegasys.teku.internal', name: 'spec', classifier: 'test-fixtures') testImplementation(testFixtures(project(':maru:core'))) - testImplementation(testFixtures('build.linea.internal:kotlin')) + testImplementation(testFixtures(project(':jvm-libs:generic:extensions:kotlin'))) } diff --git a/maru/jvm-libs/extensions/build.gradle b/maru/jvm-libs/extensions/build.gradle index 9f618171059..209b5fde19a 100644 --- a/maru/jvm-libs/extensions/build.gradle +++ b/maru/jvm-libs/extensions/build.gradle @@ -21,7 +21,7 @@ plugins { apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" dependencies { - implementation "build.linea.internal:metrics" - implementation "build.linea.internal:futures" + implementation project(':jvm-libs:linea:core:metrics') + implementation project(':jvm-libs:generic:extensions:futures') implementation "tech.pegasys.teku.internal:executionclient" } diff --git a/maru/jvm-libs/teku-web3j/build.gradle b/maru/jvm-libs/teku-web3j/build.gradle index c64985041b0..7209512c2c5 100644 --- a/maru/jvm-libs/teku-web3j/build.gradle +++ b/maru/jvm-libs/teku-web3j/build.gradle @@ -26,6 +26,6 @@ dependencies { implementation "tech.pegasys.teku.internal:time" implementation "tech.pegasys.teku.internal:ethereum-events" implementation "tech.pegasys.teku.internal:infrastructure-events" - implementation "build.linea.internal:logging" - implementation "build.linea.internal:json-rpc" + implementation project(':jvm-libs:generic:logging') + implementation project(':jvm-libs:generic:json-rpc') } diff --git a/maru/jvm-libs/test-utils/build.gradle b/maru/jvm-libs/test-utils/build.gradle index c40e53af9d3..159e89983ce 100644 --- a/maru/jvm-libs/test-utils/build.gradle +++ b/maru/jvm-libs/test-utils/build.gradle @@ -13,8 +13,8 @@ dependencies { implementation(project(':maru:p2p')) implementation(project(':maru:config')) implementation(project(':maru:jvm-libs:extensions')) - implementation "build.linea.internal:kotlin" - implementation "build.linea.internal:long-running-service" + implementation project(':jvm-libs:generic:extensions:kotlin') + implementation project(':jvm-libs:linea:core:long-running-service') api "org.hyperledger.besu.internal:besu-acceptance-tests-dsl" @@ -30,7 +30,7 @@ dependencies { implementation(group: 'org.hyperledger.besu.internal', name: 'besu-ethereum-core', classifier: 'test-support') implementation("com.fasterxml.jackson.module:jackson-module-kotlin") - implementation "build.linea.internal:metrics" + implementation project(':jvm-libs:linea:core:metrics') implementation "org.web3j:core" implementation 'org.assertj:assertj-core' diff --git a/maru/jvm-libs/utils/build.gradle b/maru/jvm-libs/utils/build.gradle index a893a276445..b7543e9bb3a 100644 --- a/maru/jvm-libs/utils/build.gradle +++ b/maru/jvm-libs/utils/build.gradle @@ -24,7 +24,7 @@ dependencies { implementation(testFixtures(project(':maru:crypto'))) implementation "io.libp2p:jvm-libp2p" implementation "tech.pegasys.teku.internal:p2p" - implementation "build.linea.internal:kotlin" + implementation project(':jvm-libs:generic:extensions:kotlin') implementation("org.hyperledger.besu.internal:besu-crypto-algorithms") implementation("org.hyperledger.besu.internal:besu-crypto-services") implementation("org.hyperledger.besu.internal:besu-ethereum-core") diff --git a/maru/linea-finalization-provider/build.gradle b/maru/linea-finalization-provider/build.gradle index 1883b387318..21ec3844202 100644 --- a/maru/linea-finalization-provider/build.gradle +++ b/maru/linea-finalization-provider/build.gradle @@ -24,9 +24,9 @@ apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" dependencies { implementation(project(':maru:jvm-libs:extensions')) api(project(':maru:core')) - api("build.linea.internal:linea-contract-clients"){ + api(project(':jvm-libs:linea:clients:linea-contract-clients')){ exclude group: "build.linea", module: "besu-libs" } - api("build.linea.internal:interfaces") - implementation("build.linea.internal:long-running-service") + api(project(':jvm-libs:linea:clients:interfaces')) + implementation(project(':jvm-libs:linea:core:long-running-service')) } diff --git a/maru/observability/build.gradle b/maru/observability/build.gradle index ddfc85122ab..cc168141283 100644 --- a/maru/observability/build.gradle +++ b/maru/observability/build.gradle @@ -6,8 +6,8 @@ plugins { apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" dependencies { - implementation "build.linea.internal:micrometer" - implementation "build.linea.internal:metrics" + implementation project(':jvm-libs:linea:metrics:micrometer') + implementation project(':jvm-libs:linea:core:metrics') implementation "org.hyperledger.besu.internal:besu-metrics-core" implementation "org.hyperledger.besu:besu-plugin-api" implementation "com.google.guava:guava" diff --git a/maru/p2p/build.gradle b/maru/p2p/build.gradle index 6df0032a6ec..588da8a7b72 100644 --- a/maru/p2p/build.gradle +++ b/maru/p2p/build.gradle @@ -46,9 +46,9 @@ dependencies { implementation "io.consensys.tuweni:tuweni-crypto" implementation "io.consensys.tuweni:tuweni-rlp" - implementation "build.linea.internal:metrics" - implementation "build.linea.internal:futures" - implementation "build.linea.internal:long-running-service" + implementation project(':jvm-libs:linea:core:metrics') + implementation project(':jvm-libs:generic:extensions:futures') + implementation project(':jvm-libs:linea:core:long-running-service') implementation 'io.consensys.protocols:discovery' implementation 'org.jetbrains.kotlinx:kotlinx-datetime' diff --git a/maru/storage/build.gradle b/maru/storage/build.gradle index 2e25b028ce3..ace3369290e 100644 --- a/maru/storage/build.gradle +++ b/maru/storage/build.gradle @@ -30,5 +30,5 @@ dependencies { implementation "org.hyperledger.besu:besu-plugin-api" testImplementation (testFixtures(project(':maru:core'))) testImplementation (project(':maru:observability')) - testImplementation ("build.linea.internal:metrics") + testImplementation (project(':jvm-libs:linea:core:metrics')) } diff --git a/maru/syncing/build.gradle b/maru/syncing/build.gradle index e7238525a04..4e3438bbc09 100644 --- a/maru/syncing/build.gradle +++ b/maru/syncing/build.gradle @@ -28,9 +28,9 @@ dependencies { implementation project(':maru:p2p') implementation project(':maru:storage') implementation project(':maru:jvm-libs:extensions') - implementation 'build.linea.internal:metrics' - implementation 'build.linea.internal:kotlin' - implementation 'build.linea.internal:long-running-service' + implementation project(':jvm-libs:linea:core:metrics') + implementation project(':jvm-libs:generic:extensions:kotlin') + implementation project(':jvm-libs:linea:core:long-running-service') implementation 'org.apache.logging.log4j:log4j-api' implementation 'org.hyperledger.besu.internal:besu-crypto-algorithms' implementation 'org.hyperledger.besu.internal:besu-metrics-core' @@ -50,6 +50,6 @@ dependencies { testImplementation 'org.mockito:mockito-core' testImplementation 'org.mockito.kotlin:mockito-kotlin' testImplementation 'org.assertj:assertj-core' - testImplementation 'build.linea.internal:metrics' + testImplementation project(':jvm-libs:linea:core:metrics') testImplementation 'org.hyperledger.besu.internal:besu-ethereum-core' } From 4f64c6499c583d19ab36920a5bcc39584b0e36ec Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Fri, 15 May 2026 14:18:25 -0400 Subject: [PATCH 09/13] build(maru): fold versions.gradle into zkevm libs.versions.toml Each maru subproject previously applied the io.spring.dependency-management plugin and `apply from: maru/gradle/versions.gradle`, which used Spring DM BOM imports (vertx-stack-depchain, besu, slf4j-bom) to govern transitive versions. This duplicated zkevm's own version source-of-truth and pulled Vert.x 4 in via the Besu BOM, conflicting with the local Vert.x 5 :jvm-libs:generic:vertx-helper at runtime. Move every maru subproject onto zkevm's gradle/libs.versions.toml: - add maru-only entries (discovery, jvm-libp2p, javalin, http4k, okhttp, pkts-core, rocksdbjni, docker-compose-rule, kotlinx-datetime) - reuse existing aliases (jackson, guava, hoplite, picoli, tuweni, teku, web3j, log4j, awaitility, etc.) via "${libs.versions.X.get()}" interpolation, matching the coordinator/* pattern - leave org.hyperledger.besu* and io.vertx:* versionless: aligned by root build.gradle's eachDependency rule and kotlin-common-conventions' vertx-stack-depchain platform respectively - drop libs.plugins.dependencyManagement and `apply from versions.gradle` from all 21 subprojects - delete maru/gradle/versions.gradle and the stale maru/gradle/libs.versions.toml left over from the import Also: replace deprecated Hash.toString() (-Werror failure post-fold) with .bytes.toHexString() in BesuTransactionsHelper. --- gradle/libs.versions.toml | 11 + maru/api/build.gradle | 11 +- maru/app/build.gradle | 24 +- maru/build.gradle | 13 +- maru/chaos-testing/build.gradle | 3 - .../chaos-testing/health-checker/build.gradle | 13 +- maru/config/build.gradle | 9 +- maru/consensus/build.gradle | 11 +- maru/core/build.gradle | 7 +- maru/crypto/build.gradle | 11 +- maru/e2e/build.gradle | 27 +-- maru/executionlayer/build.gradle | 17 +- maru/gradle/libs.versions.toml | 10 - maru/gradle/versions.gradle | 208 ------------------ maru/jvm-libs/build.gradle | 3 - maru/jvm-libs/extensions/build.gradle | 5 +- maru/jvm-libs/mappers/build.gradle | 13 +- maru/jvm-libs/teku-web3j/build.gradle | 13 +- maru/jvm-libs/test-utils/build.gradle | 11 +- .../testutils/besu/BesuTransactionsHelper.kt | 2 +- maru/jvm-libs/utils/build.gradle | 11 +- maru/linea-finalization-provider/build.gradle | 3 - maru/observability/build.gradle | 7 +- maru/p2p/build.gradle | 26 +-- maru/serialization/build.gradle | 9 +- maru/storage/build.gradle | 7 +- maru/syncing/build.gradle | 17 +- 27 files changed, 117 insertions(+), 385 deletions(-) delete mode 100644 maru/gradle/libs.versions.toml delete mode 100644 maru/gradle/versions.gradle diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 63ab8cd58d4..e656bab17ad 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -71,6 +71,17 @@ flywaydb = "12.0.3" postgresql = "42.7.10" guava = "33.5.0" +# Maru +discovery = "26.3.0" +dockerComposeRule = "2.3.0" +http4k = "6.15.1.0" +javalin = "6.7.0" +jvmLibp2p = "1.2.2-RELEASE" +kotlinxDatetime = "0.7.0" +okhttp = "4.12.0" +pktsCore = "3.0.10" +rocksdbjni = "9.7.3" + # Other googleJavaFormat = "1.27.0" dependencyLicenseReport = "3.1.1" diff --git a/maru/api/build.gradle b/maru/api/build.gradle index 9a461a9601e..b2bc818e1bf 100644 --- a/maru/api/build.gradle +++ b/maru/api/build.gradle @@ -1,20 +1,17 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation project(':jvm-libs:linea:core:metrics') implementation project(':jvm-libs:linea:core:long-running-service') - implementation "com.fasterxml.jackson.module:jackson-module-kotlin" - implementation "io.javalin:javalin" + implementation "com.fasterxml.jackson.module:jackson-module-kotlin:${libs.versions.jackson.get()}" + implementation "io.javalin:javalin:${libs.versions.javalin.get()}" implementation project(':maru:core') implementation project(':maru:p2p') implementation project(':maru:jvm-libs:extensions') testImplementation(testFixtures(project(':maru:core'))) testImplementation(project(':maru:syncing')) - testImplementation("com.squareup.okhttp3:okhttp") -} + testImplementation("com.squareup.okhttp3:okhttp:${libs.versions.okhttp.get()}") +} \ No newline at end of file diff --git a/maru/app/build.gradle b/maru/app/build.gradle index 909721c3490..554a25377eb 100644 --- a/maru/app/build.gradle +++ b/maru/app/build.gradle @@ -3,11 +3,8 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { id 'net.consensys.zkevm.kotlin-application-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - sourceSets { integrationTest { kotlin { @@ -47,25 +44,24 @@ dependencies { // Previously inherited from maru's `maru.kotlin-application-conventions` plugin (which the // import dropped in favor of zkevm's lighter `net.consensys.zkevm.kotlin-application-conventions`). - // Resolved via maru/gradle/versions.gradle until the catalog fold replaces these with project - // references / catalog accessors. implementation project(':jvm-libs:linea:core:metrics') implementation project(':jvm-libs:linea:metrics:micrometer') implementation project(':jvm-libs:generic:vertx-helper') implementation "io.vertx:vertx-micrometer-metrics" - implementation "info.picocli:picocli" - implementation "com.sksamuel.hoplite:hoplite-core" + implementation "info.picocli:picocli:${libs.versions.picoli.get()}" + implementation "com.sksamuel.hoplite:hoplite-core:${libs.versions.hoplite.get()}" implementation("org.hyperledger.besu.internal:besu-consensus-qbft-core") implementation("org.hyperledger.besu.internal:besu-metrics-core") implementation("org.hyperledger.besu.internal:besu-crypto-algorithms") - implementation("tech.pegasys.teku.internal:p2p") - implementation("tech.pegasys.teku.internal:eth2") - implementation ("io.consensys.protocols:discovery") + implementation("tech.pegasys.teku.internal:p2p:${libs.versions.teku.get()}") + implementation("tech.pegasys.teku.internal:eth2:${libs.versions.teku.get()}") + implementation ("io.consensys.protocols:discovery:${libs.versions.discovery.get()}") - integrationTestRuntimeOnly("org.junit.platform:junit-platform-launcher") - integrationTestImplementation 'org.jetbrains.kotlinx:kotlinx-datetime' + integrationTestRuntimeOnly("org.junit.platform:junit-platform-launcher:${libs.versions.junitPlatform.get()}") + integrationTestImplementation "org.jetbrains.kotlinx:kotlinx-datetime:${libs.versions.kotlinxDatetime.get()}" + integrationTestImplementation "org.awaitility:awaitility-kotlin:${libs.versions.awaitility.get()}" integrationTestImplementation(project(':maru:jvm-libs:test-utils')) integrationTestImplementation(testFixtures(project(':maru:p2p'))) integrationTestImplementation(testFixtures(project(':maru:crypto'))) @@ -74,8 +70,8 @@ dependencies { integrationTestImplementation(group: 'org.hyperledger.besu.internal', name: 'besu-ethereum-core', classifier: 'test-support') integrationTestImplementation("org.hyperledger.besu.internal:besu-ethereum-p2p") integrationTestImplementation("org.hyperledger.besu.internal:besu-consensus-qbft-core") - integrationTestImplementation("com.squareup.okhttp3:okhttp") - integrationTestImplementation("io.javalin:javalin") + integrationTestImplementation("com.squareup.okhttp3:okhttp:${libs.versions.okhttp.get()}") + integrationTestImplementation("io.javalin:javalin:${libs.versions.javalin.get()}") testImplementation(testFixtures(project(':maru:core'))) } diff --git a/maru/build.gradle b/maru/build.gradle index d499b07afce..eb339844e78 100644 --- a/maru/build.gradle +++ b/maru/build.gradle @@ -1,13 +1,8 @@ // :maru is the parent project for the maru beacon-chain client subtree, imported -// from Consensys/maru via `git filter-repo --to-subdirectory-filter maru` + merge -// (see PR that landed the import). Convention plugins (Kotlin/Java setup, base -// Spotless ktlint, JUnit, JaCoCo) come from the monorepo's root build.gradle and -// zkevm/buildSrc conventions. Each maru subproject's plugins{} block also -// applies `libs.plugins.dependencyManagement` and then `apply from: maru/gradle/ -// versions.gradle` directly (the parent's subprojects{} closure cannot reliably -// apply versions.gradle because Gradle evaluates parent's subprojects{} BEFORE -// the subproject's plugins{} block has run, so the dependencyManagement DSL -// isn't yet on the script's classpath at that point). +// from Consensys/maru via `git filter-repo --to-subdirectory-filter maru` + merge. +// Convention plugins (Kotlin/Java setup, base Spotless ktlint, JUnit, JaCoCo) +// come from the monorepo's root build.gradle and zkevm/buildSrc conventions. +// Versions are governed by zkevm's gradle/libs.versions.toml. // // This file adds the only maru-local concern that isn't part of the monorepo's // defaults: the SPDX dual MIT/Apache license-header rule + Java importOrder, diff --git a/maru/chaos-testing/build.gradle b/maru/chaos-testing/build.gradle index f033c264dc6..63961a8cba6 100644 --- a/maru/chaos-testing/build.gradle +++ b/maru/chaos-testing/build.gradle @@ -15,7 +15,4 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } - -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" diff --git a/maru/chaos-testing/health-checker/build.gradle b/maru/chaos-testing/health-checker/build.gradle index d950f187328..a83a1637dc4 100644 --- a/maru/chaos-testing/health-checker/build.gradle +++ b/maru/chaos-testing/health-checker/build.gradle @@ -3,11 +3,8 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(project(':maru:jvm-libs:extensions')) implementation project(':maru:jvm-libs:test-utils') @@ -17,9 +14,9 @@ dependencies { exclude group: "build.linea", module: "besu-libs" } - implementation("org.http4k:http4k-core") - implementation("org.http4k:http4k-client-okhttp") - implementation("org.http4k:http4k-format-jackson") + implementation("org.http4k:http4k-core:${libs.versions.http4k.get()}") + implementation("org.http4k:http4k-client-okhttp:${libs.versions.http4k.get()}") + implementation("org.http4k:http4k-format-jackson:${libs.versions.http4k.get()}") } sourceSets { @@ -33,6 +30,10 @@ sourceSets { } } +dependencies { + acceptanceTestImplementation "org.awaitility:awaitility-kotlin:${libs.versions.awaitility.get()}" +} + build.dependsOn compileAcceptanceTestKotlin tasks.register('acceptanceTest', Test) { test -> diff --git a/maru/config/build.gradle b/maru/config/build.gradle index 5c347bc2af9..b31ee732f97 100644 --- a/maru/config/build.gradle +++ b/maru/config/build.gradle @@ -15,18 +15,15 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(project(':maru:jvm-libs:extensions')) implementation(project(':maru:core')) api(project(':jvm-libs:linea:core:domain-models')) api(project(':jvm-libs:generic:extensions:kotlin')) - implementation "com.sksamuel.hoplite:hoplite-toml" - implementation "com.sksamuel.hoplite:hoplite-json" - implementation "com.sksamuel.hoplite:hoplite-core" + implementation "com.sksamuel.hoplite:hoplite-toml:${libs.versions.hoplite.get()}" + implementation "com.sksamuel.hoplite:hoplite-json:${libs.versions.hoplite.get()}" + implementation "com.sksamuel.hoplite:hoplite-core:${libs.versions.hoplite.get()}" } diff --git a/maru/consensus/build.gradle b/maru/consensus/build.gradle index 490d78e612d..bde5e7039e5 100644 --- a/maru/consensus/build.gradle +++ b/maru/consensus/build.gradle @@ -15,11 +15,8 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(project(':maru:core')) implementation(project(':maru:serialization')) @@ -49,8 +46,8 @@ dependencies { implementation("org.hyperledger.besu:besu-datatypes") implementation("org.hyperledger.besu:besu-evm") - implementation "tech.pegasys.teku.internal:executionclient" - implementation "tech.pegasys.teku.internal:spec" + implementation "tech.pegasys.teku.internal:executionclient:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:spec:${libs.versions.teku.get()}" implementation project(':jvm-libs:linea:core:long-running-service') @@ -59,7 +56,7 @@ dependencies { testImplementation(testFixtures(project(':maru:crypto'))) testImplementation(project(':maru:jvm-libs:test-utils')) testImplementation "org.jetbrains.kotlin:kotlin-test:2.1.0" - testImplementation "tech.pegasys.teku.internal:executionclient" - testImplementation "tech.pegasys.teku.internal:spec" + testImplementation "tech.pegasys.teku.internal:executionclient:${libs.versions.teku.get()}" + testImplementation "tech.pegasys.teku.internal:spec:${libs.versions.teku.get()}" testImplementation project(':jvm-libs:linea:core:metrics') } diff --git a/maru/core/build.gradle b/maru/core/build.gradle index aab2a569296..3f6b63e1323 100644 --- a/maru/core/build.gradle +++ b/maru/core/build.gradle @@ -15,19 +15,16 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) id 'java-test-fixtures' } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(project(':maru:jvm-libs:extensions')) implementation project(':jvm-libs:generic:extensions:kotlin') implementation project(':jvm-libs:linea:core:metrics') implementation project(':jvm-libs:linea:core:long-running-service') - implementation "io.consensys.tuweni:tuweni-bytes" - implementation "org.jetbrains.kotlin:kotlin-reflect" + implementation "io.consensys.tuweni:tuweni-bytes:${libs.versions.tuweni.get()}" + implementation "org.jetbrains.kotlin:kotlin-reflect:${libs.versions.kotlin.get()}" testImplementation(project(':maru:serialization')) testFixturesImplementation("org.hyperledger.besu:besu-datatypes") testFixturesImplementation("org.hyperledger.besu:besu-plugin-api") diff --git a/maru/crypto/build.gradle b/maru/crypto/build.gradle index 2643b7042a5..92de5a0a54b 100644 --- a/maru/crypto/build.gradle +++ b/maru/crypto/build.gradle @@ -1,11 +1,8 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) id 'java-test-fixtures' } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(project(':maru:core')) implementation(project(':maru:jvm-libs:extensions')) @@ -13,12 +10,12 @@ dependencies { implementation("org.hyperledger.besu.internal:besu-crypto-algorithms") implementation("org.hyperledger.besu.internal:besu-crypto-services") implementation("org.hyperledger.besu.internal:besu-ethereum-core") - implementation "io.consensys.tuweni:tuweni-bytes" + implementation "io.consensys.tuweni:tuweni-bytes:${libs.versions.tuweni.get()}" - testFixturesImplementation "io.libp2p:jvm-libp2p" - testFixturesImplementation "tech.pegasys.teku.internal:p2p" + testFixturesImplementation "io.libp2p:jvm-libp2p:${libs.versions.jvmLibp2p.get()}" + testFixturesImplementation "tech.pegasys.teku.internal:p2p:${libs.versions.teku.get()}" testFixturesImplementation project(':jvm-libs:generic:extensions:kotlin') - testFixturesImplementation "io.consensys.tuweni:tuweni-bytes" + testFixturesImplementation "io.consensys.tuweni:tuweni-bytes:${libs.versions.tuweni.get()}" testFixturesImplementation "org.hyperledger.besu.internal:besu-crypto-algorithms" testFixturesImplementation "org.hyperledger.besu.internal:besu-crypto-services" diff --git a/maru/e2e/build.gradle b/maru/e2e/build.gradle index f20b5e81bb2..de60f03bef4 100644 --- a/maru/e2e/build.gradle +++ b/maru/e2e/build.gradle @@ -3,11 +3,8 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation project(':maru:core') implementation project(':maru:app') @@ -21,20 +18,20 @@ dependencies { implementation(project(':maru:jvm-libs:extensions')) implementation project(':maru:jvm-libs:test-utils') - implementation "tech.pegasys.teku.internal:executionclient" - implementation "tech.pegasys.teku.internal:time" - implementation "tech.pegasys.teku.internal:ethereum-events" - implementation "tech.pegasys.teku.internal:spec" + implementation "tech.pegasys.teku.internal:executionclient:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:time:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:ethereum-events:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:spec:${libs.versions.teku.get()}" - implementation ("org.web3j:core") + implementation ("org.web3j:core:${libs.versions.web3j.get()}") - implementation "com.sksamuel.hoplite:hoplite-toml" - implementation "com.sksamuel.hoplite:hoplite-json" - implementation "com.sksamuel.hoplite:hoplite-core" + implementation "com.sksamuel.hoplite:hoplite-toml:${libs.versions.hoplite.get()}" + implementation "com.sksamuel.hoplite:hoplite-json:${libs.versions.hoplite.get()}" + implementation "com.sksamuel.hoplite:hoplite-core:${libs.versions.hoplite.get()}" - implementation('com.palantir.docker.compose:docker-compose-rule-junit4') - implementation('com.palantir.docker.compose:docker-compose-junit-jupiter') + implementation("com.palantir.docker.compose:docker-compose-rule-junit4:${libs.versions.dockerComposeRule.get()}") + implementation("com.palantir.docker.compose:docker-compose-junit-jupiter:${libs.versions.dockerComposeRule.get()}") implementation "org.hyperledger.besu.internal:besu-acceptance-tests-dsl" implementation project(':jvm-libs:linea:core:metrics') @@ -53,6 +50,10 @@ sourceSets { } } +dependencies { + acceptanceTestImplementation "org.awaitility:awaitility-kotlin:${libs.versions.awaitility.get()}" +} + build.dependsOn compileAcceptanceTestKotlin diff --git a/maru/executionlayer/build.gradle b/maru/executionlayer/build.gradle index 6c02cc1464e..1b7e0bc2dea 100644 --- a/maru/executionlayer/build.gradle +++ b/maru/executionlayer/build.gradle @@ -15,11 +15,8 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(project(':maru:core')) implementation(project(':maru:config')) @@ -27,16 +24,16 @@ dependencies { implementation(project(':maru:jvm-libs:mappers')) implementation(project(':maru:jvm-libs:extensions')) - api "tech.pegasys.teku.internal:executionclient" + api "tech.pegasys.teku.internal:executionclient:${libs.versions.teku.get()}" - api("tech.pegasys.teku.internal:time") - api("tech.pegasys.teku.internal:ethereum-events") - implementation "tech.pegasys.teku.internal:unsigned" - implementation "tech.pegasys.teku.internal:bytes" - implementation "tech.pegasys.teku.internal:spec" + api("tech.pegasys.teku.internal:time:${libs.versions.teku.get()}") + api("tech.pegasys.teku.internal:ethereum-events:${libs.versions.teku.get()}") + implementation "tech.pegasys.teku.internal:unsigned:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:bytes:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:spec:${libs.versions.teku.get()}" implementation project(':jvm-libs:linea:core:metrics') - testImplementation (group: 'tech.pegasys.teku.internal', name: 'spec', classifier: 'test-fixtures') + testImplementation (group: 'tech.pegasys.teku.internal', name: 'spec', version: libs.versions.teku.get(), classifier: 'test-fixtures') testImplementation(testFixtures(project(':maru:core'))) testImplementation(testFixtures(project(':jvm-libs:generic:extensions:kotlin'))) } diff --git a/maru/gradle/libs.versions.toml b/maru/gradle/libs.versions.toml deleted file mode 100644 index 9067e64c1ff..00000000000 --- a/maru/gradle/libs.versions.toml +++ /dev/null @@ -1,10 +0,0 @@ -[plugins] -spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.5" } -errorprone = { id = "net.ltgt.errorprone", version = "4.0.1" } -spotless = { id = "com.diffplug.spotless", version = "8.2.1" } - -[libraries] -kotlin-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version = "2.3.0" } - -[versions] -ktlint = "1.0.1" diff --git a/maru/gradle/versions.gradle b/maru/gradle/versions.gradle deleted file mode 100644 index 0b20f478e3d..00000000000 --- a/maru/gradle/versions.gradle +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright ConsenSys AG. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -dependencyManagement { - dependencies { - applyMavenExclusions = false - - dependencySet(group: 'com.fasterxml.jackson.core', version: '2.19.4') { - entry 'jackson-databind' - entry 'jackson-datatype' - entry 'jackson-datatype-jdk8' - } - - dependency 'com.fasterxml.jackson.module:jackson-module-kotlin:2.19.4' - -// dependency 'com.github.ben-manes.caffeine:caffeine:3.1.8' - - // For java code only - dependency 'com.google.errorprone:error_prone_core:2.29.2' - - dependency 'com.google.guava:guava:33.5.0-jre' - - dependency 'com.squareup.okhttp3:okhttp:4.12.0' - - dependency 'io.javalin:javalin:6.7.0' - - dependencySet(group: 'info.picocli', version: '4.7.6') { - entry 'picocli' - } - dependencySet(group: 'com.sksamuel.hoplite', version: '2.9.0') { - entry 'hoplite-core' - entry 'hoplite-toml' - entry 'hoplite-json' - } - - dependency group: 'io.libp2p', name: 'jvm-libp2p', version: '1.2.2-RELEASE' - -// dependency 'io.netty:netty-all:4.1.110.Final' -// dependency 'io.netty:netty-tcnative-boringssl-static:2.0.62.Final' - dependency group: 'io.netty', name: 'netty-transport-native-epoll', version: '4.2.12.Final', classifier: 'linux-x86_64' - dependency group: 'io.netty', name: 'netty-transport-native-kqueue', version: '4.2.12.Final', classifier: 'osx-x86_64' -// dependency 'io.netty:netty-transport-native-unix-common:4.1.110.Final' - -// dependency 'io.opentelemetry:opentelemetry-api:1.33.0' -// dependency 'io.opentelemetry:opentelemetry-exporter-otlp:1.33.0' -// dependency 'io.opentelemetry:opentelemetry-extension-trace-propagators:1.33.0' -// dependency 'io.opentelemetry:opentelemetry-sdk-metrics:1.33.0' -// dependency 'io.opentelemetry:opentelemetry-sdk-trace:1.33.0' -// dependency 'io.opentelemetry:opentelemetry-sdk:1.33.0' -// dependency 'io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.33.0' -// dependency 'io.opentelemetry.instrumentation:opentelemetry-okhttp-3.0:1.32.0-alpha' -// dependency 'io.opentelemetry.proto:opentelemetry-proto:1.0.0-alpha' -// dependency 'io.opentelemetry.semconv:opentelemetry-semconv:1.23.1-alpha' - -// dependency 'io.opentracing.contrib:opentracing-okhttp3:3.0.0' -// dependency 'io.opentracing:opentracing-api:0.33.0' -// dependency 'io.opentracing:opentracing-util:0.33.0' - - dependency 'io.pkts:pkts-core:3.0.10' - - dependencySet(group: 'io.consensys.tuweni', version: '2.7.1') { - entry 'tuweni-bytes' - entry 'tuweni-config' - entry 'tuweni-concurrent' - entry 'tuweni-crypto' - entry 'tuweni-devp2p' - entry 'tuweni-io' - entry 'tuweni-net' - entry 'tuweni-rlp' - entry 'tuweni-toml' - entry 'tuweni-units' - } - - dependencySet(group: 'org.http4k', version: '6.15.1.0') { - entry 'http4k-core' - entry 'http4k-client-okhttp' - entry 'http4k-format-jackson' - entry 'http4k-openapi' - } - - imports { - mavenBom("io.vertx:vertx-stack-depchain:5.0.10") - } - -// dependency 'net.java.dev.jna:jna:5.14.0' - -// dependency "org.apache.commons:commons-lang3:3.17.0" - -// dependency 'commons-net:commons-net:3.11.0' - - dependency 'org.assertj:assertj-core:3.27.3' - - dependency 'org.awaitility:awaitility-kotlin:4.3.0' - - dependencySet(group: 'org.bouncycastle', version: '1.83') { - entry 'bcpkix-jdk18on' - entry 'bcprov-jdk18on' - } - - dependencySet(group: 'org.mockito', version: '5.23.0') { - entry 'mockito-core' - entry 'mockito-junit-jupiter' - } - - dependency "org.junit:junit-bom:5.13.4" - - dependency "org.mockito.kotlin:mockito-kotlin:5.4.0" - - dependency 'org.rocksdb:rocksdbjni:9.7.3' - - dependency 'org.web3j:core:5.0.2' - - dependencySet(group: 'com.palantir.docker.compose', version: '2.3.0') { - entry 'docker-compose-rule-junit4' - entry 'docker-compose-junit-jupiter' - } - -// dependency 'org.springframework.security:spring-security-crypto:6.2.1' - -// dependency 'org.testcontainers:testcontainers:1.19.3' - - dependencySet(group: 'org.wiremock', version: '3.13.2') { - entry 'wiremock' - } - - dependency('io.consensys.protocols:discovery:26.3.0') { - exclude group: 'io.consensys.tuweni', name: 'tuweni-bytes' - exclude group: 'io.consensys.tuweni', name: 'tuweni-crypto' - exclude group: 'io.consensys.tuweni', name: 'tuweni-units' - exclude group: 'io.consensys.tuweni', name: 'tuweni-rlp' - - } - - dependencySet(group: 'tech.pegasys.teku.internal', version: '25.12.0') { - entry 'async' - entry 'time' - entry 'bytes' - entry 'ethereum-events' - entry 'infrastructure-events' - entry 'spec' - entry 'executionclient' - entry 'unsigned' - entry 'ssz' - entry 'storage' - entry 'p2p' - entry 'eth2' - entry 'logging' - } - - dependencySet(group: 'org.apache.logging.log4j', version: '2.25.3') { - entry 'log4j-api' - entry 'log4j-core' - entry 'log4j-slf4j-impl' - entry 'log4j-slf4j2-impl' - } - - def besuVersion = "26.5.0-36cda4f" - - imports { - mavenBom "org.hyperledger.besu:bom:$besuVersion" - } - - dependency "org.hyperledger.besu.internal:besu-plugins-rocksdb:$besuVersion" - - dependency "com.michael-bull.kotlin-result:kotlin-result:1.1.16" - dependency 'org.jetbrains.kotlinx:kotlinx-datetime:0.7.0' - - imports { - mavenBom "org.slf4j:slf4j-bom:2.0.16" - } - - def lineaPackagesVersion = System.getenv("LINEA_LIBS_VERSION") ?: "0.0.1-v20260327160734" - - - dependency "build.linea.internal:metrics:$lineaPackagesVersion" - dependency "build.linea.internal:micrometer:$lineaPackagesVersion" - dependency "build.linea.internal:vertx-helper:$lineaPackagesVersion" - dependency "build.linea.internal:json-rpc:$lineaPackagesVersion" - dependency "build.linea.internal:futures:$lineaPackagesVersion" - dependency "build.linea.internal:core:$lineaPackagesVersion" - dependency "build.linea.internal:kotlin:$lineaPackagesVersion" - dependency "build.linea.internal:domain-models:$lineaPackagesVersion" - dependency "build.linea.internal:interfaces:$lineaPackagesVersion" - dependency "build.linea.internal:linea-contract-clients:$lineaPackagesVersion" - dependency "build.linea.internal:web3j-extensions:$lineaPackagesVersion" - dependency "build.linea.internal:file-system:$lineaPackagesVersion" - dependency( - group: 'build.linea.internal', - name: 'linea-contract-clients', - version: lineaPackagesVersion, - classifier: 'test-fixtures', - ) - dependency "build.linea.internal:logging:$lineaPackagesVersion" - dependency "build.linea.internal:long-running-service:$lineaPackagesVersion" - } -} diff --git a/maru/jvm-libs/build.gradle b/maru/jvm-libs/build.gradle index 1101c018e85..7acff1b6940 100644 --- a/maru/jvm-libs/build.gradle +++ b/maru/jvm-libs/build.gradle @@ -15,10 +15,7 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { } diff --git a/maru/jvm-libs/extensions/build.gradle b/maru/jvm-libs/extensions/build.gradle index 209b5fde19a..d1ed677a532 100644 --- a/maru/jvm-libs/extensions/build.gradle +++ b/maru/jvm-libs/extensions/build.gradle @@ -15,13 +15,10 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation project(':jvm-libs:linea:core:metrics') implementation project(':jvm-libs:generic:extensions:futures') - implementation "tech.pegasys.teku.internal:executionclient" + implementation "tech.pegasys.teku.internal:executionclient:${libs.versions.teku.get()}" } diff --git a/maru/jvm-libs/mappers/build.gradle b/maru/jvm-libs/mappers/build.gradle index d771857f0fa..a544fe86963 100644 --- a/maru/jvm-libs/mappers/build.gradle +++ b/maru/jvm-libs/mappers/build.gradle @@ -15,23 +15,20 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(project(':maru:core')) implementation(project(':maru:jvm-libs:extensions')) - implementation "tech.pegasys.teku.internal:unsigned" - implementation "tech.pegasys.teku.internal:bytes" - implementation "tech.pegasys.teku.internal:executionclient" + implementation "tech.pegasys.teku.internal:unsigned:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:bytes:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:executionclient:${libs.versions.teku.get()}" implementation "org.hyperledger.besu.internal:besu-metrics-core" implementation "org.hyperledger.besu.internal:besu-crypto-algorithms" implementation "org.hyperledger.besu.internal:besu-ethereum-core" implementation "org.hyperledger.besu:besu-datatypes" implementation "org.hyperledger.besu:besu-plugin-api" - implementation "io.consensys.tuweni:tuweni-bytes" - implementation "tech.pegasys.teku.internal:spec" + implementation "io.consensys.tuweni:tuweni-bytes:${libs.versions.tuweni.get()}" + implementation "tech.pegasys.teku.internal:spec:${libs.versions.teku.get()}" } diff --git a/maru/jvm-libs/teku-web3j/build.gradle b/maru/jvm-libs/teku-web3j/build.gradle index 7209512c2c5..14b85659bd7 100644 --- a/maru/jvm-libs/teku-web3j/build.gradle +++ b/maru/jvm-libs/teku-web3j/build.gradle @@ -15,17 +15,14 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { - implementation "tech.pegasys.teku.internal:executionclient" - implementation "tech.pegasys.teku.internal:logging" - implementation "tech.pegasys.teku.internal:time" - implementation "tech.pegasys.teku.internal:ethereum-events" - implementation "tech.pegasys.teku.internal:infrastructure-events" + implementation "tech.pegasys.teku.internal:executionclient:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:logging:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:time:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:ethereum-events:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:infrastructure-events:${libs.versions.teku.get()}" implementation project(':jvm-libs:generic:logging') implementation project(':jvm-libs:generic:json-rpc') } diff --git a/maru/jvm-libs/test-utils/build.gradle b/maru/jvm-libs/test-utils/build.gradle index 159e89983ce..c79aa1e0cc7 100644 --- a/maru/jvm-libs/test-utils/build.gradle +++ b/maru/jvm-libs/test-utils/build.gradle @@ -1,10 +1,7 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(project(':maru:consensus')) implementation(project(':maru:app')) @@ -28,13 +25,13 @@ dependencies { implementation("org.hyperledger.besu.internal:besu-consensus-qbft") implementation("org.hyperledger.besu.internal:besu-plugins-rocksdb") implementation(group: 'org.hyperledger.besu.internal', name: 'besu-ethereum-core', classifier: 'test-support') - implementation("com.fasterxml.jackson.module:jackson-module-kotlin") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:${libs.versions.jackson.get()}") implementation project(':jvm-libs:linea:core:metrics') - implementation "org.web3j:core" - implementation 'org.assertj:assertj-core' - implementation 'org.awaitility:awaitility-kotlin' + implementation "org.web3j:core:${libs.versions.web3j.get()}" + implementation "org.assertj:assertj-core:${libs.versions.assertj.get()}" + implementation "org.awaitility:awaitility-kotlin:${libs.versions.awaitility.get()}" } test { diff --git a/maru/jvm-libs/test-utils/src/main/kotlin/testutils/besu/BesuTransactionsHelper.kt b/maru/jvm-libs/test-utils/src/main/kotlin/testutils/besu/BesuTransactionsHelper.kt index d503afa0c1f..893604ad13d 100644 --- a/maru/jvm-libs/test-utils/src/main/kotlin/testutils/besu/BesuTransactionsHelper.kt +++ b/maru/jvm-libs/test-utils/src/main/kotlin/testutils/besu/BesuTransactionsHelper.kt @@ -68,7 +68,7 @@ class BesuTransactionsHelper { this@BesuTransactionsHelper .ethConditions .expectSuccessfulTransactionReceipt( - txHash.toString(), + txHash.bytes.toHexString(), ).verify(this) logger.info("Transaction {} was mined", txHash) } diff --git a/maru/jvm-libs/utils/build.gradle b/maru/jvm-libs/utils/build.gradle index b7543e9bb3a..14d93cbaf06 100644 --- a/maru/jvm-libs/utils/build.gradle +++ b/maru/jvm-libs/utils/build.gradle @@ -15,21 +15,18 @@ plugins { id 'net.consensys.zkevm.kotlin-common-minimal-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(testFixtures(project(':maru:crypto'))) - implementation "io.libp2p:jvm-libp2p" - implementation "tech.pegasys.teku.internal:p2p" + implementation "io.libp2p:jvm-libp2p:${libs.versions.jvmLibp2p.get()}" + implementation "tech.pegasys.teku.internal:p2p:${libs.versions.teku.get()}" implementation project(':jvm-libs:generic:extensions:kotlin') implementation("org.hyperledger.besu.internal:besu-crypto-algorithms") implementation("org.hyperledger.besu.internal:besu-crypto-services") implementation("org.hyperledger.besu.internal:besu-ethereum-core") - implementation "info.picocli:picocli" - implementation("org.slf4j:slf4j-nop") { + implementation "info.picocli:picocli:${libs.versions.picoli.get()}" + implementation("org.slf4j:slf4j-nop:${libs.versions.slf4j.get()}") { because "To suppress slf4j logs" } } diff --git a/maru/linea-finalization-provider/build.gradle b/maru/linea-finalization-provider/build.gradle index 21ec3844202..e6e59b99a56 100644 --- a/maru/linea-finalization-provider/build.gradle +++ b/maru/linea-finalization-provider/build.gradle @@ -15,12 +15,9 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) id 'java-test-fixtures' } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(project(':maru:jvm-libs:extensions')) api(project(':maru:core')) diff --git a/maru/observability/build.gradle b/maru/observability/build.gradle index cc168141283..7a5fef1ae92 100644 --- a/maru/observability/build.gradle +++ b/maru/observability/build.gradle @@ -1,15 +1,14 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation project(':jvm-libs:linea:metrics:micrometer') implementation project(':jvm-libs:linea:core:metrics') implementation "org.hyperledger.besu.internal:besu-metrics-core" implementation "org.hyperledger.besu:besu-plugin-api" - implementation "com.google.guava:guava" + implementation "com.google.guava:guava:${libs.versions.guava.get()}-jre" implementation(project(':maru:core')) + + testImplementation "org.awaitility:awaitility-kotlin:${libs.versions.awaitility.get()}" } diff --git a/maru/p2p/build.gradle b/maru/p2p/build.gradle index 588da8a7b72..8844a16b0bc 100644 --- a/maru/p2p/build.gradle +++ b/maru/p2p/build.gradle @@ -15,12 +15,9 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) id 'java-test-fixtures' } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation project(':maru:config') implementation project(':maru:serialization') @@ -28,14 +25,14 @@ dependencies { implementation project(':maru:core') implementation project(':maru:observability') - api "io.libp2p:jvm-libp2p" + api "io.libp2p:jvm-libp2p:${libs.versions.jvmLibp2p.get()}" - implementation "tech.pegasys.teku.internal:p2p" - implementation "tech.pegasys.teku.internal:eth2" - implementation "tech.pegasys.teku.internal:spec" - implementation "tech.pegasys.teku.internal:storage" - implementation "tech.pegasys.teku.internal:unsigned" - implementation "tech.pegasys.teku.internal:time" + implementation "tech.pegasys.teku.internal:p2p:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:eth2:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:spec:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:storage:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:unsigned:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:time:${libs.versions.teku.get()}" implementation "org.hyperledger.besu:besu-plugin-api" implementation "org.hyperledger.besu.internal:besu-metrics-core" @@ -43,19 +40,20 @@ dependencies { implementation "org.hyperledger.besu.internal:besu-ethereum-p2p" implementation "org.hyperledger.besu.internal:besu-consensus-qbft-core" - implementation "io.consensys.tuweni:tuweni-crypto" - implementation "io.consensys.tuweni:tuweni-rlp" + implementation "io.consensys.tuweni:tuweni-crypto:${libs.versions.tuweni.get()}" + implementation "io.consensys.tuweni:tuweni-rlp:${libs.versions.tuweni.get()}" implementation project(':jvm-libs:linea:core:metrics') implementation project(':jvm-libs:generic:extensions:futures') implementation project(':jvm-libs:linea:core:long-running-service') - implementation 'io.consensys.protocols:discovery' - implementation 'org.jetbrains.kotlinx:kotlinx-datetime' + implementation "io.consensys.protocols:discovery:${libs.versions.discovery.get()}" + implementation "org.jetbrains.kotlinx:kotlinx-datetime:${libs.versions.kotlinxDatetime.get()}" implementation(project(':maru:core')) testImplementation(testFixtures(project(':maru:core'))) + testImplementation "org.awaitility:awaitility-kotlin:${libs.versions.awaitility.get()}" testFixturesImplementation(project(':maru:serialization')) testFixturesImplementation(project(':maru:crypto')) diff --git a/maru/serialization/build.gradle b/maru/serialization/build.gradle index cf2bab4f149..e5c767d03e0 100644 --- a/maru/serialization/build.gradle +++ b/maru/serialization/build.gradle @@ -15,21 +15,18 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation(project(':maru:core')) implementation(project(':maru:config')) implementation(project(':maru:crypto')) implementation(project(':maru:jvm-libs:extensions')) - implementation "io.consensys.tuweni:tuweni-bytes" - implementation "io.libp2p:jvm-libp2p" + implementation "io.consensys.tuweni:tuweni-bytes:${libs.versions.tuweni.get()}" + implementation "io.libp2p:jvm-libp2p:${libs.versions.jvmLibp2p.get()}" implementation "org.hyperledger.besu:besu-datatypes" implementation "org.hyperledger.besu.internal:besu-ethereum-rlp" implementation 'org.xerial.snappy:snappy-java' - implementation "tech.pegasys.teku.internal:eth2" + implementation "tech.pegasys.teku.internal:eth2:${libs.versions.teku.get()}" testImplementation(testFixtures(project(':maru:core'))) } diff --git a/maru/storage/build.gradle b/maru/storage/build.gradle index ace3369290e..5938be4adb6 100644 --- a/maru/storage/build.gradle +++ b/maru/storage/build.gradle @@ -15,17 +15,14 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation (project(':maru:core')) implementation (project(':maru:serialization')) implementation (project(':maru:jvm-libs:extensions')) - implementation "org.rocksdb:rocksdbjni" - implementation "tech.pegasys.teku.internal:storage" + implementation "org.rocksdb:rocksdbjni:${libs.versions.rocksdbjni.get()}" + implementation "tech.pegasys.teku.internal:storage:${libs.versions.teku.get()}" implementation "org.hyperledger.besu.internal:besu-metrics-core" implementation "org.hyperledger.besu:besu-plugin-api" testImplementation (testFixtures(project(':maru:core'))) diff --git a/maru/syncing/build.gradle b/maru/syncing/build.gradle index 4e3438bbc09..0d5565d5449 100644 --- a/maru/syncing/build.gradle +++ b/maru/syncing/build.gradle @@ -15,11 +15,8 @@ plugins { id 'net.consensys.zkevm.kotlin-library-conventions' - alias(libs.plugins.dependencyManagement) } -apply from: "${rootProject.projectDir}/maru/gradle/versions.gradle" - dependencies { implementation project(':maru:core') implementation project(':maru:consensus') @@ -31,14 +28,14 @@ dependencies { implementation project(':jvm-libs:linea:core:metrics') implementation project(':jvm-libs:generic:extensions:kotlin') implementation project(':jvm-libs:linea:core:long-running-service') - implementation 'org.apache.logging.log4j:log4j-api' + implementation "org.apache.logging.log4j:log4j-api:${libs.versions.log4j.get()}" implementation 'org.hyperledger.besu.internal:besu-crypto-algorithms' implementation 'org.hyperledger.besu.internal:besu-metrics-core' implementation 'org.hyperledger.besu.internal:besu-services-pipeline' implementation 'org.hyperledger.besu.internal:besu-util' - implementation 'tech.pegasys.teku.internal:async' - implementation 'tech.pegasys.teku.internal:p2p' - implementation "tech.pegasys.teku.internal:eth2" + implementation "tech.pegasys.teku.internal:async:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:p2p:${libs.versions.teku.get()}" + implementation "tech.pegasys.teku.internal:eth2:${libs.versions.teku.get()}" testImplementation project(':maru:config') testImplementation project(':maru:crypto') @@ -47,9 +44,9 @@ dependencies { testImplementation(testFixtures(project(':maru:core'))) testImplementation(testFixtures(project(':maru:p2p'))) testImplementation(project(':maru:jvm-libs:test-utils')) - testImplementation 'org.mockito:mockito-core' - testImplementation 'org.mockito.kotlin:mockito-kotlin' - testImplementation 'org.assertj:assertj-core' + testImplementation "org.mockito:mockito-core:${libs.versions.mockito.get()}" + testImplementation "org.mockito.kotlin:mockito-kotlin:${libs.versions.mockitoKotlin.get()}" + testImplementation "org.assertj:assertj-core:${libs.versions.assertj.get()}" testImplementation project(':jvm-libs:linea:core:metrics') testImplementation 'org.hyperledger.besu.internal:besu-ethereum-core' } From 4f1d00de90c6ce1045f1fbe0e655f98dcad11aaf Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Fri, 15 May 2026 14:18:45 -0400 Subject: [PATCH 10/13] ci(maru): port maru workflows and wire into monorepo orchestrator Port maru's standalone-repo workflows to live at the monorepo root, mirroring the established coordinator-*/tracer-*/linea-besu-* pattern: - maru-testing.yml (unit + integration tests, codecov) - maru-build-and-publish.yml (docker image build via shared composite) - maru-chaos-testing.yml (workflow_dispatch only for now) - maru-e2e-tests.yml (workflow_dispatch only for now) - maru-smoke-tests.yml (workflow_dispatch only for now) - maru-release.yml (triggered by maru-v* tags) Wire maru into the orchestrator workflows: - main.yml: add `maru` paths-filter and pipe `maru_changed`/ `maru_image_tagged` into check-and-tag-images, testing, and build-and-publish - testing.yml: add maru_changed input + maru job - build-and-publish.yml: add maru_changed/maru_image_tagged inputs and maru job - reuse-check-images-tags-and-push.yml: add maru_changed input, image_tagged_maru output, and the corresponding image-tag check and push steps Transformations applied per workflow: - Gradle invocations rewritten to :maru:* task paths - setup-java + setup-gradle replaced by ./.github/actions/setup- java-and-gradle composite - DOCKER_ORG_NAME / DOCKER_REPO_TOKEN renamed to DOCKERHUB_USERNAME / DOCKERHUB_TOKEN to share zkevm's existing Docker secrets - Release tag pattern changed from `v*` to `maru-v*` to avoid colliding with other components in the monorepo - CHANGELOG and tar paths rebased to maru/ Deferred: - security-code-scanner.yml (needs SECURITY_SCAN_METRICS_TOKEN and APPSEC_BOT_SLACK_WEBHOOK secrets provisioned first) - PR-time wiring for chaos / smoke / e2e (workflows exist but are only reachable via workflow_dispatch in this PR) - Aggregated jacoco upload (per-subproject .exec artifacts uploaded as jacoco-maru-exec; monorepo's jacoco-report job not yet consuming this artifact) --- .github/workflows/build-and-publish.yml | 18 +- .github/workflows/main.yml | 18 ++ .github/workflows/maru-build-and-publish.yml | 125 ++++++++++++++ .github/workflows/maru-chaos-testing.yml | 154 ++++++++++++++++++ .github/workflows/maru-e2e-tests.yml | 95 +++++++++++ .github/workflows/maru-release.yml | 126 ++++++++++++++ .github/workflows/maru-smoke-tests.yml | 73 +++++++++ .github/workflows/maru-testing.yml | 67 ++++++++ .../reuse-check-images-tags-and-push.yml | 28 ++++ .github/workflows/testing.yml | 12 +- 10 files changed, 714 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/maru-build-and-publish.yml create mode 100644 .github/workflows/maru-chaos-testing.yml create mode 100644 .github/workflows/maru-e2e-tests.yml create mode 100644 .github/workflows/maru-release.yml create mode 100644 .github/workflows/maru-smoke-tests.yml create mode 100644 .github/workflows/maru-testing.yml diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index ce81842e3c0..96f32b25329 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -36,6 +36,9 @@ on: transaction_exclusion_api_changed: required: true type: string + maru_changed: + required: true + type: string build_linea_besu_package: required: true type: string @@ -57,6 +60,9 @@ on: transaction_exclusion_api_image_tagged: required: true type: string + maru_image_tagged: + required: true + type: string outputs: linea_besu_package_tag: value: ${{ jobs.linea_besu_package_build_and_upload.outputs.linea_besu_package_tag }} @@ -127,6 +133,16 @@ jobs: push_image: ${{ inputs.push_image }} secrets: inherit + maru: + uses: ./.github/workflows/maru-build-and-publish.yml + if: ${{ always() && (inputs.maru_changed == 'true' || (inputs.push_image && inputs.maru_image_tagged != 'true')) }} + with: + commit_tag: ${{ inputs.commit_tag }} + develop_tag: ${{ inputs.develop_tag }} + image_name: consensys/maru + push_image: ${{ inputs.push_image }} + secrets: inherit + linea_besu_package_build_and_upload: uses: ./.github/workflows/linea-besu-package-build-and-upload.yml if: ${{ always() && inputs.build_linea_besu_package == 'true' && !inputs.push_image }} @@ -138,7 +154,7 @@ jobs: # If all jobs are skipped, the workflow will still succeed. always_succeed: runs-on: ubuntu-24.04 - needs: [coordinator, postman, prover, transaction_exclusion_api, native_yield_automation_service, linea_besu_package_build_and_upload] + needs: [coordinator, postman, prover, transaction_exclusion_api, native_yield_automation_service, maru, linea_besu_package_build_and_upload] if: ${{ always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'success') && !contains(needs.*.result, 'cancelled') }} steps: - name: Ensure Workflow Success diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 48aaac9b649..1769ccb6701 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -53,6 +53,7 @@ jobs: lido-governance-monitor: ${{ steps.filter.outputs.lido-governance-monitor }} tracer: ${{ steps.filter.outputs.tracer }} tracer-constraints: ${{ steps.filter.outputs.tracer-constraints }} + maru: ${{ steps.filter.outputs.maru }} has-changes-requiring-build: ${{ steps.exclusion-filter.outputs.has-changes-requiring-build }} has-changes-requiring-linea-besu-package-build: ${{ steps.filter.outputs.linea-sequencer-plugin == 'true' || steps.filter.outputs.tracer == 'true' || steps.filter.outputs.tracer-constraints == 'true' || steps.filter.outputs.linea-besu == 'true' || steps.filter.outputs.linea-besu-package == 'true' }} steps: @@ -160,6 +161,17 @@ jobs: - 'tracer-constraints/**' - '.github/workflows/tracer-constraints-*.yml' - 'tracer/gradle/corset.gradle' + maru: + - 'maru/**' + - 'buildSrc/**' + - 'jvm-libs/**' + - 'gradle/**' + - 'build.gradle' + - 'gradle.properties' + - 'settings.gradle' + - '.github/workflows/maru-*.yml' + - '.github/workflows/build-and-publish.yml' + - '.github/workflows/main.yml' - name: Filter out commit changes uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 #v3.0.2 @@ -191,6 +203,7 @@ jobs: transaction_exclusion_api_changed: ${{ needs.filter-commit-changes.outputs.transaction-exclusion-api }} native_yield_automation_service_changed: ${{ needs.filter-commit-changes.outputs.native-yield-automation-service }} lido_governance_monitor_changed: ${{ needs.filter-commit-changes.outputs.lido-governance-monitor }} + maru_changed: ${{ needs.filter-commit-changes.outputs.maru }} secrets: inherit testing: @@ -211,6 +224,7 @@ jobs: lido_governance_monitor_changed: ${{ needs.filter-commit-changes.outputs.lido-governance-monitor }} tracer_changed: ${{ needs.filter-commit-changes.outputs.tracer }} constraints_changed: ${{ needs.filter-commit-changes.outputs.tracer-constraints }} + maru_changed: ${{ needs.filter-commit-changes.outputs.maru }} secrets: inherit get-has-changes-requiring-e2e-testing: @@ -247,6 +261,7 @@ jobs: transaction_exclusion_api_changed: ${{ needs.filter-commit-changes.outputs.transaction-exclusion-api }} native_yield_automation_service_changed: ${{ needs.filter-commit-changes.outputs.native-yield-automation-service }} lido_governance_monitor_changed: ${{ needs.filter-commit-changes.outputs.lido-governance-monitor }} + maru_changed: ${{ needs.filter-commit-changes.outputs.maru }} build_linea_besu_package: ${{ needs.filter-commit-changes.outputs.has-changes-requiring-linea-besu-package-build }} coordinator_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_coordinator }} postman_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_postman }} @@ -254,6 +269,7 @@ jobs: transaction_exclusion_api_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_transaction_exclusion_api }} native_yield_automation_service_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_native_yield_automation_service }} lido_governance_monitor_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_lido_governance_monitor }} + maru_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_maru }} secrets: inherit run-e2e-tests: @@ -302,6 +318,7 @@ jobs: transaction_exclusion_api_changed: ${{ needs.filter-commit-changes.outputs.transaction-exclusion-api }} native_yield_automation_service_changed: ${{ needs.filter-commit-changes.outputs.native-yield-automation-service }} lido_governance_monitor_changed: ${{ needs.filter-commit-changes.outputs.lido-governance-monitor }} + maru_changed: ${{ needs.filter-commit-changes.outputs.maru }} build_linea_besu_package: ${{ needs.filter-commit-changes.outputs.has-changes-requiring-linea-besu-package-build }} coordinator_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_coordinator }} postman_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_postman }} @@ -309,6 +326,7 @@ jobs: transaction_exclusion_api_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_transaction_exclusion_api }} native_yield_automation_service_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_native_yield_automation_service }} lido_governance_monitor_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_lido_governance_monitor }} + maru_image_tagged: ${{ needs.check-and-tag-images.outputs.image_tagged_maru }} secrets: inherit cleanup-deployments: diff --git a/.github/workflows/maru-build-and-publish.yml b/.github/workflows/maru-build-and-publish.yml new file mode 100644 index 00000000000..2c829acf1be --- /dev/null +++ b/.github/workflows/maru-build-and-publish.yml @@ -0,0 +1,125 @@ +name: maru-build-and-publish + +permissions: + contents: read + actions: read + packages: write + +on: + workflow_call: + inputs: + commit_tag: + required: false + type: string + default: '' + develop_tag: + required: true + type: string + image_name: + required: true + type: string + push_image: + required: false + type: boolean + default: false + upload_dist_artifact: # Used for release process to reuse the artifact + required: false + type: boolean + default: false + outputs: + commit_tag: + value: ${{ jobs.build-and-publish.outputs.commit_tag }} + secrets: + DOCKERHUB_USERNAME: + required: false + DOCKERHUB_TOKEN: + required: false + workflow_dispatch: + inputs: + commit_tag: + description: 'Image tag, if not given, HEAD commit hash will be used' + required: false + type: string + default: '' + develop_tag: + description: 'Image tag will be "develop" if target branch is main' + required: true + type: choice + options: + - develop + default: 'develop' + image_name: + description: 'Image name' + required: true + type: string + default: 'consensys/maru' + push_image: + description: 'Toggle whether to push image to docker registry' + required: false + type: boolean + default: true + +concurrency: + group: maru-docker-build-and-publish-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + build-and-publish: + runs-on: gha-runner-scale-set-ubuntu-24-amd64-large + name: Maru build and publish + env: + COMMIT_TAG: ${{ inputs.commit_tag }} + DEVELOP_TAG: ${{ inputs.develop_tag }} + IMAGE_NAME: ${{ inputs.image_name }} + PUSH_IMAGE: ${{ inputs.push_image }} + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + outputs: + commit_tag: ${{ env.COMMIT_TAG }} + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Set commit tag if not given + if: ${{ inputs.commit_tag == '' }} + run: | + # For PR, GITHUB_SHA is NOT the last commit pushed onto the PR branch - https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + COMMIT_TAG=$(git rev-parse --short ${{ github.event.pull_request.head.sha }}) + else + COMMIT_TAG=$(git rev-parse --short $GITHUB_SHA) + fi + echo "COMMIT_TAG=$COMMIT_TAG" >> $GITHUB_ENV + echo "COMMIT_TAG=$COMMIT_TAG" + - name: Login to Docker Hub + if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }} + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Setup Java and Gradle + uses: ./.github/actions/setup-java-and-gradle + - name: Build dist + run: | + ./gradlew :maru:app:installDist + - name: Upload distribution artifact + if: ${{ inputs.upload_dist_artifact }} + uses: actions/upload-artifact@v4 + with: + name: maru-distribution + path: maru/app/build/install/app/ + retention-days: 1 + - name: Build and publish Docker image + uses: ./.github/actions/docker-build-publish + with: + docker_context: maru/app + image_name: ${{ env.IMAGE_NAME }} + image_tag: ${{ env.COMMIT_TAG }} + develop_tag: ${{ env.DEVELOP_TAG }} + push_image: ${{ env.PUSH_IMAGE }} + dockerfile_path: maru/app/Dockerfile + requires_qemu: ${{ env.PUSH_IMAGE }} + build_contexts: | + libs=./maru/app/build/install/app/lib/ + maru=./maru/app/build/libs/ + save_artifact: ${{ env.PUSH_IMAGE == 'false' }} + artifact_name: linea-maru \ No newline at end of file diff --git a/.github/workflows/maru-chaos-testing.yml b/.github/workflows/maru-chaos-testing.yml new file mode 100644 index 00000000000..4cd14d4dd82 --- /dev/null +++ b/.github/workflows/maru-chaos-testing.yml @@ -0,0 +1,154 @@ +name: maru-chaos-testing + +on: + workflow_dispatch: + inputs: + consensus-client-changed: + required: true + type: string + default: 'true' + description: 'when false, skips the job' + enable_ssh_debug: + description: 'Enable SSH debugging before tests start' + required: false + type: boolean + default: false + ssh_debug_on_failure: + required: false + type: boolean + default: false + description: 'Enable SSH debugging on test failure' + workflow_call: + inputs: + consensus-client-changed: + required: true + type: string + enable_ssh_debug: + required: false + type: boolean + default: false + ssh_debug_on_failure: + required: false + type: boolean + default: false + secrets: + DOCKERHUB_USERNAME: + required: false + DOCKERHUB_TOKEN: + required: false + +permissions: {} # lock everything by default (least-privilege) + +concurrency: + group: maru-chaos-testing-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + run-chaos-tests: + permissions: + contents: read # for actions/checkout + if: ${{ inputs.consensus-client-changed == 'true' }} + env: + COMMIT_TAG: ${{ inputs.commit_tag }} + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + runs-on: [ gha-runner-scale-set-ubuntu-24-amd64-large ] + name: chaos tests + # useful for debugging flaky tests. + # strategy: + # matrix: + # iterations: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Login to Docker Hub + if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }} + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Setup Java and Gradle + uses: ./.github/actions/setup-java-and-gradle + - name: Install helm + uses: azure/setup-helm@v4.3.1 + with: + version: 'v3.18.3' + id: install + + # SSH debugging session - before tests (if explicitly requested) + - name: Setup upterm session (pre-test) + if: ${{ inputs.enable_ssh_debug }} + uses: lhotari/action-upterm@v1 + with: + ## If no one connects shut down ssh server after timeout. + wait-timeout-minutes: 20 + + - name: Run chaos tests + id: chaos-tests + timeout-minutes: 30 + working-directory: maru/chaos-testing + run: | + mkdir -p ~/.kube + export KUBECONFIG=~/.kube/k3s-server + make k3s-reload # installs k3s K8S implementation + kubectl config set-context --current --namespace=default + make chaos-redeploy-chaos-mesh-and-linea maru_image=consensys/maru:local + make chaos-health-check # just make sure that the cluster is healthy before starting the chaos tests + make chaos-experiment-workflow-and-health-check + + - name: Collect pod logs + if: failure() + run: | + export KUBECONFIG=~/.kube/k3s-server + mkdir -p maru/chaos-testing/tmp/pod-logs + echo "Collecting logs from all pods..." + for pod in $(kubectl get pods -n default -o jsonpath='{.items[*].metadata.name}' 2>/dev/null); do + echo "Collecting logs for $pod" + kubectl logs "$pod" -n default --tail=5000 > "maru/chaos-testing/tmp/pod-logs/${pod}.log" 2>&1 || true + # Also collect previous container logs (if pod restarted) + kubectl logs "$pod" -n default --previous --tail=5000 > "maru/chaos-testing/tmp/pod-logs/${pod}-previous.log" 2>&1 || true + done + # Collect pod status/describe for context + kubectl get pods -n default -o wide > "maru/chaos-testing/tmp/pod-logs/pod-status.txt" 2>&1 || true + kubectl describe pods -n default > "maru/chaos-testing/tmp/pod-logs/pod-describe.txt" 2>&1 || true + echo "Log collection complete" + ls -la maru/chaos-testing/tmp/pod-logs/ + + - name: Collect port-forward logs + if: failure() + run: | + echo "Collecting port-forward logs..." + if [ -d maru/chaos-testing/tmp/pf ]; then + ls -la maru/chaos-testing/tmp/pf/ + else + echo "No port-forward log directory found" + fi + # Also collect port-forward summary files + for f in maru/chaos-testing/tmp/port-forward-*.txt; do + if [ -f "$f" ]; then + echo "=== $f ===" + cat "$f" + fi + done + # Check for any surviving port-forward processes + ps -o pid=,command= -ax | grep 'kubectl port-forward' | grep -v grep > maru/chaos-testing/tmp/pod-logs/port-forward-processes.txt 2>&1 || true + echo "Port-forward process collection complete" + + - name: Store reports and pod logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: chaos-test-reports-and-logs + path: | + maru/**/build/reports/tests/ + maru/chaos-testing/tmp/pod-logs/ + maru/chaos-testing/tmp/pf/ + maru/chaos-testing/tmp/port-forward-*.txt + + # SSH debugging session - on failure (if requested) + - name: Setup upterm session after failure + if: ${{ (failure() || steps.chaos-tests.outcome == 'failure') && inputs.ssh_debug_on_failure == true }} + uses: lhotari/action-upterm@v1 + with: + ## If no one connects shut down ssh server after timeout. + wait-timeout-minutes: 20 \ No newline at end of file diff --git a/.github/workflows/maru-e2e-tests.yml b/.github/workflows/maru-e2e-tests.yml new file mode 100644 index 00000000000..2d000e1072d --- /dev/null +++ b/.github/workflows/maru-e2e-tests.yml @@ -0,0 +1,95 @@ +name: maru-e2e-tests + +on: + workflow_dispatch: + inputs: + e2e-tests-with-ssh: + description: Run end to end tests with ability to ssh into environment + required: false + type: boolean + default: false + e2e-tests-logs-dump: + description: Dump logs after running end to end tests + required: false + type: boolean + default: false + workflow_call: + inputs: + e2e-tests-with-ssh: + description: Run end to end tests with ability to ssh into environment + required: false + type: boolean + default: false + e2e-tests-logs-dump: + description: Dump logs after running end to end tests + required: false + type: boolean + default: false + has-changes-requiring-build: + type: string + outputs: + tests_outcome: + value: ${{ jobs.run-e2e-tests.outputs.tests_outcome }} + secrets: + DOCKERHUB_USERNAME: + required: false + DOCKERHUB_TOKEN: + required: false + +permissions: {} # lock everything by default (least-privilege) + +concurrency: + group: maru-e2e-tests-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + # Required job + run-e2e-tests: + permissions: + contents: read # for actions/checkout + # We can only use conditionals, and not path filters to 'successfully' skip a required job - https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks + if: ${{ inputs.has-changes-requiring-build == 'true' }} + env: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + outputs: + tests_outcome: ${{ steps.run_e2e_tests.outcome }} + runs-on: [gha-runner-scale-set-ubuntu-24-amd64-med] + name: e2e tests + steps: + - name: Setup upterm session + if: ${{ inputs.e2e-tests-with-ssh }} + uses: lhotari/action-upterm@v1 + - name: Checkout + uses: actions/checkout@v6 + - name: Login to Docker Hub + if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }} + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Setup Java and Gradle + uses: ./.github/actions/setup-java-and-gradle + - name: Download images + working-directory: maru + run: | + make docker-pull + - name: Run e2e tests + id: run_e2e_tests + timeout-minutes: 10 + working-directory: maru + run: | + make run-e2e-test + - name: Show e2e tests result + if: always() + run: | + echo "E2E_TESTS_RESULT: ${{ steps.run_e2e_tests.outcome }}" + + - name: Archive debug logs + uses: actions/upload-artifact@v4 + if: ${{ failure() && inputs.e2e-tests-logs-dump }} + with: + name: end-2-end-debug-logs + if-no-files-found: error + path: | + maru/e2e/docker_logs/**/* \ No newline at end of file diff --git a/.github/workflows/maru-release.yml b/.github/workflows/maru-release.yml new file mode 100644 index 00000000000..80dbe7b8854 --- /dev/null +++ b/.github/workflows/maru-release.yml @@ -0,0 +1,126 @@ +name: maru-release + +on: + push: + tags: + # NOTE: monorepo convention - maru releases use a 'maru-v*' tag prefix + # (e.g. maru-v1.0.0) to avoid collisions with other components' release tags. + - 'maru-v*' + +permissions: {} # lock everything by default (least-privilege) + +concurrency: + group: maru-release-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +jobs: + compute-version: + permissions: + contents: read # for actions/checkout with fetch-depth: 0 + runs-on: gha-runner-scale-set-ubuntu-24-amd64-small + name: Compute version + outputs: + tag_name: ${{ steps.version.outputs.tag_name }} + semver_tag: ${{ steps.version.outputs.semver_tag }} + full_version: ${{ steps.version.outputs.full_version }} + date: ${{ steps.version.outputs.date }} + commit_hash: ${{ steps.version.outputs.commit_hash }} + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Validate tag and compute version + id: version + run: | + TAG_NAME=${GITHUB_REF#refs/tags/} + echo "Tag: $TAG_NAME" + + # Validate tag format: maru-v-? + # Examples: maru-v2.0.1-betav4 OR maru-v2.0.1 OR maru-v2.0.1-beta-v4 + if [[ ! $TAG_NAME =~ ^maru-v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9-]+)?$ ]]; then + echo "Error: Tag format is invalid. Expected format: maru-v-?" + echo "Examples: maru-v2.0.1-betav4 OR maru-v2.0.1 OR maru-v2.0.1-beta-v4" + exit 1 + fi + + # Strip the 'maru-' prefix to get the semver tag (matches the old 'v*' format used + # downstream by the docker image tag). + SEMVER_TAG=${TAG_NAME#maru-} + + # Compute date and commit hash + DATE=$(date -u +%Y%m%d%H%M%S) + COMMIT_HASH=$(git show-ref -s $TAG_NAME | cut -c1-7) + + # Create full version: -?-- + FULL_VERSION="${SEMVER_TAG}-${DATE}-${COMMIT_HASH}" + + echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT + echo "semver_tag=$SEMVER_TAG" >> $GITHUB_OUTPUT + echo "full_version=$FULL_VERSION" >> $GITHUB_OUTPUT + echo "date=$DATE" >> $GITHUB_OUTPUT + echo "commit_hash=$COMMIT_HASH" >> $GITHUB_OUTPUT + + echo "Release tag: $TAG_NAME" + echo "Semver tag: $SEMVER_TAG" + echo "Full version: $FULL_VERSION" + + build-and-publish-docker: + permissions: + contents: read # for actions/checkout in called workflow + needs: compute-version + uses: ./.github/workflows/maru-build-and-publish.yml + with: + commit_tag: ${{ needs.compute-version.outputs.full_version }} + develop_tag: ${{ needs.compute-version.outputs.semver_tag }} + image_name: 'consensys/maru' + push_image: true + upload_dist_artifact: true + secrets: inherit + + create-release: + permissions: + contents: write # for actions/checkout and softprops/action-gh-release + needs: [compute-version, build-and-publish-docker] + runs-on: gha-runner-scale-set-ubuntu-24-amd64-large + name: Create GitHub Release + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Download distribution artifact + uses: actions/download-artifact@v4 + with: + name: maru-distribution + path: maru/app/build/install/app/ + + - name: Create distribution archive + run: | + tar -czf maru-${{ needs.compute-version.outputs.full_version }}.tar.gz -C maru/app/build/install/app . + + - name: Prepare release body + run: | + cat << 'EOF' > release-body.md + ## Docker Image + + Docker Hub: https://hub.docker.com/r/consensys/maru/tags?name=${{ needs.compute-version.outputs.full_version }} + + ```bash + docker pull consensys/maru:${{ needs.compute-version.outputs.full_version }} + ``` + + EOF + cat maru/CHANGELOG.md >> release-body.md + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + draft: true + tag_name: ${{ needs.compute-version.outputs.tag_name }} + body_path: release-body.md + files: maru-${{ needs.compute-version.outputs.full_version }}.tar.gz + fail_on_unmatched_files: true + make_latest: true \ No newline at end of file diff --git a/.github/workflows/maru-smoke-tests.yml b/.github/workflows/maru-smoke-tests.yml new file mode 100644 index 00000000000..995b5ceb1b4 --- /dev/null +++ b/.github/workflows/maru-smoke-tests.yml @@ -0,0 +1,73 @@ +name: maru-smoke-tests + +on: + workflow_call: + inputs: + commit-tag: + required: true + type: string + secrets: + DOCKERHUB_USERNAME: + required: false + DOCKERHUB_TOKEN: + required: false + +permissions: {} # lock everything by default (least-privilege) + +concurrency: + group: maru-smoke-tests-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + run-smoke-tests: + permissions: + contents: read + env: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + runs-on: [gha-runner-scale-set-ubuntu-24-amd64-med] + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Download local docker image artifacts + uses: actions/download-artifact@v4 + with: + pattern: linea-maru + - name: Login to Docker Hub + if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }} + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Load Docker images + run: | + pwd && ls -la && echo "GITHUB_WORKSPACE=$GITHUB_WORKSPACE" && + gunzip -c $GITHUB_WORKSPACE/linea-maru/linea-maru-docker-image.tar.gz | docker load + - name: Run Docker with maru container + working-directory: maru + run: | + MARU_TAG=${{ inputs.commit-tag }} make docker-run-stack-partial + - name: List docker containers/images + continue-on-error: true + run: | + docker ps -la && docker images + docker container ls -a + - name: Check Maru Docker logs + run: | + SEARCH_STRING="Maru is up" + TIMEOUT_SECONDS=30 + INTERVAL_SECONDS=2 + END_TIME=$((SECONDS + TIMEOUT_SECONDS)) + while [ $SECONDS -lt $END_TIME ]; do + echo $(docker logs maru | grep -q "Maru is up") + LOGS=$(docker logs maru 2>&1) + if echo "$LOGS" | grep -q "$SEARCH_STRING"; then + echo "Found '$SEARCH_STRING' in logs. Marking job as successful." + exit 0 + fi + echo "String '$SEARCH_STRING' not found yet. Retrying in $INTERVAL_SECONDS seconds..." + sleep $INTERVAL_SECONDS + done + echo "Timeout of $TIMEOUT_SECONDS seconds reached. String '$SEARCH_STRING' not found in logs." + echo $LOGS + exit 1 \ No newline at end of file diff --git a/.github/workflows/maru-testing.yml b/.github/workflows/maru-testing.yml new file mode 100644 index 00000000000..5a2352285b9 --- /dev/null +++ b/.github/workflows/maru-testing.yml @@ -0,0 +1,67 @@ +name: maru-testing + +permissions: + contents: read + actions: read + +on: + workflow_call: + inputs: + commit_tag: + required: true + type: string + secrets: + DOCKERHUB_USERNAME: + required: false + DOCKERHUB_TOKEN: + required: false + +concurrency: + group: maru-testing-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + run-tests: + env: + COMMIT_TAG: ${{ inputs.commit_tag }} + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + runs-on: gha-runner-scale-set-ubuntu-24-amd64-med + name: maru tests + # useful for debugging flaky tests. Comment out Jacoco and Codecov steps because they override the test results. + # strategy: + # matrix: + # iterations: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + submodules: false + - name: Setup Java and Gradle + uses: ./.github/actions/setup-java-and-gradle + - name: Build consensus and Unit tests + run: | + # force tests to run even if the code is not changed + # this is to debug flaky tests + ./gradlew -V :maru:app:buildNeeded --rerun-tasks + - name: Store reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test reports + path: | + maru/**/build/reports/tests/ + - name: Upload Jacoco execution data + if: always() + uses: actions/upload-artifact@v7 + with: + name: jacoco-maru-exec + path: | + maru/**/build/jacoco/*.exec + if-no-files-found: ignore + - name: Upload test results to Codecov + if: ${{ !cancelled() && env.CODECOV_TOKEN != '' }} + uses: codecov/test-results-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/reuse-check-images-tags-and-push.yml b/.github/workflows/reuse-check-images-tags-and-push.yml index d392035620a..0208ef4638b 100644 --- a/.github/workflows/reuse-check-images-tags-and-push.yml +++ b/.github/workflows/reuse-check-images-tags-and-push.yml @@ -29,6 +29,9 @@ on: lido_governance_monitor_changed: required: true type: string + maru_changed: + required: true + type: string outputs: commit_tag: value: ${{ jobs.check_image_tags_exist.outputs.commit_tag }} @@ -48,6 +51,8 @@ on: value: ${{ jobs.image_tag_push.outputs.image_tagged_lido_governance_monitor || 'false' }} image_tagged_transaction_exclusion_api: value: ${{ jobs.image_tag_push.outputs.image_tagged_transaction_exclusion_api || 'false' }} + image_tagged_maru: + value: ${{ jobs.image_tag_push.outputs.image_tagged_maru || 'false' }} secrets: DOCKERHUB_USERNAME: required: false @@ -72,6 +77,7 @@ jobs: last_commit_tag_exists_postman: ${{ steps.check_image_tags_exist_postman.outputs.last_commit_tag_exists }} last_commit_tag_exists_prover: ${{ steps.check_image_tags_exist_prover.outputs.last_commit_tag_exists }} last_commit_tag_exists_transaction_exclusion_api: ${{ steps.check_image_tags_exist_transaction_exclusion_api.outputs.last_commit_tag_exists }} + last_commit_tag_exists_maru: ${{ steps.check_image_tags_exist_maru.outputs.last_commit_tag_exists }} commit_tag: ${{ steps.compute-version-tags.outputs.commit_tag }} last_commit_tag: ${{ steps.compute-version-tags.outputs.last_commit_tag }} develop_tag: ${{ steps.compute-version-tags.outputs.develop_tag }} @@ -138,6 +144,14 @@ jobs: last_commit_tag: ${{ steps.compute-version-tags.outputs.last_commit_tag }} image_name: consensys/linea-transaction-exclusion-api + - name: Check image tags exist for maru + uses: ./.github/actions/check-image-tags-exist + if: ${{ github.ref == 'refs/heads/main' && inputs.maru_changed == 'false' }} + id: check_image_tags_exist_maru + with: + last_commit_tag: ${{ steps.compute-version-tags.outputs.last_commit_tag }} + image_name: consensys/maru + image_tag_push: runs-on: gha-runner-scale-set-ubuntu-24-amd64-small if: ${{ github.ref == 'refs/heads/main' && inputs.has-changes-requiring-build == 'true' }} @@ -150,6 +164,7 @@ jobs: image_tagged_prover: ${{ steps.image_tag_push_prover.outputs.image_tagged }} image_tagged_postman: ${{ steps.image_tag_push_postman.outputs.image_tagged }} image_tagged_transaction_exclusion_api: ${{ steps.image_tag_push_transaction_exclusion_api.outputs.image_tagged }} + image_tagged_maru: ${{ steps.image_tag_push_maru.outputs.image_tagged }} steps: - name: Checkout uses: actions/checkout@v6 @@ -234,3 +249,16 @@ jobs: last_commit_tag_exists: ${{ needs.check_image_tags_exist.outputs.last_commit_tag_exists_transaction_exclusion_api }} docker_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Tag and push maru image + id: image_tag_push_maru + uses: ./.github/actions/image-tag-and-push + if: ${{ inputs.maru_changed == 'false' }} + with: + commit_tag: ${{ needs.check_image_tags_exist.outputs.commit_tag }} + last_commit_tag: ${{ needs.check_image_tags_exist.outputs.last_commit_tag }} + develop_tag: ${{ needs.check_image_tags_exist.outputs.develop_tag }} + image_name: consensys/maru + last_commit_tag_exists: ${{ needs.check_image_tags_exist.outputs.last_commit_tag_exists_maru }} + docker_username: ${{ secrets.DOCKERHUB_USERNAME }} + docker_password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index e22986edc24..05ac40d4250 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -46,6 +46,9 @@ on: constraints_changed: required: true type: string + maru_changed: + required: true + type: string jobs: # Cache for pulling Docker images is disabled as we empirically found that this @@ -122,6 +125,13 @@ jobs: if: ${{ inputs.constraints_changed == 'true' }} secrets: inherit + maru: + uses: ./.github/workflows/maru-testing.yml + if: ${{ inputs.maru_changed == 'true' }} + with: + commit_tag: ${{ inputs.commit_tag }} + secrets: inherit + # Run Jacoco report after all JVM tests complete jacoco-report: runs-on: gha-runner-scale-set-ubuntu-24-amd64-med @@ -208,7 +218,7 @@ jobs: # If all jobs are skipped, the workflow will still succeed. always_succeed: runs-on: ubuntu-24.04 - if: ${{ inputs.coordinator_changed == 'false' && inputs.prover_changed == 'false' && inputs.prover_ray_changed == 'false' && inputs.native_yield_automation_service_changed == 'false' && inputs.lido_governance_monitor_changed == 'false' && inputs.postman_changed == 'false' && inputs.transaction_exclusion_api_changed == 'false' && inputs.staterecovery_changed == 'false' && inputs.smart_contracts_changed == 'false' && inputs.linea_sequencer_changed == 'false' && inputs.constraints_changed == 'false' }} + if: ${{ inputs.coordinator_changed == 'false' && inputs.prover_changed == 'false' && inputs.prover_ray_changed == 'false' && inputs.native_yield_automation_service_changed == 'false' && inputs.lido_governance_monitor_changed == 'false' && inputs.postman_changed == 'false' && inputs.transaction_exclusion_api_changed == 'false' && inputs.staterecovery_changed == 'false' && inputs.smart_contracts_changed == 'false' && inputs.linea_sequencer_changed == 'false' && inputs.constraints_changed == 'false' && inputs.maru_changed == 'false' }} steps: - name: Ensure Workflow Success run: echo "All jobs were skipped, but workflow succeeds." From 2ca68b4b05ce83aded0e5a18fce30a9ef0dc0716 Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Fri, 15 May 2026 15:45:07 -0400 Subject: [PATCH 11/13] build(maru): pin Vert.x 4 + Micrometer 1.12 for Besu 26.5 bytecode compat Maru integration tests use Besu 26.5's acceptance-tests-dsl (ThreadBesuNodeRunner, Cluster) to spin up real Besu nodes in-JVM. Besu 26.5's bytecode is bound to: - Removed Vert.x 4 internal types: io.vertx.core.impl.ConcurrentHashSet, used by PeerPermissionsDenylist / MaintainedPeers / PrometheusMetricsSystem / PrometheusGuavaCache$Context / AccessLocationTracker$AccountAccessList. - Removed Vert.x 4 methods on still-present types: Vertx.nettyEventLoopGroup() (Vert.x 5 removed it entirely). - The pre-1.13 Micrometer Prometheus package io.micrometer.prometheus.PrometheusMeterRegistry (renamed to io.micrometer.prometheusmetrics.PrometheusMeterRegistry in 1.13+). Class-level shims can cover removed types but not removed methods on interfaces we don't own, so maru's test runtime must actually be on Vert.x 4 + Micrometer 1.12. Force in :maru's subprojects { ... } block: - all io.vertx:* (except vertx-stack-depchain, to avoid colliding with zkevm convention's strict 5.0.10 platform pin) -> 4.5.24 - all io.micrometer:* -> 1.12.13 And swap :maru:app's vertx-helper from the local Vert.x 5 :jvm-libs:generic:vertx-helper to the published Vert.x 4-era build.linea.internal:vertx-helper:0.0.1-v20260327160734 so its bytecode references resolve cleanly against the forced runtime. Verified: - :maru:jvm-libs:test-utils:test: 32 / 32 pass (was 23 / 32) - :maru:app:integrationTest: 38 / 39 pass (was 0 / 39); 1 flake passes on retry, unrelated to Vert.x Drop the entire eachDependency block and switch back to :jvm-libs:generic:vertx-helper once Besu moves to Vert.x 5. --- gradle/libs.versions.toml | 8 ++++++++ maru/app/build.gradle | 6 +++++- maru/build.gradle | 29 ++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e656bab17ad..c8ab4acae7b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -73,6 +73,14 @@ guava = "33.5.0" # Maru discovery = "26.3.0" +# The published build.linea.internal:vertx-helper artifact is on Vert.x 4. +# Maru depends on it (rather than the local :jvm-libs:generic:vertx-helper, which is on +# Vert.x 5) because Besu 26.5's bytecode references both removed Vert.x 4 internal +# types (e.g. io.vertx.core.impl.ConcurrentHashSet) AND removed Vert.x 4 methods on +# still-present types (e.g. Vertx.nettyEventLoopGroup). Class-level shims cover the +# former but not the latter, so maru must run on Vert.x 4 at test runtime. Drop this +# pin and switch back to :jvm-libs:generic:vertx-helper once Besu moves to Vert.x 5. +lineaPackages = "0.0.1-v20260327160734" dockerComposeRule = "2.3.0" http4k = "6.15.1.0" javalin = "6.7.0" diff --git a/maru/app/build.gradle b/maru/app/build.gradle index 554a25377eb..7cdddab878b 100644 --- a/maru/app/build.gradle +++ b/maru/app/build.gradle @@ -46,7 +46,11 @@ dependencies { // import dropped in favor of zkevm's lighter `net.consensys.zkevm.kotlin-application-conventions`). implementation project(':jvm-libs:linea:core:metrics') implementation project(':jvm-libs:linea:metrics:micrometer') - implementation project(':jvm-libs:generic:vertx-helper') + // Pinned to the published Vert.x 4-era artifact rather than the local + // :jvm-libs:generic:vertx-helper (Vert.x 5) because Besu 26.5's acceptance-tests-dsl + // and besu-ethereum-p2p call removed Vert.x 4 methods/internals at runtime. + // Tracked in libs.versions.toml `lineaPackages`. + implementation "build.linea.internal:vertx-helper:${libs.versions.lineaPackages.get()}" implementation "io.vertx:vertx-micrometer-metrics" implementation "info.picocli:picocli:${libs.versions.picoli.get()}" diff --git a/maru/build.gradle b/maru/build.gradle index eb339844e78..cbdaa81d3be 100644 --- a/maru/build.gradle +++ b/maru/build.gradle @@ -11,6 +11,33 @@ // licensing markers stay on every Kotlin and Java file. subprojects { + // Maru runs on Vert.x 4 at test runtime because Besu 26.5's acceptance-tests-dsl + // (and besu-ethereum-p2p / besu-metrics-core internals it loads via + // ThreadBesuNodeRunner) is bytecode-bound to removed Vert.x 4 types and methods + // (e.g. io.vertx.core.impl.ConcurrentHashSet, Vertx.nettyEventLoopGroup). + // zkevm's kotlin-common-conventions applies `api platform("vertx-stack-depchain + // :5.0.10")` which would normally win conflict resolution; resolutionStrategy.force + // on individual artifacts overrides that without colliding with the strict-5.0.10 + // constraint on vertx-stack-depchain itself. + // Drop this block once Besu moves to Vert.x 5. + configurations.configureEach { cfg -> + resolutionStrategy.eachDependency { details -> + if (details.requested.group == 'io.vertx' && details.requested.name != 'vertx-stack-depchain') { + details.useVersion('4.5.24') + details.because('Force Vert.x 4 for Besu 26.5 acceptance-tests-dsl bytecode compatibility') + } + // Besu 26.5's metrics-core (PrometheusMetricsSystem, PrometheusGuavaCache$Context) + // is bytecode-bound to io.micrometer.prometheus.PrometheusMeterRegistry, which was + // renamed to io.micrometer.prometheusmetrics.PrometheusMeterRegistry in Micrometer + // 1.13+. zkevm's catalog pins 1.16.4 (new package); pinning maru to the last 1.12.x + // keeps the old package so Besu's class-load succeeds. + if (details.requested.group == 'io.micrometer') { + details.useVersion('1.12.13') + details.because('Match Besu 26.5 bytecode that references io.micrometer.prometheus.* (pre-1.13 package)') + } + } + } + afterEvaluate { subproject -> if (subproject.plugins.hasPlugin('com.diffplug.spotless')) { subproject.spotless { @@ -29,4 +56,4 @@ subprojects { } } } -} \ No newline at end of file +} From a0667396b380a839684f541e92357520bbc75bf6 Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Fri, 15 May 2026 15:49:33 -0400 Subject: [PATCH 12/13] style(maru): add trailing newline to maru/api/build.gradle Missed by the catalog-fold conversion; caught by ./gradlew spotlessCheck on the monorepo-wide pass. --- maru/api/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maru/api/build.gradle b/maru/api/build.gradle index b2bc818e1bf..b14d887e0ca 100644 --- a/maru/api/build.gradle +++ b/maru/api/build.gradle @@ -14,4 +14,4 @@ dependencies { testImplementation(testFixtures(project(':maru:core'))) testImplementation(project(':maru:syncing')) testImplementation("com.squareup.okhttp3:okhttp:${libs.versions.okhttp.get()}") -} \ No newline at end of file +} From 6fbf44ea2e6bade9c1ede34ff4ceb000a1b0ac6e Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Mon, 18 May 2026 18:45:45 -0400 Subject: [PATCH 13/13] fix(maru): switch CI from :maru:app:buildNeeded to :maru:build aggregate CI was failing with a circular dependency between buildNeeded tasks: :maru:config:buildNeeded \--- :maru:core:buildNeeded \--- :maru:serialization:buildNeeded +--- :maru:config:buildNeeded +--- :maru:core:buildNeeded \--- :maru:crypto:buildNeeded \--- :maru:core:buildNeeded The cycle exists because :maru:core's testFixtures depend on :maru:serialization (+ observability, p2p, crypto), and :maru:serialization depends on :maru:core's main jar via implementation. That's a clean linear graph under normal `build`, but `buildNeeded` walks testFixtures too and trips on the cycle. Standalone maru's CI used `./gradlew build` which doesn't recurse via `buildNeeded`; our port copied coordinator-testing's pattern instead. Move maru back to the build-aggregate approach by: - Wiring :maru's existing root `build` task (auto-registered by zkevm's `allprojects { apply plugin: 'java' }`) to depend on every :maru:* subproject's `build`. Each subproject's `build` -> `check` -> (for :maru:app) integrationTest. - Switching maru-testing.yml from `:maru:app:buildNeeded` to `:maru:build`. Locally `./gradlew :maru:build` runs every :maru:*:test (passes) plus :maru:app:integrationTest (passes on isolated retry; remaining flakes are parallel-execution timing issues already known in standalone maru). --- .github/workflows/maru-testing.yml | 9 +++++++-- maru/build.gradle | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maru-testing.yml b/.github/workflows/maru-testing.yml index 5a2352285b9..b8e352e3bcc 100644 --- a/.github/workflows/maru-testing.yml +++ b/.github/workflows/maru-testing.yml @@ -40,11 +40,16 @@ jobs: submodules: false - name: Setup Java and Gradle uses: ./.github/actions/setup-java-and-gradle - - name: Build consensus and Unit tests + - name: Build maru and run unit + integration tests run: | # force tests to run even if the code is not changed # this is to debug flaky tests - ./gradlew -V :maru:app:buildNeeded --rerun-tasks + # :maru:build is an aggregate task defined in maru/build.gradle that + # depends on each :maru:* subproject's `build`. We avoid `buildNeeded` + # because :maru:core's testFixtures depend on :maru:serialization + # which depends on :maru:core's main jar -- linear under `build` but a + # cycle under `buildNeeded` (which walks testFixtures). + ./gradlew -V :maru:build --rerun-tasks - name: Store reports if: failure() uses: actions/upload-artifact@v4 diff --git a/maru/build.gradle b/maru/build.gradle index cbdaa81d3be..062ac9f80d5 100644 --- a/maru/build.gradle +++ b/maru/build.gradle @@ -10,6 +10,26 @@ // config. The monorepo doesn't enforce headers; maru retains them so the // licensing markers stay on every Kotlin and Java file. +// Aggregate task that builds every :maru:* subproject (and via each subproject's +// `check`, runs that subproject's tests + :maru:app:integrationTest). This is +// CI's entry point. Standalone maru used `./gradlew build` for the same purpose +// (it built every subproject because the standalone repo had no others); in the +// monorepo we need an aggregate scoped to :maru:* so we don't trigger zkevm builds. +// +// Avoiding `buildNeeded` is deliberate: maru's :maru:core has testFixtures that +// depend on :maru:serialization, which in turn depends on :maru:core's main jar. +// That's a clean linear dep in normal builds but `buildNeeded` walks testFixtures +// too and trips on the cycle (config -> core -> serialization -> config). Per- +// subproject `build` doesn't traverse cross-project test deps that way, so it +// resolves without conflict. +// :maru already has a `build` task from zkevm root's `allprojects { apply plugin +// 'java' }`. Wire it up to also depend on every :maru:* subproject's build, so +// `./gradlew :maru:build` becomes the CI entry point. +tasks.named('build') { + description = 'Aggregate: build every :maru:* subproject (compile + check + integrationTest).' + dependsOn(subprojects.collect { sp -> "${sp.path}:build" }) +} + subprojects { // Maru runs on Vert.x 4 at test runtime because Besu 26.5's acceptance-tests-dsl // (and besu-ethereum-p2p / besu-metrics-core internals it loads via