Use workflow_call

This commit is contained in:
Bart Thomee
2025-07-27 10:42:53 -04:00
parent 521cf7f157
commit 8030670edf
13 changed files with 820 additions and 344 deletions

View File

@@ -1,51 +0,0 @@
name: build
inputs:
build_dir:
description: 'The directory where the build will take place.'
required: true
type: string
build_type:
description: 'The build type to use.'
required: true
type: choice
options:
- Debug
- Release
cmake_args:
description: 'Additional arguments to pass to CMake.'
required: false
type: string
cmake_generator:
description: 'The CMake generator to use for the build.'
required: true
type: string
cmake_target:
description: 'The CMake target to build.'
required: false
type: string
default: 'all'
runs:
using: composite
steps:
- name: CMake configure
shell: bash
working-directory: ${{ inputs.build_dir }}
run: |
cmake \
${{ inputs.build_generator && format('-G "{0}"', inputs.build_generator) || '' }} \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \
-Dtests=TRUE \
-Dxrpld=TRUE \
${{ inputs.cmake_args }} \
..
- name: CMake build
shell: bash
working-directory: ${{ inputs.build_dir }}
run: |
cmake --build . \
--config ${{ inputs.build_type }} \
--parallel $(nproc) \
--target ${{ inputs.cmake_target }}

View File

@@ -1,42 +0,0 @@
name: conan-dependencies
inputs:
build_dir:
description: 'The directory where the build will take place.'
required: true
type: string
build_type:
description: 'The build type to use.'
required: true
type: choice
options:
- Debug
- Release
conan_remote_name:
description: 'The name of the Conan remote to use.'
required: true
type: string
# Install the Conan dependencies for the specified configuration. The ones that
# are not in the remote cache will be built from source and added to the cache.
# This action assumes that the Conan profiles have already been installed and
# that the user has logged into the specified remote, see the 'conan-configure'
# action.
runs:
using: composite
steps:
- name: Install Conan dependencies
shell: bash
run: |
mkdir -p ${{ inputs.build_dir }}
cd ${{ inputs.build_dir }}
conan install \
--output-folder . \
--build missing \
--options:host "&:tests=True" \
--options:host "&:xrpld=True" \
--settings:all build_type=${{ inputs.build_type }} \
..
- name: Upload Conan dependencies
shell: bash
run: conan upload '*' --confirm --check --remote ${{ inputs.conan_remote_name }}

200
.github/workflows/build-debian.yml vendored Normal file
View File

@@ -0,0 +1,200 @@
# This workflow builds and tests the binary on various Debian configurations.
name: Debian
on:
workflow_call:
inputs:
build_dir:
description: 'The directory where the build will take place.'
required: true
type: string
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 remote to use.'
required: true
type: string
secrets:
conan_remote_username:
description: 'The username for logging into the Conan remote.'
required: true
type: string
conan_remote_password:
description: 'The password for logging into the Conan remote.'
required: true
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
# 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.
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
# GitHub does not allow us to specify a reusable matrix strategy, so to avoid
# duplication, we define it here using environment variables and create the
# matrix in the first job. The matrix defined below should be kept in sync
# with https://github.com/XRPLF/ci/blob/main/.github/workflows/debian.yml.
# STRATEGY_MATRIX_ARCHITECTURE: >-
# [
# {
# "platform": "linux/amd64",
# "runner": "ubuntu-24.04"
# },
# {
# "platform": "linux/arm64",
# "runner": "ubuntu-24.04-arm"
# }
# ]
# STRATEGY_MATRIX_OS: >-
# [
# {
# "distro": "debian",
# "release": "bookworm",
# "compiler_name": "gcc",
# "compiler_version": "12"
# },
# {
# "distro": "debian",
# "release": "bookworm",
# "compiler_name": "gcc",
# "compiler_version": "13"
# },
# {
# "distro": "debian",
# "release": "bookworm",
# "compiler_name": "gcc",
# "compiler_version": "14"
# },
# {
# "distro": "debian",
# "release": "bookworm",
# "compiler_name": "clang",
# "compiler_version": "16"
# },
# {
# "distro": "debian",
# "release": "bookworm",
# "compiler_name": "clang",
# "compiler_version": "17"
# },
# {
# "distro": "debian",
# "release": "bookworm",
# "compiler_name": "clang",
# "compiler_version": "18"
# },
# {
# "distro": "debian",
# "release": "bookworm",
# "compiler_name": "clang",
# "compiler_version": "19"
# }
# ]
# STRATEGY_MATRIX_BUILD_TYPE: >-
# [
# "Debug",
# "Release"
# ]
# STRATEGY_MATRIX_CMAKE_ARGS: >-
# [
# "-DUnity=OFF",
# "-DUnity=ON"
# ]
STRATEGY_MATRIX_ARCHITECTURE: >-
[
{
"platform": "linux/amd64",
"runner": "ubuntu-24.04"
}
]
STRATEGY_MATRIX_OS: >-
[
{
"distro": "debian",
"release": "bookworm",
"compiler_name": "gcc",
"compiler_version": "12"
}
]
STRATEGY_MATRIX_BUILD_TYPE: >-
[
"Debug"
]
STRATEGY_MATRIX_CMAKE_ARGS: >-
[
"-DUnity=ON"
]
jobs:
# Generate the strategy matrix.
generate-matrix:
uses: .github/workflows/generate-matrix.yml
with:
architecture: ${{ env.STRATEGY_MATRIX_ARCHITECTURE }}
os: ${{ env.STRATEGY_MATRIX_OS }}
build_type: ${{ env.STRATEGY_MATRIX_BUILD_TYPE }}
cmake_args: ${{ env.STRATEGY_MATRIX_UNITY }}
# Install and cache the dependencies using various configurations.
install-dependencies:
needs:
- generate-matrix
uses: .github/workflows/install-dependencies.yml
strategy:
fail-fast: false
matrix:
architecture: ${{ fromJson(needs.generate-matrix.outputs.architecture) }}
os: ${{ fromJson(needs.generate-matrix.outputs.os) }}
build_type: ${{ fromJson(needs.generate-matrix.outputs.build_type) }}
with:
build_dir: ${{ inputs.build_dir }}
build_type: ${{ strategy.matrix.build_type }}
conan_global_conf: ${{ env.CONAN_GLOBAL_CONF }}
conan_remote_name: ${{ inputs.conan_remote_name }}
conan_remote_url: ${{ inputs.conan_remote_url }}
container: ghcr.io/xrplf/ci/${{ strategy.matrix.os.distro }}-${{ strategy.matrix.os.release }}:${{ strategy.matrix.os.compiler_name }}-${{ strategy.matrix.os.compiler_version }}
runner: ${{ strategy.matrix.architecture.runner }}
secrets:
conan_remote_username: ${{ secrets.conan_remote_username }}
conan_remote_password: ${{ secrets.conan_remote_password }}
# Build and test the binary using various configurations.
build-and-test:
needs:
- generate-matrix
- install-dependencies
uses: .github/workflows/build-nix.yml
strategy:
fail-fast: false
matrix:
architecture: ${{ fromJson(needs.generate-matrix.outputs.architecture) }}
os: ${{ fromJson(needs.generate-matrix.outputs.os) }}
build_type: ${{ fromJson(needs.generate-matrix.outputs.build_type) }}
cmake_args: ${{ fromJson(needs.generate-matrix.outputs.cmake_args) }}
with:
build_dir: ${{ inputs.build_dir }}
build_type: ${{ strategy.matrix.build_type }}
cmake_args: ${{ strategy.matrix.cmake_args }}
cmake_generator: "Ninja"
conan_global_conf: ${{ env.CONAN_GLOBAL_CONF }}
conan_remote_name: ${{ inputs.conan_remote_name }}
conan_remote_url: ${{ inputs.conan_remote_url }}
container: ghcr.io/xrplf/ci/${{ strategy.matrix.os.distro }}-${{ strategy.matrix.os.release }}:${{ strategy.matrix.os.compiler_name }}-${{ strategy.matrix.os.compiler_version }}
runner: ${{ strategy.matrix.architecture.runner }}
secrets:
conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}

131
.github/workflows/build-nix.yml vendored Normal file
View File

@@ -0,0 +1,131 @@
# This workflow build and test the project on Linux and MacOS.
name: Build and test
on:
workflow_call:
inputs:
build_dir:
description: 'The directory where the build will take place.'
required: true
type: string
build_type:
description: 'The build type to use.'
required: true
type: string
cmake_args:
description: 'Additional arguments to pass to CMake.'
required: false
type: string
cmake_generator:
description: 'The CMake generator to use for the build.'
required: true
type: string
cmake_target:
description: 'The CMake target to build.'
required: false
type: string
default: 'all'
conan_global_conf:
description: 'The contents of the global Conan configuration.'
required: true
type: string
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 remote to use.'
required: true
type: string
container:
description: 'The container image to use for the job.'
required: true
type: string
runner:
description: 'A string representing the runner to use.'
required: true
type: string
secrets:
conan_remote_username:
description: 'The username for logging into the Conan remote.'
required: true
type: string
conan_remote_password:
description: 'The password for logging into the Conan remote.'
required: true
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
# Install the Conan dependencies for the specified configuration. The ones that
# are not in the remote cache will be built from source and added to the cache.
# This action assumes that the Conan profiles have already been installed and
# that the user has logged into the specified remote, see the 'conan-configure'
# action.
jobs:
runs-on: ${{ inputs.runner }}
container: ${{ inputs.container }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Check configuration
run: |
echo "Checking path"
echo ${PATH} | tr ':' '\n'
echo "Checking environment variables."
env | sort
- name: Check versions
run: |
echo "Checking CMake version."
cmake --version
echo "Checking compiler version."
${CC} --version
- name: Configure Conan
uses: ./.github/actions/conan-configure
with:
conan_global_conf: ${{ inputs.conan_global_conf }}
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 }}
- name: Configure CMake
working-directory: ${{ inputs.build_dir }}
run: |
cmake \
${{ inputs.cmake_generator && format('-G "{0}"', inputs.cmake_generator) || '' }} \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \
-Dtests=TRUE \
-Dxrpld=TRUE \
${{ inputs.cmake_args }} \
..
- name: Build the binary
working-directory: ${{ inputs.build_dir }}
run: |
cmake --build . \
--config ${{ inputs.build_type }} \
--parallel $(nproc) \
--target ${{ inputs.cmake_target }}
- name: Check linking
working-directory: ${{ inputs.build_dir }}
run: |
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 the binary
working-directory: ${{ inputs.build_dir }}
run: |
./rippled --unittest --unittest-jobs $(nproc)
ctest -j $(nproc) --output-on-failure

149
.github/workflows/build-rhel.yml vendored Normal file
View File

@@ -0,0 +1,149 @@
# This workflow builds and tests the binary on various Red Hat Enterprise Linux
# configurations.
name: RHEL
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 remote to use.'
required: true
type: string
secrets:
conan_remote_username:
description: 'The username for logging into the Conan remote.'
required: true
type: string
conan_remote_password:
description: 'The password for logging into the Conan remote.'
required: true
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
# 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.
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
# GitHub does not allow us to specify a reusable matrix strategy, so to avoid
# duplication, we define it here using environment variables and create the
# matrix in the first job. The matrix defined below should be kept in sync
# with https://github.com/XRPLF/ci/blob/main/.github/workflows/rhel.yml.
STRATEGY_MATRIX_ARCHITECTURE: >-
[
{
"platform": "linux/amd64",
"runner": "ubuntu-24.04"
},
{
"platform": "linux/arm64",
"runner": "ubuntu-24.04-arm"
}
]
STRATEGY_MATRIX_OS: >-
[
{
"distro": "rhel",
"release": "9.6",
"compiler_name": "gcc",
"compiler_version": "13"
},
{
"distro": "rhel",
"release": "9.6",
"compiler_name": "gcc",
"compiler_version": "14"
},
{
"distro": "rhel",
"release": "9.6",
"compiler_name": "clang",
"compiler_version": "any"
},
]
STRATEGY_MATRIX_BUILD_TYPE: >-
[
"Debug",
"Release"
]
STRATEGY_MATRIX_CMAKE_ARGS: >-
[
"-DUnity=OFF",
"-DUnity=ON"
]
jobs:
# Generate the strategy matrix.
generate-matrix:
uses: .github/workflows/generate-matrix.yml
with:
architecture: ${{ env.STRATEGY_MATRIX_ARCHITECTURE }}
os: ${{ env.STRATEGY_MATRIX_OS }}
build_type: ${{ env.STRATEGY_MATRIX_BUILD_TYPE }}
cmake_args: ${{ env.STRATEGY_MATRIX_UNITY }}
# Install and cache the dependencies using various configurations.
install-dependencies:
needs:
- generate-matrix
uses: .github/workflows/install-dependencies.yml
strategy:
fail-fast: false
matrix:
architecture: ${{ fromJson(needs.generate-matrix.outputs.architecture) }}
os: ${{ fromJson(needs.generate-matrix.outputs.os) }}
build_type: ${{ fromJson(needs.generate-matrix.outputs.build_type) }}
with:
build_dir: ${{ inputs.build_dir }}
build_type: ${{ strategy.matrix.build_type }}
conan_global_conf: ${{ env.CONAN_GLOBAL_CONF }}
conan_remote_name: ${{ inputs.conan_remote_name }}
conan_remote_url: ${{ inputs.conan_remote_url }}
container: ghcr.io/xrplf/ci/${{ strategy.matrix.os.distro }}-${{ strategy.matrix.os.release }}:${{ strategy.matrix.os.compiler_name }}-${{ strategy.matrix.os.compiler_version }}
runner: ${{ strategy.matrix.architecture.runner }}
secrets:
conan_remote_username: ${{ secrets.conan_remote_username }}
conan_remote_password: ${{ secrets.conan_remote_password }}
# Build and test the binary using various configurations.
build-and-test:
needs:
- generate-matrix
- install-dependencies
uses: .github/workflows/build-nix.yml
strategy:
fail-fast: false
matrix:
architecture: ${{ fromJson(needs.generate-matrix.outputs.architecture) }}
os: ${{ fromJson(needs.generate-matrix.outputs.os) }}
build_type: ${{ fromJson(needs.generate-matrix.outputs.build_type) }}
cmake_args: ${{ fromJson(needs.generate-matrix.outputs.cmake_args) }}
with:
build_dir: ${{ inputs.build_dir }}
build_type: ${{ strategy.matrix.build_type }}
cmake_args: ${{ strategy.matrix.cmake_args }}
cmake_generator: "Ninja"
conan_global_conf: ${{ env.CONAN_GLOBAL_CONF }}
conan_remote_name: ${{ inputs.conan_remote_name }}
conan_remote_url: ${{ inputs.conan_remote_url }}
container: ghcr.io/xrplf/ci/${{ strategy.matrix.os.distro }}-${{ strategy.matrix.os.release }}:${{ strategy.matrix.os.compiler_name }}-${{ strategy.matrix.os.compiler_version }}
runner: ${{ strategy.matrix.architecture.runner }}
secrets:
conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}

View File

@@ -1,6 +1,15 @@
name: Checks # This workflow checks if the code is formatted according to the .clang-format
# rules.
name: Clang Format
on: push # This workflow can only be triggered by other workflows.
on:
workflow_call:
inputs:
runner:
description: 'An optional string representing the GitHub runner to use.'
required: true
type: string
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
@@ -11,10 +20,8 @@ defaults:
shell: bash shell: bash
jobs: jobs:
# Check if the code is formatted according to the .clang-format rules.
clang-format: clang-format:
if: github.event.pull_request.draft == false || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') runs-on: ${{ inputs.runner }}
runs-on: ubuntu-latest
container: ghcr.io/xrplf/ci/tools-rippled-clang-format container: ghcr.io/xrplf/ci/tools-rippled-clang-format
steps: steps:
# The $GITHUB_WORKSPACE and ${{ github.workspace }} might not point to the # The $GITHUB_WORKSPACE and ${{ github.workspace }} might not point to the
@@ -54,36 +61,3 @@ jobs:
echo "${MESSAGE}" echo "${MESSAGE}"
exit 1 exit 1
fi fi
# Check if the dependencies between the modules are correctly indexed
levelization:
if: github.event.pull_request.draft == false || contains(github.event.pull_request.labels.*.name, 'DraftRunCI')
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Check levelization
run: Builds/levelization/levelization.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 './Builds/levelization/levelization.sh' in your repo, and then
commit and push the changes. See Builds/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

View File

@@ -0,0 +1,52 @@
# This workflow checks if the dependencies between the modules are correctly
# indexed.
name: Levelization
# This workflow can only be triggered by other workflows.
on:
workflow_call:
inputs:
runner:
description: 'An optional string representing the GitHub runner to use.'
required: true
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
levelization:
runs-on: ${{ inputs.runner }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Check levelization
run: Builds/levelization/levelization.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 './Builds/levelization/levelization.sh' in your repo, and then
commit and push the changes. See Builds/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

View File

@@ -7,7 +7,7 @@ on:
pull_request: pull_request:
paths: paths:
- 'src/libxrpl/protocol/BuildInfo.cpp' - 'src/libxrpl/protocol/BuildInfo.cpp'
- '.github/workflows/libxrpl.yml' - 'check-libxrpl.yml'
types: [opened, reopened, synchronize, ready_for_review] types: [opened, reopened, synchronize, ready_for_review]
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}

View File

@@ -1,209 +0,0 @@
name: Debian
# TODO: Use `workflow_run` to trigger this workflow after checks have completed.
# This can only be done if the `checks` workflow already exists on the default
# branch (i.e. `develop`), so we cannot do this yet.
# See https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#workflow_run.
on:
push:
# TODO: Re-enable after testing.
# branches:
# - develop
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
BUILD_DIR: .build
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
CONAN_REMOTE_URL: https://conan.ripplex.io
CONAN_REMOTE_NAME: xrplf
# GitHub does not allow us to specify a reusable matrix strategy, so to avoid
# duplication, we define it here using environment variables and create the
# matrix in the first job. The matrix defined below should be kept in sync
# with https://github.com/XRPLF/ci/blob/main/.github/workflows/debian.yml.
# STRATEGY_MATRIX_ARCHITECTURE: >-
# [
# {
# "platform": "linux/amd64",
# "runner": "ubuntu-24.04"
# },
# {
# "platform": "linux/arm64",
# "runner": "ubuntu-24.04-arm"
# }
# ]
STRATEGY_MATRIX_ARCHITECTURE: >-
[
{
"platform": "linux/amd64",
"runner": "ubuntu-24.04"
}
]
STRATEGY_MATRIX_OS: >-
[
{
"release": "bookworm",
"compiler_name": "gcc",
"compiler_version": "12"
},
{
"release": "bookworm",
"compiler_name": "gcc",
"compiler_version": "13"
},
{
"release": "bookworm",
"compiler_name": "gcc",
"compiler_version": "14"
},
{
"release": "bookworm",
"compiler_name": "clang",
"compiler_version": "16"
},
{
"release": "bookworm",
"compiler_name": "clang",
"compiler_version": "17"
},
{
"release": "bookworm",
"compiler_name": "clang",
"compiler_version": "18"
},
{
"release": "bookworm",
"compiler_name": "clang",
"compiler_version": "19"
}
]
STRATEGY_MATRIX_BUILD_TYPE: >-
[
"Debug",
"Release"
]
STRATEGY_MATRIX_UNITY: >-
[
"-DUnity=OFF",
"-DUnity=ON"
]
jobs:
# Generate the strategy matrix.
generate-matrix:
runs-on: ubuntu-latest
steps:
- name: Generate matrix
id: generate-matrix
run: |
echo "architecture=$(jq -c <<< '${{ env.STRATEGY_MATRIX_ARCHITECTURE }}')" >> "$GITHUB_OUTPUT"
echo "os=$(jq -c <<< '${{ env.STRATEGY_MATRIX_OS }}')" >> "$GITHUB_OUTPUT"
echo "build_type=$(jq -c <<< '${{ env.STRATEGY_MATRIX_BUILD_TYPE }}')" >> "$GITHUB_OUTPUT"
echo "unity=$(jq -c <<< '${{ env.STRATEGY_MATRIX_UNITY }}')" >> "$GITHUB_OUTPUT"
outputs:
architecture: ${{ steps.generate-matrix.outputs.architecture }}
os: ${{ steps.generate-matrix.outputs.os }}
build_type: ${{ steps.generate-matrix.outputs.build_type }}
unity: ${{ steps.generate-matrix.outputs.unity }}
# Install (and cache) the Conan dependencies.
install-dependencies:
needs:
- generate-matrix
strategy:
fail-fast: false
matrix:
architecture: ${{ fromJson(needs.generate-matrix.outputs.architecture) }}
os: ${{ fromJson(needs.generate-matrix.outputs.os) }}
build_type: ${{ fromJson(needs.generate-matrix.outputs.build_type) }}
runs-on: ${{ matrix.architecture.runner }}
container: ghcr.io/xrplf/ci/debian-${{ matrix.os.release }}:${{ matrix.os.compiler_name }}-${{ matrix.os.compiler_version }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Check configuration
run: |
echo "Checking path"
echo ${PATH} | tr ':' '\n'
echo "Checking environment variables."
env | sort
- name: Check versions
run: |
echo "Checking CMake version."
cmake --version
echo "Checking compiler version."
${{ matrix.os.compiler_name }} --version
- name: Configure Conan
uses: ./.github/actions/conan-configure
with:
conan_global_conf: ${{ env.CONAN_GLOBAL_CONF }}
conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}
conan_remote_url: ${{ env.CONAN_REMOTE_URL }}
conan_remote_username: ${{ secrets.CONAN_USERNAME }}
conan_remote_password: ${{ secrets.CONAN_PASSWORD }}
- name: Install Conan dependencies
uses: ./.github/actions/conan-dependencies
with:
build_dir: ${{ env.BUILD_DIR }}
build_type: ${{ matrix.build_type }}
conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}
# Build and test the binary.
build-test:
needs:
- generate-matrix
- install-dependencies
strategy:
fail-fast: false
matrix:
architecture: ${{ fromJson(needs.generate-matrix.outputs.architecture) }}
os: ${{ fromJson(needs.generate-matrix.outputs.os) }}
build_type: ${{ fromJson(needs.generate-matrix.outputs.build_type) }}
unity: ${{ fromJson(needs.generate-matrix.outputs.unity) }}
runs-on: ${{ matrix.architecture.runner }}
container: ghcr.io/xrplf/ci/debian-${{ matrix.os.release }}:${{ matrix.os.compiler_name }}-${{ matrix.os.compiler_version }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Configure Conan
uses: ./.github/actions/conan-configure
with:
conan_global_conf: ${{ env.CONAN_GLOBAL_CONF }}
conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}
conan_remote_url: ${{ env.CONAN_REMOTE_URL }}
conan_remote_username: ${{ secrets.CONAN_USERNAME }}
conan_remote_password: ${{ secrets.CONAN_PASSWORD }}
- name: Build code
uses: ./.github/actions/build
with:
build_type: ${{ matrix.build_type }}
cmake_args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.unity }}"
cmake_generator: Ninja
- name: Check linking
working-directory: ${{ env.BUILD_DIR }}
run: |
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 code
working-directory: ${{ env.BUILD_DIR }}
run: |
./rippled --unittest --unittest-jobs $(nproc)
ctest -j $(nproc) --output-on-failure

68
.github/workflows/generate-matrix.yml vendored Normal file
View File

@@ -0,0 +1,68 @@
# This workflow is used to generate a strategy matrix for Linux, Windows, and
# MacOS build and test jobs.
name: generate-matrix
on:
workflow_call:
inputs:
runner:
description: 'An optional string representing the GitHub runner to use.'
required: true
type: string
architecture:
description: 'A string representing a JSON array holding objects containing the "platform" (e.g. "linux/arm64") and "runner" (e.g. "ubuntu-24.04-arm") to use.'
required: true
type: string
os:
description: 'A string representing a JSON array holding objects containing the "distro" (e.g. "debian"), "release" (e.g. "bookworm"), "compiler_name" (e.g. "gcc") and "compiler_version" (e.g. "13") to use.'
required: true
type: string
build_type:
description: 'A string representing a JSON array holding strings with the build type (e.g. "Debug", "Release") to use.'
required: true
type: string
cmake_args:
description: 'A string representing a JSON array holding strings with the CMake arguments (e.g. "-DUnity=ON", "-DUnity=OFF") to use. Multiple arguments can be specified by separating them with a space (e.g. "-DUnity=ON -DVoidstar=ON").'
required: true
type: string
# Generate the JSON outputs by using JQ to compact the JSON string. This
# workflow can be called and its outputs used as follows:
# ```yaml
# jobs:
# generate-matrix:
# uses: .github/workflows/generate-matrix.yml
# with:
# architecture: ${{ env.STRATEGY_MATRIX_ARCHITECTURE }}
# os: ${{ env.STRATEGY_MATRIX_OS }}
# build_type: ${{ env.STRATEGY_MATRIX_BUILD_TYPE }}
# cmake_args: ${{ env.STRATEGY_MATRIX_UNITY }}
# use-matrix:
# needs: generate-matrix
# strategy:
# fail-fast: false
# matrix:
# architecture: ${{ fromJson(needs.generate-matrix.outputs.architecture) }}
# os: ${{ fromJson(needs.generate-matrix.outputs.os) }}
# build_type: ${{ fromJson(needs.generate-matrix.outputs.build_type) }}
# cmake_args: ${{ fromJson(needs.generate-matrix.outputs.cmake_args) }}
# runs-on: ${{ matrix.architecture.runner }}
# container: ghcr.io/xrplf/ci/${{ matrix.os.distro }}-${{ matrix.os.release }}:${{ matrix.os.compiler_name }}-${{ matrix.os.compiler_version }}
# ...
# ```
jobs:
generate-matrix:
runs-on: ${{ inputs.runner }}
steps:
- name: Generate outputs
id: generate
run: |
echo "architecture=$(jq -c <<< '${{ inputs.architecture }}')" >> "$GITHUB_OUTPUT"
echo "os=$(jq -c <<< '${{ inputs.os }}')" >> "$GITHUB_OUTPUT"
echo "build_type=$(jq -c <<< '${{ inputs.build_type }}')" >> "$GITHUB_OUTPUT"
echo "cmake_args=$(jq -c <<< '${{ inputs.cmake_args }}')" >> "$GITHUB_OUTPUT"
outputs:
architecture: ${{ steps.generate.outputs.architecture }}
os: ${{ steps.generate.outputs.os }}
build_type: ${{ steps.generate.outputs.build_type }}
cmake_args: ${{ steps.generate.outputs.cmake_args }}

View File

@@ -0,0 +1,96 @@
# This workflow installs and caches the Conan dependencies for the specified
# configuration. The ones that are not in the remote cache will be built from
# source and added to the cache.
name: Install dependencies
on:
workflow_call:
inputs:
build_dir:
description: 'The directory where the build will take place.'
required: true
type: string
build_type:
description: 'The build type to use.'
required: true
type: string
conan_global_conf:
description: 'The contents of the global Conan configuration.'
required: true
type: string
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 remote to use.'
required: true
type: string
container:
description: 'The container image to use for the job.'
required: true
type: string
runner:
description: 'A string representing the runner to use.'
required: true
type: string
secrets:
conan_remote_username:
description: 'The username for logging into the Conan remote.'
required: true
type: string
conan_remote_password:
description: 'The password for logging into the Conan remote.'
required: true
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
runs-on: ${{ inputs.runner }}
container: ${{ inputs.container }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Check configuration
run: |
echo "Checking path"
echo ${PATH} | tr ':' '\n'
echo "Checking environment variables."
env | sort
- name: Check versions
run: |
echo "Checking CMake version."
cmake --version
echo "Checking compiler version."
${CC} --version
- name: Configure Conan
uses: ./.github/actions/conan-configure
with:
conan_global_conf: ${{ inputs.conan_global_conf }}
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 }}
- name: Install Conan dependencies
run: |
mkdir -p ${{ inputs.build_dir }}
cd ${{ inputs.build_dir }}
conan install \
--output-folder . \
--build missing \
--options:host "&:tests=True" \
--options:host "&:xrpld=True" \
--settings:all build_type=${{ inputs.build_type }} \
..
- name: Upload Conan dependencies
shell: bash
run: conan upload '*' --confirm --check --remote ${{ inputs.conan_remote_name }}

108
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,108 @@
# This workflow runs all workflows to check, build and test the project on
# various Linux flavors, as well as MacOS and Windows.
name: Main
# This workflow is triggered on every push to the repository, including pull
# requests. However, it will not run if the pull request is a draft unless it
# has the 'DraftRunCI' label. As GitHub Actions does not support such `if`
# conditions here, the individual jobs will check the pull request state and
# labels to determine whether to run or not. The workflows called by the jobs
# may also have their own conditions to partially or completely skip execution
# as needed.
on: push
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
# The default build directory for the project.
BUILD_DIR: .build
# The Conan remote where the dependencies will be cached.
CONAN_REMOTE_NAME: xrplf
CONAN_REMOTE_URL: https://conan.ripplex.io
# The default runner for the jobs. This can be overridden in individual jobs.
RUNNER: ubuntu-latest
jobs:
check-clang-format:
if: github.event.pull_request.draft == false || contains(github.event.pull_request.labels.*.name, 'DraftRunCI')
uses: ./.github/workflows/check-clang-format.yml
with:
runner: ${{ env.RUNNER }}
check-levelization:
if: github.event.pull_request.draft == false || contains(github.event.pull_request.labels.*.name, 'DraftRunCI')
uses: ./.github/workflows/check-levelization.yml
with:
runner: ${{ env.RUNNER }}
debian:
needs:
- check-clang-format
- check-levelization
uses: ./.github/workflows/build-debian.yml
with:
build_dir: ${{ env.BUILD_DIR }}
conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}
conan_remote_url: ${{ env.CONAN_REMOTE_URL }}
secrets:
conan_username: ${{ secrets.CONAN_USERNAME }}
conan_password: ${{ secrets.CONAN_PASSWORD }}
# rhel:
# needs:
# - check-clang-format
# - check-levelization
# uses: ./.github/workflows/build-rhel.yml
# with:
# build_dir: ${{ env.BUILD_DIR }}
# conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}
# conan_remote_url: ${{ env.CONAN_REMOTE_URL }}
# secrets:
# conan_username: ${{ secrets.CONAN_USERNAME }}
# conan_password: ${{ secrets.CONAN_PASSWORD }}
#
# ubuntu:
# needs:
# - check-clang-format
# - check-levelization
# uses: ./.github/workflows/build-ubuntu.yml
# with:
# build_dir: ${{ env.BUILD_DIR }}
# conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}
# conan_remote_url: ${{ env.CONAN_REMOTE_URL }}
# secrets:
# conan_username: ${{ secrets.CONAN_USERNAME }}
# conan_password: ${{ secrets.CONAN_PASSWORD }}
#
# macos:
# needs:
# - check-clang-format
# - check-levelization
# uses: ./.github/workflows/build-macos.yml
# with:
# build_dir: ${{ env.BUILD_DIR }}
# conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}
# conan_remote_url: ${{ env.CONAN_REMOTE_URL }}
# secrets:
# conan_username: ${{ secrets.CONAN_USERNAME }}
# conan_password: ${{ secrets.CONAN_PASSWORD }}
#
# windows:
# needs:
# - check-clang-format
# - check-levelization
# uses: ./.github/workflows/build-windows.yml
# with:
# build_dir: ${{ env.BUILD_DIR }}
# conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}
# conan_remote_url: ${{ env.CONAN_REMOTE_URL }}
# secrets:
# conan_username: ${{ secrets.CONAN_USERNAME }}
# conan_password: ${{ secrets.CONAN_PASSWORD }}

View File

@@ -72,15 +72,15 @@ It generates many files of [results](results):
desired as described above. In a perfect repo, this file will be desired as described above. In a perfect repo, this file will be
empty. empty.
This file is committed to the repo, and is used by the [levelization This file is committed to the repo, and is used by the [levelization
Github workflow](../../.github/workflows/checks.yml) to validate Github workflow](../../.github/workflows/check-levelization.yml) to validate
that nothing changed. that nothing changed.
* [`ordering.txt`](results/ordering.txt): A list showing relationships * [`ordering.txt`](results/ordering.txt): A list showing relationships
between modules where there are no loops as they actually exist, as between modules where there are no loops as they actually exist, as
opposed to how they are desired as described above. opposed to how they are desired as described above.
This file is committed to the repo, and is used by the [levelization This file is committed to the repo, and is used by the [levelization
Github workflow](../../.github/workflows/checks.yml) to validate Github workflow](../../.github/workflows/check-levelization.yml) to validate
that nothing changed. that nothing changed.
* [`levelization.yml`](../../.github/workflows/checks.yml) * [`levelization.yml`](../../.github/workflows/check-levelization.yml)
Github Actions workflow to test that levelization loops haven't Github Actions workflow to test that levelization loops haven't
changed. Unfortunately, if changes are detected, it can't tell if changed. Unfortunately, if changes are detected, it can't tell if
they are improvements or not, so if you have resolved any issues or they are improvements or not, so if you have resolved any issues or