diff --git a/.github/actions/build-deps/action.yml b/.github/actions/build-deps/action.yml new file mode 100644 index 0000000000..272af0f97d --- /dev/null +++ b/.github/actions/build-deps/action.yml @@ -0,0 +1,62 @@ +# This action installs and optionally uploads Conan dependencies to a remote +# repository. The dependencies will only be uploaded if the credentials are +# provided. +name: Build Conan dependencies + +# Note that actions do not support 'type' and all inputs are strings, see +# https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs. +inputs: + build_dir: + description: 'The directory where to build.' + required: true + build_type: + description: 'The build type to use ("Debug", "Release").' + required: true + conan_remote_name: + description: 'The name of the Conan remote to use.' + required: true + conan_remote_url: + description: 'The URL of the Conan endpoint to use.' + required: true + conan_remote_username: + description: 'The username for logging into the Conan remote. If not provided, the dependencies will not be uploaded.' + required: false + default: '' + conan_remote_password: + description: 'The password for logging into the Conan remote. If not provided, the dependencies will not be uploaded.' + required: false + default: '' + force_build: + description: 'Force building of all dependencies ("true", "false").' + required: false + default: 'false' + force_upload: + description: 'Force uploading of all dependencies ("true", "false").' + required: false + default: 'false' + +runs: + using: composite + steps: + - name: Install Conan dependencies + shell: bash + run: | + echo 'Installing dependencies.' + mkdir -p ${{ inputs.build_dir }} + cd ${{ inputs.build_dir }} + conan install \ + --output-folder . \ + --build ${{ inputs.force_build == 'true' && '"*"' || 'missing' }} \ + --options:host '&:tests=True' \ + --options:host '&:xrpld=True' \ + --settings:all build_type=${{ inputs.build_type }} \ + --format=json .. + - name: Upload Conan dependencies + if: ${{ inputs.conan_remote_username != '' && inputs.conan_remote_password != '' }} + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + echo "Logging into Conan remote '${{ inputs.conan_remote_name }}' at ${{ inputs.conan_remote_url }}." + conan remote login ${{ inputs.conan_remote_name }} "${{ inputs.conan_remote_username }}" --password "${{ inputs.conan_remote_password }}" + echo 'Uploading dependencies.' + conan upload '*' --confirm --check ${{ inputs.force_upload == 'true' && '--force' || '' }} --remote=${{ inputs.conan_remote_name }} diff --git a/.github/actions/build-test/action.yml b/.github/actions/build-test/action.yml new file mode 100644 index 0000000000..44292e7318 --- /dev/null +++ b/.github/actions/build-test/action.yml @@ -0,0 +1,95 @@ +# This action build and tests the binary. The Conan dependencies must have +# already been installed (see the build-deps action). +name: Build and Test + +# Note that actions do not support 'type' and all inputs are strings, see +# https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs. +inputs: + build_dir: + description: 'The directory where to build.' + required: true + build_only: + description: 'Whether to only build or to build and test the code ("true", "false").' + required: false + default: 'false' + build_type: + description: 'The build type to use ("Debug", "Release").' + required: true + cmake_args: + description: 'Additional arguments to pass to CMake.' + required: false + default: '' + cmake_target: + description: 'The CMake target to build.' + required: true + codecov_token: + description: 'The Codecov token to use for uploading coverage reports.' + required: false + default: '' + os: + description: 'The operating system to use for the build ("linux", "macos", "windows").' + required: true + +runs: + using: composite + steps: + - name: Configure CMake + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + echo 'Configuring CMake.' + cmake \ + -G '${{ inputs.os == 'windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \ + -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \ + -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \ + ${{ inputs.cmake_args }} \ + .. + - name: Build the binary + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + echo 'Building binary.' + cmake \ + --build . \ + --config ${{ inputs.build_type }} \ + --parallel $(nproc) \ + --target ${{ inputs.cmake_target }} + - name: Check linking + if: ${{ inputs.os == 'linux' }} + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + echo 'Checking linking.' + ldd ./rippled + if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then + echo 'The binary is statically linked.' + else + echo 'The binary is dynamically linked.' + exit 1 + fi + - name: Verify voidstar + if: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }} + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + echo 'Verifying presence of instrumentation.' + ./rippled --version | grep libvoidstar + - name: Test the binary + if: ${{ inputs.build_only == 'false' }} + shell: bash + working-directory: ${{ inputs.build_dir }}/${{ inputs.os == 'windows' && inputs.build_type || '' }} + run: | + echo 'Testing binary.' + ./rippled --unittest --unittest-jobs $(nproc) + ctest -j $(nproc) --output-on-failure + - name: Upload coverage report + if: ${{ inputs.cmake_target == 'coverage' && inputs.codecov_token }} + uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3 + with: + disable_search: true + disable_telem: true + fail_ci_if_error: true + files: ${{ inputs.build_dir }}/coverage.xml + plugins: noop + token: ${{ inputs.codecov_token }} + verbose: true diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml deleted file mode 100644 index 6714369155..0000000000 --- a/.github/actions/build/action.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: build -inputs: - generator: - default: null - configuration: - required: true - cmake-args: - default: null - cmake-target: - default: all -# An implicit input is the environment variable `build_dir`. -runs: - using: composite - steps: - - name: configure - shell: bash - run: | - cd ${build_dir} - cmake \ - ${{ inputs.generator && format('-G "{0}"', inputs.generator) || '' }} \ - -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \ - -DCMAKE_BUILD_TYPE=${{ inputs.configuration }} \ - -Dtests=TRUE \ - -Dxrpld=TRUE \ - ${{ inputs.cmake-args }} \ - .. - - name: build - shell: bash - run: | - cmake \ - --build ${build_dir} \ - --config ${{ inputs.configuration }} \ - --parallel ${NUM_PROCESSORS:-$(nproc)} \ - --target ${{ inputs.cmake-target }} diff --git a/.github/actions/dependencies/action.yml b/.github/actions/dependencies/action.yml deleted file mode 100644 index 0bd28f15dd..0000000000 --- a/.github/actions/dependencies/action.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: dependencies -inputs: - configuration: - required: true -# Implicit inputs are the environment variables `build_dir`, CONAN_REMOTE_URL, -# CONAN_REMOTE_USERNAME, and CONAN_REMOTE_PASSWORD. The latter two are only -# used to upload newly built dependencies to the Conan remote. -runs: - using: composite - steps: - - name: add Conan remote - if: ${{ env.CONAN_REMOTE_URL != '' }} - shell: bash - run: | - echo "Adding Conan remote 'xrplf' at ${{ env.CONAN_REMOTE_URL }}." - conan remote add --index 0 --force xrplf ${{ env.CONAN_REMOTE_URL }} - echo "Listing Conan remotes." - conan remote list - - name: install dependencies - shell: bash - run: | - mkdir -p ${{ env.build_dir }} - cd ${{ env.build_dir }} - conan install \ - --output-folder . \ - --build missing \ - --options:host "&:tests=True" \ - --options:host "&:xrpld=True" \ - --settings:all build_type=${{ inputs.configuration }} \ - .. - - name: upload dependencies - if: ${{ env.CONAN_REMOTE_URL != '' && env.CONAN_REMOTE_USERNAME != '' && env.CONAN_REMOTE_PASSWORD != '' && github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }} - shell: bash - run: | - echo "Logging into Conan remote 'xrplf' at ${{ env.CONAN_REMOTE_URL }}." - conan remote login xrplf "${{ env.CONAN_REMOTE_USERNAME }}" --password "${{ env.CONAN_REMOTE_PASSWORD }}" - echo "Uploading dependencies." - conan upload '*' --confirm --check --remote xrplf diff --git a/Builds/levelization/README.md b/.github/scripts/levelization/README.md similarity index 95% rename from Builds/levelization/README.md rename to .github/scripts/levelization/README.md index 93aa316b61..ec41a021cc 100644 --- a/Builds/levelization/README.md +++ b/.github/scripts/levelization/README.md @@ -50,7 +50,7 @@ that `test` code should _never_ be included in `ripple` code.) ## Validation -The [levelization.sh](levelization.sh) script takes no parameters, +The [levelization](generate.sh) script takes no parameters, reads no environment variables, and can be run from any directory, as long as it is in the expected location in the rippled repo. It can be run at any time from within a checked out repo, and will @@ -72,15 +72,15 @@ It generates many files of [results](results): desired as described above. In a perfect repo, this file will be empty. This file is committed to the repo, and is used by the [levelization - Github workflow](../../.github/workflows/levelization.yml) to validate + Github workflow](../../workflows/check-levelization.yml) to validate that nothing changed. - [`ordering.txt`](results/ordering.txt): A list showing relationships between modules where there are no loops as they actually exist, as opposed to how they are desired as described above. This file is committed to the repo, and is used by the [levelization - Github workflow](../../.github/workflows/levelization.yml) to validate + Github workflow](../../workflows/check-levelization.yml) to validate that nothing changed. -- [`levelization.yml`](../../.github/workflows/levelization.yml) +- [`levelization.yml`](../../workflows/check-levelization.yml) Github Actions workflow to test that levelization loops haven't changed. Unfortunately, if changes are detected, it can't tell if they are improvements or not, so if you have resolved any issues or @@ -111,4 +111,4 @@ get those details locally. 1. Run `levelization.sh` 2. Grep the modules in `paths.txt`. - For example, if a cycle is found `A ~= B`, simply `grep -w -A Builds/levelization/results/paths.txt | grep -w B` + A .github/scripts/levelization/results/paths.txt | grep -w B` diff --git a/Builds/levelization/levelization.sh b/.github/scripts/levelization/generate.sh similarity index 98% rename from Builds/levelization/levelization.sh rename to .github/scripts/levelization/generate.sh index c18ca703f7..775ddf789f 100755 --- a/Builds/levelization/levelization.sh +++ b/.github/scripts/levelization/generate.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Usage: levelization.sh +# Usage: generate.sh # This script takes no parameters, reads no environment variables, # and can be run from any directory, as long as it is in the expected # location in the repo. @@ -19,7 +19,7 @@ export LANG=C rm -rfv results mkdir results includes="$( pwd )/results/rawincludes.txt" -pushd ../.. +pushd ../../.. echo Raw includes: grep -r '^[ ]*#include.*/.*\.h' include src | \ grep -v boost | tee ${includes} diff --git a/Builds/levelization/results/loops.txt b/.github/scripts/levelization/results/loops.txt similarity index 80% rename from Builds/levelization/results/loops.txt rename to .github/scripts/levelization/results/loops.txt index df1d273f93..0bbd65a9e4 100644 --- a/Builds/levelization/results/loops.txt +++ b/.github/scripts/levelization/results/loops.txt @@ -10,9 +10,6 @@ Loop: xrpld.app xrpld.core Loop: xrpld.app xrpld.ledger xrpld.app > xrpld.ledger -Loop: xrpld.app xrpld.net - xrpld.app > xrpld.net - Loop: xrpld.app xrpld.overlay xrpld.overlay > xrpld.app @@ -25,15 +22,9 @@ Loop: xrpld.app xrpld.rpc Loop: xrpld.app xrpld.shamap xrpld.app > xrpld.shamap -Loop: xrpld.core xrpld.net - xrpld.net > xrpld.core - Loop: xrpld.core xrpld.perflog xrpld.perflog == xrpld.core -Loop: xrpld.net xrpld.rpc - xrpld.rpc ~= xrpld.net - Loop: xrpld.overlay xrpld.rpc xrpld.rpc ~= xrpld.overlay diff --git a/Builds/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt similarity index 97% rename from Builds/levelization/results/ordering.txt rename to .github/scripts/levelization/results/ordering.txt index ce22d8edb0..bf2d1db693 100644 --- a/Builds/levelization/results/ordering.txt +++ b/.github/scripts/levelization/results/ordering.txt @@ -2,6 +2,8 @@ libxrpl.basics > xrpl.basics libxrpl.crypto > xrpl.basics libxrpl.json > xrpl.basics libxrpl.json > xrpl.json +libxrpl.net > xrpl.basics +libxrpl.net > xrpl.net libxrpl.protocol > xrpl.basics libxrpl.protocol > xrpl.json libxrpl.protocol > xrpl.protocol @@ -62,9 +64,9 @@ test.jtx > xrpl.basics test.jtx > xrpld.app test.jtx > xrpld.core test.jtx > xrpld.ledger -test.jtx > xrpld.net test.jtx > xrpld.rpc test.jtx > xrpl.json +test.jtx > xrpl.net test.jtx > xrpl.protocol test.jtx > xrpl.resource test.jtx > xrpl.server @@ -109,7 +111,6 @@ test.rpc > test.toplevel test.rpc > xrpl.basics test.rpc > xrpld.app test.rpc > xrpld.core -test.rpc > xrpld.net test.rpc > xrpld.overlay test.rpc > xrpld.rpc test.rpc > xrpl.json @@ -134,6 +135,7 @@ test.toplevel > xrpl.json test.unit_test > xrpl.basics tests.libxrpl > xrpl.basics xrpl.json > xrpl.basics +xrpl.net > xrpl.basics xrpl.protocol > xrpl.basics xrpl.protocol > xrpl.json xrpl.resource > xrpl.basics @@ -149,6 +151,7 @@ xrpld.app > xrpld.consensus xrpld.app > xrpld.nodestore xrpld.app > xrpld.perflog xrpld.app > xrpl.json +xrpld.app > xrpl.net xrpld.app > xrpl.protocol xrpld.app > xrpl.resource xrpld.conditions > xrpl.basics @@ -158,14 +161,11 @@ xrpld.consensus > xrpl.json xrpld.consensus > xrpl.protocol xrpld.core > xrpl.basics xrpld.core > xrpl.json +xrpld.core > xrpl.net xrpld.core > xrpl.protocol xrpld.ledger > xrpl.basics xrpld.ledger > xrpl.json xrpld.ledger > xrpl.protocol -xrpld.net > xrpl.basics -xrpld.net > xrpl.json -xrpld.net > xrpl.protocol -xrpld.net > xrpl.resource xrpld.nodestore > xrpl.basics xrpld.nodestore > xrpld.core xrpld.nodestore > xrpld.unity @@ -189,6 +189,7 @@ xrpld.rpc > xrpld.core xrpld.rpc > xrpld.ledger xrpld.rpc > xrpld.nodestore xrpld.rpc > xrpl.json +xrpld.rpc > xrpl.net xrpld.rpc > xrpl.protocol xrpld.rpc > xrpl.resource xrpld.rpc > xrpl.server diff --git a/.github/scripts/strategy-matrix/generate.py b/.github/scripts/strategy-matrix/generate.py new file mode 100644 index 0000000000..42927b5ccd --- /dev/null +++ b/.github/scripts/strategy-matrix/generate.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +import argparse +import itertools +import json +import re + +''' +Generate a strategy matrix for GitHub Actions CI. + +On each PR commit we will build a selection of Debian, RHEL, Ubuntu, MacOS, and +Windows configurations, while upon merge into the develop, release, or master +branches, we will build all configurations, and test most of them. + +We will further set additional CMake arguments as follows: +- All builds will have the `tests`, `werr`, and `xrpld` options. +- All builds will have the `wextra` option except for GCC 12 and Clang 16. +- All release builds will have the `assert` option. +- Certain Debian Bookworm configurations will change the reference fee, enable + codecov, and enable voidstar in PRs. +''' +def generate_strategy_matrix(all: bool, architecture: list[dict], os: list[dict], build_type: list[str], cmake_args: list[str]) -> dict: + configurations = [] + for architecture, os, build_type, cmake_args in itertools.product(architecture, os, build_type, cmake_args): + # The default CMake target is 'all' for Linux and MacOS and 'install' + # for Windows, but it can get overridden for certain configurations. + cmake_target = 'install' if os["distro_name"] == 'windows' else 'all' + + # We build and test all configurations by default, except for Windows in + # Debug, because it is too slow, as well as when code coverage is + # enabled as that mode already runs the tests. + build_only = False + if os['distro_name'] == 'windows' and build_type == 'Debug': + build_only = True + + # Only generate a subset of configurations in PRs. + if not all: + # Debian: + # - Bookworm using GCC 13: Release and Unity on linux/arm64, set + # the reference fee to 500. + # - Bookworm using GCC 15: Debug and no Unity on linux/amd64, enable + # code coverage. + # - Bookworm using Clang 16: Debug and no Unity on linux/arm64, + # enable voidstar. + # - Bookworm using Clang 17: Release and no Unity on linux/amd64, + # set the reference fee to 1000. + # - Bookworm using Clang 20: Debug and Unity on linux/amd64. + if os['distro_name'] == 'debian': + skip = True + if os['distro_version'] == 'bookworm': + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-13' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/arm64': + cmake_args = f'{cmake_args} -DUNIT_TEST_REFERENCE_FEE=500' + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': + cmake_args = f'{cmake_args} -Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0' + cmake_target = 'coverage' + build_only = True + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-16' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64': + cmake_args = f'{cmake_args} -Dvoidstar=ON' + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-17' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': + cmake_args = f'{cmake_args} -DUNIT_TEST_REFERENCE_FEE=1000' + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-20' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': + skip = False + if skip: + continue + + # RHEL: + # - 9.4 using GCC 12: Debug and Unity on linux/amd64. + # - 9.6 using Clang: Release and no Unity on linux/amd64. + if os['distro_name'] == 'rhel': + skip = True + if os['distro_version'] == '9.4': + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': + skip = False + elif os['distro_version'] == '9.6': + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-any' and build_type == 'Release' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': + skip = False + if skip: + continue + + # Ubuntu: + # - Jammy using GCC 12: Debug and no Unity on linux/arm64. + # - Noble using GCC 14: Release and Unity on linux/amd64. + # - Noble using Clang 18: Debug and no Unity on linux/amd64. + # - Noble using Clang 19: Release and Unity on linux/arm64. + if os['distro_name'] == 'ubuntu': + skip = True + if os['distro_version'] == 'jammy': + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64': + skip = False + elif os['distro_version'] == 'noble': + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-14' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-18' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-19' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/arm64': + skip = False + if skip: + continue + + # MacOS: + # - Debug and no Unity on macos/arm64. + if os['distro_name'] == 'macos' and not (build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'macos/arm64'): + continue + + # Windows: + # - Release and Unity on windows/amd64. + if os['distro_name'] == 'windows' and not (build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'windows/amd64'): + continue + + + # Additional CMake arguments. + cmake_args = f'{cmake_args} -Dtests=ON -Dwerr=ON -Dxrpld=ON' + if not f'{os['compiler_name']}-{os['compiler_version']}' in ['gcc-12', 'clang-16']: + cmake_args = f'{cmake_args} -Dwextra=ON' + if build_type == 'Release': + cmake_args = f'{cmake_args} -Dassert=ON' + + # We skip all RHEL on arm64 due to a build failure that needs further + # investigation. + if os['distro_name'] == 'rhel' and architecture['platform'] == 'linux/arm64': + continue + + # Generate a unique name for the configuration, e.g. macos-arm64-debug + # or debian-bookworm-gcc-12-amd64-release-unity. + config_name = os['distro_name'] + if (n := os['distro_version']) != '': + config_name += f'-{n}' + if (n := os['compiler_name']) != '': + config_name += f'-{n}' + if (n := os['compiler_version']) != '': + config_name += f'-{n}' + config_name += f'-{architecture['platform'][architecture['platform'].find('/')+1:]}' + config_name += f'-{build_type.lower()}' + if '-Dunity=ON' in cmake_args: + config_name += '-unity' + + configurations.append({ + 'architecture': architecture, + 'os': os, + 'build_type': build_type, + 'build_only': 'true' if build_only else 'false', + 'cmake_args': cmake_args, + 'cmake_target': cmake_target, + 'config_name': config_name, + }) + + return {'include': configurations} + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-a', '--all', help='Set to generate all configurations (generally used when merging a PR) or leave unset to generate a subset of configurations (generally used when committing to a PR).', action="store_true") + parser.add_argument('-c', '--config', help='Path to the JSON file containing the strategy matrix configurations.', required=True, type=str) + args = parser.parse_args() + + # Load the JSON configuration file. + config = None + with open(args.config, 'r') as f: + config = json.load(f) + if config['architecture'] is None or config['os'] is None or config['build_type'] is None or config['cmake_args'] is None: + raise Exception('Invalid configuration file.') + + # Generate the strategy matrix. + print(f'matrix={json.dumps(generate_strategy_matrix(args.all, config['architecture'], config['os'], config['build_type'], config['cmake_args']))}') diff --git a/.github/scripts/strategy-matrix/linux.json b/.github/scripts/strategy-matrix/linux.json new file mode 100644 index 0000000000..d8f176273d --- /dev/null +++ b/.github/scripts/strategy-matrix/linux.json @@ -0,0 +1,170 @@ +{ + "architecture": [ + { + "platform": "linux/amd64", + "runner": [ + "self-hosted", + "Linux", + "X64", + "heavy" + ] + }, + { + "platform": "linux/arm64", + "runner": [ + "self-hosted", + "Linux", + "ARM64", + "heavy-arm64" + ] + } + ], + "os": [ + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "gcc", + "compiler_version": "12" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "gcc", + "compiler_version": "13" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "gcc", + "compiler_version": "14" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "gcc", + "compiler_version": "15" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "clang", + "compiler_version": "16" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "clang", + "compiler_version": "17" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "clang", + "compiler_version": "18" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "clang", + "compiler_version": "19" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "clang", + "compiler_version": "20" + }, + { + "distro_name": "rhel", + "distro_version": "9.4", + "compiler_name": "gcc", + "compiler_version": "12" + }, + { + "distro_name": "rhel", + "distro_version": "9.4", + "compiler_name": "gcc", + "compiler_version": "13" + }, + { + "distro_name": "rhel", + "distro_version": "9.4", + "compiler_name": "gcc", + "compiler_version": "14" + }, + { + "distro_name": "rhel", + "distro_version": "9.6", + "compiler_name": "gcc", + "compiler_version": "13" + }, + { + "distro_name": "rhel", + "distro_version": "9.6", + "compiler_name": "gcc", + "compiler_version": "14" + }, + { + "distro_name": "rhel", + "distro_version": "9.4", + "compiler_name": "clang", + "compiler_version": "any" + }, + { + "distro_name": "rhel", + "distro_version": "9.6", + "compiler_name": "clang", + "compiler_version": "any" + }, + { + "distro_name": "ubuntu", + "distro_version": "jammy", + "compiler_name": "gcc", + "compiler_version": "12" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "gcc", + "compiler_version": "13" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "gcc", + "compiler_version": "14" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "clang", + "compiler_version": "16" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "clang", + "compiler_version": "17" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "clang", + "compiler_version": "18" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "clang", + "compiler_version": "19" + } + ], + "build_type": [ + "Debug", + "Release" + ], + "cmake_args": [ + "-Dunity=OFF", + "-Dunity=ON" + ] +} diff --git a/.github/scripts/strategy-matrix/macos.json b/.github/scripts/strategy-matrix/macos.json new file mode 100644 index 0000000000..a6ffdf14b7 --- /dev/null +++ b/.github/scripts/strategy-matrix/macos.json @@ -0,0 +1,29 @@ +{ + "architecture": [ + { + "platform": "macos/arm64", + "runner": [ + "self-hosted", + "macOS", + "ARM64", + "mac-runner-m1" + ] + } + ], + "os": [ + { + "distro_name": "macos", + "distro_version": "", + "compiler_name": "", + "compiler_version": "" + } + ], + "build_type": [ + "Debug", + "Release" + ], + "cmake_args": [ + "-Dunity=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5", + "-Dunity=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5" + ] +} diff --git a/.github/scripts/strategy-matrix/windows.json b/.github/scripts/strategy-matrix/windows.json new file mode 100644 index 0000000000..aaa8c94411 --- /dev/null +++ b/.github/scripts/strategy-matrix/windows.json @@ -0,0 +1,26 @@ +{ + "architecture": [ + { + "platform": "windows/amd64", + "runner": [ + "windows-latest" + ] + } + ], + "os": [ + { + "distro_name": "windows", + "distro_version": "", + "compiler_name": "", + "compiler_version": "" + } + ], + "build_type": [ + "Debug", + "Release" + ], + "cmake_args": [ + "-Dunity=OFF", + "-Dunity=ON" + ] +} diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml new file mode 100644 index 0000000000..2fa557f671 --- /dev/null +++ b/.github/workflows/build-test.yml @@ -0,0 +1,219 @@ +# This workflow builds and tests the binary for various configurations. +name: Build and test + +# This workflow can only be triggered by other workflows. Note that the +# workflow_call event does not support the 'choice' input type, see +# https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#onworkflow_callinputsinput_idtype, +# so we use 'string' instead. +on: + workflow_call: + inputs: + build_dir: + description: 'The directory where to build.' + required: false + type: string + default: '.build' + conan_remote_name: + description: 'The name of the Conan remote to use.' + required: true + type: string + conan_remote_url: + description: 'The URL of the Conan endpoint to use.' + required: true + type: string + dependencies_force_build: + description: 'Force building of all dependencies.' + required: false + type: boolean + default: false + dependencies_force_upload: + description: 'Force uploading of all dependencies.' + required: false + type: boolean + default: false + os: + description: 'The operating system to use for the build ("linux", "macos", "windows").' + required: true + type: string + strategy_matrix: + # TODO: Support additional strategies, e.g. "ubuntu" for generating all Ubuntu configurations. + description: 'The strategy matrix to use for generating the configurations ("minimal", "all").' + required: false + type: string + default: 'minimal' + secrets: + codecov_token: + description: 'The Codecov token to use for uploading coverage reports.' + required: false + conan_remote_username: + description: 'The username for logging into the Conan remote. If not provided, the dependencies will not be uploaded.' + required: false + conan_remote_password: + description: 'The password for logging into the Conan remote. If not provided, the dependencies will not be uploaded.' + required: false + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.os }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + # Generate the strategy matrix to be used by the following job. + generate-matrix: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Set up Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: 3.13 + - name: Generate strategy matrix + working-directory: .github/scripts/strategy-matrix + id: generate + run: python generate.py ${{ inputs.strategy_matrix == 'all' && '--all' || '' }} --config=${{ inputs.os }}.json >> "${GITHUB_OUTPUT}" + outputs: + matrix: ${{ steps.generate.outputs.matrix }} + + # Build and test the binary. + build-test: + needs: + - generate-matrix + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} + runs-on: ${{ matrix.architecture.runner }} + container: ${{ inputs.os == 'linux' && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version) || null }} + steps: + - name: Check strategy matrix + run: | + echo 'Operating system distro name: ${{ matrix.os.distro_name }}' + echo 'Operating system distro version: ${{ matrix.os.distro_version }}' + echo 'Operating system compiler name: ${{ matrix.os.compiler_name }}' + echo 'Operating system compiler version: ${{ matrix.os.compiler_version }}' + echo 'Architecture platform: ${{ matrix.architecture.platform }}' + echo 'Architecture runner: ${{ toJson(matrix.architecture.runner) }}' + echo 'Build type: ${{ matrix.build_type }}' + echo 'Build only: ${{ matrix.build_only }}' + echo 'CMake arguments: ${{ matrix.cmake_args }}' + echo 'CMake target: ${{ matrix.cmake_target }}' + echo 'Config name: ${{ matrix.config_name }}' + - name: Clean workspace (MacOS) + if: ${{ inputs.os == 'macos' }} + run: | + WORKSPACE=${{ github.workspace }} + echo "Cleaning workspace '${WORKSPACE}'." + if [ -z "${WORKSPACE}" ] || [ "${WORKSPACE}" = "/" ]; then + echo "Invalid working directory '${WORKSPACE}'." + exit 1 + fi + find "${WORKSPACE}" -depth 1 | xargs rm -rfv + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Set up Python (Windows) + if: ${{ inputs.os == 'windows' }} + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: 3.13 + - name: Install build tools (Windows) + if: ${{ inputs.os == 'windows' }} + run: | + echo 'Installing build tools.' + pip install wheel conan + - name: Check configuration (Windows) + if: ${{ inputs.os == 'windows' }} + run: | + echo 'Checking environment variables.' + set + + echo 'Checking CMake version.' + cmake --version + + echo 'Checking Conan version.' + conan --version + - name: Install build tools (MacOS) + if: ${{ inputs.os == 'macos' }} + run: | + echo 'Installing build tools.' + brew install cmake conan ninja coreutils + - name: Check configuration (Linux and MacOS) + if: ${{ inputs.os == 'linux' || inputs.os == 'macos' }} + run: | + echo 'Checking path.' + echo ${PATH} | tr ':' '\n' + + echo 'Checking environment variables.' + env | sort + + echo 'Checking CMake version.' + cmake --version + + echo 'Checking compiler version.' + ${{ inputs.os == 'linux' && '${CC}' || 'clang' }} --version + + echo 'Checking Conan version.' + conan --version + + echo 'Checking Ninja version.' + ninja --version + + echo 'Checking nproc version.' + nproc --version + - name: Set up Conan home directory (MacOS) + if: ${{ inputs.os == 'macos' }} + run: | + echo 'Setting up Conan home directory.' + export CONAN_HOME=${{ github.workspace }}/.conan + mkdir -p ${CONAN_HOME} + - name: Set up Conan home directory (Windows) + if: ${{ inputs.os == 'windows' }} + run: | + echo 'Setting up Conan home directory.' + set CONAN_HOME=${{ github.workspace }}\.conan + mkdir -p %CONAN_HOME% + - name: Set up Conan configuration + run: | + echo 'Installing configuration.' + cat conan/global.conf ${{ inputs.os == 'linux' && '>>' || '>' }} $(conan config home)/global.conf + + echo 'Conan configuration:' + conan config show '*' + - name: Set up Conan profile + run: | + echo 'Installing profile.' + conan config install conan/profiles/default -tf $(conan config home)/profiles/ + + echo 'Conan profile:' + conan profile show + - name: Set up Conan remote + shell: bash + run: | + echo "Adding Conan remote '${{ inputs.conan_remote_name }}' at ${{ inputs.conan_remote_url }}." + conan remote add --index 0 --force ${{ inputs.conan_remote_name }} ${{ inputs.conan_remote_url }} + + echo 'Listing Conan remotes.' + conan remote list + - name: Build dependencies + uses: ./.github/actions/build-deps + with: + build_dir: ${{ inputs.build_dir }} + build_type: ${{ matrix.build_type }} + conan_remote_name: ${{ inputs.conan_remote_name }} + conan_remote_url: ${{ inputs.conan_remote_url }} + conan_remote_username: ${{ secrets.conan_remote_username }} + conan_remote_password: ${{ secrets.conan_remote_password }} + force_build: ${{ inputs.dependencies_force_build }} + force_upload: ${{ inputs.dependencies_force_upload }} + - name: Build and test binary + uses: ./.github/actions/build-test + with: + build_dir: ${{ inputs.build_dir }} + build_only: ${{ matrix.build_only }} + build_type: ${{ matrix.build_type }} + cmake_args: ${{ matrix.cmake_args }} + cmake_target: ${{ matrix.cmake_target }} + codecov_token: ${{ secrets.codecov_token }} + os: ${{ inputs.os }} diff --git a/.github/workflows/check-format.yml b/.github/workflows/check-format.yml new file mode 100644 index 0000000000..5e3da10028 --- /dev/null +++ b/.github/workflows/check-format.yml @@ -0,0 +1,112 @@ +# This workflow checks if the code is properly formatted. +name: Check format + +# This workflow can only be triggered by other workflows. +on: workflow_call + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-format + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + clang-format: + runs-on: ubuntu-latest + container: ghcr.io/xrplf/ci/tools-rippled-clang-format + steps: + # The $GITHUB_WORKSPACE and ${{ github.workspace }} might not point to the + # same directory for jobs running in containers. The actions/checkout step + # is *supposed* to checkout into $GITHUB_WORKSPACE and then add it to + # safe.directory (see instructions at https://github.com/actions/checkout) + # but that is apparently not happening for some container images. We + # therefore preemptively add both directories to safe.directory. See also + # https://github.com/actions/runner/issues/2058 for more details. + - name: Configure git safe.directory + run: | + git config --global --add safe.directory $GITHUB_WORKSPACE + git config --global --add safe.directory ${{ github.workspace }} + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Check configuration + run: | + echo 'Checking path.' + echo ${PATH} | tr ':' '\n' + + echo 'Checking environment variables.' + env | sort + + echo 'Checking clang-format version.' + clang-format --version + - name: Format code + run: find include src tests -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format -i {} + + - name: Check for differences + env: + MESSAGE: | + One or more files did not conform to the formatting specified in + .clang-format. Maybe you did not run 'git-clang-format' or + 'clang-format' before committing, or your version of clang-format + has an incompatibility with the one used here (see the "Check + configuration" step above). + + Run 'git-clang-format --extensions cpp,h,hpp,ipp develop' in your + repo, and then commit and push the changes. + run: | + DIFF=$(git status --porcelain) + if [ -n "${DIFF}" ]; then + # Print the files that changed to give the contributor a hint about + # what to expect when running git-clang-format on their own machine. + git status + echo "${MESSAGE}" + exit 1 + fi + + prettier: + runs-on: ubuntu-latest + container: ghcr.io/xrplf/ci/tools-rippled-prettier + steps: + - name: Configure git safe.directory + run: | + git config --global --add safe.directory $GITHUB_WORKSPACE + git config --global --add safe.directory ${{ github.workspace }} + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - name: Check configuration + run: | + echo 'Checking path.' + echo ${PATH} | tr ':' '\n' + + echo 'Checking environment variables.' + env | sort + + echo 'Checking NPM version.' + npm --version + + echo 'Checking Node.js version.' + node --version + + echo 'Checking prettier version.' + prettier --version + - name: Format code + run: prettier --check . + - name: Check for differences + env: + MESSAGE: | + One or more files did not conform to the formatting rules specified + by Prettier. Maybe you did not run 'prettier' before committing, or + your version of prettier has an incompatibility with the one used + here (see the "Check configuration" step above). + + Run 'prettier --check .' in your repo, and then commit and push the + changes. + run: | + DIFF=$(git status --porcelain) + if [ -n "${DIFF}" ]; then + # Print the files that changed to give the contributor a hint about + # what to expect when running prettier on their own machine. + git status + echo "${MESSAGE}" + exit 1 + fi diff --git a/.github/workflows/check-levelization.yml b/.github/workflows/check-levelization.yml new file mode 100644 index 0000000000..3430ca28a2 --- /dev/null +++ b/.github/workflows/check-levelization.yml @@ -0,0 +1,46 @@ +# This workflow checks if the dependencies between the modules are correctly +# indexed. +name: Check levelization + +# This workflow can only be triggered by other workflows. +on: workflow_call + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-levelization + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + levelization: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Check levelization + run: .github/scripts/levelization/generate.sh + - name: Check for differences + env: + MESSAGE: | + + The dependency relationships between the modules in rippled have + changed, which may be an improvement or a regression. + + A rule of thumb is that if your changes caused something to be + removed from loops.txt, it's probably an improvement, while if + something was added, it's probably a regression. + + Run '.github/scripts/levelization/generate.sh' in your repo, commit + and push the changes. See .github/scripts/levelization/README.md for + more info. + run: | + DIFF=$(git status --porcelain) + if [ -n "${DIFF}" ]; then + # Print the differences to give the contributor a hint about what to + # expect when running levelization on their own machine. + git diff + echo "${MESSAGE}" + exit 1 + fi diff --git a/.github/workflows/check-missing-commits.yml b/.github/workflows/check-missing-commits.yml new file mode 100644 index 0000000000..da0e296e70 --- /dev/null +++ b/.github/workflows/check-missing-commits.yml @@ -0,0 +1,62 @@ +# This workflow checks that all commits in the "master" branch are also in the +# "release" and "develop" branches, and that all commits in the "release" branch +# are also in the "develop" branch. +name: Check for missing commits + +# This workflow can only be triggered by other workflows. +on: workflow_call + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-missing-commits + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + fetch-depth: 0 + - name: Check for missing commits + env: + MESSAGE: | + + If you are reading this, then the commits indicated above are missing + from the "develop" and/or "release" branch. Do a reverse-merge as soon + as possible. See CONTRIBUTING.md for instructions. + run: | + set -o pipefail + # Branches are ordered by how "canonical" they are. Every commit in one + # branch should be in all the branches behind it. + order=(master release develop) + branches=() + for branch in "${order[@]}"; do + # Check that the branches exist so that this job will work on forked + # repos, which don't necessarily have master and release branches. + echo "Checking if ${branch} exists." + if git ls-remote --exit-code --heads origin \ + refs/heads/${branch} > /dev/null; then + branches+=(origin/${branch}) + fi + done + + prior=() + for branch in "${branches[@]}"; do + if [[ ${#prior[@]} -ne 0 ]]; then + echo "Checking ${prior[@]} for commits missing from ${branch}." + git log --oneline --no-merges "${prior[@]}" \ + ^$branch | tee -a "missing-commits.txt" + echo + fi + prior+=("${branch}") + done + + if [[ $(cat missing-commits.txt | wc -l) -ne 0 ]]; then + echo "${MESSAGE}" + exit 1 + fi diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml deleted file mode 100644 index 0d81f87791..0000000000 --- a/.github/workflows/clang-format.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: clang-format - -on: - push: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - -jobs: - check: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - runs-on: ubuntu-24.04 - container: ghcr.io/xrplf/ci/tools-rippled-clang-format - steps: - # For jobs running in containers, $GITHUB_WORKSPACE and ${{ github.workspace }} might not be the - # same directory. The actions/checkout step is *supposed* to checkout into $GITHUB_WORKSPACE and - # then add it to safe.directory (see instructions at https://github.com/actions/checkout) - # but that's apparently not happening for some container images. We can't be sure what is actually - # happening, so let's pre-emptively add both directories to safe.directory. There's a - # Github issue opened in 2022 and not resolved in 2025 https://github.com/actions/runner/issues/2058 ¯\_(ツ)_/¯ - - run: | - git config --global --add safe.directory $GITHUB_WORKSPACE - git config --global --add safe.directory ${{ github.workspace }} - - uses: actions/checkout@v4 - - name: Format first-party sources - run: | - clang-format --version - find include src tests -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format -i {} + - - name: Check for differences - id: assert - shell: bash - run: | - set -o pipefail - git diff --exit-code | tee "clang-format.patch" - - name: Upload patch - if: failure() && steps.assert.outcome == 'failure' - uses: actions/upload-artifact@v4 - continue-on-error: true - with: - name: clang-format.patch - if-no-files-found: ignore - path: clang-format.patch - - name: What happened? - if: failure() && steps.assert.outcome == 'failure' - env: - PREAMBLE: | - If you are reading this, you are looking at a failed Github Actions - job. That means you pushed one or more files that did not conform - to the formatting specified in .clang-format. That may be because - you neglected to run 'git clang-format' or 'clang-format' before - committing, or that your version of clang-format has an - incompatibility with the one on this - machine, which is: - SUGGESTION: | - - To fix it, you can do one of two things: - 1. Download and apply the patch generated as an artifact of this - job to your repo, commit, and push. - 2. Run 'git-clang-format --extensions cpp,h,hpp,ipp develop' - in your repo, commit, and push. - run: | - echo "${PREAMBLE}" - clang-format --version - echo "${SUGGESTION}" - exit 1 diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml deleted file mode 100644 index 01e04a3f5a..0000000000 --- a/.github/workflows/doxygen.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Build and publish Doxygen documentation -# To test this workflow, push your changes to your fork's `develop` branch. -on: - push: - branches: - - develop - - doxygen -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - documentation: - runs-on: ubuntu-latest - permissions: - contents: write - container: ghcr.io/xrplf/rippled-build-ubuntu:aaf5e3e - steps: - - name: checkout - uses: actions/checkout@v4 - - name: check environment - run: | - echo ${PATH} | tr ':' '\n' - cmake --version - doxygen --version - env | sort - - name: build - run: | - mkdir build - cd build - cmake -Donly_docs=TRUE .. - cmake --build . --target docs --parallel $(nproc) - - name: publish - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: build/docs/html diff --git a/.github/workflows/levelization.yml b/.github/workflows/levelization.yml deleted file mode 100644 index 979049d630..0000000000 --- a/.github/workflows/levelization.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: levelization - -on: - push: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - -jobs: - check: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - runs-on: ubuntu-latest - env: - CLANG_VERSION: 10 - steps: - - uses: actions/checkout@v4 - - name: Check levelization - run: Builds/levelization/levelization.sh - - name: Check for differences - id: assert - run: | - set -o pipefail - git diff --exit-code | tee "levelization.patch" - - name: Upload patch - if: failure() && steps.assert.outcome == 'failure' - uses: actions/upload-artifact@v4 - continue-on-error: true - with: - name: levelization.patch - if-no-files-found: ignore - path: levelization.patch - - name: What happened? - if: failure() && steps.assert.outcome == 'failure' - env: - MESSAGE: | - If you are reading this, you are looking at a failed Github - Actions job. That means you changed the dependency relationships - between the modules in rippled. That may be an improvement or a - regression. This check doesn't judge. - - A rule of thumb, though, is that if your changes caused - something to be removed from loops.txt, that's probably an - improvement. If something was added, it's probably a regression. - - To fix it, you can do one of two things: - 1. Download and apply the patch generated as an artifact of this - job to your repo, commit, and push. - 2. Run './Builds/levelization/levelization.sh' in your repo, - commit, and push. - - See Builds/levelization/README.md for more info. - run: | - echo "${MESSAGE}" - exit 1 diff --git a/.github/workflows/libxrpl.yml b/.github/workflows/libxrpl.yml deleted file mode 100644 index 5880c03d71..0000000000 --- a/.github/workflows/libxrpl.yml +++ /dev/null @@ -1,91 +0,0 @@ -name: Check libXRPL compatibility with Clio -env: - CONAN_REMOTE_URL: https://conan.ripplex.io - CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.CONAN_REMOTE_USERNAME }} - CONAN_PASSWORD_XRPLF: ${{ secrets.CONAN_REMOTE_PASSWORD }} -on: - pull_request: - paths: - - "src/libxrpl/protocol/BuildInfo.cpp" - - ".github/workflows/libxrpl.yml" - types: [opened, reopened, synchronize, ready_for_review] -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - publish: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - name: Publish libXRPL - outputs: - outcome: ${{ steps.upload.outputs.outcome }} - version: ${{ steps.version.outputs.version }} - channel: ${{ steps.channel.outputs.channel }} - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/rippled-build-ubuntu:aaf5e3e - steps: - - name: Wait for essential checks to succeed - uses: lewagon/wait-on-check-action@v1.3.4 - with: - ref: ${{ github.event.pull_request.head.sha || github.sha }} - running-workflow-name: wait-for-check-regexp - check-regexp: "(dependencies|test).*linux.*" # Ignore windows and mac tests but make sure linux passes - repo-token: ${{ secrets.GITHUB_TOKEN }} - wait-interval: 10 - - name: Checkout - uses: actions/checkout@v4 - - name: Generate channel - id: channel - shell: bash - run: | - echo channel="clio/pr_${{ github.event.pull_request.number }}" | tee ${GITHUB_OUTPUT} - - name: Export new package - shell: bash - run: | - conan export . ${{ steps.channel.outputs.channel }} - - name: Add Conan remote - shell: bash - run: | - echo "Adding Conan remote 'xrplf' at ${{ env.CONAN_REMOTE_URL }}." - conan remote add xrplf ${{ env.CONAN_REMOTE_URL }} --insert 0 --force - echo "Listing Conan remotes." - conan remote list - - name: Parse new version - id: version - shell: bash - run: | - echo version="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" \ - | awk -F '"' '{print $2}')" | tee ${GITHUB_OUTPUT} - - name: Try to authenticate to Conan remote - id: remote - shell: bash - run: | - # `conan user` implicitly uses the environment variables CONAN_LOGIN_USERNAME_ and CONAN_PASSWORD_. - # https://docs.conan.io/1/reference/commands/misc/user.html#using-environment-variables - # https://docs.conan.io/1/reference/env_vars.html#conan-login-username-conan-login-username-remote-name - # https://docs.conan.io/1/reference/env_vars.html#conan-password-conan-password-remote-name - echo outcome=$(conan user --remote xrplf --password >&2 \ - && echo success || echo failure) | tee ${GITHUB_OUTPUT} - - name: Upload new package - id: upload - if: (steps.remote.outputs.outcome == 'success') - shell: bash - run: | - echo "conan upload version ${{ steps.version.outputs.version }} on channel ${{ steps.channel.outputs.channel }}" - echo outcome=$(conan upload xrpl/${{ steps.version.outputs.version }}@${{ steps.channel.outputs.channel }} --remote ripple --confirm >&2 \ - && echo success || echo failure) | tee ${GITHUB_OUTPUT} - notify_clio: - name: Notify Clio - runs-on: ubuntu-latest - needs: publish - env: - GH_TOKEN: ${{ secrets.CLIO_NOTIFY_TOKEN }} - steps: - - name: Notify Clio about new version - if: (needs.publish.outputs.outcome == 'success') - shell: bash - run: | - gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \ - -F "client_payload[version]=${{ needs.publish.outputs.version }}@${{ needs.publish.outputs.channel }}" \ - -F "client_payload[pr]=${{ github.event.pull_request.number }}" diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml deleted file mode 100644 index 73e25c357f..0000000000 --- a/.github/workflows/macos.yml +++ /dev/null @@ -1,112 +0,0 @@ -name: macos -on: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - push: - # If the branches list is ever changed, be sure to change it on all - # build/test jobs (nix, macos, windows, instrumentation) - branches: - # Always build the package branches - - develop - - release - - master - # Branches that opt-in to running - - "ci/**" -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true -# This part of Conan configuration is specific to this workflow only; we do not want -# to pollute conan/profiles directory with settings which might not work for others -env: - CONAN_REMOTE_URL: https://conan.ripplex.io - CONAN_REMOTE_USERNAME: ${{ secrets.CONAN_REMOTE_USERNAME }} - CONAN_REMOTE_PASSWORD: ${{ secrets.CONAN_REMOTE_PASSWORD }} - # This part of the Conan configuration is specific to this workflow only; we - # do not want to pollute the 'conan/profiles' directory with settings that - # might not work for other workflows. - CONAN_GLOBAL_CONF: | - core.download:parallel={{os.cpu_count()}} - core.upload:parallel={{os.cpu_count()}} - tools.build:jobs={{ (os.cpu_count() * 4/5) | int }} - tools.build:verbosity=verbose - tools.compilation:verbosity=verbose - -jobs: - test: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - strategy: - matrix: - platform: - - macos - generator: - - Ninja - configuration: - - Release - runs-on: [self-hosted, macOS, mac-runner-m1] - env: - # The `build` action requires these variables. - build_dir: .build - NUM_PROCESSORS: 12 - steps: - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: install Conan - run: | - brew install conan - - name: install Ninja - if: matrix.generator == 'Ninja' - run: brew install ninja - - name: install python - run: | - if which python > /dev/null 2>&1; then - echo "Python executable exists" - else - brew install python@3.13 - ln -s /opt/homebrew/bin/python3 /opt/homebrew/bin/python - fi - - name: install cmake - run: | - if which cmake > /dev/null 2>&1; then - echo "cmake executable exists" - else - brew install cmake - fi - - name: install nproc - run: | - brew install coreutils - - name: check environment - run: | - env | sort - echo ${PATH} | tr ':' '\n' - python --version - conan --version - cmake --version - nproc --version - echo -n "nproc returns: " - nproc - system_profiler SPHardwareDataType - sysctl -n hw.logicalcpu - clang --version - - name: configure Conan - run: | - echo "${CONAN_GLOBAL_CONF}" > $(conan config home)/global.conf - conan config install conan/profiles/ -tf $(conan config home)/profiles/ - conan profile show - - name: build dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration }} - - name: build - uses: ./.github/actions/build - with: - generator: ${{ matrix.generator }} - configuration: ${{ matrix.configuration }} - cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}" - - name: test - run: | - n=$(nproc) - echo "Using $n test jobs" - - cd ${build_dir} - ./rippled --unittest --unittest-jobs $n - ctest -j $n --output-on-failure diff --git a/.github/workflows/missing-commits.yml b/.github/workflows/missing-commits.yml deleted file mode 100644 index ed478a2327..0000000000 --- a/.github/workflows/missing-commits.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: missing-commits - -on: - push: - branches: - # Only check that the branches are up to date when updating the - # relevant branches. - - develop - - release - -jobs: - up_to_date: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Check for missing commits - id: commits - env: - SUGGESTION: | - - If you are reading this, then the commits indicated above are - missing from "develop" and/or "release". Do a reverse-merge - as soon as possible. See CONTRIBUTING.md for instructions. - run: | - set -o pipefail - # Branches ordered by how "canonical" they are. Every commit in - # one branch should be in all the branches behind it - order=( master release develop ) - branches=() - for branch in "${order[@]}" - do - # Check that the branches exist so that this job will work on - # forked repos, which don't necessarily have master and - # release branches. - if git ls-remote --exit-code --heads origin \ - refs/heads/${branch} > /dev/null - then - branches+=( origin/${branch} ) - fi - done - - prior=() - for branch in "${branches[@]}" - do - if [[ ${#prior[@]} -ne 0 ]] - then - echo "Checking ${prior[@]} for commits missing from ${branch}" - git log --oneline --no-merges "${prior[@]}" \ - ^$branch | tee -a "missing-commits.txt" - echo - fi - prior+=( "${branch}" ) - done - if [[ $( cat missing-commits.txt | wc -l ) -ne 0 ]] - then - echo "${SUGGESTION}" - exit 1 - fi diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml deleted file mode 100644 index 395bd72b8d..0000000000 --- a/.github/workflows/nix.yml +++ /dev/null @@ -1,422 +0,0 @@ -name: nix -on: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - push: - # If the branches list is ever changed, be sure to change it on all - # build/test jobs (nix, macos, windows) - branches: - # Always build the package branches - - develop - - release - - master - # Branches that opt-in to running - - "ci/**" -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -env: - CONAN_REMOTE_URL: https://conan.ripplex.io - CONAN_REMOTE_USERNAME: ${{ secrets.CONAN_REMOTE_USERNAME }} - CONAN_REMOTE_PASSWORD: ${{ secrets.CONAN_REMOTE_PASSWORD }} - # This part of the Conan configuration is specific to this workflow only; we - # do not want to pollute the 'conan/profiles' directory with settings that - # might not work for other workflows. - CONAN_GLOBAL_CONF: | - core.download:parallel={{ os.cpu_count() }} - core.upload:parallel={{ os.cpu_count() }} - tools.build:jobs={{ (os.cpu_count() * 4/5) | int }} - tools.build:verbosity=verbose - tools.compilation:verbosity=verbose - -# This workflow has multiple job matrixes. -# They can be considered phases because most of the matrices ("test", -# "coverage", "conan", ) depend on the first ("dependencies"). -# -# The first phase has a job in the matrix for each combination of -# variables that affects dependency ABI: -# platform, compiler, and configuration. -# It creates a GitHub artifact holding the Conan profile, -# and builds and caches binaries for all the dependencies. -# If an Artifactory remote is configured, they are cached there. -# If not, they are added to the GitHub artifact. -# GitHub's "cache" action has a size limit (10 GB) that is too small -# to hold the binaries if they are built locally. -# We must use the "{upload,download}-artifact" actions instead. -# -# The remaining phases have a job in the matrix for each test -# configuration. They install dependency binaries from the cache, -# whichever was used, and build and test rippled. -# -# "instrumentation" is independent, but is included here because it also -# builds on linux in the same "on:" conditions. - -jobs: - dependencies: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - strategy: - fail-fast: false - matrix: - platform: - - linux - compiler: - - gcc - - clang - configuration: - - Debug - - Release - include: - - compiler: gcc - compiler_version: 12 - distro: ubuntu - codename: jammy - - compiler: clang - compiler_version: 16 - distro: debian - codename: bookworm - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/ci/${{ matrix.distro }}-${{ matrix.codename }}:${{ matrix.compiler }}-${{ matrix.compiler_version }} - env: - build_dir: .build - steps: - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: check environment - run: | - echo ${PATH} | tr ':' '\n' - lsb_release -a || true - ${{ matrix.compiler }}-${{ matrix.compiler_version }} --version - conan --version - cmake --version - env | sort - - name: configure Conan - run: | - echo "${CONAN_GLOBAL_CONF}" >> $(conan config home)/global.conf - conan config install conan/profiles/ -tf $(conan config home)/profiles/ - conan profile show - - name: archive profile - # Create this archive before dependencies are added to the local cache. - run: tar -czf conan.tar.gz -C ${CONAN_HOME} . - - name: build dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration }} - - name: upload archive - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 - with: - name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }} - path: conan.tar.gz - if-no-files-found: error - - test: - strategy: - fail-fast: false - matrix: - platform: - - linux - compiler: - - gcc - - clang - configuration: - - Debug - - Release - include: - - compiler: gcc - compiler_version: 12 - distro: ubuntu - codename: jammy - - compiler: clang - compiler_version: 16 - distro: debian - codename: bookworm - cmake-args: - - - - "-Dunity=ON" - needs: dependencies - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/ci/${{ matrix.distro }}-${{ matrix.codename }}:${{ matrix.compiler }}-${{ matrix.compiler_version }} - env: - build_dir: .build - steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }} - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} - - name: check environment - run: | - env | sort - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration }} - - name: build - uses: ./.github/actions/build - with: - generator: Ninja - configuration: ${{ matrix.configuration }} - cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}" - - name: check linking - run: | - cd ${build_dir} - ldd ./rippled - if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then - echo 'The binary is statically linked.' - else - echo 'The binary is dynamically linked.' - exit 1 - fi - - name: test - run: | - cd ${build_dir} - ./rippled --unittest --unittest-jobs $(nproc) - ctest -j $(nproc) --output-on-failure - - reference-fee-test: - strategy: - fail-fast: false - matrix: - platform: - - linux - compiler: - - gcc - configuration: - - Debug - cmake-args: - - "-DUNIT_TEST_REFERENCE_FEE=200" - - "-DUNIT_TEST_REFERENCE_FEE=1000" - needs: dependencies - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12 - env: - build_dir: .build - steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }} - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} - - name: check environment - run: | - env | sort - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration }} - - name: build - uses: ./.github/actions/build - with: - generator: Ninja - configuration: ${{ matrix.configuration }} - cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}" - - name: test - run: | - cd ${build_dir} - ./rippled --unittest --unittest-jobs $(nproc) - ctest -j $(nproc) --output-on-failure - - coverage: - strategy: - fail-fast: false - matrix: - platform: - - linux - compiler: - - gcc - configuration: - - Debug - needs: dependencies - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12 - env: - build_dir: .build - steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }} - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} - - name: check environment - run: | - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - gcovr --version - env | sort - ls ${CONAN_HOME} - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration }} - - name: build - uses: ./.github/actions/build - with: - generator: Ninja - configuration: ${{ matrix.configuration }} - cmake-args: >- - -Dassert=TRUE - -Dwerr=TRUE - -Dcoverage=ON - -Dcoverage_format=xml - -DCODE_COVERAGE_VERBOSE=ON - -DCMAKE_CXX_FLAGS="-O0" - -DCMAKE_C_FLAGS="-O0" - cmake-target: coverage - - name: move coverage report - shell: bash - run: | - mv "${build_dir}/coverage.xml" ./ - - name: archive coverage report - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 - with: - name: coverage.xml - path: coverage.xml - retention-days: 30 - - name: upload coverage report - uses: wandalen/wretry.action@v1.4.10 - with: - action: codecov/codecov-action@v4.5.0 - with: | - files: coverage.xml - fail_ci_if_error: true - disable_search: true - verbose: true - plugin: noop - token: ${{ secrets.CODECOV_TOKEN }} - attempt_limit: 5 - attempt_delay: 210000 # in milliseconds - - conan: - needs: dependencies - runs-on: [self-hosted, heavy] - container: - image: ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12 - env: - build_dir: .build - platform: linux - compiler: gcc - compiler_version: 12 - configuration: Release - steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: ${{ env.platform }}-${{ env.compiler }}-${{ env.configuration }} - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} - - name: check environment - run: | - env | sort - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ env.configuration }} - - name: export - run: | - conan export . --version head - - name: build - run: | - cd tests/conan - mkdir ${build_dir} && cd ${build_dir} - conan install .. \ - --settings:all build_type=${configuration} \ - --output-folder . \ - --build missing - cmake .. \ - -DCMAKE_TOOLCHAIN_FILE:FILEPATH=./build/${configuration}/generators/conan_toolchain.cmake \ - -DCMAKE_BUILD_TYPE=${configuration} - cmake --build . - ./example | grep '^[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+' - - instrumentation-build: - needs: dependencies - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/ci/debian-bookworm:clang-16 - env: - build_dir: .build - steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: linux-clang-Debug - - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} - - - name: check environment - run: | - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - env | sort - ls ${CONAN_HOME} - - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: Debug - - - name: prepare environment - run: | - mkdir -p ${build_dir} - echo "SOURCE_DIR=$(pwd)" >> $GITHUB_ENV - echo "BUILD_DIR=$(pwd)/${build_dir}" >> $GITHUB_ENV - - - name: build with instrumentation - run: | - cd ${BUILD_DIR} - cmake -S ${SOURCE_DIR} -B ${BUILD_DIR} \ - -Dvoidstar=ON \ - -Dtests=ON \ - -Dxrpld=ON \ - -DCMAKE_BUILD_TYPE=Debug \ - -DSECP256K1_BUILD_BENCHMARK=OFF \ - -DSECP256K1_BUILD_TESTS=OFF \ - -DSECP256K1_BUILD_EXHAUSTIVE_TESTS=OFF \ - -DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/build/generators/conan_toolchain.cmake - cmake --build . --parallel $(nproc) - - - name: verify instrumentation enabled - run: | - cd ${BUILD_DIR} - ./rippled --version | grep libvoidstar - - - name: run unit tests - run: | - cd ${BUILD_DIR} - ./rippled -u --unittest-jobs $(( $(nproc)/4 )) - ctest -j $(nproc) --output-on-failure diff --git a/.github/workflows/notify-clio.yml b/.github/workflows/notify-clio.yml new file mode 100644 index 0000000000..6ccf527ea6 --- /dev/null +++ b/.github/workflows/notify-clio.yml @@ -0,0 +1,79 @@ +# This workflow exports the built libxrpl package to the Conan remote on a +# a channel named after the pull request, and notifies the Clio repository about +# the new version so it can check for compatibility. +name: Notify Clio + +# This workflow can only be triggered by other workflows. +on: + workflow_call: + inputs: + conan_remote_name: + description: 'The name of the Conan remote to use.' + required: true + type: string + conan_remote_url: + description: 'The URL of the Conan endpoint to use.' + required: true + type: string + secrets: + clio_notify_token: + description: 'The GitHub token to notify Clio about new versions.' + required: true + conan_remote_username: + description: 'The username for logging into the Conan remote.' + required: true + conan_remote_password: + description: 'The password for logging into the Conan remote.' + required: true + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-clio + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + upload: + runs-on: ubuntu-latest + container: ghcr.io/xrplf/ci/ubuntu-noble:gcc-13 + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Generate outputs + id: generate + run: | + echo 'Generating user and channel.' + echo "user=clio" >> "${GITHUB_OUTPUT}" + echo "channel=pr_${{ github.event.pull_request.number }}" >> "${GITHUB_OUTPUT}" + echo 'Extracting version.' + echo "version=$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" >> "${GITHUB_OUTPUT}" + - name: Add Conan remote + run: | + echo "Adding Conan remote '${{ inputs.conan_remote_name }}' at ${{ inputs.conan_remote_url }}." + conan remote add --index 0 --force ${{ inputs.conan_remote_name }} ${{ inputs.conan_remote_url }} + echo 'Listing Conan remotes.' + conan remote list + - name: Log into Conan remote + run: conan remote login ${{ inputs.conan_remote_name }} "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}" + - name: Upload package + run: | + conan export --user=${{ steps.generate.outputs.user }} --channel=${{ steps.generate.outputs.channel }} . + conan upload --confirm --check --remote=${{ inputs.conan_remote_name }} xrpl/${{ steps.generate.outputs.version }}@${{ steps.generate.outputs.user }}/${{ steps.generate.outputs.channel }} + outputs: + channel: ${{ steps.generate.outputs.channel }} + version: ${{ steps.generate.outputs.version }} + + notify: + needs: upload + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.clio_notify_token }} + steps: + - name: Notify Clio + run: | + gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \ + -F "client_payload[version]=${{ needs.upload.outputs.version }}@${{ needs.upload.outputs.user }}/${{ needs.upload.outputs.channel }}" \ + -F "client_payload[pr]=${{ github.event.pull_request.number }}" diff --git a/.github/workflows/on-pr.yml b/.github/workflows/on-pr.yml new file mode 100644 index 0000000000..9d7bbbf89c --- /dev/null +++ b/.github/workflows/on-pr.yml @@ -0,0 +1,118 @@ +# This workflow runs all workflows to check, build and test the project on +# various Linux flavors, as well as on MacOS and Windows, on every push to a +# user branch. However, it will not run if the pull request is a draft unless it +# has the 'DraftRunCI' label. +name: PR + +on: + pull_request: + paths: + - '.github/actions/build-deps/**' + - '.github/actions/build-test/**' + - '.github/scripts/levelization/**' + - '.github/scripts/strategy-matrix/**' + - '.github/workflows/build-test.yml' + - '.github/workflows/check-format.yml' + - '.github/workflows/check-levelization.yml' + - '.github/workflows/notify-clio.yml' + - '.github/workflows/on-pr.yml' + # Keep the list of paths below in sync with those in the `on-trigger.yml` + # file. + - 'cmake/**' + - 'conan/**' + - 'external/**' + - 'include/**' + - 'src/**' + - 'tests/**' + - '.clang-format' + - '.codecov.yml' + - '.pre-commit-config.yaml' + - 'CMakeLists.txt' + - 'conanfile.py' + types: + - opened + - synchronize + - labeled + - unlabeled + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +env: + CONAN_REMOTE_NAME: xrplf + CONAN_REMOTE_URL: https://conan.ripplex.io + +jobs: + # This job determines whether the workflow should run. It runs when: + # * Opened as a non-draft PR. + # * A commit is added to a non-draft PR or the PR has the 'DraftRunCI' label. + # * A draft PR has the 'DraftRunCI' label added. + # * A non-draft PR has the 'DraftRunCI' label removed. + # These checks are in part to ensure the workflow won't run needlessly while + # also allowing it to be triggered without having to add a no-op commit. A new + # workflow execution can be triggered by adding and then removing the label on + # a non-draft PR, or conversely by removing it and then adding it back on a + # draft PR; this can be useful in certain cases. + should-run: + if: >- + ${{ + (github.event.action == 'opened' && !github.event.pull_request.draft) || + (github.event.action == 'synchronize' && (!github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'DraftRunCI'))) || + (github.event.action == 'labeled' && github.event.pull_request.draft && github.event.label.name == 'DraftRunCI') || + (github.event.action == 'unlabeled' && !github.event.pull_request.draft && github.event.label.name == 'DraftRunCI') + }} + runs-on: ubuntu-latest + steps: + - name: No-op + run: echo '' + + check-format: + needs: should-run + uses: ./.github/workflows/check-format.yml + + check-levelization: + needs: should-run + uses: ./.github/workflows/check-levelization.yml + + # This job works around the limitation that GitHub Actions does not support + # using environment variables as inputs for reusable workflows. + generate-outputs: + needs: should-run + runs-on: ubuntu-latest + steps: + - name: No-op + run: echo '' + outputs: + conan_remote_name: ${{ env.CONAN_REMOTE_NAME }} + conan_remote_url: ${{ env.CONAN_REMOTE_URL }} + + build-test: + needs: generate-outputs + uses: ./.github/workflows/build-test.yml + strategy: + matrix: + os: [linux, macos, windows] + with: + conan_remote_name: ${{ needs.generate-outputs.outputs.conan_remote_name }} + conan_remote_url: ${{ needs.generate-outputs.outputs.conan_remote_url }} + os: ${{ matrix.os }} + secrets: + codecov_token: ${{ secrets.CODECOV_TOKEN }} + + notify-clio: + needs: + - generate-outputs + - build-test + uses: ./.github/workflows/notify-clio.yml + with: + conan_remote_name: ${{ needs.generate-outputs.outputs.conan_remote_name }} + conan_remote_url: ${{ needs.generate-outputs.outputs.conan_remote_url }} + secrets: + clio_notify_token: ${{ secrets.CLIO_NOTIFY_TOKEN }} + conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }} + conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }} diff --git a/.github/workflows/on-trigger.yml b/.github/workflows/on-trigger.yml new file mode 100644 index 0000000000..ed9a794985 --- /dev/null +++ b/.github/workflows/on-trigger.yml @@ -0,0 +1,115 @@ +# This workflow runs all workflows to build the dependencies required for the +# project on various Linux flavors, as well as on MacOS and Windows, on a +# scheduled basis, on merge into the 'develop', 'release', or 'master' branches, +# or manually. The missing commits check is only run when the code is merged +# into the 'develop' or 'release' branches, and the documentation is built when +# the code is merged into the 'develop' branch. +name: Trigger + +on: + push: + branches: + - develop + - release + - master + paths: + - '.github/actions/build-deps/**' + - '.github/actions/build-test/**' + - '.github/scripts/strategy-matrix/**' + - '.github/workflows/build-test.yml' + - '.github/workflows/check-missing-commits.yml' + - '.github/workflows/on-trigger.yml' + - '.github/workflows/publish-docs.yml' + # Keep the list of paths below in sync with those in `on-pr.yml`. + - 'cmake/**' + - 'conan/**' + - 'external/**' + - 'include/**' + - 'src/**' + - 'tests/**' + - '.clang-format' + - '.codecov.yml' + - '.pre-commit-config.yaml' + - 'CMakeLists.txt' + - 'conanfile.py' + # Run at 06:32 UTC on every day of the week from Monday through Friday. This + # will force all dependencies to be rebuilt, which is useful to verify that + # all dependencies can be built successfully. Only the dependencies that + # are actually missing from the remote will be uploaded. + schedule: + - cron: '32 6 * * 1-5' + # Run when manually triggered via the GitHub UI or API. If `force_upload` is + # true, then the dependencies that were missing (`force_rebuild` is false) or + # rebuilt (`force_rebuild` is true) will be uploaded, overwriting existing + # dependencies if needed. + workflow_dispatch: + inputs: + dependencies_force_build: + description: 'Force building of all dependencies.' + required: false + type: boolean + default: false + dependencies_force_upload: + description: 'Force uploading of all dependencies.' + required: false + type: boolean + default: false + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +env: + CONAN_REMOTE_NAME: xrplf + CONAN_REMOTE_URL: https://conan.ripplex.io + +jobs: + check-missing-commits: + if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && contains(fromJSON('["develop", "release"]'), github.ref_name) }} + uses: ./.github/workflows/check-missing-commits.yml + + # This job works around the limitation that GitHub Actions does not support + # using environment variables as inputs for reusable workflows. It also sets + # outputs that depend on the event that triggered the workflow. + generate-outputs: + runs-on: ubuntu-latest + steps: + - name: Check inputs and set outputs + id: generate + run: | + if [[ '${{ github.event_name }}' == 'push' ]]; then + echo 'dependencies_force_build=false' >> "${GITHUB_OUTPUT}" + echo 'dependencies_force_upload=false' >> "${GITHUB_OUTPUT}" + elif [[ '${{ github.event_name }}' == 'schedule' ]]; then + echo 'dependencies_force_build=true' >> "${GITHUB_OUTPUT}" + echo 'dependencies_force_upload=false' >> "${GITHUB_OUTPUT}" + else + echo 'dependencies_force_build=${{ inputs.dependencies_force_build }}' >> "${GITHUB_OUTPUT}" + echo 'dependencies_force_upload=${{ inputs.dependencies_force_upload }}' >> "${GITHUB_OUTPUT}" + fi + outputs: + conan_remote_name: ${{ env.CONAN_REMOTE_NAME }} + conan_remote_url: ${{ env.CONAN_REMOTE_URL }} + dependencies_force_build: ${{ steps.generate.outputs.dependencies_force_build }} + dependencies_force_upload: ${{ steps.generate.outputs.dependencies_force_upload }} + + build-test: + needs: generate-outputs + uses: ./.github/workflows/build-test.yml + strategy: + matrix: + os: [linux, macos, windows] + with: + conan_remote_name: ${{ needs.generate-outputs.outputs.conan_remote_name }} + conan_remote_url: ${{ needs.generate-outputs.outputs.conan_remote_url }} + dependencies_force_build: ${{ needs.generate-outputs.outputs.dependencies_force_build == 'true' }} + dependencies_force_upload: ${{ needs.generate-outputs.outputs.dependencies_force_upload == 'true' }} + os: ${{ matrix.os }} + strategy_matrix: 'all' + secrets: + conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }} + conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }} diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml new file mode 100644 index 0000000000..509644e6b5 --- /dev/null +++ b/.github/workflows/publish-docs.yml @@ -0,0 +1,60 @@ +# This workflow builds the documentation for the repository, and publishes it to +# GitHub Pages when changes are merged into the default branch. +name: Build and publish documentation + +on: + push: + paths: + - '.github/workflows/publish-docs.yml' + - '*.md' + - '**/*.md' + - 'docs/**' + - 'include/**' + - 'src/libxrpl/**' + - 'src/xrpld/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +env: + BUILD_DIR: .build + +jobs: + publish: + runs-on: ubuntu-latest + container: ghcr.io/xrplf/ci/tools-rippled-documentation + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Check configuration + run: | + echo 'Checking path.' + echo ${PATH} | tr ':' '\n' + + echo 'Checking environment variables.' + env | sort + + echo 'Checking CMake version.' + cmake --version + + echo 'Checking Doxygen version.' + doxygen --version + - name: Build documentation + run: | + mkdir -p ${{ env.BUILD_DIR }} + cd ${{ env.BUILD_DIR }} + cmake -Donly_docs=ON .. + cmake --build . --target docs --parallel $(nproc) + - name: Publish documentation + if: ${{ github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }} + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ${{ env.BUILD_DIR }}/docs/html diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index b81ffc8d3a..0000000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,106 +0,0 @@ -name: windows - -on: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - push: - # If the branches list is ever changed, be sure to change it on all - # build/test jobs (nix, macos, windows, instrumentation) - branches: - # Always build the package branches - - develop - - release - - master - # Branches that opt-in to running - - "ci/**" - -# https://docs.github.com/en/actions/using-jobs/using-concurrency -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true -env: - CONAN_REMOTE_URL: https://conan.ripplex.io - CONAN_REMOTE_USERNAME: ${{ secrets.CONAN_REMOTE_USERNAME }} - CONAN_REMOTE_PASSWORD: ${{ secrets.CONAN_REMOTE_PASSWORD }} - # This part of the Conan configuration is specific to this workflow only; we - # do not want to pollute the 'conan/profiles' directory with settings that - # might not work for other workflows. - CONAN_GLOBAL_CONF: | - core.download:parallel={{os.cpu_count()}} - core.upload:parallel={{os.cpu_count()}} - tools.build:jobs=24 - tools.build:verbosity=verbose - tools.compilation:verbosity=verbose - -jobs: - test: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - strategy: - fail-fast: false - matrix: - version: - - generator: Visual Studio 17 2022 - runs-on: windows-2022 - configuration: - - type: Release - tests: true - - type: Debug - # Skip running unit tests on debug builds, because they - # take an unreasonable amount of time - tests: false - runtime: d - runs-on: ${{ matrix.version.runs-on }} - env: - build_dir: .build - steps: - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: choose Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 - with: - python-version: 3.13 - - name: learn Python cache directory - id: pip-cache - shell: bash - run: | - python -m pip install --upgrade pip - echo "dir=$(pip cache dir)" | tee ${GITHUB_OUTPUT} - - name: restore Python cache directory - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 - with: - path: ${{ steps.pip-cache.outputs.dir }} - key: ${{ runner.os }}-${{ hashFiles('.github/workflows/windows.yml') }} - - name: install Conan - run: pip install wheel conan - - name: check environment - run: | - dir env: - $env:PATH -split ';' - python --version - conan --version - cmake --version - - name: configure Conan - shell: bash - run: | - echo "${CONAN_GLOBAL_CONF}" > $(conan config home)/global.conf - conan config install conan/profiles/ -tf $(conan config home)/profiles/ - conan profile show - - name: build dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration.type }} - - name: build - uses: ./.github/actions/build - with: - generator: "${{ matrix.version.generator }}" - configuration: ${{ matrix.configuration.type }} - # Hard code for now. Move to the matrix if varied options are needed - cmake-args: "-Dassert=TRUE -Dwerr=TRUE -Dreporting=OFF -Dunity=ON" - cmake-target: install - - name: test - shell: bash - if: ${{ matrix.configuration.tests }} - run: | - cd ${build_dir}/${{ matrix.configuration.type }} - ./rippled --unittest --unittest-jobs $(nproc) - ctest -j $(nproc) --output-on-failure diff --git a/.gitignore b/.gitignore index e5952e0de1..ab54adba74 100644 --- a/.gitignore +++ b/.gitignore @@ -37,10 +37,9 @@ Release/*.* *.gcov # Levelization checking -Builds/levelization/results/rawincludes.txt -Builds/levelization/results/paths.txt -Builds/levelization/results/includes/ -Builds/levelization/results/includedby/ +.github/scripts/levelization/results/* +!.github/scripts/levelization/results/loops.txt +!.github/scripts/levelization/results/ordering.txt # Ignore tmp directory. tmp diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..477120ade1 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +external +.* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b0ae72ae54..a5e0933d00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,7 @@ If you create new source files, they must be organized as follows: The source must be formatted according to the style guide below. -Header includes must be [levelized](./Builds/levelization). +Header includes must be [levelized](.github/scripts/levelization). Changes should be usually squashed down into a single commit. Some larger or more complicated change sets make more sense, diff --git a/README.md b/README.md index 4fdb89dffa..fe7daa38bc 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ If you are interested in running an **API Server** (including a **Full History S Here are some good places to start learning the source code: - Read the markdown files in the source tree: `src/ripple/**/*.md`. -- Read [the levelization document](./Builds/levelization) to get an idea of the internal dependency graph. +- Read [the levelization document](.github/scripts/levelization) to get an idea of the internal dependency graph. - In the big picture, the `main` function constructs an `ApplicationImp` object, which implements the `Application` virtual interface. Almost every component in the application takes an `Application&` parameter in its constructor, typically named `app` and stored as a member variable `app_`. This allows most components to depend on any other component. ### Repository Contents diff --git a/cmake/RippledCore.cmake b/cmake/RippledCore.cmake index 1ef5a4ad68..83b27e6c4f 100644 --- a/cmake/RippledCore.cmake +++ b/cmake/RippledCore.cmake @@ -99,6 +99,15 @@ target_link_libraries(xrpl.libxrpl.protocol PUBLIC add_module(xrpl resource) target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol) +# Level 06 +add_module(xrpl net) +target_link_libraries(xrpl.libxrpl.net PUBLIC + xrpl.libxrpl.basics + xrpl.libxrpl.json + xrpl.libxrpl.protocol + xrpl.libxrpl.resource +) + add_module(xrpl server) target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol) @@ -121,6 +130,7 @@ target_link_modules(xrpl PUBLIC protocol resource server + net ) # All headers in libxrpl are in modules. diff --git a/cmake/RippledInstall.cmake b/cmake/RippledInstall.cmake index 9ce288d785..f32781f596 100644 --- a/cmake/RippledInstall.cmake +++ b/cmake/RippledInstall.cmake @@ -19,6 +19,7 @@ install ( xrpl.libxrpl.protocol xrpl.libxrpl.resource xrpl.libxrpl.server + xrpl.libxrpl.net xrpl.libxrpl antithesis-sdk-cpp EXPORT RippleExports diff --git a/conan/global.conf b/conan/global.conf new file mode 100644 index 0000000000..ae03818232 --- /dev/null +++ b/conan/global.conf @@ -0,0 +1,9 @@ +# Global configuration for Conan. This is used to set the number of parallel +# downloads, uploads, and build jobs. The verbosity is set to verbose to +# provide more information during the build process. +core:non_interactive=True +core.download:parallel={{ os.cpu_count() }} +core.upload:parallel={{ os.cpu_count() }} +tools.build:jobs={{ (os.cpu_count() * 4/5) | int }} +tools.build:verbosity=verbose +tools.compilation:verbosity=verbose diff --git a/external/README.md b/external/README.md index 99ce2c337e..7de1fd25a0 100644 --- a/external/README.md +++ b/external/README.md @@ -1,7 +1,6 @@ # External Conan recipes -The subdirectories in this directory contain copies of external libraries used -by rippled. +The subdirectories in this directory contain external libraries used by rippled. | Folder | Upstream | Description | | :--------------- | :------------------------------------------------------------- | :------------------------------------------------------------------------------------------- | diff --git a/src/xrpld/net/AutoSocket.h b/include/xrpl/net/AutoSocket.h similarity index 100% rename from src/xrpld/net/AutoSocket.h rename to include/xrpl/net/AutoSocket.h diff --git a/src/xrpld/net/HTTPClient.h b/include/xrpl/net/HTTPClient.h similarity index 93% rename from src/xrpld/net/HTTPClient.h rename to include/xrpl/net/HTTPClient.h index a11b885290..ef295e8e5a 100644 --- a/src/xrpld/net/HTTPClient.h +++ b/include/xrpl/net/HTTPClient.h @@ -20,9 +20,8 @@ #ifndef RIPPLE_NET_HTTPCLIENT_H_INCLUDED #define RIPPLE_NET_HTTPCLIENT_H_INCLUDED -#include - #include +#include #include #include @@ -44,7 +43,11 @@ public: static constexpr auto maxClientHeaderBytes = kilobytes(32); static void - initializeSSLContext(Config const& config, beast::Journal j); + initializeSSLContext( + std::string const& sslVerifyDir, + std::string const& sslVerifyFile, + bool sslVerify, + beast::Journal j); static void get(bool bSSL, diff --git a/src/xrpld/net/HTTPClientSSLContext.h b/include/xrpl/net/HTTPClientSSLContext.h similarity index 92% rename from src/xrpld/net/HTTPClientSSLContext.h rename to include/xrpl/net/HTTPClientSSLContext.h index 68f91b18b0..2f7d6c005e 100644 --- a/src/xrpld/net/HTTPClientSSLContext.h +++ b/include/xrpl/net/HTTPClientSSLContext.h @@ -20,11 +20,10 @@ #ifndef RIPPLE_NET_HTTPCLIENTSSLCONTEXT_H_INCLUDED #define RIPPLE_NET_HTTPCLIENTSSLCONTEXT_H_INCLUDED -#include -#include - #include #include +#include +#include #include #include @@ -37,31 +36,33 @@ class HTTPClientSSLContext { public: explicit HTTPClientSSLContext( - Config const& config, + std::string const& sslVerifyDir, + std::string const& sslVerifyFile, + bool sslVerify, beast::Journal j, boost::asio::ssl::context_base::method method = boost::asio::ssl::context::sslv23) - : ssl_context_{method}, j_(j), verify_{config.SSL_VERIFY} + : ssl_context_{method}, j_(j), verify_{sslVerify} { boost::system::error_code ec; - if (config.SSL_VERIFY_FILE.empty()) + if (sslVerifyFile.empty()) { registerSSLCerts(ssl_context_, ec, j_); - if (ec && config.SSL_VERIFY_DIR.empty()) + if (ec && sslVerifyDir.empty()) Throw(boost::str( boost::format("Failed to set_default_verify_paths: %s") % ec.message())); } else { - ssl_context_.load_verify_file(config.SSL_VERIFY_FILE); + ssl_context_.load_verify_file(sslVerifyFile); } - if (!config.SSL_VERIFY_DIR.empty()) + if (!sslVerifyDir.empty()) { - ssl_context_.add_verify_path(config.SSL_VERIFY_DIR, ec); + ssl_context_.add_verify_path(sslVerifyDir, ec); if (ec) Throw(boost::str( diff --git a/src/xrpld/net/RegisterSSLCerts.h b/include/xrpl/net/RegisterSSLCerts.h similarity index 100% rename from src/xrpld/net/RegisterSSLCerts.h rename to include/xrpl/net/RegisterSSLCerts.h diff --git a/src/xrpld/net/detail/HTTPClient.cpp b/src/libxrpl/net/HTTPClient.cpp similarity index 98% rename from src/xrpld/net/detail/HTTPClient.cpp rename to src/libxrpl/net/HTTPClient.cpp index 901237e1e3..f7d540750a 100644 --- a/src/xrpld/net/detail/HTTPClient.cpp +++ b/src/libxrpl/net/HTTPClient.cpp @@ -17,12 +17,11 @@ */ //============================================================================== -#include -#include -#include - #include #include +#include +#include +#include #include #include @@ -36,9 +35,13 @@ namespace ripple { static std::optional httpClientSSLContext; void -HTTPClient::initializeSSLContext(Config const& config, beast::Journal j) +HTTPClient::initializeSSLContext( + std::string const& sslVerifyDir, + std::string const& sslVerifyFile, + bool sslVerify, + beast::Journal j) { - httpClientSSLContext.emplace(config, j); + httpClientSSLContext.emplace(sslVerifyDir, sslVerifyFile, sslVerify, j); } //------------------------------------------------------------------------------ diff --git a/src/xrpld/net/detail/RegisterSSLCerts.cpp b/src/libxrpl/net/RegisterSSLCerts.cpp similarity index 98% rename from src/xrpld/net/detail/RegisterSSLCerts.cpp rename to src/libxrpl/net/RegisterSSLCerts.cpp index 5a710323ad..cd5bd631aa 100644 --- a/src/xrpld/net/detail/RegisterSSLCerts.cpp +++ b/src/libxrpl/net/RegisterSSLCerts.cpp @@ -17,7 +17,7 @@ */ //============================================================================== -#include +#include #if BOOST_OS_WINDOWS #include diff --git a/src/xrpld/net/images/interrupt_sequence.png b/src/libxrpl/net/images/interrupt_sequence.png similarity index 100% rename from src/xrpld/net/images/interrupt_sequence.png rename to src/libxrpl/net/images/interrupt_sequence.png diff --git a/src/xrpld/net/images/states.png b/src/libxrpl/net/images/states.png similarity index 100% rename from src/xrpld/net/images/states.png rename to src/libxrpl/net/images/states.png diff --git a/src/libxrpl/protocol/BuildInfo.cpp b/src/libxrpl/protocol/BuildInfo.cpp index fb4bc086f6..0d7ea1a7ca 100644 --- a/src/libxrpl/protocol/BuildInfo.cpp +++ b/src/libxrpl/protocol/BuildInfo.cpp @@ -36,7 +36,7 @@ namespace BuildInfo { // and follow the format described at http://semver.org/ //------------------------------------------------------------------------------ // clang-format off -char const* const versionString = "2.6.0-rc1" +char const* const versionString = "2.6.0-rc2" // clang-format on #if defined(DEBUG) || defined(SANITIZER) diff --git a/src/test/jtx/impl/Env.cpp b/src/test/jtx/impl/Env.cpp index 7c17687eee..46558a188a 100644 --- a/src/test/jtx/impl/Env.cpp +++ b/src/test/jtx/impl/Env.cpp @@ -30,12 +30,12 @@ #include #include -#include -#include +#include #include #include #include +#include #include #include #include @@ -74,7 +74,11 @@ Env::AppBundle::AppBundle( auto timeKeeper_ = std::make_unique(); timeKeeper = timeKeeper_.get(); // Hack so we don't have to call Config::setup - HTTPClient::initializeSSLContext(*config, debugLog()); + HTTPClient::initializeSSLContext( + config->SSL_VERIFY_DIR, + config->SSL_VERIFY_FILE, + config->SSL_VERIFY, + debugLog()); owned = make_Application( std::move(config), std::move(logs), std::move(timeKeeper_)); app = owned.get(); diff --git a/src/test/jtx/impl/utility.cpp b/src/test/jtx/impl/utility.cpp index afa7ee8f35..27b45a32cb 100644 --- a/src/test/jtx/impl/utility.cpp +++ b/src/test/jtx/impl/utility.cpp @@ -19,7 +19,7 @@ #include -#include +#include #include #include diff --git a/src/test/rpc/RPCCall_test.cpp b/src/test/rpc/RPCCall_test.cpp index b73f2e11a0..d22896388d 100644 --- a/src/test/rpc/RPCCall_test.cpp +++ b/src/test/rpc/RPCCall_test.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/src/xrpld/app/ledger/BookListeners.h b/src/xrpld/app/ledger/BookListeners.h index ca58bf3058..5522ad3ec0 100644 --- a/src/xrpld/app/ledger/BookListeners.h +++ b/src/xrpld/app/ledger/BookListeners.h @@ -20,7 +20,7 @@ #ifndef RIPPLE_APP_LEDGER_BOOKLISTENERS_H_INCLUDED #define RIPPLE_APP_LEDGER_BOOKLISTENERS_H_INCLUDED -#include +#include #include diff --git a/src/xrpld/app/main/GRPCServer.h b/src/xrpld/app/main/GRPCServer.h index 5ed4ba8454..c48138cd92 100644 --- a/src/xrpld/app/main/GRPCServer.h +++ b/src/xrpld/app/main/GRPCServer.h @@ -22,9 +22,9 @@ #include #include -#include #include #include +#include #include #include #include diff --git a/src/xrpld/app/main/Main.cpp b/src/xrpld/app/main/Main.cpp index 19c8c9910d..3fdf362dd9 100644 --- a/src/xrpld/app/main/Main.cpp +++ b/src/xrpld/app/main/Main.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/xrpld/app/misc/NetworkOPs.h b/src/xrpld/app/misc/NetworkOPs.h index b8da7d7dc7..639cd782b7 100644 --- a/src/xrpld/app/misc/NetworkOPs.h +++ b/src/xrpld/app/misc/NetworkOPs.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/xrpld/app/misc/detail/WorkSSL.cpp b/src/xrpld/app/misc/detail/WorkSSL.cpp index 0285f43502..0d6801ab84 100644 --- a/src/xrpld/app/misc/detail/WorkSSL.cpp +++ b/src/xrpld/app/misc/detail/WorkSSL.cpp @@ -33,7 +33,12 @@ WorkSSL::WorkSSL( bool lastStatus, callback_type cb) : WorkBase(host, path, port, ios, lastEndpoint, lastStatus, cb) - , context_(config, j, boost::asio::ssl::context::tlsv12_client) + , context_( + config.SSL_VERIFY_DIR, + config.SSL_VERIFY_FILE, + config.SSL_VERIFY, + j, + boost::asio::ssl::context::tlsv12_client) , stream_(socket_, context_.context()) { auto ec = context_.preConnectVerify(stream_, host_); diff --git a/src/xrpld/app/misc/detail/WorkSSL.h b/src/xrpld/app/misc/detail/WorkSSL.h index 2d423a9e50..6a310986e7 100644 --- a/src/xrpld/app/misc/detail/WorkSSL.h +++ b/src/xrpld/app/misc/detail/WorkSSL.h @@ -22,9 +22,9 @@ #include #include -#include #include +#include #include #include diff --git a/src/xrpld/app/paths/PathRequest.h b/src/xrpld/app/paths/PathRequest.h index aea0e564fb..854a0f6129 100644 --- a/src/xrpld/app/paths/PathRequest.h +++ b/src/xrpld/app/paths/PathRequest.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/xrpld/core/detail/Config.cpp b/src/xrpld/core/detail/Config.cpp index 1a07109b74..95147e23d5 100644 --- a/src/xrpld/core/detail/Config.cpp +++ b/src/xrpld/core/detail/Config.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -27,6 +26,7 @@ #include #include #include +#include #include #include @@ -409,7 +409,8 @@ Config::setup( legacy("database_path", boost::filesystem::absolute(dataDir).string()); } - HTTPClient::initializeSSLContext(*this, j_); + HTTPClient::initializeSSLContext( + this->SSL_VERIFY_DIR, this->SSL_VERIFY_FILE, this->SSL_VERIFY, j_); if (RUN_STANDALONE) LEDGER_HISTORY = 0; diff --git a/src/xrpld/rpc/Context.h b/src/xrpld/rpc/Context.h index 32a7cca653..0b1a8dfbf5 100644 --- a/src/xrpld/rpc/Context.h +++ b/src/xrpld/rpc/Context.h @@ -21,7 +21,7 @@ #define RIPPLE_RPC_CONTEXT_H_INCLUDED #include -#include +#include #include #include diff --git a/src/xrpld/net/InfoSub.h b/src/xrpld/rpc/InfoSub.h similarity index 100% rename from src/xrpld/net/InfoSub.h rename to src/xrpld/rpc/InfoSub.h diff --git a/src/xrpld/net/RPCCall.h b/src/xrpld/rpc/RPCCall.h similarity index 100% rename from src/xrpld/net/RPCCall.h rename to src/xrpld/rpc/RPCCall.h diff --git a/src/xrpld/net/RPCSub.h b/src/xrpld/rpc/RPCSub.h similarity index 98% rename from src/xrpld/net/RPCSub.h rename to src/xrpld/rpc/RPCSub.h index 9730ca2dec..0f106be018 100644 --- a/src/xrpld/net/RPCSub.h +++ b/src/xrpld/rpc/RPCSub.h @@ -21,7 +21,7 @@ #define RIPPLE_NET_RPCSUB_H_INCLUDED #include -#include +#include #include diff --git a/src/xrpld/net/detail/InfoSub.cpp b/src/xrpld/rpc/detail/InfoSub.cpp similarity index 99% rename from src/xrpld/net/detail/InfoSub.cpp rename to src/xrpld/rpc/detail/InfoSub.cpp index 9f394cf08e..de00f518a5 100644 --- a/src/xrpld/net/detail/InfoSub.cpp +++ b/src/xrpld/rpc/detail/InfoSub.cpp @@ -17,7 +17,7 @@ */ //============================================================================== -#include +#include namespace ripple { diff --git a/src/xrpld/net/detail/RPCCall.cpp b/src/xrpld/rpc/detail/RPCCall.cpp similarity index 99% rename from src/xrpld/net/detail/RPCCall.cpp rename to src/xrpld/rpc/detail/RPCCall.cpp index 0cc3cb6618..aa8c80fff7 100644 --- a/src/xrpld/net/detail/RPCCall.cpp +++ b/src/xrpld/rpc/detail/RPCCall.cpp @@ -17,12 +17,8 @@ */ //============================================================================== -#include -#include -#include -#include +#include #include -#include #include #include @@ -33,7 +29,10 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -160,7 +159,7 @@ private: std::string const& strPk, TokenType type = TokenType::AccountPublic) { - if (parseBase58(type, strPk)) + if (parseBase58(type, strPk)) return true; auto pkHex = strUnHex(strPk); @@ -1508,7 +1507,7 @@ rpcClient( } else { - ServerHandler::Setup setup; + ripple::ServerHandler::Setup setup; try { setup = setup_ServerHandler( diff --git a/src/xrpld/rpc/detail/RPCHandler.cpp b/src/xrpld/rpc/detail/RPCHandler.cpp index c261666eb9..b2e4c2c440 100644 --- a/src/xrpld/rpc/detail/RPCHandler.cpp +++ b/src/xrpld/rpc/detail/RPCHandler.cpp @@ -24,9 +24,9 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/src/xrpld/net/detail/RPCSub.cpp b/src/xrpld/rpc/detail/RPCSub.cpp similarity index 99% rename from src/xrpld/net/detail/RPCSub.cpp rename to src/xrpld/rpc/detail/RPCSub.cpp index 3f0c923e13..966ad6df4b 100644 --- a/src/xrpld/net/detail/RPCSub.cpp +++ b/src/xrpld/rpc/detail/RPCSub.cpp @@ -17,8 +17,8 @@ */ //============================================================================== -#include -#include +#include +#include #include #include diff --git a/src/xrpld/rpc/detail/WSInfoSub.h b/src/xrpld/rpc/detail/WSInfoSub.h index 1652617455..030eac318e 100644 --- a/src/xrpld/rpc/detail/WSInfoSub.h +++ b/src/xrpld/rpc/detail/WSInfoSub.h @@ -20,7 +20,7 @@ #ifndef RIPPLE_RPC_WSINFOSUB_H #define RIPPLE_RPC_WSINFOSUB_H -#include +#include #include #include diff --git a/src/xrpld/rpc/handlers/Subscribe.cpp b/src/xrpld/rpc/handlers/Subscribe.cpp index e71d973b7b..c089f0255d 100644 --- a/src/xrpld/rpc/handlers/Subscribe.cpp +++ b/src/xrpld/rpc/handlers/Subscribe.cpp @@ -21,8 +21,8 @@ #include #include #include -#include #include +#include #include #include