fix(tests): Round 42 - Remove unused imports from servicemonitor_test.go #76
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docker Build and Push | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| tags: [ 'v*' ] | |
| pull_request: | |
| branches: [ main ] | |
| workflow_dispatch: | |
| inputs: | |
| platforms: | |
| description: 'Target platforms (comma-separated)' | |
| default: 'linux/amd64,linux/arm64' | |
| required: false | |
| push_images: | |
| description: 'Push images to registry' | |
| type: boolean | |
| default: true | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_PREFIX: ghcr.io/${{ github.repository_owner }} | |
| GO_VERSION: '1.22.10' | |
| COSIGN_EXPERIMENTAL: 1 | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| attestations: write | |
| jobs: | |
| # Build matrix for all components | |
| docker-build: | |
| name: Build Docker Images | |
| runs-on: ubuntu-24.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| component: | |
| - name: orchestrator | |
| dockerfile: deploy/docker/orchestrator/Dockerfile | |
| context: . | |
| - name: vnf-operator | |
| dockerfile: deploy/docker/vnf-operator/Dockerfile | |
| context: . | |
| - name: o2-client | |
| dockerfile: deploy/docker/o2-client/Dockerfile | |
| context: . | |
| - name: tn-manager | |
| dockerfile: deploy/docker/tn-manager/Dockerfile | |
| context: . | |
| - name: tn-agent | |
| dockerfile: deploy/docker/tn-agent/Dockerfile | |
| context: . | |
| - name: cn-dms | |
| dockerfile: deploy/docker/cn-dms/Dockerfile | |
| context: . | |
| - name: ran-dms | |
| dockerfile: deploy/docker/ran-dms/Dockerfile | |
| context: . | |
| outputs: | |
| image-digest: ${{ steps.build.outputs.digest }} | |
| image-tags: ${{ steps.meta.outputs.tags }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| with: | |
| driver-opts: | | |
| image=moby/buildkit:v0.17.1 | |
| network=host | |
| - name: Log in to Container Registry | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.IMAGE_PREFIX }}/oran-${{ matrix.component.name }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=semver,pattern={{major}} | |
| type=sha,prefix={{branch}}- | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| labels: | | |
| org.opencontainers.image.title=O-RAN Intent-MANO ${{ matrix.component.name }} | |
| org.opencontainers.image.description=${{ matrix.component.name }} component for O-RAN Intent-based MANO | |
| org.opencontainers.image.vendor=O-RAN Intent-MANO Project | |
| org.opencontainers.image.licenses=Apache-2.0 | |
| - name: Create Dockerfile if not exists | |
| run: | | |
| dockerfile_path="${{ matrix.component.dockerfile }}" | |
| context_path="${{ matrix.component.context }}" | |
| if [ ! -f "$dockerfile_path" ]; then | |
| echo "Creating Dockerfile for ${{ matrix.component.name }}" | |
| mkdir -p "$(dirname "$dockerfile_path")" | |
| cat > "$dockerfile_path" << 'EOF' | |
| # Multi-stage build for optimized image size | |
| FROM golang:1.22.10-alpine AS builder | |
| # Install system dependencies | |
| RUN apk add --no-cache git ca-certificates tzdata | |
| # Set working directory | |
| WORKDIR /app | |
| # Copy go mod files | |
| COPY go.mod go.sum ./ | |
| # Download dependencies | |
| RUN go mod download && go mod verify | |
| # Copy source code | |
| COPY . . | |
| # Build the binary with optimizations | |
| RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} \ | |
| go build -a -installsuffix cgo \ | |
| -ldflags='-w -s -extldflags "-static"' \ | |
| -o /usr/local/bin/app \ | |
| ./cmd/... | |
| # Final stage - minimal runtime image | |
| FROM scratch | |
| # Copy CA certificates from builder | |
| COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ | |
| # Copy timezone data | |
| COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo | |
| # Copy the binary | |
| COPY --from=builder /usr/local/bin/app /app | |
| # Add metadata | |
| LABEL org.opencontainers.image.title="O-RAN Intent-MANO ${{ matrix.component.name }}" | |
| LABEL org.opencontainers.image.description="${{ matrix.component.name }} component" | |
| # Expose common port (override in compose if needed) | |
| EXPOSE 8080 | |
| # Run as non-root user | |
| USER 65534:65534 | |
| ENTRYPOINT ["/app"] | |
| EOF | |
| echo "Created Dockerfile at $dockerfile_path" | |
| else | |
| echo "Dockerfile exists at $dockerfile_path" | |
| fi | |
| - name: Prepare build context | |
| run: | | |
| context_path="${{ matrix.component.context }}" | |
| # Ensure context directory exists | |
| mkdir -p "$context_path" | |
| # Copy common dependencies if needed | |
| if [ -f "go.work" ]; then | |
| cp go.work "$context_path/" || echo "Could not copy go.work" | |
| fi | |
| if [ -f "pkg/security/security.go" ] && [ ! -f "$context_path/pkg/security/security.go" ]; then | |
| mkdir -p "$context_path/pkg/security" | |
| cp -r pkg/security/* "$context_path/pkg/security/" || echo "Could not copy security package" | |
| fi | |
| - name: Build and push Docker image | |
| id: build | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: ${{ matrix.component.context }} | |
| file: ${{ matrix.component.dockerfile }} | |
| platforms: ${{ github.event.inputs.platforms || 'linux/amd64,linux/arm64' }} | |
| push: ${{ github.event_name != 'pull_request' && (github.event.inputs.push_images != 'false') }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha,scope=${{ matrix.component.name }} | |
| cache-to: type=gha,mode=max,scope=${{ matrix.component.name }} | |
| sbom: true | |
| provenance: true | |
| build-args: | | |
| BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} | |
| VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} | |
| REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} | |
| GO_VERSION=${{ env.GO_VERSION }} | |
| - name: Install cosign | |
| if: github.event_name != 'pull_request' | |
| uses: sigstore/cosign-installer@v3.7.0 | |
| with: | |
| cosign-release: 'v2.4.1' | |
| - name: Sign container images | |
| if: github.event_name != 'pull_request' | |
| env: | |
| COSIGN_EXPERIMENTAL: 1 | |
| run: | | |
| # Sign the container image | |
| echo "Signing container images..." | |
| echo "${{ steps.meta.outputs.tags }}" | while read tag; do | |
| if [ -n "$tag" ]; then | |
| echo "Signing $tag" | |
| cosign sign --yes "$tag@${{ steps.build.outputs.digest }}" || echo "Failed to sign $tag" | |
| fi | |
| done | |
| - name: Generate SBOM | |
| if: github.event_name != 'pull_request' | |
| run: | | |
| echo "SBOM generation completed during build process" | |
| echo "SBOM attestation available in registry metadata" | |
| - name: Create image summary | |
| run: | | |
| cat > image-summary-${{ matrix.component.name }}.json << EOF | |
| { | |
| "component": "${{ matrix.component.name }}", | |
| "tags": $(echo '${{ steps.meta.outputs.tags }}' | jq -R 'split("\n") | map(select(length > 0))'), | |
| "digest": "${{ steps.build.outputs.digest }}", | |
| "platforms": "${{ github.event.inputs.platforms || 'linux/amd64,linux/arm64' }}", | |
| "build_time": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", | |
| "pushed": ${{ github.event_name != 'pull_request' && (github.event.inputs.push_images != 'false') }}, | |
| "signed": ${{ github.event_name != 'pull_request' }}, | |
| "sbom_generated": true, | |
| "provenance_generated": true | |
| } | |
| EOF | |
| - name: Upload image summary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: image-summary-${{ matrix.component.name }} | |
| path: image-summary-${{ matrix.component.name }}.json | |
| retention-days: 30 | |
| # Security scanning of built images | |
| image-security-scan: | |
| name: Container Security Scan | |
| runs-on: ubuntu-24.04 | |
| needs: docker-build | |
| if: github.event_name != 'pull_request' | |
| timeout-minutes: 30 | |
| strategy: | |
| matrix: | |
| component: [orchestrator, vnf-operator, o2-client, tn-manager, tn-agent, cn-dms, ran-dms] | |
| steps: | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@0.28.0 | |
| with: | |
| image-ref: ${{ env.IMAGE_PREFIX }}/oran-${{ matrix.component }}:${{ github.sha }} | |
| format: 'sarif' | |
| output: 'trivy-${{ matrix.component }}.sarif' | |
| severity: 'CRITICAL,HIGH,MEDIUM' | |
| - name: Upload Trivy scan results | |
| uses: github/codeql-action/upload-sarif@v3 | |
| if: always() | |
| with: | |
| sarif_file: 'trivy-${{ matrix.component }}.sarif' | |
| category: 'trivy-${{ matrix.component }}' | |
| - name: Check for critical vulnerabilities | |
| run: | | |
| echo "Checking for critical vulnerabilities in ${{ matrix.component }}..." | |
| # Parse SARIF results for critical issues | |
| critical_count=$(jq '[.runs[]?.results[]? | select(.level == "error")] | length' trivy-${{ matrix.component }}.sarif 2>/dev/null || echo "0") | |
| high_count=$(jq '[.runs[]?.results[]? | select(.level == "warning")] | length' trivy-${{ matrix.component }}.sarif 2>/dev/null || echo "0") | |
| echo "Critical vulnerabilities: $critical_count" | |
| echo "High vulnerabilities: $high_count" | |
| # Create GitHub step summary | |
| echo "## Security Scan Results for ${{ matrix.component }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Critical**: $critical_count" >> $GITHUB_STEP_SUMMARY | |
| echo "- **High**: $high_count" >> $GITHUB_STEP_SUMMARY | |
| if [ "$critical_count" -gt "5" ]; then | |
| echo "ERROR: Too many critical vulnerabilities ($critical_count > 5)" | |
| echo "❌ **FAILED**: Too many critical vulnerabilities" >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| fi | |
| if [ "$high_count" -gt "20" ]; then | |
| echo "WARNING: High number of high-severity vulnerabilities: $high_count" | |
| echo "⚠️ **WARNING**: High number of vulnerabilities" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "✅ **PASSED**: Security scan within acceptable limits" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Generate security attestation | |
| if: github.event_name != 'pull_request' | |
| uses: actions/attest-build-provenance@v1 | |
| with: | |
| subject-name: ${{ env.IMAGE_PREFIX }}/oran-${{ matrix.component }} | |
| subject-digest: ${{ needs.docker-build.outputs.image-digest }} | |
| push-to-registry: true | |
| # Multi-arch manifest creation | |
| manifest: | |
| name: Create Multi-arch Manifests | |
| runs-on: ubuntu-24.04 | |
| needs: [docker-build, image-security-scan] | |
| if: github.event_name != 'pull_request' && (github.event.inputs.push_images != 'false') | |
| strategy: | |
| matrix: | |
| component: [orchestrator, vnf-operator, o2-client, tn-manager, tn-agent, cn-dms, ran-dms] | |
| steps: | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Create and push multi-arch manifest | |
| run: | | |
| component="${{ matrix.component }}" | |
| image_base="${{ env.IMAGE_PREFIX }}/oran-$component" | |
| # Create manifest for latest tag (if main branch) | |
| if [ "${{ github.ref }}" = "refs/heads/main" ]; then | |
| echo "Creating multi-arch manifest for latest tag..." | |
| docker manifest create "$image_base:latest" \ | |
| "$image_base:latest" \ | |
| --amend | |
| docker manifest push "$image_base:latest" | |
| fi | |
| # Create manifest for branch/tag | |
| if [ "${{ github.ref_type }}" = "tag" ]; then | |
| tag_name="${{ github.ref_name }}" | |
| echo "Creating multi-arch manifest for tag: $tag_name" | |
| docker manifest create "$image_base:$tag_name" \ | |
| "$image_base:$tag_name" \ | |
| --amend | |
| docker manifest push "$image_base:$tag_name" | |
| elif [ "${{ github.ref_type }}" = "branch" ]; then | |
| branch_name="${{ github.ref_name }}" | |
| echo "Creating multi-arch manifest for branch: $branch_name" | |
| docker manifest create "$image_base:$branch_name" \ | |
| "$image_base:$branch_name" \ | |
| --amend | |
| docker manifest push "$image_base:$branch_name" | |
| fi | |
| # Final summary and cleanup | |
| summary: | |
| name: Build Summary | |
| runs-on: ubuntu-24.04 | |
| needs: [docker-build, image-security-scan, manifest] | |
| if: always() | |
| steps: | |
| - name: Download all summaries | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: image-summary-* | |
| merge-multiple: true | |
| - name: Generate build report | |
| run: | | |
| echo "## Docker Build Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Images Built" >> $GITHUB_STEP_SUMMARY | |
| echo "| Component | Status | Platforms | Signed |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-----------|--------|-----------|--------|" >> $GITHUB_STEP_SUMMARY | |
| for summary_file in image-summary-*.json; do | |
| if [ -f "$summary_file" ]; then | |
| component=$(jq -r '.component' "$summary_file") | |
| pushed=$(jq -r '.pushed' "$summary_file") | |
| signed=$(jq -r '.signed' "$summary_file") | |
| platforms=$(jq -r '.platforms' "$summary_file") | |
| status="❌ Failed" | |
| if [ "$pushed" = "true" ]; then | |
| status="✅ Success" | |
| elif [ "${{ github.event_name }}" = "pull_request" ]; then | |
| status="🔍 Built (PR)" | |
| fi | |
| sign_status="❌" | |
| if [ "$signed" = "true" ]; then | |
| sign_status="✅" | |
| fi | |
| echo "| $component | $status | $platforms | $sign_status |" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| done | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Security Scan Results" >> $GITHUB_STEP_SUMMARY | |
| if [[ "${{ needs.image-security-scan.result }}" == "success" ]]; then | |
| echo "✅ All images passed security scanning" >> $GITHUB_STEP_SUMMARY | |
| elif [[ "${{ needs.image-security-scan.result }}" == "failure" ]]; then | |
| echo "❌ Some images failed security scanning" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "⏭️ Security scanning skipped" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Registry Information" >> $GITHUB_STEP_SUMMARY | |
| echo "- Registry: \`${{ env.REGISTRY }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- Namespace: \`${{ github.repository_owner }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- Tag Strategy: branch, tag, SHA, and latest" >> $GITHUB_STEP_SUMMARY |