Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 7 additions & 32 deletions .github/actions/configure-docker/action.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,14 @@
name: 'Configure Docker'
description: 'Set up Docker build driver and configure build cache args'
inputs:
cache-provider:
description: 'gha or cirrus cache provider'
required: true
runs:
using: 'composite'
steps:
- name: Check inputs
shell: python
run: |
# We expect only gha or cirrus as inputs to cache-provider
if "${{ inputs.cache-provider }}" not in ("gha", "cirrus"):
print("::warning title=Unknown input to configure docker action::Provided value was ${{ inputs.cache-provider }}")

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
with:
# Use host network to allow access to cirrus gha cache running on the host
driver-opts: |
network=host

# This is required to allow buildkit to access the actions cache
# This is required when using the gha cache backend with a manual docker buildx invocation.
# Docker will check for variables $ACTIONS_CACHE_URL, $ACTIONS_RESULTS_URL and $ACTIONS_RUNTIME_TOKEN
# which are set automatically when running on GitHub infra: https://docs.docker.com/build/cache/backends/gha/#synopsis
- name: Expose actions cache variables
uses: actions/github-script@v8
with:
Expand All @@ -37,24 +24,12 @@ runs:
shell: bash
run: |
# Configure docker build cache backend
#
# On forks the gha cache will work but will use Github's cache backend.
# Docker will check for variables $ACTIONS_CACHE_URL, $ACTIONS_RESULTS_URL and $ACTIONS_RUNTIME_TOKEN
# which are set automatically when running on GitHub infra: https://docs.docker.com/build/cache/backends/gha/#synopsis

# Use cirrus cache host
if [[ ${{ inputs.cache-provider }} == 'cirrus' ]]; then
url_args="url=${CIRRUS_CACHE_HOST},url_v2=${CIRRUS_CACHE_HOST}"
else
url_args=""
fi

# Always optimistically --cache‑from in case a cache blob exists
args=(--cache-from "type=gha${url_args:+,${url_args}},scope=${CONTAINER_NAME}")
args=(--cache-from "type=gha,scope=${CONTAINER_NAME}")

# Only add --cache-to when using the Cirrus cache provider and pushing to the default branch.
if [[ ${{ inputs.cache-provider }} == 'cirrus' && ${{ github.event_name }} == "push" && ${{ github.ref_name }} == ${{ github.event.repository.default_branch }} ]]; then
args+=(--cache-to "type=gha${url_args:+,${url_args}},mode=max,ignore-error=true,scope=${CONTAINER_NAME}")
# Only add --cache-to when pushing to the default branch.
if [[ ${{ github.event_name }} == "push" && ${{ github.ref_name }} == ${{ github.event.repository.default_branch }} ]]; then
args+=(--cache-to "type=gha,mode=max,ignore-error=true,scope=${CONTAINER_NAME}")
fi

# Always `--load` into docker images (needed when using the `docker-container` build driver).
Expand Down
8 changes: 4 additions & 4 deletions .github/actions/restore-caches/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ runs:
steps:
- name: Restore Ccache cache
id: ccache-cache
uses: cirruslabs/cache/restore@v5
uses: actions/cache/restore@v5
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-${{ env.CONTAINER_NAME }}-${{ github.run_id }}
Expand All @@ -14,7 +14,7 @@ runs:

- name: Restore depends sources cache
id: depends-sources
uses: cirruslabs/cache/restore@v5
uses: actions/cache/restore@v5
with:
path: ${{ env.SOURCES_PATH }}
key: depends-sources-${{ env.CONTAINER_NAME }}-${{ env.DEPENDS_HASH }}
Expand All @@ -23,7 +23,7 @@ runs:

- name: Restore built depends cache
id: depends-built
uses: cirruslabs/cache/restore@v5
uses: actions/cache/restore@v5
with:
path: ${{ env.BASE_CACHE }}
key: depends-built-${{ env.CONTAINER_NAME }}-${{ env.DEPENDS_HASH }}
Expand All @@ -32,7 +32,7 @@ runs:

- name: Restore previous releases cache
id: previous-releases
uses: cirruslabs/cache/restore@v5
uses: actions/cache/restore@v5
with:
path: ${{ env.PREVIOUS_RELEASES_DIR }}
key: previous-releases-${{ env.CONTAINER_NAME }}-${{ env.PREVIOUS_RELEASES_HASH }}
Expand Down
8 changes: 4 additions & 4 deletions .github/actions/save-caches/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,28 @@ runs:
echo "previous releases direct cache hit to primary key: ${{ env.previous-releases-cache-hit }}"

- name: Save Ccache cache
uses: cirruslabs/cache/save@v5
uses: actions/cache/save@v5
if: ${{ (github.event_name == 'push') && (github.ref_name == github.event.repository.default_branch) }}
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-${{ env.CONTAINER_NAME }}-${{ github.run_id }}

- name: Save depends sources cache
uses: cirruslabs/cache/save@v5
uses: actions/cache/save@v5
if: ${{ (github.event_name == 'push') && (github.ref_name == github.event.repository.default_branch) && (env.depends-sources-cache-hit != 'true') }}
with:
path: ${{ env.SOURCES_PATH }}
key: depends-sources-${{ env.CONTAINER_NAME }}-${{ env.DEPENDS_HASH }}

- name: Save built depends cache
uses: cirruslabs/cache/save@v5
uses: actions/cache/save@v5
if: ${{ (github.event_name == 'push') && (github.ref_name == github.event.repository.default_branch) && (env.depends-built-cache-hit != 'true' )}}
with:
path: ${{ env.BASE_CACHE }}
key: depends-built-${{ env.CONTAINER_NAME }}-${{ env.DEPENDS_HASH }}

- name: Save previous releases cache
uses: cirruslabs/cache/save@v5
uses: actions/cache/save@v5
if: ${{ (github.event_name == 'push') && (github.ref_name == github.event.repository.default_branch) && (env.previous-releases-cache-hit != 'true' )}}
with:
path: ${{ env.PREVIOUS_RELEASES_DIR }}
Expand Down
9 changes: 2 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ concurrency:

env:
CI_FAILFAST_TEST_LEAVE_DANGLING: 1 # GHA does not care about dangling processes and setting this variable avoids killing the CI script itself on error
CIRRUS_CACHE_HOST: http://127.0.0.1:12321/ # When using Cirrus Runners this host can be used by the docker `gha` build cache type.
REPO_USE_CIRRUS_RUNNERS: 'bitcoin/bitcoin' # Use cirrus runners and cache for this repo, instead of falling back to the slow GHA runners
REPO_USE_CIRRUS_RUNNERS: 'bitcoin/bitcoin' # Use cirrus runners for this repo, instead of falling back to the slow GHA runners

defaults:
run:
Expand Down Expand Up @@ -60,7 +59,7 @@ jobs:
needs: runners
runs-on: ${{ needs.runners.outputs.provider == 'cirrus' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' || 'ubuntu-24.04' }}
env:
TEST_RUNNER_PORT_MIN: "14000" # Use a larger port, to avoid colliding with CIRRUS_CACHE_HOST port 12321.
TEST_RUNNER_PORT_MIN: "14000" # Use a larger port range to avoid colliding with other CI services.
if: github.event_name == 'pull_request' && github.event.pull_request.commits != 1
timeout-minutes: 360 # Use maximum time, see https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes.
steps:
Expand Down Expand Up @@ -327,8 +326,6 @@ jobs:

- name: Configure Docker
uses: ./.github/actions/configure-docker
with:
cache-provider: ${{ matrix.provider || needs.runners.outputs.provider }}

- name: Clear unnecessary files
if: ${{ needs.runners.outputs.provider == 'gha' && true || false }} # Only needed on GHA runners
Expand Down Expand Up @@ -370,8 +367,6 @@ jobs:

- name: Configure Docker
uses: ./.github/actions/configure-docker
with:
cache-provider: ${{ needs.runners.outputs.provider }}

- name: CI script
run: |
Expand Down
6 changes: 3 additions & 3 deletions ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ To configure the primary repository, follow these steps:
3. Enable organisation-level runners to be used in public repositories:
1. `Org settings -> Actions -> Runner Groups -> Default -> Allow public repos`
4. Permit the following actions to run:
1. cirruslabs/cache/restore@\*
1. cirruslabs/cache/save@\*
1. actions/cache/restore@\*
1. actions/cache/save@\*
1. docker/setup-buildx-action@\*
1. actions/github-script@\*

### Forked repositories

When used in a fork the CI will run on GitHub's free hosted runners by default.
In this case, due to GitHub's 10GB-per-repo cache size limitations caches will be frequently evicted and missed, but the workflows will run (slowly).
In this case, GitHub's cache size limitations may cause caches to be frequently evicted and missed, but the workflows will run (slowly).

It is also possible to use your own Cirrus Runners in your own fork with an appropriate patch to the `REPO_USE_CIRRUS_RUNNERS` variable in ../.github/workflows/ci.yml
NB that Cirrus Runners only work at an organisation level, therefore in order to use your own Cirrus Runners, *the fork must be within your own organisation*.
38 changes: 30 additions & 8 deletions ci/test/03_test_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

export LC_ALL=C.UTF-8

set -o errexit -o xtrace
set -o errexit -o xtrace -o pipefail

if [ "${DANGER_RUN_CI_ON_HOST}" != "1" ]; then
echo "This script will make unsafe local and global modifications, so it can only be run inside a container and requires DANGER_RUN_CI_ON_HOST=1"
Expand Down Expand Up @@ -136,10 +136,30 @@ cmake --build "${BASE_BUILD_DIR}" "$MAKEJOBS" --target $GOAL || (
)

ccache --version | head -n 1 && ccache --show-stats --verbose
hit_rate=$(ccache --show-stats | grep "Hits:" | head -1 | sed 's/.*(\(.*\)%).*/\1/')
if [ "${hit_rate%.*}" -lt 75 ]; then
echo "::notice title=low ccache hitrate::Ccache hit-rate in $CONTAINER_NAME was $hit_rate%"
fi
ccache --print-stats | python3 -c '
import os
import sys

for line in sys.stdin:
key, value = line.split("\t", 1)
# "primary storage" fallback only needed for ccache version 4.5.1
if key in ("local_storage_hit", "primary_storage_hit"):
hits = int(value)
elif key in ("local_storage_miss", "primary_storage_miss"):
miss = int(value)

calls = hits + miss
# codegen has no calls, so skip that here
if calls:
rate = (hits / calls * 100)
print(f"{rate:.2f}")
if rate < 75:
container = os.environ["CONTAINER_NAME"]
print(
"::notice title=low ccache hitrate::"
f"Ccache hit-rate in {container} was {rate:.2f}%"
)
'
du -sh "${DEPENDS_DIR}"/*/
du -sh "${PREVIOUS_RELEASES_DIR}"

Expand Down Expand Up @@ -183,20 +203,22 @@ fi

if [[ "${RUN_IWYU}" == true ]]; then
# TODO: Consider enforcing IWYU across the entire codebase.
FILES_WITH_ENFORCED_IWYU="/src/(((crypto|index|kernel|primitives|univalue/(lib|test)|util|zmq)/.*|common/license_info|node/blockstorage|node/utxo_snapshot|clientversion|core_io|signet)\\.cpp)"
FILES_WITH_ENFORCED_IWYU="/src/(((crypto|index|kernel|primitives|univalue/(lib|test)|util|zmq)/.*|bench/(block_assemble|connectblock)|common/license_info|node/(blockstorage|interfaces|miner|mining_args|utxo_snapshot)|rpc/mining|clientversion|core_io|signet|init)\\.cpp)"
jq --arg patterns "$FILES_WITH_ENFORCED_IWYU" 'map(select(.file | test($patterns)))' "${BASE_BUILD_DIR}/compile_commands.json" > "${BASE_BUILD_DIR}/compile_commands_iwyu_errors.json"
jq --arg patterns "$FILES_WITH_ENFORCED_IWYU" 'map(select(.file | test($patterns) | not))' "${BASE_BUILD_DIR}/compile_commands.json" > "${BASE_BUILD_DIR}/compile_commands_iwyu_warnings.json"

cd "${BASE_ROOT_DIR}"

run_iwyu() {
mv "${BASE_BUILD_DIR}/$1" "${BASE_BUILD_DIR}/compile_commands.json"
python3 "/include-what-you-use/iwyu_tool.py" \
{
python3 "/include-what-you-use/iwyu_tool.py" \
-p "${BASE_BUILD_DIR}" "${MAKEJOBS}" \
-- -Xiwyu --cxx17ns -Xiwyu --mapping_file="${BASE_ROOT_DIR}/contrib/devtools/iwyu/bitcoin.core.imp" \
-Xiwyu --max_line_length=160 \
-Xiwyu --check_also="*/primitives/*.h" \
2>&1 | tee /tmp/iwyu_ci.out
2>&1 || true
} | tee /tmp/iwyu_ci.out
python3 "/include-what-you-use/fix_includes.py" --nosafe_headers < /tmp/iwyu_ci.out
git diff -U1 | ./contrib/devtools/clang-format-diff.py -binary="clang-format-${IWYU_LLVM_V}" -p1 -i -v
}
Expand Down
2 changes: 1 addition & 1 deletion contrib/guix/guix-build
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ EOF
# more information.
#
# shellcheck disable=SC2086,SC2031
time-machine shell --manifest="${PWD}/contrib/guix/manifest.scm" \
time-machine shell --manifest="${PWD}/contrib/guix/manifest_build.scm" \
--container \
--writable-root \
--pure \
Expand Down
2 changes: 1 addition & 1 deletion contrib/guix/guix-codesign
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ EOF
# more information.
#
# shellcheck disable=SC2086,SC2031
time-machine shell --manifest="${PWD}/contrib/guix/manifest.scm" \
time-machine shell --manifest="${PWD}/contrib/guix/manifest_codesign.scm" \
--container \
--writable-root \
--pure \
Expand Down
Loading
Loading