Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4fb7093
refactor: update docker-compose to use GitHub Container Registry images
RonTuretzky Sep 16, 2025
27e75a4
feat: add node key setup script and Docker documentation
RonTuretzky Sep 16, 2025
3fbace2
chore: deleting incomplete config
RonTuretzky Sep 16, 2025
dff8180
chore: delete
RonTuretzky Sep 16, 2025
fe8a329
chore: tracking to prevent hallucinations
RonTuretzky Sep 16, 2025
4e40714
chore: track working
RonTuretzky Sep 17, 2025
c6f1d8f
feat: implement hostname resolution for Docker service discovery
RonTuretzky Sep 17, 2025
0a328c5
refactor: address PR review comments
RonTuretzky Sep 17, 2025
960cf2e
feat: enable Docker image builds for pull requests
RonTuretzky Sep 22, 2025
208c77e
chore: fix clippy warnings and remove commonware-avs-node CI checks
RonTuretzky Sep 22, 2025
f1f525c
fix: allow clippy warnings from auto-generated and existing code
RonTuretzky Sep 22, 2025
8f530e5
revert: restore original format string in executor.rs
RonTuretzky Sep 22, 2025
b8293af
feat: add Docker Compose based CI workflow
RonTuretzky Sep 22, 2025
bccee8c
Merge remote-tracking branch 'origin/dev' into docker-compose-refactor
RonTuretzky Sep 22, 2025
75f2076
feat: add counter increment verification to docker-compose test
RonTuretzky Sep 22, 2025
7cf0bc1
fix: address PR review comments for docker-compose CI workflow
RonTuretzky Sep 22, 2025
2ad9397
fix: resolve CI failures for docker-compose test workflow
RonTuretzky Sep 22, 2025
b0a0ab4
chore: add support for RPC_URL secret and counter address validation
RonTuretzky Sep 22, 2025
f7c18b1
fix: address all PR review comments
RonTuretzky Sep 22, 2025
efc3192
chore: refactor nodes dir
RonTuretzky Sep 22, 2025
8c5037b
fix: address PR review comments for docker-compose CI workflow
RonTuretzky Sep 22, 2025
1ff74d2
fix: resolve CI failures for docker-compose test workflow
RonTuretzky Sep 22, 2025
553c374
fix: address PR review comments for docker-compose CI workflow
RonTuretzky Sep 22, 2025
f9658fe
fix: address PR review comments for docker-compose CI workflow
RonTuretzky Sep 22, 2025
fcedc8b
chore: remove old local-test.yml workflow
RonTuretzky Sep 22, 2025
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
256 changes: 256 additions & 0 deletions .github/workflows/docker-compose-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
name: Docker Compose Test

on:
push:
branches:
- main
- dev
pull_request:
branches:
- main
- dev

jobs:
docker-compose-test:
name: Test with Docker Compose
runs-on: ubuntu-latest

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

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

- name: Create .env file from example
run: |
cp example.env .env

# Set to LOCAL mode
sed -i 's|^ENVIRONMENT=.*|ENVIRONMENT=LOCAL|' .env

# Uncomment local RPC URLs
sed -i '/^# HTTP_RPC=http:\/\/localhost:8545/s/^# //' .env
sed -i '/^# WS_RPC=ws:\/\/localhost:8545/s/^# //' .env
sed -i '/^# RPC_URL=http:\/\/ethereum:8545/s/^# //' .env

# Set FORK_URL for local forking from repository secret or default to Holesky
if [ -n "${{ secrets.RPC_URL }}" ]; then
sed -i "s|^# FORK_URL=.*|FORK_URL=${{ secrets.RPC_URL }}|" .env
else
sed -i 's|^# FORK_URL=.*|FORK_URL=https://ethereum-holesky.publicnode.com|' .env
fi

# Uncomment Holesky testnet contract addresses (needed for LOCAL mode with fork)
sed -i 's/^#DELEGATION_MANAGER_ADDRESS=/DELEGATION_MANAGER_ADDRESS=/' .env
sed -i 's/^#STRATEGY_MANAGER_ADDRESS=/STRATEGY_MANAGER_ADDRESS=/' .env
sed -i 's/^#LST_CONTRACT_ADDRESS=/LST_CONTRACT_ADDRESS=/' .env
sed -i 's/^#LST_STRATEGY_ADDRESS=/LST_STRATEGY_ADDRESS=/' .env
sed -i 's/^#BLS_SIGNATURE_CHECKER_ADDRESS=/BLS_SIGNATURE_CHECKER_ADDRESS=/' .env
sed -i 's/^#OPERATOR_STATE_RETRIEVER_ADDRESS=/OPERATOR_STATE_RETRIEVER_ADDRESS=/' .env
sed -i 's/^#ALLOCATION_MANAGER_ADDRESS=/ALLOCATION_MANAGER_ADDRESS=/' .env

# Use default Anvil private key for testing
DEFAULT_ANVIL_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
sed -i "s|^PRIVATE_KEY=.*|PRIVATE_KEY=$DEFAULT_ANVIL_KEY|" .env
sed -i "s|^FUNDED_KEY=.*|FUNDED_KEY=$DEFAULT_ANVIL_KEY|" .env

- name: Build router image locally
run: |
docker build -t commonware-avs-router:debug-v2 .

- name: Pull required images
run: |
docker compose pull ethereum eigenlayer signer node-1 node-2 node-3

- name: Prepare for EigenLayer setup
run: |
# Create config.json from the example (required by eigenlayer service)
cp config/config.example.json config/config.json

echo "EigenLayer will generate BLS keys and deploy contracts..."

- name: Start services with docker-compose
run: |
docker compose up -d

- name: Wait for EigenLayer setup to complete
run: |
echo "Waiting for EigenLayer to complete setup..."
timeout=300
elapsed=0

while [ $elapsed -lt $timeout ]; do
# Check if the keys have been generated by EigenLayer
if [ -f ".nodes/operator_keys/testacc1.private.bls.key.json" ] &&
[ -f ".nodes/operator_keys/testacc2.private.bls.key.json" ] &&
[ -f ".nodes/operator_keys/testacc3.private.bls.key.json" ]; then
echo "✓ BLS keys generated by EigenLayer"

# Check if AVS deployment file exists
if [ -f ".nodes/avs_deploy.json" ]; then
echo "✓ AVS deployed"
echo "=== EigenLayer setup complete ==="
ls -la .nodes/
ls -la .nodes/operator_keys/
break
fi
fi

# Check if container exited with error
container_id=$(docker compose ps -q eigenlayer)
if [ -n "$container_id" ] && [ "$(docker inspect -f '{{.State.Status}}' $container_id 2>/dev/null)" = "exited" ]; then
exit_code=$(docker inspect -f '{{.State.ExitCode}}' $container_id)
if [ "$exit_code" != "0" ]; then
echo "EigenLayer container exited with error code: $exit_code"
docker compose logs eigenlayer --tail=50
exit 1
fi
fi

echo "Waiting for EigenLayer setup... ($elapsed/$timeout seconds)"
sleep 10
elapsed=$((elapsed + 10))
done

if [ $elapsed -ge $timeout ]; then
echo "Timeout waiting for EigenLayer setup"
docker compose logs eigenlayer --tail=50
exit 1
fi

# Check if nodes and router are still running
for service in node-1 node-2 node-3 router; do
if [ "$(docker compose ps $service --format json | jq -r ".State // empty")" != "running" ]; then
echo "Service $service is not running!"
docker compose logs $service --tail 50
exit 1
fi
done

- name: Run health checks
run: |
# Check Ethereum RPC
curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
|| (echo "Ethereum RPC not responding" && exit 1)

# Check if services are communicating (via logs)
echo "=== Router logs ==="
docker compose logs router --tail 20

echo "=== Node-1 logs ==="
docker compose logs node-1 --tail 20

- name: Verify services are running
run: |
# Check if all critical services are running
echo "Checking service status..."
docker compose ps

for service in node-1 node-2 node-3 router; do
if [ "$(docker compose ps $service --format json | jq -r ".State // empty")" != "running" ]; then
echo "Service $service is not running!"
docker compose logs $service --tail 50
exit 1
fi
done

echo "✓ All services are running"

- name: Test counter increment functionality
run: |
echo "Testing counter increment..."

# Wait for services to be fully ready
sleep 20

# Get the counter contract address from the deployment file
if [ ! -f ".nodes/avs_deploy.json" ]; then
echo "AVS deployment file not found"
exit 1
fi

COUNTER_ADDRESS=$(cat .nodes/avs_deploy.json | jq -r '.addresses.counter' || echo "")
if [ -z "$COUNTER_ADDRESS" ]; then
echo "Counter contract address not found in deployment file"
cat .nodes/avs_deploy.json
exit 1
fi
echo "Counter contract address: $COUNTER_ADDRESS"

# Read the initial counter value from the smart contract
# The function signature for "number()" is 0x8381f58a
INITIAL_COUNT=$(curl -s -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"eth_call",
"params":[{
"to":"'$COUNTER_ADDRESS'",
"data":"0x8381f58a"
}, "latest"],
"id":1
}' | jq -r '.result' | xargs printf "%d\n")

echo "Initial counter value: $INITIAL_COUNT"

# Wait for 5 aggregation cycles (30 seconds each by default = 150 seconds)
echo "Waiting for 5 aggregation cycles (150 seconds)..."
sleep 150

# Read the final counter value from the smart contract
FINAL_COUNT=$(curl -s -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"eth_call",
"params":[{
"to":"'$COUNTER_ADDRESS'",
"data":"0x8381f58a"
}, "latest"],
"id":1
}' | jq -r '.result' | xargs printf "%d\n")

echo "Final counter value: $FINAL_COUNT"

# Verify increment
if [ "$FINAL_COUNT" -gt "$INITIAL_COUNT" ]; then
echo "✓ Counter successfully incremented from $INITIAL_COUNT to $FINAL_COUNT"
else
echo "✗ Counter did not increment (still at $FINAL_COUNT)"
echo "=== Recent router logs ==="
docker compose logs router --tail 50
exit 1
fi


- name: Collect logs on failure
if: failure()
run: |
echo "=== Docker Compose Status ==="
docker compose ps -a

echo "=== Ethereum Logs ==="
docker compose logs ethereum --tail 50

echo "=== EigenLayer Logs ==="
docker compose logs eigenlayer --tail 100

echo "=== Router Logs ==="
docker compose logs router --tail 100

echo "=== Node-1 Logs ==="
docker compose logs node-1 --tail 100

echo "=== Node-2 Logs ==="
docker compose logs node-2 --tail 100

echo "=== Node-3 Logs ==="
docker compose logs node-3 --tail 100

- name: Cleanup
if: always()
run: |
docker compose down --volumes --remove-orphans
19 changes: 17 additions & 2 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ on:
- main
- dev
- staging
pull_request:
branches:
- main
- dev
release:
types: [created]

Expand Down Expand Up @@ -57,8 +61,19 @@ jobs:
shell: bash
run: |
SHORT_SHA="$(echo "${GITHUB_SHA}" | cut -c1-7)"
CHANNEL_TAG="${GITHUB_REF_NAME}"
[[ "${GITHUB_EVENT_NAME}" != "release" && "$CHANNEL_TAG" == "main" ]] && CHANNEL_TAG="latest"

# Handle different event types
if [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then
# For PRs, use pr-<number> as the tag
CHANNEL_TAG="pr-${{ github.event.pull_request.number }}"
elif [[ "${GITHUB_EVENT_NAME}" == "release" ]]; then
# For releases, use the release tag
CHANNEL_TAG="${GITHUB_REF_NAME}"
else
# For pushes to branches
CHANNEL_TAG="${GITHUB_REF_NAME}"
[[ "$CHANNEL_TAG" == "main" ]] && CHANNEL_TAG="latest"
fi

echo "short_sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT"
echo "channel_tag=${CHANNEL_TAG}" >> "$GITHUB_OUTPUT"
Expand Down
Loading
Loading