Skip to content

Add pixiu-admin CI test #7

Add pixiu-admin CI test

Add pixiu-admin CI test #7

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Pixiu-Admin CI
on:
push:
branches: [ main, develop ]
paths:
- 'admin/**'
- 'docker-compose.yml'
- '.github/workflows/pixiu-admin-ci.yml'
pull_request:
branches: [ main, develop ]
paths:
- 'admin/**'
- 'docker-compose.yml'
- '.github/workflows/pixiu-admin-ci.yml'
# cancel in-progress runs for the same branch or PR
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
# Build and test backend
backend-build:
name: Build Admin Backend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
cache: true
- name: Download dependencies
run: |
go mod download
go mod verify
- name: Build admin binary
run: |
go build -v -o pixiu-admin ./cmd/admin/admin.go
- name: Run Go tests
run: |
go test -v -race -coverprofile=coverage.out -covermode=atomic ./admin/...
- name: Upload coverage to Codecov
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4
with:
files: ./coverage.out
flags: admin-backend
name: admin-backend-coverage
# Build and test frontend
frontend-build:
name: Build Admin Frontend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Cache node modules
uses: actions/cache@v4
with:
path: |
admin/web/node_modules
~/.yarn
key: ${{ runner.os }}-yarn-${{ hashFiles('admin/web/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies
run: |
cd admin/web
yarn install --ignore-engines
- name: Run unit tests
run: |
cd admin/web
yarn test:unit
- name: Build frontend
run: |
cd admin/web
yarn build
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: frontend-dist
path: admin/web/dist/
retention-days: 7
# Docker Compose deployment test
docker-compose-test:
name: Docker Compose Deployment Test
runs-on: ubuntu-latest
needs: [backend-build, frontend-build]
steps:
- uses: actions/checkout@v5
- name: Check if docker-compose.yml exists
run: |
if [ ! -f docker-compose.yml ]; then
echo "⚠️ docker-compose.yml not found in root directory"
echo "Skipping docker-compose tests"
exit 0
fi
- name: Start services with docker-compose
run: |
# Start etcd and any other services defined in docker-compose
docker-compose up -d
- name: Wait for etcd to be ready
run: |
echo "Waiting for etcd to be ready..."
timeout 60 bash -c 'until docker ps | grep etcd | grep -q "Up"; do sleep 2; done'
# Test etcd health
sleep 10
curl -sf http://localhost:2379/health || exit 1
- name: Show running containers
run: |
echo "=== Running Docker Containers ==="
docker ps
- name: Show docker-compose services
if: always()
run: |
docker-compose ps || true
- name: Show service logs on failure
if: failure()
run: |
echo "=== Docker Compose Logs ==="
docker-compose logs || true
- name: Stop services
if: always()
run: |
docker-compose down -v
# Integration tests with database
# NOTE: These tests are temporarily marked as non-blocking because pixiu admin is not fully functional
integration-tests:
name: Integration Tests
runs-on: ubuntu-latest
needs: [backend-build]
continue-on-error: true # Allow CI to pass even if integration tests fail
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: pixiu
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
etcd:
image: quay.io/coreos/etcd:v3.6.1
env:
ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379
ETCD_ADVERTISE_CLIENT_URLS: http://localhost:2379
ports:
- 2379:2379
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
cache: true
- name: Initialize database
run: |
mysql -h 127.0.0.1 -u root -proot pixiu < admin/resources/sql/pixiu_demo.sql
- name: Create test config
run: |
cat > /tmp/test-config.yaml <<EOF
server:
address: "127.0.0.1:8081"
etcd:
address: "127.0.0.1:2379"
path: "/pixiu/config/api"
mysql:
username: "root"
password: "root"
host: "127.0.0.1"
port: "3306"
dbname: "pixiu"
EOF
- name: Test API operations
run: |
# Ensure cleanup on exit
cleanup() {
if [ -n "$ADMIN_PID" ]; then
kill $ADMIN_PID 2>/dev/null || true
fi
}
trap cleanup EXIT
# Start admin server in background
go run ./cmd/admin/admin.go -c /tmp/test-config.yaml &
ADMIN_PID=$!
# Wait for server to start
for i in {1..30}; do
if curl -sf http://localhost:8081/config/api/base >/dev/null 2>&1; then
echo "Admin server is ready"
break
fi
echo "Waiting for admin server... attempt $i/30"
sleep 2
done
# Test resource creation
cat > /tmp/resource.yaml <<'EOFRESOURCE'
path: '/test'
type: restful
description: test resource
EOFRESOURCE
curl -f -X POST http://localhost:8081/config/api/resource \
-H "Content-Type: multipart/form-data" \
-F "content=@/tmp/resource.yaml"
# Test resource list and validate response
RESPONSE=$(curl -sf http://localhost:8081/config/api/resource/list)
if [ -z "$RESPONSE" ]; then
echo "Error: Empty response from resource list endpoint"
exit 1
fi
echo "Resource list response: $RESPONSE"
# Manual deployment test (following README instructions)
# NOTE: Temporarily marked as non-blocking because pixiu admin is not fully functional
manual-deployment-test:
name: Manual Deployment Test
runs-on: ubuntu-latest
needs: [backend-build]
continue-on-error: true # Allow CI to pass even if this test fails
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
cache: true
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Start etcd service
run: |
docker run -d -p 2379:2379 \
--env ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 \
--env ETCD_ADVERTISE_CLIENT_URLS=http://localhost:2379 \
--name etcd \
quay.io/coreos/etcd:v3.6.1
- name: Wait for etcd to be ready
run: |
echo "Waiting for etcd..."
timeout 60 bash -c 'until curl -sf http://localhost:2379/health 2>/dev/null; do sleep 2; done'
echo "✅ Etcd is ready"
- name: Create test config file
run: |
mkdir -p /tmp/admin-test
cat > /tmp/admin-test/conf.yaml <<'EOF'
server:
address: "127.0.0.1:8081"
etcd:
address: "127.0.0.1:2379"
path: "/pixiu/config/api"
mysql:
username: "root"
password: "root"
host: "127.0.0.1"
port: "3306"
dbname: "pixiu"
zap:
level: "info"
format: "console"
prefix: "[PIXIU-ADMIN]"
director: "/tmp/logs"
linkName: "latest.log"
showLine: true
encodeLevel: "LowercaseColorLevelEncoder"
stacktraceKey: "stacktrace"
logInConsole: true
system:
env: "develop"
addr: 8081
dbType: "mysql"
EOF
- name: Build admin binary
run: |
go build -v -o /tmp/admin-test/pixiu-admin ./cmd/admin/admin.go
- name: Start admin service in background
run: |
cd /tmp/admin-test
mkdir -p /tmp/logs
nohup ./pixiu-admin -c conf.yaml > /tmp/logs/admin.log 2>&1 &
echo $! > /tmp/admin.pid
echo "Admin PID: $(cat /tmp/admin.pid)"
- name: Wait for admin service to be ready
run: |
echo "Waiting for admin service..."
for i in {1..30}; do
if curl -f http://localhost:8081/config/api/base 2>/dev/null; then
echo "✅ Admin service is ready"
exit 0
fi
echo "Attempt $i/30 - waiting..."
sleep 2
done
echo "❌ Admin service failed to start"
cat /tmp/logs/admin.log
exit 1
- name: Test admin API endpoints
run: |
echo "Testing base info endpoint..."
BASE_RESPONSE=$(curl -sf http://localhost:8081/config/api/base)
if [ -z "$BASE_RESPONSE" ]; then
echo "Error: Empty response from base endpoint"
exit 1
fi
echo "Base response: $BASE_RESPONSE"
echo -e "\nTesting resource list endpoint..."
RESOURCE_RESPONSE=$(curl -sf http://localhost:8081/config/api/resource/list)
if [ -z "$RESOURCE_RESPONSE" ]; then
echo "Error: Empty response from resource list endpoint"
exit 1
fi
echo "Resource list response: $RESOURCE_RESPONSE"
echo -e "\nTesting cluster list endpoint..."
CLUSTER_RESPONSE=$(curl -sf http://localhost:8081/config/api/cluster/list)
if [ -z "$CLUSTER_RESPONSE" ]; then
echo "Error: Empty response from cluster list endpoint"
exit 1
fi
echo "Cluster list response: $CLUSTER_RESPONSE"
echo -e "\nTesting listener list endpoint..."
LISTENER_RESPONSE=$(curl -sf http://localhost:8081/config/api/listener/list)
if [ -z "$LISTENER_RESPONSE" ]; then
echo "Error: Empty response from listener list endpoint"
exit 1
fi
echo "Listener list response: $LISTENER_RESPONSE"
- name: Build frontend
run: |
cd admin/web
yarn install
yarn build
- name: Verify frontend build output
run: |
ls -la admin/web/dist/
test -d admin/web/dist/ || exit 1
- name: Show logs on failure
if: failure()
run: |
echo "=== Admin Service Logs ==="
cat /tmp/logs/admin.log || echo "No logs found"
echo -e "\n=== Etcd Status ==="
docker logs etcd || echo "No etcd logs"
- name: Cleanup
if: always()
run: |
if [ -f /tmp/admin.pid ]; then
kill $(cat /tmp/admin.pid) || true
fi
docker stop etcd || true
docker rm etcd || true
# Security and code quality checks
code-quality:
name: Code Quality & Security
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
cache: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v8 # NOSONAR
with:
version: v2.4.0
args: ./admin/...
- name: Run gosec security scanner
run: |
go install github.com/securego/gosec/v2/cmd/gosec@latest
gosec -fmt=json -out=gosec-report.json ./admin/... || true
- name: Upload security report
uses: actions/upload-artifact@v4
if: always()
with:
name: gosec-report
path: gosec-report.json
- name: Check for SQL injection vulnerabilities
run: |
# Use gosec report to detect SQL injection issues (rules G20x)
if [ ! -f gosec-report.json ]; then
echo "gosec-report.json not found. Ensure 'Run gosec security scanner' step completed successfully."
exit 1
fi
if grep -q '"rule_id":"G20' gosec-report.json; then
echo "Potential SQL injection vulnerabilities detected by gosec (rules G20x)."
grep -n '"rule_id":"G20' gosec-report.json || true
exit 1
else
echo "No SQL injection vulnerabilities (G20x rules) detected by gosec."
fi
# Performance tests
# NOTE: Temporarily marked as non-blocking because pixiu admin is not fully functional
performance-tests:
name: Performance Tests
runs-on: ubuntu-latest
needs: [manual-deployment-test]
continue-on-error: true # Allow CI to pass even if performance tests fail
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version-file: 'go.mod'
cache: true
- name: Start etcd
run: |
docker run -d -p 2379:2379 \
--env ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 \
--env ETCD_ADVERTISE_CLIENT_URLS=http://localhost:2379 \
--name etcd \
quay.io/coreos/etcd:v3.6.1
sleep 10
- name: Build and start admin service
run: |
go build -o /tmp/pixiu-admin ./cmd/admin/admin.go
cat > /tmp/conf.yaml <<EOF
server:
address: "127.0.0.1:8081"
etcd:
address: "127.0.0.1:2379"
path: "/pixiu/config/api"
EOF
nohup /tmp/pixiu-admin -c /tmp/conf.yaml > /tmp/admin.log 2>&1 &
sleep 15
- name: Install Apache Bench
run: |
sudo apt-get update
sudo apt-get install -y apache2-utils
- name: Run load tests
run: |
echo "Testing base info endpoint..."
ab -n 100 -c 5 http://localhost:8081/config/api/base
echo -e "\nTesting resource list endpoint..."
ab -n 100 -c 5 http://localhost:8081/config/api/resource/list
- name: Cleanup
if: always()
run: |
pkill -f pixiu-admin || true
docker stop etcd || true
docker rm etcd || true
# Documentation check
docs-check:
name: Documentation Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Check API documentation exists
run: |
test -f admin/API.md || exit 1
test -f admin/API_CN.md || exit 1
test -f admin/README.md || exit 1
test -f admin/README_CN.md || exit 1
- name: Check Swagger documentation
run: |
test -f admin/doc/swagger.json || exit 1
test -f admin/doc/swagger.yaml || exit 1
- name: Verify API documentation completeness
run: |
# Check if all controller methods have Swagger annotations
cd admin
grep -r "@Tags\|@Summary\|@Router" controller/ | wc -l
# Final status check
ci-success:
name: CI Success
runs-on: ubuntu-latest
needs:
- backend-build
- frontend-build
- docker-compose-test
# Temporarily skip deployment/integration tests as pixiu admin is not fully functional
# - manual-deployment-test
# - integration-tests
# - performance-tests
- code-quality
- docs-check
steps:
- name: All tests passed
run: |
echo "✅ All Pixiu-Admin CI checks passed successfully!"