Skip to content

Merge pull request #17 from thc1006/dependabot/go_modules/github.com/… #72

Merge pull request #17 from thc1006/dependabot/go_modules/github.com/…

Merge pull request #17 from thc1006/dependabot/go_modules/github.com/… #72

Workflow file for this run

name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
GO_VERSION: '1.24'
COVERAGE_THRESHOLD: 60
GOPROXY: https://proxy.golang.org,direct
GOSUMDB: sum.golang.org
jobs:
# =============================================================================
# Code Quality and Linting
# =============================================================================
lint:
name: Code Quality & Linting
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Go Environment
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
cache: true
- name: Cache Go Modules
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum', '**/go.mod') }}
restore-keys: |
${{ runner.os }}-go-${{ env.GO_VERSION }}-
${{ runner.os }}-go-
- name: Download Dependencies
run: go mod download && go mod verify
- name: Install golangci-lint
run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Run golangci-lint
run: |
golangci-lint run --timeout=10m --issues-exit-code=1 \
--out-format=github-actions \
--enable=gofmt,govet,ineffassign,misspell,revive,staticcheck,unused,gosimple
- name: Verify Go Formatting
run: |
if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then
echo "❌ Code is not properly formatted:"
gofmt -s -l .
exit 1
fi
echo "✅ All Go code is properly formatted"
- name: Run Go Vet
run: go vet ./...
- name: golangci-lint
run: golangci-lint run --timeout=5m
- name: govulncheck
run: govulncheck ./...
- name: golangci-lint
run: golangci-lint run --timeout=5m
- name: govulncheck
run: govulncheck ./...
# =============================================================================
# Test with Coverage Analysis
# =============================================================================
test:
name: Test & Coverage
runs-on: ubuntu-latest
needs: lint
services:
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
weaviate:
image: semitechnologies/weaviate:1.28.0
ports:
- 8080:8080
env:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
DEFAULT_VECTORIZER_MODULE: 'none'
ENABLE_MODULES: 'text2vec-openai,generative-openai'
CLUSTER_HOSTNAME: 'node1'
options: >-
--health-cmd="wget --no-verbose --tries=3 --spider http://localhost:8080/v1/.well-known/ready || exit 1"
--health-interval=30s
--health-timeout=10s
--health-retries=5
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Go Environment
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
cache: true
- name: Cache Go Modules and Build Cache
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum', '**/go.mod') }}
restore-keys: |
${{ runner.os }}-go-${{ env.GO_VERSION }}-
${{ runner.os }}-go-
- name: Download Dependencies
run: go mod download && go mod verify
- name: Install Test Dependencies
run: |
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
go install golang.org/x/tools/cmd/cover@latest
go install github.com/wadey/gocovmerge@latest
# Install test result parsing tools for better CI reporting
go install github.com/jstemmer/go-junit-report/v2@latest
- name: Setup Test Environment
run: |
setup-envtest use 1.29.0 --bin-dir ~/.local/bin
echo "KUBEBUILDER_ASSETS=~/.local/bin" >> $GITHUB_ENV
# Set optimal configuration for envtest
echo "USE_EXISTING_CLUSTER=false" >> $GITHUB_ENV
echo "ENVTEST_K8S_VERSION=1.29.0" >> $GITHUB_ENV
- name: Create Coverage Directory
run: mkdir -p coverage
- name: Run Tests with Race Detection and Coverage
env:
WEAVIATE_URL: http://localhost:8080
REDIS_URL: redis://localhost:6379
# Optimize for envtest parallel execution
GOMAXPROCS: 4
# Environment configuration for different test categories
TEST_CATEGORY: integration
run: |
echo "=== Running Tests with Coverage ==="
# Run tests with better output formatting and parallel execution
go test ./... \
-race \
-coverprofile=cover.out \
-covermode=atomic \
-timeout=15m \
-v \
-parallel=4 \
-json | tee test-results.json
echo "=== Test execution completed ==="
- name: Generate Test Reports
if: always()
run: |
echo "=== Generating Test Reports ==="
# Convert test results to JUnit format for better CI integration
if [ -f test-results.json ]; then
cat test-results.json | go-junit-report -set-exit-code > test-report.xml
fi
# Generate test summary
echo "## Test Execution Summary" > test-summary.md
if [ -f test-results.json ]; then
echo "**Test Results:** Available in test-results.json" >> test-summary.md
echo "**JUnit Report:** Available in test-report.xml" >> test-summary.md
fi
- name: Calculate Coverage Percentage
id: coverage
run: |
echo "=== Calculating Coverage Percentage ==="
# Generate coverage report
go tool cover -func=cover.out > coverage-report.txt
go tool cover -html=cover.out -o coverage-report.html
# Extract total coverage percentage
coverage_percent=$(go tool cover -func=cover.out | grep total: | awk '{print $3}' | sed 's/%//')
echo "Current coverage: ${coverage_percent}%"
echo "Threshold: ${{ env.COVERAGE_THRESHOLD }}%"
# Set outputs
echo "coverage_percent=${coverage_percent}" >> $GITHUB_OUTPUT
# Check if coverage meets threshold
if (( $(echo "${coverage_percent} >= ${{ env.COVERAGE_THRESHOLD }}" | bc -l) )); then
echo "✅ Coverage threshold met: ${coverage_percent}% >= ${{ env.COVERAGE_THRESHOLD }}%"
echo "coverage_passed=true" >> $GITHUB_OUTPUT
else
echo "❌ Coverage threshold not met: ${coverage_percent}% < ${{ env.COVERAGE_THRESHOLD }}%"
echo "coverage_passed=false" >> $GITHUB_OUTPUT
fi
- name: Display Coverage Report
run: |
echo "=== Coverage Report ==="
echo ""
echo "## 📊 Test Coverage Summary"
echo ""
echo "**Total Coverage:** ${{ steps.coverage.outputs.coverage_percent }}%"
echo "**Coverage Threshold:** ${{ env.COVERAGE_THRESHOLD }}%"
echo "**Status:** ${{ steps.coverage.outputs.coverage_passed == 'true' && '✅ PASSED' || '❌ FAILED' }}"
echo ""
echo "### Package Coverage Details"
echo '```'
head -20 coverage-report.txt
echo '```'
echo ""
echo "### Total Coverage"
echo '```'
tail -1 coverage-report.txt
echo '```'
- name: Generate Coverage Summary for PR
if: github.event_name == 'pull_request'
run: |
echo "## 📊 Test Coverage Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Total Coverage:** ${{ steps.coverage.outputs.coverage_percent }}%" >> $GITHUB_STEP_SUMMARY
echo "**Coverage Threshold:** ${{ env.COVERAGE_THRESHOLD }}%" >> $GITHUB_STEP_SUMMARY
echo "**Status:** ${{ steps.coverage.outputs.coverage_passed == 'true' && '✅ PASSED' || '❌ FAILED' }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Package Coverage Details" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
head -20 coverage-report.txt >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Total Coverage" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
tail -1 coverage-report.txt >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- name: Upload Coverage Artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-reports
path: |
cover.out
coverage-report.txt
coverage-report.html
test-results.json
test-report.xml
test-summary.md
retention-days: 30
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v4
if: always()
with:
file: cover.out
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
- name: Coverage Threshold Check
if: steps.coverage.outputs.coverage_passed == 'false'
run: |
echo "❌ Code coverage ${{ steps.coverage.outputs.coverage_percent }}% is below the required threshold of ${{ env.COVERAGE_THRESHOLD }}%"
echo ""
echo "Please add more tests to improve coverage. The following packages may need additional test coverage:"
echo ""
go tool cover -func=cover.out | awk '$3 < 60 {print "- " $1 ": " $3}'
echo ""
echo "Coverage report has been uploaded as an artifact for detailed analysis."
exit 1
# =============================================================================
# Security Scanning
# =============================================================================
security:
name: Security Scan
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Go Environment
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: Install Security Tools
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
go install github.com/securego/gosec/v2/cmd/gosec@latest
- name: Run Vulnerability Check
run: |
echo "=== Running Vulnerability Scan ==="
govulncheck ./...
- name: Run Security Analysis
run: |
echo "=== Running Security Analysis ==="
gosec -fmt=json -out=security-report.json ./... || true
- name: Upload Security Results
uses: actions/upload-artifact@v4
if: always()
with:
name: security-reports
path: security-report.json
retention-days: 30
# =============================================================================
# Build Verification
# =============================================================================
build:
name: Build Verification
runs-on: ubuntu-latest
needs: [test, security]
strategy:
fail-fast: false
matrix:
goos: [linux, darwin, windows]
goarch: [amd64]
include:
- goos: linux
goarch: arm64
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Go Environment
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: Cache Go Build Cache
uses: actions/cache@v4
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-${{ matrix.goos }}-${{ matrix.goarch }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-go-build-${{ matrix.goos }}-${{ matrix.goarch }}-
${{ runner.os }}-go-build-
- name: Build Binaries
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: 0
run: |
echo "=== Building for ${{ matrix.goos }}/${{ matrix.goarch }} ==="
# Create bin directory
mkdir -p bin/${{ matrix.goos }}_${{ matrix.goarch }}
# Build all main packages
for cmd in cmd/*/; do
if [ -f "${cmd}main.go" ]; then
cmd_name=$(basename "$cmd")
echo "Building ${cmd_name}..."
if [ "${{ matrix.goos }}" = "windows" ]; then
go build -ldflags="-s -w" -o "bin/${{ matrix.goos }}_${{ matrix.goarch }}/${cmd_name}.exe" "./${cmd}"
else
go build -ldflags="-s -w" -o "bin/${{ matrix.goos }}_${{ matrix.goarch }}/${cmd_name}" "./${cmd}"
fi
fi
done
echo "✅ Build completed successfully for ${{ matrix.goos }}/${{ matrix.goarch }}"
- name: Upload Build Artifacts
uses: actions/upload-artifact@v4
with:
name: binaries-${{ matrix.goos }}-${{ matrix.goarch }}
path: bin/${{ matrix.goos }}_${{ matrix.goarch }}/
retention-days: 7
# =============================================================================
# Final Status Check
# =============================================================================
ci-status:
name: CI Status Check
runs-on: ubuntu-latest
needs: [lint, test, security, build]
if: always()
steps:
- name: Check All Jobs Status
run: |
echo "=== CI Pipeline Status ==="
echo ""
echo "**Job Results:**"
echo "- Lint: ${{ needs.lint.result }}"
echo "- Test: ${{ needs.test.result }}"
echo "- Security: ${{ needs.security.result }}"
echo "- Build: ${{ needs.build.result }}"
echo ""
# Check if any critical job failed
if [ "${{ needs.lint.result }}" != "success" ] || [ "${{ needs.test.result }}" != "success" ]; then
echo "❌ Critical jobs failed. CI pipeline failed."
exit 1
fi
# Check if any job failed
if [ "${{ needs.security.result }}" != "success" ] || [ "${{ needs.build.result }}" != "success" ]; then
echo "⚠️ Some non-critical jobs failed, but core functionality is verified."
echo "Please review the failed jobs and address any issues."
else
echo "✅ All CI jobs completed successfully!"
fi
- name: Generate CI Summary
if: always()
run: |
echo "## 🔄 CI Pipeline Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Pipeline Status:** ${{ (needs.lint.result == 'success' && needs.test.result == 'success') && '✅ PASSED' || '❌ FAILED' }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Job Results" >> $GITHUB_STEP_SUMMARY
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Lint | ${{ needs.lint.result == 'success' && '✅ PASSED' || '❌ FAILED' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Test & Coverage | ${{ needs.test.result == 'success' && '✅ PASSED' || '❌ FAILED' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Security Scan | ${{ needs.security.result == 'success' && '✅ PASSED' || '❌ FAILED' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Build Verification | ${{ needs.build.result == 'success' && '✅ PASSED' || '❌ FAILED' }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Artifacts Generated" >> $GITHUB_STEP_SUMMARY
echo "- 📊 Coverage reports (HTML & text)" >> $GITHUB_STEP_SUMMARY
echo "- 🔒 Security scan results" >> $GITHUB_STEP_SUMMARY
echo "- 🏗️ Cross-platform binaries" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Commit:** \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**Branch:** \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "**Triggered by:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY