Skip to content

ci: run functional tests on GitHub Actions, upload functional test logs as artifacts #6583

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 25, 2025
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
23 changes: 20 additions & 3 deletions .github/workflows/build-src.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ on:
description: "Key needed to access cached depends"
required: true
type: string
outputs:
key:
description: "Key needed for restoring artifacts bundle"
value: ${{ jobs.build-src.outputs.key }}

jobs:
build-src:
name: Build source
runs-on: ubuntu-24.04
outputs:
key: ${{ steps.bundle.outputs.key }}
container:
image: ${{ inputs.container-path }}
options: --user root
Expand Down Expand Up @@ -89,9 +95,20 @@ jobs:
./ci/dash/test_unittests.sh
shell: bash

- name: Upload build artifacts
- name: Bundle artifacts
id: bundle
run: |
export BUILD_TARGET="${{ inputs.build-target }}"
export BUNDLE_KEY="build-${BUILD_TARGET}-$(git rev-parse --short=8 HEAD)"
./ci/dash/bundle-artifacts.sh create
echo "key=${BUNDLE_KEY}" >> "${GITHUB_OUTPUT}"

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts-${{ inputs.build-target }}
name: ${{ steps.bundle.outputs.key }}
path: |
/output
${{ steps.bundle.outputs.key }}.tar.zst
compression-level: 0
overwrite: true
retention-days: 3
36 changes: 36 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,39 @@ jobs:
build-target: win64
container-path: ${{ needs.container.outputs.path }}
depends-key: ${{ needs.depends-win64.outputs.key }}

test-linux64:
name: linux64-test
uses: ./.github/workflows/test-src.yml
needs: [container, depends-linux64, src-linux64]
with:
bundle-key: ${{ needs.src-linux64.outputs.key }}
build-target: linux64
container-path: ${{ needs.container.outputs.path }}

test-linux64_nowallet:
name: linux64_nowallet-test
uses: ./.github/workflows/test-src.yml
needs: [container, depends-linux64_nowallet, src-linux64_nowallet]
with:
bundle-key: ${{ needs.src-linux64_nowallet.outputs.key }}
build-target: linux64_nowallet
container-path: ${{ needs.container.outputs.path }}

test-linux64_sqlite:
name: linux64_sqlite-test
uses: ./.github/workflows/test-src.yml
needs: [container, depends-linux64, src-linux64_sqlite]
with:
bundle-key: ${{ needs.src-linux64_sqlite.outputs.key }}
build-target: linux64_sqlite
container-path: ${{ needs.container.outputs.path }}

test-linux64_ubsan:
name: linux64_ubsan-test
uses: ./.github/workflows/test-src.yml
needs: [container, depends-linux64, src-linux64_ubsan]
with:
bundle-key: ${{ needs.src-linux64_ubsan.outputs.key }}
build-target: linux64_ubsan
container-path: ${{ needs.container.outputs.path }}
83 changes: 83 additions & 0 deletions .github/workflows/test-src.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Test source

on:
workflow_call:
inputs:
bundle-key:
description: "Key needed to access bundle of artifacts"
required: true
type: string
build-target:
description: "Target name as defined by inputs.sh"
required: true
type: string
container-path:
description: "Path to built container at registry"
required: true
type: string

env:
INTEGRATION_TESTS_ARGS: "--extended --exclude feature_pruning,feature_dbcrash"

jobs:
test-src:
name: Test source
runs-on: ubuntu-24.04
container:
image: ${{ inputs.container-path }}
options: --user root
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 1

- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: ${{ inputs.bundle-key }}

- name: Manage releases cache
uses: actions/cache@v4
if: inputs.build-target == 'linux64'
with:
path: |
releases
key: releases-${{ hashFiles('ci/test/00_setup_env_native_qt5.sh', 'test/get_previous_releases.py') }}

- name: Run functional tests
id: test
run: |
git config --global --add safe.directory "$PWD"
export BUILD_TARGET="${{ inputs.build-target }}"
export BUNDLE_KEY="${{ inputs.bundle-key }}"
./ci/dash/bundle-artifacts.sh extract
./ci/dash/slim-workspace.sh
source ./ci/dash/matrix.sh
./ci/dash/test_integrationtests.sh ${INTEGRATION_TESTS_ARGS}
shell: bash

- name: Bundle test logs
id: bundle
if: success() || (failure() && steps.test.outcome == 'failure')
run: |
export BUILD_TARGET="${{ inputs.build-target }}"
echo "short-sha=$(git rev-parse --short=8 HEAD)" >> "${GITHUB_OUTPUT}"
( [ -d "testlogs" ] && echo "upload-logs=true" >> "${GITHUB_OUTPUT}" && ./ci/dash/bundle-logs.sh ) \
|| echo "upload-logs=false" >> "${GITHUB_OUTPUT}"
shell: bash

- name: Upload test logs
uses: actions/upload-artifact@v4
if: |
success() || (failure() && steps.test.outcome == 'failure')
&& steps.bundle.outputs.upload-logs == 'true'
with:
name: test_logs-${{ inputs.build-target }}-${{ steps.bundle.outputs.short-sha }}
path: |
test_logs-${{ inputs.build-target }}.tar.zst
test_logs-${{ inputs.build-target }}.tar.zst.sha256
compression-level: 0
overwrite: true
retention-days: 1
59 changes: 59 additions & 0 deletions ci/dash/bundle-artifacts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# Copyright (c) 2024-2025 The Dash Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

export LC_ALL=C.UTF-8

set -eo pipefail

SH_NAME="$(basename "${0}")"
VERB="${1}"

if [ -z "${BUILD_TARGET}" ]; then
echo "${SH_NAME}: BUILD_TARGET not defined, cannot continue!";
exit 1;
elif [ -z "${BUNDLE_KEY}" ]; then
echo "${SH_NAME}: BUNDLE_KEY not defined, cannot continue!";
exit 1;
elif [ ! "$(command -v zstd)" ]; then
echo "${SH_NAME}: zstd not found, cannot continue!";
exit 1;
elif [ -z "${VERB}" ]; then
echo "${SH_NAME}: Verb missing, acceptable values 'create' or 'extract'";
exit 1;
elif [ "${VERB}" != "create" ] && [ "${VERB}" != "extract" ]; then
echo "${SH_NAME}: Invalid verb '${VERB}', expected 'create' or 'extract'";
exit 1;
fi

OUTPUT_ARCHIVE="${BUNDLE_KEY}.tar.zst"
if [ -f "${OUTPUT_ARCHIVE}" ] && [ "${VERB}" = "create" ]; then
echo "${SH_NAME}: ${OUTPUT_ARCHIVE} already exists, cannot continue!";
exit 1;
elif [ ! -f "${OUTPUT_ARCHIVE}" ] && [ "${VERB}" = "extract" ]; then
echo "${SH_NAME}: ${OUTPUT_ARCHIVE} missing, cannot continue!";
exit 1;
fi

if [ "${VERB}" = "create" ]; then
EXCLUSIONS=(
"*.a"
"*.o"
".deps"
".libs"
)
EXCLUSIONS_ARG=""
for excl in "${EXCLUSIONS[@]}"
do
EXCLUSIONS_ARG+=" --exclude=${excl}";
done

# shellcheck disable=SC2086
tar ${EXCLUSIONS_ARG} --use-compress-program="zstd -T0 -5" -cf "${OUTPUT_ARCHIVE}" "build-ci";
elif [ "${VERB}" = "extract" ]; then
tar --use-compress-program="unzstd" -xf "${OUTPUT_ARCHIVE}";
else
echo "${SH_NAME}: Generic error";
exit 1;
fi
28 changes: 28 additions & 0 deletions ci/dash/bundle-logs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Copyright (c) 2025 The Dash Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

export LC_ALL=C.UTF-8

set -eo pipefail

SH_NAME="$(basename "${0}")"
LOG_DIRECTORY="testlogs"

if [ ! -d "${LOG_DIRECTORY}" ]; then
echo "${SH_NAME}: '${LOG_DIRECTORY}' directory missing, will skip!";
exit 0;
elif [ -z "${BUILD_TARGET}" ]; then
echo "${SH_NAME}: BUILD_TARGET not defined, cannot continue!";
exit 1;
fi

LOG_ARCHIVE="test_logs-${BUILD_TARGET}.tar.zst"
if [ -f "${LOG_ARCHIVE}" ]; then
echo "${SH_NAME}: ${LOG_ARCHIVE} already exists, cannot continue!";
exit 1;
fi

tar --use-compress-program="zstd -T0 -5" -cf "${LOG_ARCHIVE}" "${LOG_DIRECTORY}"
sha256sum "${LOG_ARCHIVE}" > "${LOG_ARCHIVE}.sha256";
41 changes: 41 additions & 0 deletions ci/dash/slim-workspace.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# Copyright (c) 2025 The Dash Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

export LC_ALL=C.UTF-8

set -eo pipefail

SH_NAME="$(basename "${0}")"

if [ -z "${BUILD_TARGET}" ]; then
echo "${SH_NAME}: BUILD_TARGET not defined, cannot continue!";
exit 1;
elif [ -z "${BUNDLE_KEY}" ]; then
echo "${SH_NAME}: BUNDLE_KEY not defined, cannot continue!";
exit 1;
fi

TARGETS=(
# Bundle restored from artifact
"${BUNDLE_KEY}.tar.zst"
# Binaries not needed by functional tests
"build-ci/dashcore-${BUILD_TARGET}/src/dash-tx"
"build-ci/dashcore-${BUILD_TARGET}/src/bench/bench_dash"
"build-ci/dashcore-${BUILD_TARGET}/src/qt/dash-qt"
"build-ci/dashcore-${BUILD_TARGET}/src/qt/test/test_dash-qt"
"build-ci/dashcore-${BUILD_TARGET}/src/test/test_dash"
"build-ci/dashcore-${BUILD_TARGET}/src/test/fuzz/fuzz"
# Misc. files that can be heavy
"build-ci/dashcore-${BUILD_TARGET}/src/qt/qrc_bitcoin.cpp"
"build-ci/dashcore-${BUILD_TARGET}/src/qt/qrc_dash_locale.cpp"
)

# Delete directories we don't need
for target in "${TARGETS[@]}"
do
if [[ -d "${target}" ]] || [[ -f "${target}" ]]; then
rm -rf "${target}";
fi
done
1 change: 1 addition & 0 deletions contrib/containers/ci/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ RUN apt-get update && apt-get install $APT_ARGS \
wine-stable \
wine64 \
zip \
zstd \
&& rm -rf /var/lib/apt/lists/*

# Make sure std::thread and friends is available
Expand Down
Loading