Skip to content

Commit c08eb40

Browse files
committed
fix last details
1 parent 9a855c6 commit c08eb40

File tree

8 files changed

+165
-89
lines changed

8 files changed

+165
-89
lines changed

.github/workflows/docker-workflow.yml

Lines changed: 97 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: Docker Build & Push All Services
22

33
on:
4+
delete:
45
push:
56
tags:
67
- "v*.*.*"
@@ -20,22 +21,6 @@ jobs:
2021
- name: 🧠 Discover components and services
2122
id: set-matrix
2223
run: |
23-
# Customize these lists as needed
24-
EXCLUDED_COMPONENTS=(core validator)
25-
EXCLUDED_SERVICES=()
26-
27-
should_exclude() {
28-
local item=$1
29-
shift
30-
local list=("$@")
31-
for ex in "${list[@]}"; do
32-
if [[ "$item" == "$ex" ]]; then
33-
return 0
34-
fi
35-
done
36-
return 1
37-
}
38-
3924
mkdir -p .build/tmp_matrix
4025
echo '{ "include": [' > .build/tmp_matrix/matrix.json
4126
FIRST=true
@@ -44,32 +29,15 @@ jobs:
4429
[ -d "$comp" ] || continue
4530
comp_name=$(basename "$comp")
4631
47-
# 🔥 Skip excluded components
48-
if should_exclude "$comp_name" "${EXCLUDED_COMPONENTS[@]}"; then
49-
echo "⏭️ Skipping excluded component: $comp_name"
50-
continue
51-
fi
52-
53-
for service in "$comp"/*; do
54-
[ -d "$service" ] || continue
55-
service_name=$(basename "$service")
56-
57-
# 🔥 Skip excluded services
58-
if should_exclude "$service_name" "${EXCLUDED_SERVICES[@]}"; then
59-
echo "⏭️ Skipping excluded service: $service_name"
60-
continue
32+
# ✅ Include only if it has a pyproject or version.py
33+
if [[ -f "$comp/pyproject.toml" || -f "$comp/version.py" ]]; then
34+
if [ "$FIRST" = true ]; then
35+
FIRST=false
36+
else
37+
echo "," >> .build/tmp_matrix/matrix.json
6138
fi
62-
63-
# ✅ Include only if it has a pyproject or version.py
64-
if [[ -f "$service/pyproject.toml" || -f "$service/version.py" ]]; then
65-
if [ "$FIRST" = true ]; then
66-
FIRST=false
67-
else
68-
echo "," >> .build/tmp_matrix/matrix.json
69-
fi
70-
echo " { \"component\": \"$comp_name\", \"service\": \"$service_name\" }" >> .build/tmp_matrix/matrix.json
71-
fi
72-
done
39+
echo " { \"component\": \"$comp_name\" }" >> .build/tmp_matrix/matrix.json
40+
fi
7341
done
7442
7543
echo "] }" >> .build/tmp_matrix/matrix.json
@@ -124,6 +92,7 @@ jobs:
12492
fi
12593
12694
build:
95+
if: github.event_name == 'push' || github.event_name == 'delete'
12796
needs: [discover, wheel-builder]
12897
runs-on: ubuntu-latest
12998
permissions:
@@ -166,30 +135,48 @@ jobs:
166135
- name: 🚀 Build and push version-tagged image (on tag push only)
167136
if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push'
168137
run: |
169-
COMP=${{ matrix.component }}
170-
SERVICE=${{ matrix.service }}
171-
IMAGE="subvortex/subvortex-$COMP-$SERVICE"
138+
COMP="${{ matrix.component }}"
139+
REPO_NAME="subvortex-${COMP//_/-}" && echo "$COMP"
140+
IMAGE="subvortex/$REPO_NAME"
172141
WHEEL_IMAGE="${{ needs.wheel-builder.outputs.tag }}"
173-
RAW_VERSION_TAG="${{ steps.taginfo.outputs.version_tag }}"
174-
VERSION_TAG="${RAW_VERSION_TAG#v}"
175-
DOCKERFILE="subvortex/$COMP/$SERVICE/Dockerfile"
142+
VERSION_TAG="${{ steps.taginfo.outputs.version_tag }}"
143+
VERSION="${VERSION_TAG#v}"
144+
DOCKERFILE="subvortex/$COMP/Dockerfile"
145+
146+
echo "🔍 Searching for component version... $COMP / $IMAGE"
147+
COMPONENT_PATH="subvortex/$COMP"
148+
if [ -f "$COMPONENT_PATH/pyproject.toml" ]; then
149+
echo "✅ Found pyproject.toml"
150+
COMPONENT_VERSION=$(grep -E '^version\s*=' "$COMPONENT_PATH/pyproject.toml" | head -1 | sed -E 's/version\s*=\s*"([^"]+)"/\1/')
151+
elif [ -f "$COMPONENT_PATH/version.py" ]; then
152+
echo "✅ Found version.py"
153+
COMPONENT_VERSION=$(python -c "import ast; f=open('$COMPONENT_PATH/version.py'); print([n.value.s for n in ast.walk(ast.parse(f.read())) if isinstance(n, ast.Assign) and n.targets[0].id == '__version__'][0])")
154+
else
155+
echo "❌ No version file found for component"
156+
exit 1
157+
fi
158+
159+
echo "🧾 Final versions:"
160+
echo "VERSION=$VERSION"
161+
echo "COMPONENT_VERSION=$COMPONENT_VERSION"
176162
177-
echo "🚀 Building image $IMAGE:$VERSION_TAG"
163+
echo "🚀 Building image $IMAGE:$VERSION"
178164
179165
docker buildx build \
180166
--squash \
181167
--platform linux/amd64,linux/arm64 \
182168
--build-context wheelbuilder=docker-image://$WHEEL_IMAGE \
183-
--build-arg VERSION=$VERSION_TAG \
184-
--build-arg COMPONENT_VERSION=$VERSION_TAG \
185-
--cache-from=type=gha,scope=wheels_${COMP}_${SERVICE}_${ARCH} \
186-
--cache-to=type=gha,mode=max,scope=wheels_${COMP}_${SERVICE}_${ARCH} \
187-
--tag $IMAGE:$VERSION_TAG \
169+
--build-arg VERSION=$VERSION \
170+
--build-arg COMPONENT_VERSION=$COMPONENT_VERSION \
171+
--cache-from=type=gha,scope=wheels_${COMP}_${ARCH} \
172+
--cache-to=type=gha,mode=max,scope=wheels_${COMP}_${ARCH} \
173+
--tag $IMAGE:$VERSION \
188174
--file $DOCKERFILE \
189175
--push \
190176
.
191177
192178
release:
179+
if: github.event_name == 'release'
193180
needs: [discover]
194181
runs-on: ubuntu-latest
195182
permissions:
@@ -232,11 +219,11 @@ jobs:
232219
- name: 🚀 Retag and push floating tags (on release or prerelease)
233220
if: github.event_name == 'release' && github.event.action != 'deleted'
234221
run: |
235-
COMP=${{ matrix.component }}
236-
SERVICE=${{ matrix.service }}
237-
IMAGE="subvortex/subvortex-$COMP-$SERVICE"
222+
COMP="${{ matrix.component }}"
223+
REPO_NAME="subvortex-${COMP//_/-}" && echo "$COMP"
224+
IMAGE="subvortex/$REPO_NAME"
238225
RAW_VERSION_TAG="${{ steps.taginfo.outputs.version_tag }}"
239-
VERSION_TAG="${RAW_VERSION_TAG#v}"
226+
VERSION="${RAW_VERSION_TAG#v}"
240227
FLOATING_TAGS="${{ steps.taginfo.outputs.floating_tags }}"
241228
IS_PRERELEASE=${{ github.event.release.prerelease }}
242229
IS_DRAFT=${{ github.event.release.draft }}
@@ -249,8 +236,8 @@ jobs:
249236
exit 0
250237
fi
251238

252-
echo "🔍 Getting manifest for $IMAGE:$VERSION_TAG"
253-
docker buildx imagetools inspect $IMAGE:$VERSION_TAG
239+
echo "🔍 Getting manifest for $IMAGE:$VERSION"
240+
docker buildx imagetools inspect $IMAGE:$VERSION
254241

255242
for TAG in $FLOATING_TAGS; do
256243
# Skip "latest" for prereleases
@@ -259,27 +246,26 @@ jobs:
259246
continue
260247
fi
261248

262-
echo "🔁 Creating manifest for $IMAGE:$TAG from $IMAGE:$VERSION_TAG"
249+
echo "🔁 Creating manifest for $IMAGE:$TAG from $IMAGE:$VERSION"
263250
docker buildx imagetools create \
264251
--tag $IMAGE:$TAG \
265-
$IMAGE:$VERSION_TAG
252+
$IMAGE:$VERSION
266253
done
267254

268255
- name: 🧹 Remove floating tags (on release or prerelease delete)
269256
if: github.event_name == 'release' && github.event.action == 'deleted'
270257
run: |
271-
COMP=${{ matrix.component }}
272-
SERVICE=${{ matrix.service }}
273-
IMAGE="subvortex/subvortex-$COMP-$SERVICE"
258+
COMP="${{ matrix.component }}"
259+
REPO_NAME="subvortex-${COMP//_/-}" && echo "$COMP"
260+
IMAGE="subvortex/$REPO_NAME"
274261
RAW_VERSION_TAG="${{ github.event.release.tag_name }}"
275-
VERSION_TAG="${RAW_VERSION_TAG#v}"
262+
VERSION="${RAW_VERSION_TAG#v}"
276263
FLOATING_TAGS="${{ steps.taginfo.outputs.floating_tags }}"
277264
USERNAME="${{ secrets.DOCKER_USERNAME }}"
278265
PASSWORD="${{ secrets.DOCKER_PASSWORD }}"
279-
REPO_NAME="subvortex-$COMP-$SERVICE"
280266
281-
echo "🗑️ Release deleted: $RAW_VERSION_TAG"
282-
echo "🔍 Attempting to delete floating tags: $FLOATING_TAGS"
267+
echo "🗑️ Release deleted: $VERSION"
268+
echo "🔍 Handling floating tags: $FLOATING_TAGS"
283269
284270
echo "🔐 Requesting Docker Hub JWT token..."
285271
TOKEN=$(curl -s -X POST https://hub.docker.com/v2/users/login/ \
@@ -291,18 +277,51 @@ jobs:
291277
exit 1
292278
fi
293279
280+
echo "📦 Fetching all tags from Docker Hub (excluding deleted tag: $VERSION)..."
281+
ALL_TAGS=$(curl -s -H "Authorization: JWT $TOKEN" \
282+
"https://hub.docker.com/v2/repositories/$USERNAME/$REPO_NAME/tags?page_size=100" | jq -r '.results[].name' | grep -v "^$VERSION$")
283+
284+
RELEASE_TAGS=$(echo "$ALL_TAGS" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' || true)
285+
PRERELEASE_TAGS=$(echo "$ALL_TAGS" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+-(alpha|rc)\.[0-9]+$' || true)
286+
294287
for TAG in $FLOATING_TAGS; do
295-
echo "❌ Deleting tag: $IMAGE:$TAG"
296-
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
297-
"https://hub.docker.com/v2/repositories/$USERNAME/$REPO_NAME/tags/$TAG/" \
298-
-H "Authorization: JWT $TOKEN")
299-
300-
if [ "$RESPONSE" = "204" ]; then
301-
echo "✅ Successfully deleted $IMAGE:$TAG"
302-
elif [ "$RESPONSE" = "404" ]; then
303-
echo "⚠️ Tag $TAG not found (already deleted or never pushed)"
288+
echo "🔁 Handling floating tag: $TAG"
289+
290+
case "$TAG" in
291+
dev)
292+
TARGET=$(echo "$PRERELEASE_TAGS" | grep 'alpha' | sort -Vr | head -n1)
293+
;;
294+
stage)
295+
TARGET=$(echo "$PRERELEASE_TAGS" | grep 'rc' | sort -Vr | head -n1)
296+
;;
297+
latest)
298+
TARGET=$(echo "$RELEASE_TAGS" | sort -Vr | head -n1)
299+
;;
300+
*)
301+
echo "⚠️ Unknown floating tag: $TAG"
302+
continue
303+
;;
304+
esac
305+
306+
if [ -n "$TARGET" ]; then
307+
echo "🔄 Re-pointing $TAG to $TARGET as multi-platform manifest"
308+
echo "$PASSWORD" | docker login -u "$USERNAME" --password-stdin
309+
docker buildx imagetools create \
310+
--tag "$IMAGE:$TAG" \
311+
"$IMAGE:$TARGET"
312+
docker logout
304313
else
305-
echo "❌ Failed to delete tag $TAG (HTTP $RESPONSE)"
314+
echo "🗑️ No matching version for $TAG. Deleting..."
315+
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
316+
"https://hub.docker.com/v2/repositories/$USERNAME/$REPO_NAME/tags/$TAG/" \
317+
-H "Authorization: JWT $TOKEN")
318+
if [ "$RESPONSE" = "204" ]; then
319+
echo "✅ Deleted $IMAGE:$TAG"
320+
elif [ "$RESPONSE" = "404" ]; then
321+
echo "⚠️ Tag $TAG not found"
322+
else
323+
echo "❌ Failed to delete $TAG (HTTP $RESPONSE)"
324+
fi
306325
fi
307326
done
308327

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,7 @@ ips_blocked.json
171171

172172
firewall-events.json
173173
.DS_Store
174-
DS_Store
174+
DS_Store
175+
176+
.build
177+
.secrets

docker-compose.local.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
services:
2+
auto_upgrader:
3+
build:
4+
context: ../../
5+
dockerfile: ./subvortex/auto_upgrader/Dockerfile
6+
additional_contexts:
7+
wheelbuilder: docker-image://subvortex/subvortex-wheel-builder:latest
8+
container_name: subvortex-auto-upgrader
9+
restart: unless-stopped
10+
env_file:
11+
- ./subvortex/auto_upgrader/.env
12+
volumes:
13+
- /var/log:/app/logs
14+
labels:
15+
- "com.centurylinklabs.watchtower.enable=true"
16+
17+
watchtower:
18+
image: containrrr/watchtower
19+
container_name: subvortex-watchtower
20+
volumes:
21+
- /var/run/docker.sock:/var/run/docker.sock
22+
command: --interval ${SUBVORTEX_CHECK_INTERVAL} --cleanup --label-enable
23+
restart: unless-stopped
24+
environment:
25+
- WATCHTOWER_CLEANUP=true
26+
- WATCHTOWER_LABEL_ENABLE=true
27+
- WATCHTOWER_INCLUDE_RESTARTING=true

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ include = ["subvortex", "subvortex.auto_upgrader"]
4848
"**/requirements.txt",
4949
"**/README.md",
5050
"**/env.template",
51+
"**/docker-compose.yml",
5152
]
5253

5354
[tool.setuptools.exclude-package-data]

subvortex/auto_upgrader/Dockerfile

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ LABEL auto_upgrader.version=$COMPONENT_VERSION
2727

2828
# ---------- Environment ----------
2929
ENV PYTHONUNBUFFERED=1
30+
ARG SUBVORTEX_EXECUTION_ROLE=miner
31+
ENV SV_EXECUTION_ROLE=${SUBVORTEX_EXECUTION_ROLE}
3032

3133
WORKDIR /app
3234

@@ -42,13 +44,14 @@ RUN pip install --no-cache-dir --find-links=/tmp/wheels -r requirements.txt \
4244
# 📁 Copy source code
4345
COPY ./pyproject.toml ./pyproject.toml
4446
COPY ./subvortex/pyproject.toml ./subvortex/pyproject.toml
45-
COPY ./subvortex/auto_upgrader/version.py ./subvortex/auto_upgrader/version.py
46-
COPY ./subvortex/miner/auto_upgrader/src ./subvortex/auto_upgrader/src
47-
COPY ./subvortex/miner/auto_upgrader/entrypoint.sh ./subvortex/auto_upgrader/entrypoint.sh
48-
COPY ./subvortex/miner/auto_upgrader/pyproject.toml ./subvortex/auto_upgrader/pyproject.toml
47+
COPY ./subvortex/version.py ./subvortex/version.py
48+
COPY ./subvortex/auto_upgrader/src ./subvortex/auto_upgrader/src
49+
COPY ./subvortex/auto_upgrader/entrypoint.sh ./subvortex/auto_upgrader/entrypoint.sh
50+
COPY ./subvortex/auto_upgrader/pyproject.toml ./subvortex/auto_upgrader/pyproject.toml
4951

5052
# 🧩 Install project (editable)
51-
RUN pip install -e . \
53+
RUN pip install "./subvortex/auto_upgrader[${SV_EXECUTION_ROLE}]" \
54+
&& pip install -e . \
5255
&& rm -rf ~/.cache/pip
5356

5457
ENTRYPOINT ["/bin/bash", "./subvortex/auto_upgrader/entrypoint.sh"]

subvortex/auto_upgrader/entrypoint.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ export $(grep -v '^#' .env | xargs)
77
ARGS=()
88
PREFIX="SUBVORTEX_"
99

10-
while IFS='=' read -r key value; do
10+
while IFS= read -r line; do
11+
key="${line%%=*}"
12+
value="${line#*=}"
1113
if [[ $key == ${PREFIX}* ]]; then
1214
key_suffix="${key#$PREFIX}"
1315
cli_key="--$(echo "$key_suffix" | tr '[:upper:]' '[:lower:]' | tr '_' '.')"

subvortex/core/Dockerfile.builder

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# syntax=docker/dockerfile:1.4
2+
3+
FROM python:3.11-slim AS builder
4+
5+
WORKDIR /build
6+
7+
# Install only necessary system libraries (minimal footprint)
8+
RUN apt-get update && \
9+
apt-get install -y --no-install-recommends \
10+
build-essential \
11+
curl \
12+
git \
13+
libssl-dev \
14+
libffi-dev \
15+
libpcap-dev \
16+
libnfnetlink-dev \
17+
libnetfilter-queue-dev \
18+
python3-dev \
19+
pkg-config && \
20+
curl https://sh.rustup.rs -sSf | sh -s -- -y --profile=minimal && \
21+
rm -rf /var/lib/apt/lists/*
22+
23+
ENV CFLAGS="-I/usr/include/libnetfilter_queue"
24+
ENV PATH="/root/.cargo/bin:$PATH"

subvortex/pyproject.toml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "subvortex"
7-
dynamic = ["version"]
7+
version = "0.0.1"
88
description = "SubVortex Auto Upgrader"
99
authors = [{ name = "Eclipse Vortex", email = "subvortex.bt@gmail.com" }]
1010
readme = "README.md"
@@ -29,9 +29,6 @@ classifiers = [
2929
[project.license]
3030
text = "MIT"
3131

32-
[tool.setuptools.dynamic]
33-
version = { attr = "subvortex.version.__version__" }
34-
3532
[tool.setuptools]
3633
include-package-data = true
3734

0 commit comments

Comments
 (0)