Summary
This issue is created by StepSecurity related to security issues in ci.yml . The platform has identified 3 vulnerabilities (1 critical, 1 high, 0 medium, 1 low).
Remediation Overview
The platform can generate remediations for a few vulnerabilities. For such vulnerabilities, you can find the fixed workflow file in the Suggested Fix For Auto-Remediable Issues section. You can manually deploy these changes or create a pull request by commenting @stepsecurity-app pull-request create on this issue.
If you’d like an automated pull request with the fixed workflow file, comment:
@stepsecurity-app pull-request create
Other issues require manual investigation and changes.
Once a vulnerability has been remediated, ✅ will appear in the title. Note that it may take up to 24 hours for these issues to be updated.
Please review the individual vulnerability section below and follow the recommended resolution steps.
Security Checks Details
❌ Actions should be pinned to a full-length commit SHA
-
Severity: Critical
-
Description: GitHub Action tags and Docker tags are mutable. This poses a security risk. GitHub's Security Hardening guide recommends pinning actions to full length commit.
-
Resolution: Pin Actions to a full-length commit SHA..
-
Automated Remediation Available ?: true
-
References:
❌ Network and runtime security monitoring should be enabled for GitHub-hosted runners
-
Severity: Low
-
Description: This check passes if the step-security/harden-runner GitHub Action is used in a job that runs on a GitHub-hosted runner. Harden-Runner prevents exfiltration of code and CI/CD credentials, and detects tampering of files during build.
-
Resolution: Add the step-security/harden-runner GitHub Action to the job.
-
Automated Remediation Available ?: true
-
References:
❌ GITHUB_TOKEN should have minimum permissions
-
Severity: High
-
Description: This check passes if the job's GITHUB_TOKEN does not have all the read and write permissions.
-
Resolution: Set minimum GitHub token permissions at the job or workflow level.
-
Automated Remediation Available ?: true
-
References:
Suggested Fix For Auto-Remediable Issues
Below is the updated workflow, which fixes the following security vulnerabilities:
-
Actions should be pinned to a full-length commit SHA
-
Network and runtime security monitoring should be enabled for GitHub-hosted runners
-
GITHUB_TOKEN should have minimum permissions
# Copyright (c) 2023-present The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit.
name: CI
on:
# See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request.
pull_request:
# See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#push.
push:
branches:
- '**'
tags-ignore:
- '**'
concurrency:
group: ${{ github.event_name != 'pull_request' && github.run_id || github.ref }}
cancel-in-progress: true
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
defaults:
run:
# Enforce fail-fast behavior for all platforms.
# See: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference
shell: bash
jobs:
runners:
name: '[meta] determine runners'
runs-on: ubuntu-latest
outputs:
provider: ${{ steps.runners.outputs.provider }}
steps:
-
+ name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ with:
+ egress-policy: audit
+ -
&ANNOTATION_PR_NUMBER
name: Annotate with pull request number
# This annotation is machine-readable and can be used to assign a check
# run to its corresponding pull request. Running in all check runs is
# required, because check re-runs discard the annotations of other
# tasks in the test suite.
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "::notice title=debug_pull_request_number_str::${{ github.event.number }}"
fi
- id: runners
run: |
if [[ "${REPO_USE_CIRRUS_RUNNERS}" == "${{ github.repository }}" ]]; then
echo "provider=cirrus" >> "$GITHUB_OUTPUT"
echo "::notice title=Runner Selection::Using Cirrus Runners"
else
echo "provider=gha" >> "$GITHUB_OUTPUT"
echo "::notice title=Runner Selection::Using GitHub-hosted runners"
fi
test-each-commit:
name: 'test max 6 ancestor commits'
runs-on: ubuntu-24.04
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. Assuming a worst case time of 1 hour per commit, this leads to a --max-count=6 below.
env:
MAX_COUNT: 6 # Keep in sync with name above
steps:
- name:
+ Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ with:
+ egress-policy: audit
+ - name:
Determine fetch depth
run: echo "FETCH_DEPTH=$((${{ github.event.pull_request.commits }} + 2))" >> "$GITHUB_ENV"
- *ANNOTATION_PR_NUMBER
- uses: actions/checkout@
+ de0fac2e4500dabe0009e67214ff5f5447ce83dd #
v6
+ .0.2
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: ${{ env.FETCH_DEPTH }}
- name: Determine commit range
run: |
# Checkout HEAD~ and find the test base commit
# Checkout HEAD~ because it would be wasteful to rerun tests on the PR
# head commit that are already run by other jobs.
git checkout HEAD~
# Figure out test base commit by listing ancestors of HEAD, excluding
# ancestors of the most recent merge commit, limiting the list to the
# newest MAX_COUNT ancestors, ordering it from oldest to newest, and
# taking the first one.
#
# If the branch contains up to MAX_COUNT ancestor commits after the
# most recent merge commit, all of those commits will be tested. If it
# contains more, only the most recent MAX_COUNT commits will be
# tested.
#
# In the command below, the ^@ suffix is used to refer to all parents
# of the merge commit as described in:
# https://git-scm.com/docs/git-rev-parse#_other_rev_parent_shorthand_notations
# and the ^ prefix is used to exclude these parents and all their
# ancestors from the rev-list output as described in:
# https://git-scm.com/docs/git-rev-list
MERGE_BASE=$(git rev-list -n1 --merges HEAD)
EXCLUDE_MERGE_BASE_ANCESTORS=
# MERGE_BASE can be empty due to limited fetch-depth
if test -n "$MERGE_BASE"; then
EXCLUDE_MERGE_BASE_ANCESTORS=^${MERGE_BASE}^@
fi
echo "TEST_BASE=$(git rev-list -n$((${{ env.MAX_COUNT }} + 1)) --reverse HEAD $EXCLUDE_MERGE_BASE_ANCESTORS | head -1)" >> "$GITHUB_ENV"
- run: |
git fetch origin "${GITHUB_BASE_REF}"
git config user.email "ci@example.com"
git config user.name "CI"
- run: |
sudo apt-get update
sudo apt-get install clang mold ccache build-essential cmake ninja-build pkgconf python3-zmq libevent-dev libboost-dev libsqlite3-dev systemtap-sdt-dev libzmq3-dev qt6-base-dev qt6-tools-dev qt6-l10n-tools libqrencode-dev capnproto libcapnp-dev -y
sudo pip3 install --break-system-packages pycapnp
- name: Compile and run tests
run: |
# Run tests on commits after the last merge commit and before the PR head commit
git rebase --exec "git merge --no-commit origin/${GITHUB_BASE_REF} && python3 ./.github/ci-test-each-commit-exec.py && git reset --hard" ${{ env.TEST_BASE }}
macos-native-arm64:
name: ${{ matrix.job-name }}
# Use any image to support the xcode-select below, but hardcode version to avoid silent upgrades (and breaks).
# See: https://github.com/actions/runner-images#available-images.
runs-on: macos-15
# When a contributor maintains a fork of the repo, any pull request they make
# to their own fork, or to the main repository, will trigger two CI runs:
# one for the branch push and one for the pull request.
# This can be avoided by setting SKIP_BRANCH_PUSH=true as a custom env variable
# in Github repository settings.
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
job-type: [standard, fuzz]
include:
- job-type: standard
file-env: './ci/test/00_setup_env_mac_native.sh'
job-name: 'macOS native'
- job-type: fuzz
file-env: './ci/test/00_setup_env_mac_native_fuzz.sh'
job-name: 'macOS native, fuzz'
env:
DANGER_RUN_CI_ON_HOST: 1
BASE_ROOT_DIR: ${{ github.workspace }}/repo_archive
steps:
-
+ name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ with:
+ egress-policy: audit
+ -
*ANNOTATION_PR_NUMBER
- &CHECKOUT
name: Checkout
uses: actions/checkout@
+ de0fac2e4500dabe0009e67214ff5f5447ce83dd #
v6
+ .0.2
with:
# Ensure the latest merged pull request state is used, even on re-runs.
ref: &CHECKOUT_REF_TMPL ${{ github.event_name == 'pull_request' && github.ref || '' }}
- name: Clang version
run: |
# Use the latest Xcode supported by the version of macOS denoted in
# doc/release-notes-empty-template.md and providing at least the
# minimum clang version denoted in doc/dependencies.md.
# See: https://developer.apple.com/documentation/xcode-release-notes/xcode-16_2-release-notes
sudo xcode-select --switch /Applications/Xcode_16.2.app
clang --version
- name: Install Homebrew packages
env:
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
run: |
# A workaround for "The `brew link` step did not complete successfully" error.
brew install --quiet python@3 || brew link --overwrite python@3
brew install --quiet coreutils ninja pkgconf ccache boost libevent zeromq qt@6 qrencode capnp
- name: Set Ccache directory
run: echo "CCACHE_DIR=${RUNNER_TEMP}/ccache_dir" >> "$GITHUB_ENV"
- name: Restore Ccache cache
id: ccache-cache
uses: actions/cache/restore@
+ 0057852bfaa89a56745cba8c7296529d2fc39830 #
v4
+ .3.0
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ github.job }}-${{ matrix.job-type }}-ccache-${{ github.run_id }}
restore-keys: ${{ github.job }}-${{ matrix.job-type }}-ccache-
- name: Create git archive
run: |
git log -1
git archive --format=tar --prefix=repo_archive/ --output=repo.tar HEAD
tar -xf repo.tar
- name: CI script
run: |
cd repo_archive
./ci/test_run_all.sh
env:
FILE_ENV: ${{ matrix.file-env }}
- name: Save Ccache cache
uses: actions/cache/save@
+ 0057852bfaa89a56745cba8c7296529d2fc39830 #
v4
+ .3.0
if: github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch && steps.ccache-cache.outputs.cache-hit != 'true'
with:
path: ${{ env.CCACHE_DIR }}
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache
key: ${{ github.job }}-${{ matrix.job-type }}-ccache-${{ github.run_id }}
windows-native-dll:
name: ${{ matrix.job-name }}
runs-on: windows-2022
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
env:
PYTHONUTF8: 1
TEST_RUNNER_TIMEOUT_FACTOR: 40
strategy:
fail-fast: false
matrix:
job-type: [standard, fuzz]
include:
- job-type: standard
generate-options: '-DBUILD_BENCH=ON -DBUILD_KERNEL_LIB=ON -DBUILD_UTIL_CHAINSTATE=ON -DWERROR=ON'
job-name: 'Windows native, VS 2022'
- job-type: fuzz
generate-options: '-DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON -DVCPKG_MANIFEST_FEATURES="wallet" -DBUILD_GUI=OFF -DWITH_ZMQ=OFF -DBUILD_FOR_FUZZING=ON -DWERROR=ON'
job-name: 'Windows native, fuzz, VS 2022'
steps:
-
+ name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ with:
+ egress-policy: audit
+ -
*ANNOTATION_PR_NUMBER
- *CHECKOUT
- &SET_UP_VS
name: Set up VS Developer Prompt
shell: pwsh -Command "$PSVersionTable; $PSNativeCommandUseErrorActionPreference = $true; $ErrorActionPreference = 'Stop'; & '{0}'"
run: |
$vswherePath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$installationPath = & $vswherePath -latest -property installationPath
& "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x64 -no_logo && set" | foreach-object {
$name, $value = $_ -split '=', 2
echo "$name=$value" >> $env:GITHUB_ENV
}
- name: Get tool information
shell: pwsh
run: |
cmake -version | Tee-Object -FilePath "cmake_version"
Write-Output "---"
msbuild -version | Tee-Object -FilePath "msbuild_version"
$env:VCToolsVersion | Tee-Object -FilePath "toolset_version"
py -3 --version
Write-Host "PowerShell version $($PSVersionTable.PSVersion.ToString())"
bash --version
- name: Using vcpkg with MSBuild
run: |
echo "set(VCPKG_BUILD_TYPE release)" >> "${VCPKG_INSTALLATION_ROOT}/triplets/x64-windows.cmake"
# Workaround for libevent, which requires CMake 3.1 but is incompatible with CMake >= 4.0.
sed -i '1s/^/set(ENV{CMAKE_POLICY_VERSION_MINIMUM} 3.5)\n/' "${VCPKG_INSTALLATION_ROOT}/scripts/ports.cmake"
- name: vcpkg tools cache
uses: actions/cache@
+ 668228422ae6a00e4ad889ee87cd7109ec5666a7 #
v5
+ .0.4
with:
path: C:/vcpkg/downloads/tools
key: ${{ github.job }}-vcpkg-tools
- name: Restore vcpkg binary cache
uses: actions/cache/restore@
+ 0057852bfaa89a56745cba8c7296529d2fc39830 #
v4
+ .3.0
id: vcpkg-binary-cache
with:
path: ~/AppData/Local/vcpkg/archives
key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }}
- name: Generate build system
run: |
cmake -B build -Werror=dev --preset vs2022 -DCMAKE_TOOLCHAIN_FILE="${VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" ${{ matrix.generate-options }}
- name: Save vcpkg binary cache
uses: actions/cache/save@
+ 0057852bfaa89a56745cba8c7296529d2fc39830 #
v4
+ .3.0
if: github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch && steps.vcpkg-binary-cache.outputs.cache-hit != 'true' && matrix.job-type == 'standard'
with:
path: ~/AppData/Local/vcpkg/archives
key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }}
- name: Build
working-directory: build
run: |
cmake --build . -j $NUMBER_OF_PROCESSORS --config Release
- name: Check executable manifests
if: matrix.job-type == 'standard'
working-directory: build
shell: pwsh -Command "$PSVersionTable; $PSNativeCommandUseErrorActionPreference = $true; $ErrorActionPreference = 'Stop'; & '{0}'"
run: |
mt.exe -nologo -inputresource:bin\Release\bitcoind.exe -out:bitcoind.manifest
Get-Content bitcoind.manifest
Get-ChildItem -Filter "bin\Release\*.exe" | ForEach-Object {
$exeName = $_.Name
# Skip as they currently do not have manifests
if ($exeName -eq "fuzz.exe" -or $exeName -eq "bench_bitcoin.exe" -or $exeName -eq "test_bitcoin-qt.exe" -or $exeName -eq "test_kernel.exe" -or $exeName -eq "bitcoin-chainstate.exe") {
Write-Host "Skipping $exeName (no manifest present)"
return
}
Write-Host "Checking $exeName"
& mt.exe -nologo -inputresource:$_.FullName -validate_manifest
}
- name: Run test suite
if: matrix.job-type == 'standard'
working-directory: build
run: |
ctest --output-on-failure --stop-on-failure -j $NUMBER_OF_PROCESSORS -C Release
- name: Run functional tests
if: matrix.job-type == 'standard'
working-directory: build
env:
BITCOIN_BIN: '${{ github.workspace }}\build\bin\Release\bitcoin.exe'
BITCOIND: '${{ github.workspace }}\build\bin\Release\bitcoind.exe'
BITCOINCLI: '${{ github.workspace }}\build\bin\Release\bitcoin-cli.exe'
BITCOIN_BENCH: '${{ github.workspace }}\build\bin\Release\bench_bitcoin.exe'
BITCOINTX: '${{ github.workspace }}\build\bin\Release\bitcoin-tx.exe'
BITCOINUTIL: '${{ github.workspace }}\build\bin\Release\bitcoin-util.exe'
BITCOINWALLET: '${{ github.workspace }}\build\bin\Release\bitcoin-wallet.exe'
BITCOINCHAINSTATE: '${{ github.workspace }}\build\bin\Release\bitcoin-chainstate.exe'
TEST_RUNNER_EXTRA: ${{ github.event_name != 'pull_request' && '--extended' || '' }}
run: |
py -3 -m pip install pyzmq
py -3 test/functional/test_runner.py --jobs $NUMBER_OF_PROCESSORS --quiet --tmpdirprefix="${RUNNER_TEMP}" --combinedlogslen=99999999 --timeout-factor=${TEST_RUNNER_TIMEOUT_FACTOR} ${TEST_RUNNER_EXTRA}
- name: Clone corpora
if: matrix.job-type == 'fuzz'
run: |
git clone --depth=1 https://github.com/bitcoin-core/qa-assets "${RUNNER_TEMP}/qa-assets"
cd "${RUNNER_TEMP}/qa-assets"
echo "Using qa-assets repo from commit ..."
git log -1
- name: Run fuzz tests
if: matrix.job-type == 'fuzz'
working-directory: build
env:
BITCOINFUZZ: '${{ github.workspace }}\build\bin\Release\fuzz.exe'
run: |
py -3 test/fuzz/test_runner.py --par $NUMBER_OF_PROCESSORS --loglevel DEBUG "${RUNNER_TEMP}/qa-assets/fuzz_corpora"
record-frozen-commit:
# Record frozen commit, so that the native tests on cross-builds can run on
# the exact same commit id of the build.
name: '[meta] record frozen commit'
runs-on: ubuntu-latest
outputs:
commit: ${{ steps.record-commit.outputs.commit }}
steps:
-
+ name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ with:
+ egress-policy: audit
+ -
*ANNOTATION_PR_NUMBER
- *CHECKOUT
- name: Record commit
id: record-commit
run: echo "commit=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
windows-cross:
name: 'Windows-cross to x86_64, ${{ matrix.crt }}'
needs: [runners, record-frozen-commit]
runs-on: ${{ needs.runners.outputs.provider == 'cirrus' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' || 'ubuntu-24.04' }}
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
strategy:
fail-fast: false
matrix:
crt: [msvcrt, ucrt]
include:
- crt: msvcrt
file-env: './ci/test/00_setup_env_win64_msvcrt.sh'
artifact-name: 'x86_64-w64-mingw32-executables'
- crt: ucrt
file-env: './ci/test/00_setup_env_win64.sh'
artifact-name: 'x86_64-w64-mingw32ucrt-executables'
env:
FILE_ENV: ${{ matrix.file-env }}
DANGER_CI_ON_HOST_FOLDERS: 1
steps:
-
+ name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ with:
+ egress-policy: audit
+ -
*ANNOTATION_PR_NUMBER
- name: Checkout
uses: actions/checkout@
+ de0fac2e4500dabe0009e67214ff5f5447ce83dd #
v6
+ .0.2
with:
ref: ${{ needs.record-frozen-commit.outputs.commit }}
- name: Configure environment
uses: ./.github/actions/configure-environment
- name: Restore caches
id: restore-cache
uses: ./.github/actions/restore-caches
- name: Configure Docker
uses: ./.github/actions/configure-docker
with:
cache-provider: ${{ needs.runners.outputs.provider }}
- name: CI script
run: ./ci/test_run_all.sh
- name: Save caches
uses: ./.github/actions/save-caches
- name: Upload built executables
uses: actions/upload-artifact@
+ b7c566a772e6b6bfb58ed0dc250532a479d7789f #
v6
+ .0.0
with:
name: ${{ matrix.artifact-name }}-${{ github.run_id }}
path: |
${{ env.BASE_BUILD_DIR }}/bin/*.dll
${{ env.BASE_BUILD_DIR }}/bin/*.exe
${{ env.BASE_BUILD_DIR }}/src/secp256k1/bin/*.exe
${{ env.BASE_BUILD_DIR }}/src/univalue/*.exe
${{ env.BASE_BUILD_DIR }}/test/config.ini
windows-native-test:
name: 'Windows, ${{ matrix.crt }}, test cross-built'
runs-on: windows-2022
needs: [windows-cross, record-frozen-commit]
strategy:
fail-fast: false
matrix:
crt: [msvcrt, ucrt]
include:
- crt: msvcrt
artifact-name: 'x86_64-w64-mingw32-executables'
- crt: ucrt
artifact-name: 'x86_64-w64-mingw32ucrt-executables'
env:
PYTHONUTF8: 1
TEST_RUNNER_TIMEOUT_FACTOR: 40
steps:
-
+ name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ with:
+ egress-policy: audit
+ -
*ANNOTATION_PR_NUMBER
- name: Checkout
uses: actions/checkout@
+ de0fac2e4500dabe0009e67214ff5f5447ce83dd #
v6
+ .0.2
with:
ref: ${{ needs.record-frozen-commit.outputs.commit }}
- name: Download built executables
uses: actions/download-artifact@
+ 37930b1c2abaa49bbe596cd826c3c89aef350131 #
v7
+ .0.0
with:
name: ${{ matrix.artifact-name }}-${{ github.run_id }}
- name: Run bitcoind.exe
run: ./bin/bitcoind.exe -version
- *SET_UP_VS
- name: Check executable manifests
shell: pwsh -Command "$PSVersionTable; $PSNativeCommandUseErrorActionPreference = $true; $ErrorActionPreference = 'Stop'; & '{0}'"
run: |
mt.exe -nologo -inputresource:bin\bitcoind.exe -out:bitcoind.manifest
Get-Content bitcoind.manifest
Get-ChildItem -Filter "bin\*.exe" | ForEach-Object {
$exeName = $_.Name
# Skip as they currently do not have manifests
if ($exeName -eq "fuzz.exe" -or $exeName -eq "bench_bitcoin.exe" -or $exeName -eq "test_kernel.exe") {
Write-Host "Skipping $exeName (no manifest present)"
return
}
Write-Host "Checking $exeName"
& mt.exe -nologo -inputresource:$_.FullName -validate_manifest
}
- name: Run unit tests
# Can't use ctest here like other jobs as we don't have a CMake build tree.
run: |
./bin/test_bitcoin-qt.exe
./bin/test_bitcoin.exe -l test_suite # Intentionally run sequentially here, to catch test case failures caused by dirty global state from prior test cases.
./src/secp256k1/bin/exhaustive_tests.exe
./src/secp256k1/bin/noverify_tests.exe
./src/secp256k1/bin/tests.exe
./src/univalue/object.exe
./src/univalue/unitester.exe
- name: Adjust paths in test/config.ini
shell: pwsh
run: |
(Get-Content "test/config.ini") -replace '(?<=^SRCDIR=).*', '${{ github.workspace }}' -replace '(?<=^BUILDDIR=).*', '${{ github.workspace }}' -replace '(?<=^RPCAUTH=).*', '${{ github.workspace }}/share/rpcauth/rpcauth.py' | Set-Content "test/config.ini"
Get-Content "test/config.ini"
- name: Set previous release directory
run: |
echo "PREVIOUS_RELEASES_DIR=${{ runner.temp }}/previous_releases" >> "$GITHUB_ENV"
- name: Get previous releases
run: ./test/get_previous_releases.py --target-dir $PREVIOUS_RELEASES_DIR
- name: Run functional tests
env:
TEST_RUNNER_EXTRA: ${{ github.event_name != 'pull_request' && '--extended' || '' }}
run: |
py -3 -m pip install pyzmq
py -3 test/functional/test_runner.py --jobs $NUMBER_OF_PROCESSORS --quiet --tmpdirprefix="$RUNNER_TEMP" --combinedlogslen=99999999 --timeout-factor=$TEST_RUNNER_TIMEOUT_FACTOR $TEST_RUNNER_EXTRA \
`# feature_unsupported_utxo_db.py fails on Windows because of emojis in the test data directory.` \
--exclude feature_unsupported_utxo_db.py \
`# See https://github.com/bitcoin/bitcoin/issues/31409.` \
--exclude wallet_multiwallet.py
# Run feature_unsupported_utxo_db sequentially in ASCII-only tmp dir,
# because it is excluded above due to lack of UTF-8 support in the
# ancient release.
py -3 test/functional/feature_unsupported_utxo_db.py --previous-releases --tmpdir="${RUNNER_TEMP}/test_feature_unsupported_utxo_db"
ci-matrix:
name: ${{ matrix.name }}
needs: runners
runs-on: ${{ needs.runners.outputs.provider == 'cirrus' && matrix.cirrus-runner || matrix.fallback-runner }}
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
timeout-minutes: ${{ matrix.timeout-minutes }}
env:
DANGER_CI_ON_HOST_FOLDERS: 1
FILE_ENV: ${{ matrix.file-env }}
strategy:
fail-fast: false
matrix:
include:
- name: 'iwyu'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_iwyu.sh'
- name: '32 bit ARM'
cirrus-runner: 'ubuntu-24.04-arm' # Cirrus' Arm runners are Apple (with virtual Linux aarch64), which doesn't support 32-bit mode
fallback-runner: 'ubuntu-24.04-arm'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_arm.sh'
provider: 'gha'
- name: 'ASan + LSan + UBSan + integer'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' # has to match container in ci/test/00_setup_env_native_asan.sh for tracing tools
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_asan.sh'
- name: 'macOS-cross to arm64'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_mac_cross.sh'
- name: 'macOS-cross to x86_64'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_mac_cross_intel.sh'
- name: 'No wallet'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_nowallet.sh'
- name: 'i686, no IPC'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_i686_no_ipc.sh'
- name: 'fuzzer,address,undefined,integer'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 240
file-env: './ci/test/00_setup_env_native_fuzz.sh'
- name: 'Valgrind, fuzz'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 240
file-env: './ci/test/00_setup_env_native_fuzz_with_valgrind.sh'
- name: 'previous releases'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_previous_releases.sh'
- name: 'Alpine (musl)'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_alpine_musl.sh'
- name: 'tidy'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_tidy.sh'
- name: 'TSan'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_tsan.sh'
- name: 'MSan, fuzz'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 150
file-env: './ci/test/00_setup_env_native_fuzz_with_msan.sh'
- name: 'MSan'
cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg'
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_msan.sh'
steps:
-
+ name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ with:
+ egress-policy: audit
+ -
*ANNOTATION_PR_NUMBER
- *CHECKOUT
- name: Configure environment
uses: ./.github/actions/configure-environment
- name: Restore caches
id: restore-cache
uses: ./.github/actions/restore-caches
- 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
uses: ./.github/actions/clear-files
- name: Enable bpfcc script
if: ${{ env.CONTAINER_NAME == 'ci_native_asan' }}
# In the image build step, no external environment variables are available,
# so any settings will need to be written to the settings env file:
run: sed -i "s|\${INSTALL_BCC_TRACING_TOOLS}|true|g" ./ci/test/00_setup_env_native_asan.sh
- name: Set mmap_rnd_bits
if: ${{ env.CONTAINER_NAME == 'ci_native_tsan' || env.CONTAINER_NAME == 'ci_native_msan' || env.CONTAINER_NAME == 'ci_native_fuzz_msan' }}
# Prevents crashes due to high ASLR entropy
run: sudo sysctl -w vm.mmap_rnd_bits=28
- name: CI script
run: ./ci/test_run_all.sh
- name: Save caches
uses: ./.github/actions/save-caches
lint:
name: 'lint'
needs: runners
runs-on: ${{ needs.runners.outputs.provider == 'cirrus' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-xs' || 'ubuntu-24.04' }}
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
timeout-minutes: 20
env:
CONTAINER_NAME: "bitcoin-linter"
steps:
-
+ name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ with:
+ egress-policy: audit
+ -
*ANNOTATION_PR_NUMBER
- name: Checkout
uses: actions/checkout@
+ de0fac2e4500dabe0009e67214ff5f5447ce83dd #
v6
+ .0.2
with:
ref: *CHECKOUT_REF_TMPL
fetch-depth: 0
- name: Configure Docker
uses: ./.github/actions/configure-docker
with:
cache-provider: ${{ needs.runners.outputs.provider }}
- name: CI script
run: |
git worktree add ../lint-worktree HEAD
../lint-worktree/ci/lint.py
Additional Information
For more information, refer to the documentation page here.
Please don't make any changes in the description as the platform makes automated updates in description. Please use the comment section below to provide input.
Automated remediation commands and options
- Create a pull request with automated security fixes
@stepsecurity-app pull-request create
- Close this issue and prevent it from being reopened
@stepsecurity-app issue close <REASON>
- Update issue description with latest security check status
@stepsecurity-app issue force-update
- View all available commands and their usage
Which GitHub Actions security best practices were evaluated?
The workflow was evaluated for the following GitHub Actions security best practices:
- Network & runtime security monitoring
- Token permissions
- Third‐party GitHub Actions usage & pinning
Summary
This issue is created by StepSecurity related to security issues in ci.yml . The platform has identified 3 vulnerabilities (1 critical, 1 high, 0 medium, 1 low).
Remediation Overview
The platform can generate remediations for a few vulnerabilities. For such vulnerabilities, you can find the fixed workflow file in the
Suggested Fix For Auto-Remediable Issuessection. You can manually deploy these changes or create a pull request by commenting@stepsecurity-app pull-request createon this issue.Other issues require manual investigation and changes.
Once a vulnerability has been remediated, ✅ will appear in the title. Note that it may take up to 24 hours for these issues to be updated.
Please review the individual vulnerability section below and follow the recommended resolution steps.
Security Checks Details
❌ Actions should be pinned to a full-length commit SHA
Severity: Critical
Description: GitHub Action tags and Docker tags are mutable. This poses a security risk. GitHub's Security Hardening guide recommends pinning actions to full length commit.
Resolution: Pin Actions to a full-length commit SHA..
Automated Remediation Available ?: true
References:
GitHub Security Guide
The Open Source Security Foundation (OpenSSF) Security Guide
❌ Network and runtime security monitoring should be enabled for GitHub-hosted runners
Severity: Low
Description: This check passes if the step-security/harden-runner GitHub Action is used in a job that runs on a GitHub-hosted runner. Harden-Runner prevents exfiltration of code and CI/CD credentials, and detects tampering of files during build.
Resolution: Add the step-security/harden-runner GitHub Action to the job.
Automated Remediation Available ?: true
References:
GitHub Security Guide
The Open Source Security Foundation (OpenSSF) Security Guide
❌ GITHUB_TOKEN should have minimum permissions
Severity: High
Description: This check passes if the job's GITHUB_TOKEN does not have all the read and write permissions.
Resolution: Set minimum GitHub token permissions at the job or workflow level.
Automated Remediation Available ?: true
References:
GitHub Security Guide
The Open Source Security Foundation (OpenSSF) Security Guide
Suggested Fix For Auto-Remediable Issues
Below is the updated workflow, which fixes the following security vulnerabilities:
Actions should be pinned to a full-length commit SHA
Network and runtime security monitoring should be enabled for GitHub-hosted runners
GITHUB_TOKEN should have minimum permissions
# Copyright (c) 2023-present The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/license/mit. name: CI on: # See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request. pull_request: # See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#push. push: branches: - '**' tags-ignore: - '**' concurrency: group: ${{ github.event_name != 'pull_request' && github.run_id || github.ref }} cancel-in-progress: true 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 defaults: run: # Enforce fail-fast behavior for all platforms. # See: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference shell: bash jobs: runners: name: '[meta] determine runners' runs-on: ubuntu-latest outputs: provider: ${{ steps.runners.outputs.provider }} steps: - + name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - &ANNOTATION_PR_NUMBER name: Annotate with pull request number # This annotation is machine-readable and can be used to assign a check # run to its corresponding pull request. Running in all check runs is # required, because check re-runs discard the annotations of other # tasks in the test suite. run: | if [ "${{ github.event_name }}" = "pull_request" ]; then echo "::notice title=debug_pull_request_number_str::${{ github.event.number }}" fi - id: runners run: | if [[ "${REPO_USE_CIRRUS_RUNNERS}" == "${{ github.repository }}" ]]; then echo "provider=cirrus" >> "$GITHUB_OUTPUT" echo "::notice title=Runner Selection::Using Cirrus Runners" else echo "provider=gha" >> "$GITHUB_OUTPUT" echo "::notice title=Runner Selection::Using GitHub-hosted runners" fi test-each-commit: name: 'test max 6 ancestor commits' runs-on: ubuntu-24.04 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. Assuming a worst case time of 1 hour per commit, this leads to a --max-count=6 below. env: MAX_COUNT: 6 # Keep in sync with name above steps: - name: + Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - name: Determine fetch depth run: echo "FETCH_DEPTH=$((${{ github.event.pull_request.commits }} + 2))" >> "$GITHUB_ENV" - *ANNOTATION_PR_NUMBER - uses: actions/checkout@ + de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + .0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: ${{ env.FETCH_DEPTH }} - name: Determine commit range run: | # Checkout HEAD~ and find the test base commit # Checkout HEAD~ because it would be wasteful to rerun tests on the PR # head commit that are already run by other jobs. git checkout HEAD~ # Figure out test base commit by listing ancestors of HEAD, excluding # ancestors of the most recent merge commit, limiting the list to the # newest MAX_COUNT ancestors, ordering it from oldest to newest, and # taking the first one. # # If the branch contains up to MAX_COUNT ancestor commits after the # most recent merge commit, all of those commits will be tested. If it # contains more, only the most recent MAX_COUNT commits will be # tested. # # In the command below, the ^@ suffix is used to refer to all parents # of the merge commit as described in: # https://git-scm.com/docs/git-rev-parse#_other_rev_parent_shorthand_notations # and the ^ prefix is used to exclude these parents and all their # ancestors from the rev-list output as described in: # https://git-scm.com/docs/git-rev-list MERGE_BASE=$(git rev-list -n1 --merges HEAD) EXCLUDE_MERGE_BASE_ANCESTORS= # MERGE_BASE can be empty due to limited fetch-depth if test -n "$MERGE_BASE"; then EXCLUDE_MERGE_BASE_ANCESTORS=^${MERGE_BASE}^@ fi echo "TEST_BASE=$(git rev-list -n$((${{ env.MAX_COUNT }} + 1)) --reverse HEAD $EXCLUDE_MERGE_BASE_ANCESTORS | head -1)" >> "$GITHUB_ENV" - run: | git fetch origin "${GITHUB_BASE_REF}" git config user.email "ci@example.com" git config user.name "CI" - run: | sudo apt-get update sudo apt-get install clang mold ccache build-essential cmake ninja-build pkgconf python3-zmq libevent-dev libboost-dev libsqlite3-dev systemtap-sdt-dev libzmq3-dev qt6-base-dev qt6-tools-dev qt6-l10n-tools libqrencode-dev capnproto libcapnp-dev -y sudo pip3 install --break-system-packages pycapnp - name: Compile and run tests run: | # Run tests on commits after the last merge commit and before the PR head commit git rebase --exec "git merge --no-commit origin/${GITHUB_BASE_REF} && python3 ./.github/ci-test-each-commit-exec.py && git reset --hard" ${{ env.TEST_BASE }} macos-native-arm64: name: ${{ matrix.job-name }} # Use any image to support the xcode-select below, but hardcode version to avoid silent upgrades (and breaks). # See: https://github.com/actions/runner-images#available-images. runs-on: macos-15 # When a contributor maintains a fork of the repo, any pull request they make # to their own fork, or to the main repository, will trigger two CI runs: # one for the branch push and one for the pull request. # This can be avoided by setting SKIP_BRANCH_PUSH=true as a custom env variable # in Github repository settings. if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} timeout-minutes: 120 strategy: fail-fast: false matrix: job-type: [standard, fuzz] include: - job-type: standard file-env: './ci/test/00_setup_env_mac_native.sh' job-name: 'macOS native' - job-type: fuzz file-env: './ci/test/00_setup_env_mac_native_fuzz.sh' job-name: 'macOS native, fuzz' env: DANGER_RUN_CI_ON_HOST: 1 BASE_ROOT_DIR: ${{ github.workspace }}/repo_archive steps: - + name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - *ANNOTATION_PR_NUMBER - &CHECKOUT name: Checkout uses: actions/checkout@ + de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + .0.2 with: # Ensure the latest merged pull request state is used, even on re-runs. ref: &CHECKOUT_REF_TMPL ${{ github.event_name == 'pull_request' && github.ref || '' }} - name: Clang version run: | # Use the latest Xcode supported by the version of macOS denoted in # doc/release-notes-empty-template.md and providing at least the # minimum clang version denoted in doc/dependencies.md. # See: https://developer.apple.com/documentation/xcode-release-notes/xcode-16_2-release-notes sudo xcode-select --switch /Applications/Xcode_16.2.app clang --version - name: Install Homebrew packages env: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 run: | # A workaround for "The `brew link` step did not complete successfully" error. brew install --quiet python@3 || brew link --overwrite python@3 brew install --quiet coreutils ninja pkgconf ccache boost libevent zeromq qt@6 qrencode capnp - name: Set Ccache directory run: echo "CCACHE_DIR=${RUNNER_TEMP}/ccache_dir" >> "$GITHUB_ENV" - name: Restore Ccache cache id: ccache-cache uses: actions/cache/restore@ + 0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + .3.0 with: path: ${{ env.CCACHE_DIR }} key: ${{ github.job }}-${{ matrix.job-type }}-ccache-${{ github.run_id }} restore-keys: ${{ github.job }}-${{ matrix.job-type }}-ccache- - name: Create git archive run: | git log -1 git archive --format=tar --prefix=repo_archive/ --output=repo.tar HEAD tar -xf repo.tar - name: CI script run: | cd repo_archive ./ci/test_run_all.sh env: FILE_ENV: ${{ matrix.file-env }} - name: Save Ccache cache uses: actions/cache/save@ + 0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + .3.0 if: github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch && steps.ccache-cache.outputs.cache-hit != 'true' with: path: ${{ env.CCACHE_DIR }} # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache key: ${{ github.job }}-${{ matrix.job-type }}-ccache-${{ github.run_id }} windows-native-dll: name: ${{ matrix.job-name }} runs-on: windows-2022 if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} env: PYTHONUTF8: 1 TEST_RUNNER_TIMEOUT_FACTOR: 40 strategy: fail-fast: false matrix: job-type: [standard, fuzz] include: - job-type: standard generate-options: '-DBUILD_BENCH=ON -DBUILD_KERNEL_LIB=ON -DBUILD_UTIL_CHAINSTATE=ON -DWERROR=ON' job-name: 'Windows native, VS 2022' - job-type: fuzz generate-options: '-DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON -DVCPKG_MANIFEST_FEATURES="wallet" -DBUILD_GUI=OFF -DWITH_ZMQ=OFF -DBUILD_FOR_FUZZING=ON -DWERROR=ON' job-name: 'Windows native, fuzz, VS 2022' steps: - + name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - *ANNOTATION_PR_NUMBER - *CHECKOUT - &SET_UP_VS name: Set up VS Developer Prompt shell: pwsh -Command "$PSVersionTable; $PSNativeCommandUseErrorActionPreference = $true; $ErrorActionPreference = 'Stop'; & '{0}'" run: | $vswherePath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" $installationPath = & $vswherePath -latest -property installationPath & "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x64 -no_logo && set" | foreach-object { $name, $value = $_ -split '=', 2 echo "$name=$value" >> $env:GITHUB_ENV } - name: Get tool information shell: pwsh run: | cmake -version | Tee-Object -FilePath "cmake_version" Write-Output "---" msbuild -version | Tee-Object -FilePath "msbuild_version" $env:VCToolsVersion | Tee-Object -FilePath "toolset_version" py -3 --version Write-Host "PowerShell version $($PSVersionTable.PSVersion.ToString())" bash --version - name: Using vcpkg with MSBuild run: | echo "set(VCPKG_BUILD_TYPE release)" >> "${VCPKG_INSTALLATION_ROOT}/triplets/x64-windows.cmake" # Workaround for libevent, which requires CMake 3.1 but is incompatible with CMake >= 4.0. sed -i '1s/^/set(ENV{CMAKE_POLICY_VERSION_MINIMUM} 3.5)\n/' "${VCPKG_INSTALLATION_ROOT}/scripts/ports.cmake" - name: vcpkg tools cache uses: actions/cache@ + 668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + .0.4 with: path: C:/vcpkg/downloads/tools key: ${{ github.job }}-vcpkg-tools - name: Restore vcpkg binary cache uses: actions/cache/restore@ + 0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + .3.0 id: vcpkg-binary-cache with: path: ~/AppData/Local/vcpkg/archives key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} - name: Generate build system run: | cmake -B build -Werror=dev --preset vs2022 -DCMAKE_TOOLCHAIN_FILE="${VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" ${{ matrix.generate-options }} - name: Save vcpkg binary cache uses: actions/cache/save@ + 0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + .3.0 if: github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch && steps.vcpkg-binary-cache.outputs.cache-hit != 'true' && matrix.job-type == 'standard' with: path: ~/AppData/Local/vcpkg/archives key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }} - name: Build working-directory: build run: | cmake --build . -j $NUMBER_OF_PROCESSORS --config Release - name: Check executable manifests if: matrix.job-type == 'standard' working-directory: build shell: pwsh -Command "$PSVersionTable; $PSNativeCommandUseErrorActionPreference = $true; $ErrorActionPreference = 'Stop'; & '{0}'" run: | mt.exe -nologo -inputresource:bin\Release\bitcoind.exe -out:bitcoind.manifest Get-Content bitcoind.manifest Get-ChildItem -Filter "bin\Release\*.exe" | ForEach-Object { $exeName = $_.Name # Skip as they currently do not have manifests if ($exeName -eq "fuzz.exe" -or $exeName -eq "bench_bitcoin.exe" -or $exeName -eq "test_bitcoin-qt.exe" -or $exeName -eq "test_kernel.exe" -or $exeName -eq "bitcoin-chainstate.exe") { Write-Host "Skipping $exeName (no manifest present)" return } Write-Host "Checking $exeName" & mt.exe -nologo -inputresource:$_.FullName -validate_manifest } - name: Run test suite if: matrix.job-type == 'standard' working-directory: build run: | ctest --output-on-failure --stop-on-failure -j $NUMBER_OF_PROCESSORS -C Release - name: Run functional tests if: matrix.job-type == 'standard' working-directory: build env: BITCOIN_BIN: '${{ github.workspace }}\build\bin\Release\bitcoin.exe' BITCOIND: '${{ github.workspace }}\build\bin\Release\bitcoind.exe' BITCOINCLI: '${{ github.workspace }}\build\bin\Release\bitcoin-cli.exe' BITCOIN_BENCH: '${{ github.workspace }}\build\bin\Release\bench_bitcoin.exe' BITCOINTX: '${{ github.workspace }}\build\bin\Release\bitcoin-tx.exe' BITCOINUTIL: '${{ github.workspace }}\build\bin\Release\bitcoin-util.exe' BITCOINWALLET: '${{ github.workspace }}\build\bin\Release\bitcoin-wallet.exe' BITCOINCHAINSTATE: '${{ github.workspace }}\build\bin\Release\bitcoin-chainstate.exe' TEST_RUNNER_EXTRA: ${{ github.event_name != 'pull_request' && '--extended' || '' }} run: | py -3 -m pip install pyzmq py -3 test/functional/test_runner.py --jobs $NUMBER_OF_PROCESSORS --quiet --tmpdirprefix="${RUNNER_TEMP}" --combinedlogslen=99999999 --timeout-factor=${TEST_RUNNER_TIMEOUT_FACTOR} ${TEST_RUNNER_EXTRA} - name: Clone corpora if: matrix.job-type == 'fuzz' run: | git clone --depth=1 https://github.com/bitcoin-core/qa-assets "${RUNNER_TEMP}/qa-assets" cd "${RUNNER_TEMP}/qa-assets" echo "Using qa-assets repo from commit ..." git log -1 - name: Run fuzz tests if: matrix.job-type == 'fuzz' working-directory: build env: BITCOINFUZZ: '${{ github.workspace }}\build\bin\Release\fuzz.exe' run: | py -3 test/fuzz/test_runner.py --par $NUMBER_OF_PROCESSORS --loglevel DEBUG "${RUNNER_TEMP}/qa-assets/fuzz_corpora" record-frozen-commit: # Record frozen commit, so that the native tests on cross-builds can run on # the exact same commit id of the build. name: '[meta] record frozen commit' runs-on: ubuntu-latest outputs: commit: ${{ steps.record-commit.outputs.commit }} steps: - + name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - *ANNOTATION_PR_NUMBER - *CHECKOUT - name: Record commit id: record-commit run: echo "commit=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" windows-cross: name: 'Windows-cross to x86_64, ${{ matrix.crt }}' needs: [runners, record-frozen-commit] runs-on: ${{ needs.runners.outputs.provider == 'cirrus' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' || 'ubuntu-24.04' }} if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} strategy: fail-fast: false matrix: crt: [msvcrt, ucrt] include: - crt: msvcrt file-env: './ci/test/00_setup_env_win64_msvcrt.sh' artifact-name: 'x86_64-w64-mingw32-executables' - crt: ucrt file-env: './ci/test/00_setup_env_win64.sh' artifact-name: 'x86_64-w64-mingw32ucrt-executables' env: FILE_ENV: ${{ matrix.file-env }} DANGER_CI_ON_HOST_FOLDERS: 1 steps: - + name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - *ANNOTATION_PR_NUMBER - name: Checkout uses: actions/checkout@ + de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + .0.2 with: ref: ${{ needs.record-frozen-commit.outputs.commit }} - name: Configure environment uses: ./.github/actions/configure-environment - name: Restore caches id: restore-cache uses: ./.github/actions/restore-caches - name: Configure Docker uses: ./.github/actions/configure-docker with: cache-provider: ${{ needs.runners.outputs.provider }} - name: CI script run: ./ci/test_run_all.sh - name: Save caches uses: ./.github/actions/save-caches - name: Upload built executables uses: actions/upload-artifact@ + b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 + .0.0 with: name: ${{ matrix.artifact-name }}-${{ github.run_id }} path: | ${{ env.BASE_BUILD_DIR }}/bin/*.dll ${{ env.BASE_BUILD_DIR }}/bin/*.exe ${{ env.BASE_BUILD_DIR }}/src/secp256k1/bin/*.exe ${{ env.BASE_BUILD_DIR }}/src/univalue/*.exe ${{ env.BASE_BUILD_DIR }}/test/config.ini windows-native-test: name: 'Windows, ${{ matrix.crt }}, test cross-built' runs-on: windows-2022 needs: [windows-cross, record-frozen-commit] strategy: fail-fast: false matrix: crt: [msvcrt, ucrt] include: - crt: msvcrt artifact-name: 'x86_64-w64-mingw32-executables' - crt: ucrt artifact-name: 'x86_64-w64-mingw32ucrt-executables' env: PYTHONUTF8: 1 TEST_RUNNER_TIMEOUT_FACTOR: 40 steps: - + name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - *ANNOTATION_PR_NUMBER - name: Checkout uses: actions/checkout@ + de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + .0.2 with: ref: ${{ needs.record-frozen-commit.outputs.commit }} - name: Download built executables uses: actions/download-artifact@ + 37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + .0.0 with: name: ${{ matrix.artifact-name }}-${{ github.run_id }} - name: Run bitcoind.exe run: ./bin/bitcoind.exe -version - *SET_UP_VS - name: Check executable manifests shell: pwsh -Command "$PSVersionTable; $PSNativeCommandUseErrorActionPreference = $true; $ErrorActionPreference = 'Stop'; & '{0}'" run: | mt.exe -nologo -inputresource:bin\bitcoind.exe -out:bitcoind.manifest Get-Content bitcoind.manifest Get-ChildItem -Filter "bin\*.exe" | ForEach-Object { $exeName = $_.Name # Skip as they currently do not have manifests if ($exeName -eq "fuzz.exe" -or $exeName -eq "bench_bitcoin.exe" -or $exeName -eq "test_kernel.exe") { Write-Host "Skipping $exeName (no manifest present)" return } Write-Host "Checking $exeName" & mt.exe -nologo -inputresource:$_.FullName -validate_manifest } - name: Run unit tests # Can't use ctest here like other jobs as we don't have a CMake build tree. run: | ./bin/test_bitcoin-qt.exe ./bin/test_bitcoin.exe -l test_suite # Intentionally run sequentially here, to catch test case failures caused by dirty global state from prior test cases. ./src/secp256k1/bin/exhaustive_tests.exe ./src/secp256k1/bin/noverify_tests.exe ./src/secp256k1/bin/tests.exe ./src/univalue/object.exe ./src/univalue/unitester.exe - name: Adjust paths in test/config.ini shell: pwsh run: | (Get-Content "test/config.ini") -replace '(?<=^SRCDIR=).*', '${{ github.workspace }}' -replace '(?<=^BUILDDIR=).*', '${{ github.workspace }}' -replace '(?<=^RPCAUTH=).*', '${{ github.workspace }}/share/rpcauth/rpcauth.py' | Set-Content "test/config.ini" Get-Content "test/config.ini" - name: Set previous release directory run: | echo "PREVIOUS_RELEASES_DIR=${{ runner.temp }}/previous_releases" >> "$GITHUB_ENV" - name: Get previous releases run: ./test/get_previous_releases.py --target-dir $PREVIOUS_RELEASES_DIR - name: Run functional tests env: TEST_RUNNER_EXTRA: ${{ github.event_name != 'pull_request' && '--extended' || '' }} run: | py -3 -m pip install pyzmq py -3 test/functional/test_runner.py --jobs $NUMBER_OF_PROCESSORS --quiet --tmpdirprefix="$RUNNER_TEMP" --combinedlogslen=99999999 --timeout-factor=$TEST_RUNNER_TIMEOUT_FACTOR $TEST_RUNNER_EXTRA \ `# feature_unsupported_utxo_db.py fails on Windows because of emojis in the test data directory.` \ --exclude feature_unsupported_utxo_db.py \ `# See https://github.com/bitcoin/bitcoin/issues/31409.` \ --exclude wallet_multiwallet.py # Run feature_unsupported_utxo_db sequentially in ASCII-only tmp dir, # because it is excluded above due to lack of UTF-8 support in the # ancient release. py -3 test/functional/feature_unsupported_utxo_db.py --previous-releases --tmpdir="${RUNNER_TEMP}/test_feature_unsupported_utxo_db" ci-matrix: name: ${{ matrix.name }} needs: runners runs-on: ${{ needs.runners.outputs.provider == 'cirrus' && matrix.cirrus-runner || matrix.fallback-runner }} if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} timeout-minutes: ${{ matrix.timeout-minutes }} env: DANGER_CI_ON_HOST_FOLDERS: 1 FILE_ENV: ${{ matrix.file-env }} strategy: fail-fast: false matrix: include: - name: 'iwyu' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_iwyu.sh' - name: '32 bit ARM' cirrus-runner: 'ubuntu-24.04-arm' # Cirrus' Arm runners are Apple (with virtual Linux aarch64), which doesn't support 32-bit mode fallback-runner: 'ubuntu-24.04-arm' timeout-minutes: 120 file-env: './ci/test/00_setup_env_arm.sh' provider: 'gha' - name: 'ASan + LSan + UBSan + integer' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' # has to match container in ci/test/00_setup_env_native_asan.sh for tracing tools fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_asan.sh' - name: 'macOS-cross to arm64' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_mac_cross.sh' - name: 'macOS-cross to x86_64' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_mac_cross_intel.sh' - name: 'No wallet' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-sm' fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_nowallet.sh' - name: 'i686, no IPC' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_i686_no_ipc.sh' - name: 'fuzzer,address,undefined,integer' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg' fallback-runner: 'ubuntu-24.04' timeout-minutes: 240 file-env: './ci/test/00_setup_env_native_fuzz.sh' - name: 'Valgrind, fuzz' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' fallback-runner: 'ubuntu-24.04' timeout-minutes: 240 file-env: './ci/test/00_setup_env_native_fuzz_with_valgrind.sh' - name: 'previous releases' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_previous_releases.sh' - name: 'Alpine (musl)' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_alpine_musl.sh' - name: 'tidy' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_tidy.sh' - name: 'TSan' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_tsan.sh' - name: 'MSan, fuzz' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-md' fallback-runner: 'ubuntu-24.04' timeout-minutes: 150 file-env: './ci/test/00_setup_env_native_fuzz_with_msan.sh' - name: 'MSan' cirrus-runner: 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-lg' fallback-runner: 'ubuntu-24.04' timeout-minutes: 120 file-env: './ci/test/00_setup_env_native_msan.sh' steps: - + name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - *ANNOTATION_PR_NUMBER - *CHECKOUT - name: Configure environment uses: ./.github/actions/configure-environment - name: Restore caches id: restore-cache uses: ./.github/actions/restore-caches - 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 uses: ./.github/actions/clear-files - name: Enable bpfcc script if: ${{ env.CONTAINER_NAME == 'ci_native_asan' }} # In the image build step, no external environment variables are available, # so any settings will need to be written to the settings env file: run: sed -i "s|\${INSTALL_BCC_TRACING_TOOLS}|true|g" ./ci/test/00_setup_env_native_asan.sh - name: Set mmap_rnd_bits if: ${{ env.CONTAINER_NAME == 'ci_native_tsan' || env.CONTAINER_NAME == 'ci_native_msan' || env.CONTAINER_NAME == 'ci_native_fuzz_msan' }} # Prevents crashes due to high ASLR entropy run: sudo sysctl -w vm.mmap_rnd_bits=28 - name: CI script run: ./ci/test_run_all.sh - name: Save caches uses: ./.github/actions/save-caches lint: name: 'lint' needs: runners runs-on: ${{ needs.runners.outputs.provider == 'cirrus' && 'ghcr.io/cirruslabs/ubuntu-runner-amd64:24.04-xs' || 'ubuntu-24.04' }} if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }} timeout-minutes: 20 env: CONTAINER_NAME: "bitcoin-linter" steps: - + name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - *ANNOTATION_PR_NUMBER - name: Checkout uses: actions/checkout@ + de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + .0.2 with: ref: *CHECKOUT_REF_TMPL fetch-depth: 0 - name: Configure Docker uses: ./.github/actions/configure-docker with: cache-provider: ${{ needs.runners.outputs.provider }} - name: CI script run: | git worktree add ../lint-worktree HEAD ../lint-worktree/ci/lint.pyAdditional Information
For more information, refer to the documentation page here.
Please don't make any changes in the description as the platform makes automated updates in description. Please use the comment section below to provide input.
Automated remediation commands and options
@stepsecurity-app helpWhich GitHub Actions security best practices were evaluated?
The workflow was evaluated for the following GitHub Actions security best practices: