Skip to content
Closed

. #1535

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
105 changes: 105 additions & 0 deletions .github/workflows/win.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Windows Build & Test

# Windows counterpart to testing.yml's unit-tests job. Builds Blockbook's native
# deps (libzmq + RocksDB) from source as static libraries with the MSYS2 UCRT64
# GCC toolchain, then builds blockbook.exe / blockbookgen.exe and runs the Go
# unit-test suite. Mirrors the steps documented in docs/win-build.md and driven
# by build/scripts/build-deps.ps1 and build/scripts/build-blockbook.ps1.

on:
push:
branches: [ master, develop ]
pull_request:
branches: [ '**' ]
workflow_dispatch:

permissions:
contents: read

jobs:
build-and-test:
name: Build & Unit Test (Windows)
runs-on: windows-latest

# build-deps.ps1 / build-blockbook.ps1 auto-detect the UCRT64 toolchain
# (MSYS2_ROOT is exported below) and run from the repo root in PowerShell.
defaults:
run:
shell: pwsh
working-directory: ${{ github.workspace }}

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true

# Install the UCRT64 GCC toolchain, CMake, Ninja and the compression libs
# RocksDB links against (lz4, zstd, zlib, snappy, bzip2) — exactly the
# package set from docs/win-build.md. The action installs MSYS2 to a path
# it reports via the 'msys2-location' output (NOT necessarily C:\msys64),
# which the next step exports as MSYS2_ROOT for the build scripts.
- name: Set up MSYS2 UCRT64 toolchain
id: msys2
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: true
install: >-
base-devel
mingw-w64-ucrt-x86_64-toolchain
mingw-w64-ucrt-x86_64-cmake
mingw-w64-ucrt-x86_64-ninja
git
mingw-w64-ucrt-x86_64-lz4
mingw-w64-ucrt-x86_64-zstd
mingw-w64-ucrt-x86_64-zlib
mingw-w64-ucrt-x86_64-snappy
mingw-w64-ucrt-x86_64-bzip2

# build-deps.ps1 / build-blockbook.ps1 auto-detect the MSYS2 root (gcc on
# PATH -> MSYS2_ROOT env hint -> common install locations -> registry).
# gcc is not on the pwsh PATH here and the action may install MSYS2 to a
# non-default path, so export its msys2-location output as MSYS2_ROOT.
- name: Export MSYS2 root for build scripts
run: |
"MSYS2_ROOT=${{ steps.msys2.outputs.msys2-location }}" >> $env:GITHUB_ENV

# Cache the built static deps under ./.dev keyed on the dep versions pinned
# in build-deps.ps1, so we don't rebuild libzmq + RocksDB every run.
- name: Cache native deps (.dev)
id: cache-dev
uses: actions/cache@v5
with:
path: .dev
key: win-dev-${{ runner.os }}-${{ hashFiles('build/scripts/build-deps.ps1') }}

- name: Build native deps (libzmq + RocksDB, static)
if: steps.cache-dev.outputs.cache-hit != 'true'
run: .\build\scripts\build-deps.ps1

- name: Build blockbook.exe
run: .\build\scripts\build-blockbook.ps1

# Unit-test failures are surfaced as a GitHub Actions warning rather than
# failing the job — the Windows build is the gate here, the unit suite is
# informational. build-blockbook.ps1 throws (it sets $ErrorActionPreference
# = 'Stop') when tests fail, so we run it in a child pwsh and catch both a
# thrown terminating error and a non-zero exit, emitting a ::warning::
# annotation instead of failing.
- name: Run unit tests
run: |
try {
.\build\scripts\build-blockbook.ps1 test
if ($LASTEXITCODE -ne 0) { throw "tests exited with code $LASTEXITCODE" }
} catch {
Write-Output "::warning::Windows unit tests failed: $($_.Exception.Message); not failing the job."
}
# go test / the script leave $LASTEXITCODE non-zero on failure, and the
# Actions pwsh wrapper appends `if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }`.
# Reset it so the caught failure stays a warning and the job passes.
exit 0
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ __pycache__/
.dev/
.spec/
static/api-docs/swagger-ui/
configs/grafana/grafana.json
configs/grafana/grafana.json
*.exe
34 changes: 29 additions & 5 deletions build/docker/bin/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,28 @@ RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y build-essential git wget pkg-config lxc-dev libzmq3-dev \
libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev \
libzstd-dev liblz4-dev graphviz && \
libzstd-dev liblz4-dev graphviz \
autoconf automake libtool && \
apt-get clean
ARG GOLANG_VERSION
ENV GOLANG_VERSION=go1.25.4
ENV ROCKSDB_VERSION=v9.10.0
ENV ROCKSDB_VERSION=v11.1.1
ENV ROCKSDB_COMMIT=6cdeb9d9d0630763327f512e6255cab33f6834e7
ENV LIBZMQ_VERSION=v4.3.5
ENV LIBZMQ_COMMIT=622fc6dde99ee172ebaa9c8628d85a7a1995a21d
ENV GOPATH=/go
ENV PATH=$PATH:$GOPATH/bin
ENV CGO_CFLAGS="-I/opt/rocksdb/include"
ENV CGO_LDFLAGS="-L/opt/rocksdb -ldl -lrocksdb -lstdc++ -lm -lz -lbz2 -lsnappy -llz4 -lzstd"
# Static linkage: blockbook is linked against librocksdb.a + a static libzmq.a +
# the compression libs, then libstdc++/libgcc are pulled in statically. Only glibc
# and a few system libs remain dynamic. This removes the runtime dependency on a
# shared librocksdb / libzmq, so the RocksDB ABI/version can never mismatch at runtime.
# -Wl,-Bstatic ... -Wl,-Bdynamic brackets the libraries we want archived in;
# everything after -Bdynamic (pthread, dl, m, glibc) links dynamically as usual.
ENV CGO_CFLAGS="-I/opt/rocksdb/include -I/opt/libzmq/include -DZMQ_STATIC"
ENV CGO_LDFLAGS="-L/opt/rocksdb -L/opt/libzmq/src/.libs \
-Wl,-Bstatic -lrocksdb -lzmq -llz4 -lzstd -lz -lsnappy -lbz2 -lstdc++ \
-Wl,-Bdynamic -lm -lpthread -ldl \
-static-libgcc -static-libstdc++"
ARG TCMALLOC

RUN mkdir /build
Expand All @@ -43,11 +56,22 @@ RUN echo -n "GOPATH: " && echo $GOPATH

# install rocksdb
RUN cd /opt && git clone -b $ROCKSDB_VERSION --depth 1 https://github.com/facebook/rocksdb.git \
&& test "$(git -C /opt/rocksdb rev-parse HEAD)" = "ae8fb3e5000e46d8d4c9dbf3a36019c0aaceebff"
&& test "$(git -C /opt/rocksdb rev-parse HEAD)" = $ROCKSDB_COMMIT
RUN cd /opt/rocksdb && CFLAGS=-fPIC CXXFLAGS=-fPIC PORTABLE=$PORTABLE_ROCKSDB DISABLE_WARNING_AS_ERROR=1 make -j 4 release
RUN strip /opt/rocksdb/ldb /opt/rocksdb/sst_dump && \
cp /opt/rocksdb/ldb /opt/rocksdb/sst_dump /build

# install libzmq (static)
# The libzmq3-dev package only ships a shared library; to link zmq statically we build
# libzmq from source and keep the static archive at /opt/libzmq/src/.libs/libzmq.a.
# --without-libsodium keeps the dependency set minimal (blockbook uses plain tcp://).
RUN cd /opt && git clone -b $LIBZMQ_VERSION --depth 1 https://github.com/zeromq/libzmq.git \
&& test "$(git -C /opt/libzmq rev-parse HEAD)" = $LIBZMQ_COMMIT
RUN cd /opt/libzmq && ./autogen.sh && \
./configure --enable-static --disable-shared --without-libsodium \
--disable-Werror CFLAGS=-fPIC CXXFLAGS=-fPIC && \
make -j 4

# pre-load depencencies
RUN \
cleanup() { rm -rf $GOPATH/src/github.com/trezor ; } && \
Expand Down
10 changes: 7 additions & 3 deletions build/docker/bin/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,24 @@ SHELL = /bin/bash
VERSION ?= devel
GITCOMMIT ?= $(shell cd /src && git config --global --add safe.directory /src && git describe --always --dirty)
BUILDTIME = $(shell date --iso-8601=seconds)
LDFLAGS := -X github.com/trezor/blockbook/common.version=$(VERSION) -X github.com/trezor/blockbook/common.gitcommit=$(GITCOMMIT) -X github.com/trezor/blockbook/common.buildtime=$(BUILDTIME)
# Force the external (C) linker and pass the static C-runtime flags through to it, so
# libgcc/libstdc++ are linked statically alongside the static librocksdb.a / libzmq.a
# brought in by CGO_LDFLAGS (set in the Docker image). glibc stays dynamic.
EXTLDFLAGS := -static-libgcc -static-libstdc++
LDFLAGS := -X github.com/trezor/blockbook/common.version=$(VERSION) -X github.com/trezor/blockbook/common.gitcommit=$(GITCOMMIT) -X github.com/trezor/blockbook/common.buildtime=$(BUILDTIME) -linkmode external -extldflags "$(EXTLDFLAGS)"
BLOCKBOOK_BASE := $(GOPATH)/src/github.com/trezor
BLOCKBOOK_SRC := $(BLOCKBOOK_BASE)/blockbook
ARGS ?=

all: build tools

build: prepare-sources
cd $(BLOCKBOOK_SRC) && go build -o $(CURDIR)/blockbook -ldflags="-s -w $(LDFLAGS)" $(ARGS)
cd $(BLOCKBOOK_SRC) && go build -o $(CURDIR)/blockbook -ldflags='-s -w $(LDFLAGS)' $(ARGS)
cp $(CURDIR)/blockbook /out/blockbook
chown $(PACKAGER) /out/blockbook

build-debug: prepare-sources
cd $(BLOCKBOOK_SRC) && go build -o $(CURDIR)/blockbook -ldflags="$(LDFLAGS)" $(ARGS)
cd $(BLOCKBOOK_SRC) && go build -o $(CURDIR)/blockbook -ldflags='$(LDFLAGS)' $(ARGS)
cp $(CURDIR)/blockbook /out/blockbook
chown $(PACKAGER) /out/blockbook

Expand Down
Loading