diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..5136a38ec --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,207 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +env: + GOPATH: /home/runner/go + +jobs: + lint-and-format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + - name: Install lint tools + run: make install-golangci-lint install-controller-gen + - name: Format + run: | + make fmt + git diff --exit-code + - name: Vet + run: make vet + - name: Lint + run: make lint + + test: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + - name: Get Datadog credentials + id: dd-sts + uses: DataDog/dd-sts-action@main + with: + policy: chaos-controller + - name: Install tools + run: make -j4 install-controller-gen install-yamlfmt install-kubebuilder install-datadog-ci + - name: Run unit tests + run: make test GINKGO_PROCS=2 + env: + DATADOG_API_KEY: ${{ steps.dd-sts.outputs.api_key }} + - name: Upload code coverage + if: success() + run: datadog-ci coverage upload --format go-coverprofile --flags "type:unit-tests" cover.profile + env: + DATADOG_API_KEY: ${{ steps.dd-sts.outputs.api_key }} + - name: Upload test report + if: always() + uses: actions/upload-artifact@v4 + with: + name: report-test.xml + path: report-test.xml + + docker-build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + target: [injector, manager, handler] + steps: + - uses: actions/checkout@v2 + - name: Build ${{ matrix.target }} + run: make docker-build-${{ matrix.target }} SKIP_GENERATE=true + - name: Upload tarball + uses: actions/upload-artifact@v4 + with: + name: docker-${{ matrix.target }} + path: bin/${{ matrix.target }}/${{ matrix.target }}.tar.gz + retention-days: 1 + + e2e-test: + runs-on: ubuntu-latest + needs: docker-build + timeout-minutes: 45 + permissions: + id-token: write + contents: read + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + - name: Get Datadog credentials + id: dd-sts + uses: DataDog/dd-sts-action@main + with: + policy: chaos-controller + - name: Install tools + run: make -j6 install-controller-gen install-yamlfmt install-helm install-kubebuilder install-datadog-ci + - name: Download docker tarballs + uses: actions/download-artifact@v4 + with: + pattern: docker-* + merge-multiple: false + - name: Move tarballs into place + run: | + for target in injector manager handler; do + mkdir -p bin/${target} + mv docker-${target}/${target}.tar.gz bin/${target}/ + done + - name: Install Minikube + run: make ci-install-minikube MINIKUBE_CPUS=max MINIKUBE_MEMORY=max + - name: Install cert-manager + run: make lima-install-cert-manager KUBECTL="minikube kubectl --" + - name: Load images into Minikube + run: make minikube-load-all + - name: Run e2e tests + env: + DATADOG_API_KEY: ${{ steps.dd-sts.outputs.api_key }} + run: | + for attempt in 1 2 3; do + echo "=== Attempt ${attempt}/3 ===" + if make e2e-test KUBECTL="minikube kubectl --" E2E_TEST_CLUSTER_NAME="minikube" E2E_TEST_KUBECTL_CONTEXT="minikube"; then + exit 0 + fi + echo "Attempt ${attempt} failed" + done + echo "All 3 attempts failed" + exit 1 + - name: Save controller logs + if: failure() + run: | + mkdir -p /tmp/logs + minikube kubectl -- -n chaos-engineering logs -lapp=chaos-controller -c manager --tail=-1 > /tmp/logs/e2e.txt 2>&1 || true + - name: Upload controller logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: e2e-controller-logs + path: /tmp/logs + - name: Upload e2e test report + if: always() + uses: actions/upload-artifact@v4 + with: + name: report-e2e-test.xml + path: report-e2e-test.xml + + validate-codegen: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + - name: Install tools + run: make -j6 install-controller-gen install-yamlfmt install-mockery install-protobuf PROTOC_OS=linux + - name: Validate go dependencies + run: | + make godeps + git diff --exit-code + - name: Validate manifests + run: | + make manifests + git diff --exit-code + - name: Validate mocks + run: | + make generate-mocks + git diff --exit-code + - name: Validate disruptionlistener protobuf + run: | + make generate-disruptionlistener-protobuf + git diff --exit-code ':!go.*' + - name: Validate chaosdogfood protobuf + run: | + make generate-chaosdogfood-protobuf + git diff --exit-code ':!go.*' + + python-checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install Python dependencies + run: pip install -r tasks/requirements.txt + - name: Check third-party licenses + run: | + inv license-check + git diff --exit-code + - name: Check license headers + run: | + inv header-check + git diff --exit-code + + doc-spellcheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install markdown-spellcheck + run: npm install -g markdown-spellcheck + - name: Spellcheck + run: mdspell --report --en-us --ignore-numbers --ignore-acronyms $(find . -name vendor -prune -o -name '*.md' -print) || echo "please run 'make spellcheck' for local testing" diff --git a/Makefile b/Makefile index a8eb3d66c..4b3b5db53 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,8 @@ NOW_ISO8601 = $(shell date -u +"%Y-%m-%dT%H:%M:%S") GOOS = $(shell go env GOOS) GOARCH = $(shell go env GOARCH) -# change also circleci go build version "cimb/go:" if you change the version below -# https://github.com/DataDog/chaos-controller/blob/main/.circleci/config.yml#L85 +# change also github actions go build version "GO_VERSION:" if you change the version below +# https://github.com/DataDog/chaos-controller/blob/main/.github/workflows/ci.yml#L13 BUILDGOVERSION = 1.25.6 # GOBIN can be provided (gitlab), defined (custom user setup), or empty/guessed (default go setup) @@ -160,13 +160,15 @@ chaosli: GOOS=darwin GOARCH=$(GOARCH) CGO_ENABLED=0 go build -ldflags="-X github.com/DataDog/chaos-controller/cli/chaosli/cmd.Version=$(VERSION)" -o bin/chaosli/chaosli_darwin_$(GOARCH) ./cli/chaosli/ # https://onsi.github.io/ginkgo/#recommended-continuous-integration-configuration +GINKGO_PROCS ?= 4 + _ginkgo_test: # Run the test and write a file if succeed # Do not stop on any error -go run github.com/onsi/ginkgo/v2/ginkgo --fail-on-pending --keep-going --vv \ --cover --coverprofile=cover.profile --randomize-all \ --race --trace --json-report=report-$(GO_TEST_REPORT_NAME).json --junit-report=report-$(GO_TEST_REPORT_NAME).xml \ - --compilers=4 --procs=4 \ + --compilers=$(GINKGO_PROCS) --procs=$(GINKGO_PROCS) \ --poll-progress-after=10s --poll-progress-interval=10s \ $(GINKGO_TEST_ARGS) \ && touch report-$(GO_TEST_REPORT_NAME)-succeed @@ -224,11 +226,13 @@ spellcheck-format-spelling: sort < .spelling | sort | uniq | grep -v '^-' | tee .spelling.tmp > /dev/null && mv .spelling.tmp .spelling ## This target is dedicated for CI and aims to reuse the Kubernetes version defined here as the source of truth +MINIKUBE_CPUS ?= 6 +MINIKUBE_MEMORY ?= 28672 + ci-install-minikube: curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb sudo dpkg -i minikube_latest_amd64.deb -# adapt here according to circleCI VM resource_class https://circleci.com/docs/configuration-reference/#linuxvm-execution-environment - minikube start --cpus='6' --memory='28672' --vm-driver=docker --container-runtime=containerd --kubernetes-version=${KUBERNETES_VERSION} + minikube start --cpus='$(MINIKUBE_CPUS)' --memory='$(MINIKUBE_MEMORY)' --vm-driver=docker --container-runtime=containerd --kubernetes-version=${KUBERNETES_VERSION} minikube status SKIP_DEPLOY ?=