[Fix] NVMe-oF end-to-end: NQN, device discovery, stale nodes, port reset #15
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| checks: write | |
| security-events: write | |
| jobs: | |
| changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| outputs: | |
| go: ${{ steps.filter.outputs.go }} | |
| helm: ${{ steps.filter.outputs.helm }} | |
| docs: ${{ steps.filter.outputs.docs }} | |
| proto: ${{ steps.filter.outputs.proto }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| go: | |
| - '**/*.go' | |
| - 'go.mod' | |
| - 'go.sum' | |
| - '.golangci.yml' | |
| helm: | |
| - 'deploy/helm/**' | |
| - 'config/crd/**' | |
| docs: | |
| - 'docs/**' | |
| - 'mkdocs.yml' | |
| proto: | |
| - 'api/proto/**' | |
| lint: | |
| name: Lint | |
| needs: changes | |
| if: needs.changes.outputs.go == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Check formatting | |
| run: | | |
| unformatted=$(gofmt -l .) | |
| if [ -n "$unformatted" ]; then | |
| echo "::error::Files not formatted with gofmt:" | |
| echo "$unformatted" | |
| exit 1 | |
| fi | |
| - name: Run golangci-lint | |
| uses: golangci/golangci-lint-action@v6 | |
| with: | |
| version: v2.9.0 | |
| - name: Check go mod tidy | |
| run: | | |
| go mod tidy | |
| if ! git diff --quiet go.mod go.sum; then | |
| echo "::error::go.mod or go.sum is not tidy. Run 'go mod tidy' and commit." | |
| git diff go.mod go.sum | |
| exit 1 | |
| fi | |
| security: | |
| name: Security | |
| needs: changes | |
| if: needs.changes.outputs.go == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Run govulncheck | |
| run: | | |
| go install golang.org/x/vuln/cmd/govulncheck@latest | |
| govulncheck ./... | |
| - name: Run gitleaks | |
| uses: gitleaks/gitleaks-action@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| test: | |
| name: Test | |
| needs: changes | |
| if: needs.changes.outputs.go == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Run tests | |
| run: go test -v -race -coverprofile=coverage.out ./... | |
| - name: Upload coverage | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage | |
| path: coverage.out | |
| build: | |
| name: Build | |
| needs: changes | |
| if: needs.changes.outputs.go == 'true' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| binary: | |
| - controller | |
| - agent | |
| - meta | |
| - csi | |
| - filer | |
| - s3gw | |
| - cli | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Build binary | |
| env: | |
| BINARY_NAME: ${{ matrix.binary }} | |
| run: go build -o "bin/novastor-${BINARY_NAME}" "./cmd/${BINARY_NAME}/" | |
| integration-tests: | |
| name: Integration Tests | |
| needs: [changes, test] | |
| if: needs.changes.outputs.go == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Run integration tests | |
| run: make test-integration | |
| e2e-tests: | |
| name: E2E Tests | |
| needs: [changes, test] | |
| if: needs.changes.outputs.go == 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Run E2E tests | |
| run: go test -tags e2e -race -count=1 ./test/e2e/... | |
| helm-lint: | |
| name: Helm Lint | |
| needs: changes | |
| if: needs.changes.outputs.helm == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: azure/setup-helm@v4 | |
| - name: Lint Helm chart | |
| run: helm lint deploy/helm/novastor/ | |
| - name: Verify CRD sync | |
| run: | | |
| # Extract CRDs from Helm templates and compare with generated CRDs | |
| # First, check if templates/crds.yaml exists | |
| if [ ! -f "deploy/helm/novastor/templates/crds.yaml" ]; then | |
| echo "::error::deploy/helm/novastor/templates/crds.yaml not found" | |
| exit 1 | |
| fi | |
| # Extract raw CRD manifests from the Helm template (strip Helm templating) | |
| # We check that the CRD kinds and names match what's defined in api/v1alpha1 | |
| echo "Checking CRD definitions in Helm templates..." | |
| # List of expected CRDs based on api/v1alpha1/types.go | |
| EXPECTED_CRDS="StoragePool BlockVolume SharedFileSystem ObjectStore Snapshot" | |
| for crd in $EXPECTED_CRDS; do | |
| # Convert to plural lowercase for the resource name | |
| plural=$(echo "$crd" | sed 's/\([A-Z]\)/\L\1/g') | |
| # Check for the CRD kind in the templates | |
| if ! grep -q "kind: CustomResourceDefinition" deploy/helm/novastor/templates/crds.yaml; then | |
| echo "::error::No CustomResourceDefinition found in templates/crds.yaml" | |
| exit 1 | |
| fi | |
| if ! grep -q "kind: ${crd}$" deploy/helm/novastor/templates/crds.yaml 2>/dev/null; then | |
| echo "::warning::CRD kind '$crd' may not be properly defined in templates/crds.yaml" | |
| fi | |
| done | |
| echo "CRD verification completed successfully" | |
| proto-sync: | |
| name: Protobuf Sync | |
| needs: changes | |
| if: needs.changes.outputs.proto == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Install protoc | |
| uses: arduino/setup-protoc@v3 | |
| with: | |
| version: "25.x" | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Install Go protoc plugins | |
| run: | | |
| go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.35.1 | |
| go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.5.1 | |
| - name: Verify protobuf sync | |
| run: | | |
| # Store current state of generated files | |
| cp -r api/proto/chunk api/proto/chunk.before | |
| cp -r api/proto/metadata api/proto/metadata.before | |
| # Regenerate protobuf code | |
| make generate-proto | |
| # Check for differences | |
| if ! diff -r api/proto/chunk.before api/proto/chunk > /dev/null 2>&1; then | |
| echo "::error::Protobuf Go code in api/proto/chunk/ is out of sync with api/proto/chunk/chunk.proto" | |
| echo "Please run 'make generate-proto' and commit the changes." | |
| diff -r api/proto/chunk.before api/proto/chunk || true | |
| exit 1 | |
| fi | |
| if ! diff -r api/proto/metadata.before api/proto/metadata > /dev/null 2>&1; then | |
| echo "::error::Protobuf Go code in api/proto/metadata/ is out of sync with api/proto/metadata/metadata.proto" | |
| echo "Please run 'make generate-proto' and commit the changes." | |
| diff -r api/proto/metadata.before api/proto/metadata || true | |
| exit 1 | |
| fi | |
| echo "Protobuf files are in sync" | |
| docs-build: | |
| name: Docs Build | |
| needs: changes | |
| if: needs.changes.outputs.docs == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install MkDocs | |
| run: | | |
| pip install mkdocs-material \ | |
| mkdocs-git-revision-date-localized-plugin | |
| - name: Build docs | |
| run: mkdocs build --strict |