Skip to content

Commit 3fde7dc

Browse files
authored
Merge pull request #2067 from opentensor/feat/roman/improve-localnet-workflow
Improve docker-localnet workflow
2 parents f17472f + 68af1e8 commit 3fde7dc

File tree

5 files changed

+314
-41
lines changed

5 files changed

+314
-41
lines changed

.github/workflows/docker-localnet.yml

Lines changed: 115 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
workflow_dispatch:
77
inputs:
88
branch-or-tag:
9-
description: "Branch or tag to use for the Docker image tag and ref to checkout (optional)"
9+
description: "The branch or tag to use as the Docker image tag (optional)."
1010
required: false
1111
default: ""
1212
push:
@@ -15,7 +15,7 @@ on:
1515
- main
1616
- testnet
1717
- devnet
18-
18+
1919
concurrency:
2020
group: docker-localnet-${{ github.ref }}
2121
cancel-in-progress: true
@@ -27,29 +27,123 @@ permissions:
2727
security-events: write
2828

2929
jobs:
30-
publish:
31-
runs-on: SubtensorCI
32-
30+
setup:
31+
runs-on: ubuntu-latest
32+
outputs:
33+
tag: ${{ steps.vars.outputs.tag }}
34+
ref: ${{ steps.vars.outputs.ref }}
35+
latest_tag: ${{ steps.vars.outputs.latest_tag }}
3336
steps:
3437
- name: Determine Docker tag and ref
35-
id: tag
38+
id: vars
39+
run: |
40+
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
41+
echo "ref=${{ github.head_ref }}" >> $GITHUB_OUTPUT
42+
echo "tag=${{ github.base_ref }}" >> $GITHUB_OUTPUT
43+
else
44+
tag="${{ github.event.inputs.branch-or-tag || github.ref_name }}"
45+
echo "ref=${{ github.ref_name }}" >> $GITHUB_OUTPUT
46+
echo "tag=$tag" >> $GITHUB_OUTPUT
47+
fi
48+
49+
if [[ "$tag" != "devnet-ready" ]]; then
50+
echo "latest_tag=true" >> $GITHUB_OUTPUT
51+
else
52+
echo "latest_tag=false" >> $GITHUB_OUTPUT
53+
fi
54+
55+
# build artifacts for fast-runtime and non-fast-runtime
56+
artifacts:
57+
name: Node • ${{ matrix.runtime }} • ${{ matrix.platform.arch }}
58+
needs: setup
59+
strategy:
60+
matrix:
61+
platform:
62+
# triple names used `in scripts/install_prebuilt_binaries.sh` file
63+
- runner: [self-hosted, type-ccx33]
64+
triple: x86_64-unknown-linux-gnu
65+
arch: amd64
66+
- runner: [ubuntu-24.04-arm]
67+
triple: aarch64-unknown-linux-gnu
68+
arch: arm64
69+
70+
runtime: ["fast-runtime", "non-fast-runtime"]
71+
72+
runs-on: ${{ matrix.platform.runner }}
73+
74+
steps:
75+
- name: Checkout code
76+
uses: actions/checkout@v4
77+
with:
78+
ref: ${{ needs.setup.outputs.ref }}
79+
80+
- name: Install Rust + dependencies
81+
run: |
82+
chmod +x ./scripts/install_build_env.sh
83+
./scripts/install_build_env.sh
84+
85+
- name: Add Rust target triple
86+
run: |
87+
source "$HOME/.cargo/env"
88+
rustup target add ${{ matrix.platform.triple }}
89+
90+
- name: Patch limits for local run
91+
run: |
92+
chmod +x ./scripts/localnet_patch.sh
93+
./scripts/localnet_patch.sh
94+
95+
- name: Build binaries
3696
run: |
37-
branch_or_tag="${{ github.event.inputs.branch-or-tag || github.ref_name }}"
38-
echo "Determined branch or tag: $branch_or_tag"
39-
echo "tag=$branch_or_tag" >> $GITHUB_ENV
40-
echo "ref=$branch_or_tag" >> $GITHUB_ENV
41-
42-
# Check if this is a tagged release (not devnet-ready/devnet/testnet)
43-
if [[ "$branch_or_tag" != "devnet-ready" ]]; then
44-
echo "latest_tag=true" >> $GITHUB_ENV
97+
export PATH="$HOME/.cargo/bin:$PATH"
98+
export CARGO_BUILD_TARGET="${{ matrix.platform.triple }}"
99+
100+
if [ "${{ matrix.runtime }}" = "fast-runtime" ]; then
101+
./scripts/localnet.sh --build-only
45102
else
46-
echo "latest_tag=false" >> $GITHUB_ENV
103+
./scripts/localnet.sh False --build-only
47104
fi
48105
106+
# use `ci_target` name bc .dockerignore excludes `target`
107+
- name: Prepare artifacts for upload
108+
run: |
109+
RUNTIME="${{ matrix.runtime }}"
110+
TRIPLE="${{ matrix.platform.triple }}"
111+
112+
mkdir -p build/ci_target/${RUNTIME}/${TRIPLE}/release/
113+
cp -v target/${RUNTIME}/${TRIPLE}/release/node-subtensor \
114+
build/ci_target/${RUNTIME}/${TRIPLE}/release/
115+
116+
mkdir -p build/ci_target/${RUNTIME}/${TRIPLE}/release/wbuild/node-subtensor-runtime/
117+
cp -v target/${RUNTIME}/${TRIPLE}/release/wbuild/node-subtensor-runtime/node_subtensor_runtime.compact.compressed.wasm \
118+
build/ci_target/${RUNTIME}/${TRIPLE}/release/wbuild/node-subtensor-runtime/
119+
120+
- name: Upload artifact
121+
uses: actions/upload-artifact@v4
122+
with:
123+
name: binaries-${{ matrix.platform.triple }}-${{ matrix.runtime }}
124+
path: build/
125+
if-no-files-found: error
126+
127+
# Collect all artifacts and publish them to docker repo
128+
docker:
129+
needs: [setup, artifacts]
130+
runs-on: [self-hosted, type-ccx33]
131+
defaults:
132+
run:
133+
working-directory: ${{ github.workspace }}
134+
135+
steps:
49136
- name: Checkout code
50137
uses: actions/checkout@v4
51138
with:
52-
ref: ${{ env.ref }}
139+
ref: ${{ needs.setup.outputs.ref }}
140+
141+
- name: Download all binary artifacts
142+
uses: actions/download-artifact@v5
143+
with:
144+
pattern: binaries-*
145+
path: build/
146+
merge-multiple: true
53147

54148
- name: Show current Git branch
55149
run: |
@@ -71,20 +165,16 @@ jobs:
71165
username: ${{ github.actor }}
72166
password: ${{ secrets.GITHUB_TOKEN }}
73167

74-
- name: Patch non-fast-block node
75-
run: |
76-
chmod +x ./scripts/localnet_patch.sh
77-
./scripts/localnet_patch.sh
78-
79168
- name: Build and push Docker image
80169
uses: docker/build-push-action@v6
81170
with:
82171
context: .
83172
file: Dockerfile-localnet
173+
build-args: |
174+
BUILT_IN_CI="Boom shakalaka"
175+
84176
push: true
85177
platforms: linux/amd64,linux/arm64
86178
tags: |
87-
ghcr.io/${{ github.repository }}-localnet:${{ env.tag }}
88-
${{ env.latest_tag == 'true' && format('ghcr.io/{0}-localnet:latest', github.repository) || '' }}
89-
cache-from: type=gha
90-
cache-to: type=gha,mode=max
179+
ghcr.io/${{ github.repository }}-localnet:${{ needs.setup.outputs.tag }}
180+
${{ needs.setup.outputs.latest_tag == 'true' && format('ghcr.io/{0}-localnet:latest', github.repository) || '' }}

Dockerfile-localnet

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
ARG BASE_IMAGE=ubuntu:latest
22

33
FROM $BASE_IMAGE AS builder
4+
45
SHELL ["/bin/bash", "-c"]
56

67
# Set noninteractive mode for apt-get
@@ -12,29 +13,34 @@ LABEL ai.opentensor.image.authors="[email protected]" \
1213
ai.opentensor.image.description="Opentensor Subtensor Blockchain" \
1314
ai.opentensor.image.documentation="https://docs.bittensor.com"
1415

15-
# Set up Rust environment
16-
ENV RUST_BACKTRACE=1
17-
18-
RUN sed -i 's|http://archive.ubuntu.com/ubuntu|http://mirrors.edge.kernel.org/ubuntu|g' /etc/apt/sources.list
19-
RUN apt-get update
20-
RUN apt-get install -y curl build-essential protobuf-compiler clang git pkg-config libssl-dev llvm libudev-dev
21-
22-
# Copy entire repository
16+
# Copy repo first (you want this *before* RUN to enable layer cache reuse)
2317
COPY . /build
2418
WORKDIR /build
2519

26-
# Install Rust
27-
RUN set -o pipefail && curl https://sh.rustup.rs -sSf | sh -s -- -y
20+
# Set up env var
21+
ARG BUILT_IN_CI
22+
ARG TARGETARCH
23+
24+
ENV BUILT_IN_CI=${BUILT_IN_CI}
25+
ENV RUST_BACKTRACE=1
2826
ENV PATH="/root/.cargo/bin:${PATH}"
29-
RUN rustup toolchain install 1.88.0 --profile minimal
30-
RUN rustup default 1.88.0''
31-
RUN rustup target add wasm32v1-none
27+
28+
## Ubdate certificates
29+
RUN apt-get update && apt-get install -y ca-certificates
30+
31+
# Install requirements
32+
RUN chmod +x ./scripts/install_build_env.sh
33+
RUN ./scripts/install_build_env.sh
3234

3335
## Build fast-runtime node
3436
RUN ./scripts/localnet.sh --build-only
3537
# Build non-fast-runtime
3638
RUN ./scripts/localnet.sh False --build-only
3739

40+
# We will prepare the necessary binaries if they are created in CI
41+
RUN chmod +x ./scripts/install_prebuilt_binaries.sh
42+
RUN ./scripts/install_prebuilt_binaries.sh
43+
3844
# Verify the binaries was produced
3945
RUN test -e /build/target/fast-runtime/release/node-subtensor
4046
RUN test -e /build/target/non-fast-runtime/release/node-subtensor
@@ -57,7 +63,7 @@ RUN chmod +x /scripts/localnet.sh
5763
COPY --from=builder /build/target/fast-runtime/release/wbuild/node-subtensor-runtime/node_subtensor_runtime.compact.compressed.wasm target/fast-runtime/release/node_subtensor_runtime.compact.compressed.wasm
5864
COPY --from=builder /build/target/non-fast-runtime/release/wbuild/node-subtensor-runtime/node_subtensor_runtime.compact.compressed.wasm target/non-fast-runtime/release/node_subtensor_runtime.compact.compressed.wasm
5965

60-
## Ubdate certificates
66+
# Update certificates for next layer
6167
RUN apt-get update && apt-get install -y ca-certificates
6268

6369
# Do not build (just run)

scripts/install_build_env.sh

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/bin/bash
2+
3+
# If binaries are compiled in CI then skip this script
4+
if [ -n "$BUILT_IN_CI" ]; then
5+
echo "[*] BUILT_IN_CI is set to '$BUILT_IN_CI'. Skipping script..."
6+
exit 0
7+
fi
8+
9+
echo ""
10+
echo "######################################################################"
11+
echo "### Install build environment dependencies ###"
12+
echo "######################################################################"
13+
echo "### WARNING: DO NOT MODIFY THIS SCRIPT UNLESS YOU KNOW WHY! ###"
14+
echo "### ###"
15+
echo "### This script is used by: ###"
16+
echo "### • .github/workflows/docker-localnet.yml ###"
17+
echo "### • Dockerfile-localnet ###"
18+
echo "### ###"
19+
echo "### Any changes may break CI builds or local Docker environments. ###"
20+
echo "######################################################################"
21+
echo ""
22+
23+
set -e
24+
25+
echo "[*] Detecting platform..."
26+
UNAME_OUT="$(uname -s)"
27+
case "${UNAME_OUT}" in
28+
Linux*) OS=Linux;;
29+
Darwin*) OS=Mac;;
30+
*) OS="UNKNOWN:${UNAME_OUT}"
31+
esac
32+
33+
echo "[+] Platform: $OS"
34+
35+
# Determine if we have root privileges
36+
if [ "$(id -u)" -eq 0 ]; then
37+
SUDO=""
38+
else
39+
if command -v sudo &>/dev/null; then
40+
SUDO="sudo"
41+
else
42+
SUDO=""
43+
fi
44+
fi
45+
46+
# System Dependencies
47+
if [ "$OS" = "Linux" ]; then
48+
echo "[+] Installing dependencies on Linux..."
49+
50+
if [ -z "$SUDO" ] && [ "$(id -u)" -ne 0 ]; then
51+
echo "[!] Warning: No sudo and not root. Skipping apt install."
52+
else
53+
$SUDO sed -i 's|http://archive.ubuntu.com/ubuntu|http://mirrors.edge.kernel.org/ubuntu|g' /etc/apt/sources.list || true
54+
$SUDO apt-get update
55+
$SUDO apt-get install -y ca-certificates
56+
$SUDO apt-get install -y --no-install-recommends \
57+
curl build-essential protobuf-compiler clang git pkg-config libssl-dev llvm libudev-dev \
58+
gcc-aarch64-linux-gnu gcc-x86-64-linux-gnu
59+
fi
60+
61+
elif [ "$OS" = "Mac" ]; then
62+
echo "[+] Installing dependencies on macOS..."
63+
64+
if ! command -v brew &> /dev/null; then
65+
echo "[!] Homebrew not found. Installing..."
66+
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
67+
eval "$(/opt/homebrew/bin/brew shellenv)"
68+
fi
69+
70+
brew install protobuf openssl llvm pkg-config
71+
72+
LDFLAGS="-L$(brew --prefix openssl)/lib"
73+
export LDFLAGS
74+
75+
CPPFLAGS="-I$(brew --prefix openssl)/include"
76+
export CPPFLAGS
77+
78+
else
79+
echo "[!] Unsupported OS: $OS"
80+
exit 1
81+
fi
82+
83+
# Rust Toolchain
84+
85+
echo "[+] Installing Rust toolchain..."
86+
curl https://sh.rustup.rs -sSf | sh -s -- -y
87+
88+
# Activate rust in shell
89+
source "$HOME/.cargo/env" || export PATH="$HOME/.cargo/bin:$PATH"
90+
91+
rustup toolchain install 1.88.0 --profile minimal
92+
rustup default 1.88.0
93+
94+
# Add Rust Targets
95+
96+
echo "Adding Rust targets for wasm + cross-arch binaries..."
97+
rustup target add wasm32v1-none
98+
rustup target add aarch64-unknown-linux-gnu
99+
rustup target add x86_64-unknown-linux-gnu
100+
101+
echo "[✓] Environment setup complete."

0 commit comments

Comments
 (0)