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
72 changes: 72 additions & 0 deletions .github/workflows/imagebuild.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Build BitcoinCore tank image and push to DockerHub

on:
push:
branches:
- main

jobs:
detect-new-tags:
runs-on: ubuntu-latest
outputs:
new_tags: ${{ steps.diff.outputs.new_tags }}

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Detect new tags
id: diff
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
# Compare PR head against base branch
git fetch origin "${{ github.base_ref }}" --depth=1
DIFF_BASE="origin/${{ github.base_ref }}"
else
# Compare push against previous commit
DIFF_BASE="${{ github.event.before }}"
fi

new_tags=$(git diff --unified=0 "$DIFF_BASE" HEAD -- src/warnet/bitcoincore.tags \
| grep '^+[^+]' \
| sed 's/^+//')

echo "new_tags<<EOF" >> $GITHUB_OUTPUT
echo "$new_tags" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

build-images:
needs: detect-new-tags
if: needs.detect-new-tags.outputs.new_tags != ''
runs-on: ubuntu-latest

steps:
- name: Checkout repo
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push multi-platform images
run: |
for tag in ${{ needs.detect-new-tags.outputs.new_tags }}; do
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg REPO=bitcoin/bitcoin \
--build-arg COMMIT_SHA=v$tag \
--build-arg BUILD_ARGS='-DBUILD_TESTS=OFF -DBUILD_GUI=OFF -DBUILD_BENCH=OFF -DBUILD_UTIL=ON -DBUILD_FUZZ_BINARY=OFF -DWITH_ZMQ=ON' \
-t bitcoindevproject/bitcoin:$tag \
--file resources/images/bitcoin/Dockerfile.dev \
resources/images/bitcoin/ \
--push
done
23 changes: 19 additions & 4 deletions resources/images/bitcoin/Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,27 @@ FROM deps AS build
ENV BITCOIN_PREFIX=/opt/bitcoin
WORKDIR /build

# Assume $COMMIT_SHA is a git commit but if that fails, then
# assume it is a release tag that can be checked out
RUN set -ex \
&& cd /build \
&& git clone --depth 1 "https://github.com/${REPO}" \
&& cd bitcoin \
&& git fetch --depth 1 origin "$COMMIT_SHA" \
&& git checkout "$COMMIT_SHA" \
&& git init \
&& git remote add origin "https://github.com/${REPO}" \

# Try commit/branch first
&& if git fetch --depth 1 origin "$COMMIT_SHA:refs/temp/ref" 2>/dev/null; then \
REF=refs/temp/ref; \
else \

# Fallback: fetch tag explicitly into local refs
git fetch --depth 1 origin "refs/tags/$COMMIT_SHA:refs/tags/$COMMIT_SHA"; \
REF="refs/tags/$COMMIT_SHA"; \
fi \

# Resolve tag -> commit if needed
&& resolved=$(git rev-parse --verify "$REF^{commit}") \
&& git checkout "$resolved" \

&& git apply /tmp/isroutable.patch \
&& git apply /tmp/addrman.patch \
&& sed -i s:sys/fcntl.h:fcntl.h: src/compat/compat.h \
Expand Down
10 changes: 10 additions & 0 deletions src/warnet/bitcoincore.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
22.2
23.2
24.2
25.1
26.0
27.0
28.1
29.0
30.2
31.0
11 changes: 4 additions & 7 deletions src/warnet/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
from importlib.resources import files
from pathlib import Path

# Constants used throughout the project
# Storing as constants for now but we might want a more sophisticated config management
# at some point.
SUPPORTED_TAGS = ["29.0", "28.1", "27.0", "26.0", "25.1", "24.2", "23.2", "22.2"]
SUPPORTED_TAGS = []
tags_file_path = Path(__file__).with_name("bitcoincore.tags")
with tags_file_path.open() as f:
SUPPORTED_TAGS = [line.strip() for line in f if line.strip()][::-1]
DEFAULT_TAG = SUPPORTED_TAGS[0]
WEIGHTED_TAGS = [
tag for index, tag in enumerate(reversed(SUPPORTED_TAGS)) for _ in range(index + 1)
]

DEFAULT_NAMESPACE = "default"
LOGGING_NAMESPACE = "warnet-logging"
Expand Down
10 changes: 6 additions & 4 deletions src/warnet/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@ def image():
@click.option("--arches", required=False, type=str)
@click.option("--action", required=False, type=str, default="load")
def build(repo, commit_sha, tags, build_args, arches, action):
"""Build a Bitcoin Core Docker image with specified parameters.
"""Build a Bitcoin Core Docker image with specified parameters from specified commit or tag.

\b
Usage Examples:
# Build an image for Warnet repository
warnet image build --repo bitcoin/bitcoin --commit-sha d6db87165c6dc2123a759c79ec236ea1ed90c0e3 --tags bitcoindevproject/bitcoin:v29.0-rc2 --arches amd64,arm64,armhf --action push
# Build an image for local testing
warnet image build --repo bitcoin/bitcoin --commit-sha d6db87165c6dc2123a759c79ec236ea1ed90c0e3 --tags bitcoindevproject/bitcoin:v29.0-rc2 --action load
warnet image build --repo bitcoin/bitcoin --commit-sha d6db87165c6dc2123a759c79ec236ea1ed90c0e3 --tags bitcoindevproject/bitcoin:v29.0-rc2 --action push
# Build from a tag instead of commit hash
warnet image build --repo bitcoin/bitcoin --commit-sha v31.0 --tags bitcoindevproject/bitcoin:v31.0 --action push
# Build an image for local testing on arm64 only
warnet image build --repo bitcoin/bitcoin --commit-sha d6db87165c6dc2123a759c79ec236ea1ed90c0e3 --tags bitcoindevproject/bitcoin:v29.0-rc2 --arches arm64 --action load
"""
res = build_image(repo, commit_sha, tags, build_args, arches, action)
if not res:
Expand Down
9 changes: 2 additions & 7 deletions src/warnet/image_build.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import subprocess
from importlib.resources import files

ARCHES = ["amd64", "arm64", "armhf"]
ARCHES = ["amd64", "arm64"]

dockerfile_path = files("resources.images.bitcoin").joinpath("Dockerfile.dev")

Expand Down Expand Up @@ -29,15 +29,10 @@ def build_image(

build_arches = []
if not arches:
build_arches.append("amd64")
build_arches = ARCHES
else:
build_arches.extend(arches.split(","))

for arch in build_arches:
if arch not in ARCHES:
print(f"Error: {arch} is not a supported architecture")
return False

print(f"{repo=:}")
print(f"{commit_sha=:}")
print(f"{tags=:}")
Expand Down
Loading