diff --git a/.circleci/config.yml b/.circleci/config.yml index 9e0cb37350242..93387cb790ef7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -43,7 +43,7 @@ commands: - persist_to_workspace: root: . paths: - - coverage.out + - test-results/coverage.out save_node_modules: steps: - persist_to_workspace: @@ -149,7 +149,7 @@ jobs: - run: make test-local - run: name: Uploading code coverage - command: bash <(curl -s https://codecov.io/bash) -f coverage.out + command: bash <(curl -s https://codecov.io/bash) -f test-results/coverage.out - run: name: Output of test-results command: | @@ -355,11 +355,11 @@ workflows: - ui: requires: - build - - sonarcloud: - context: SonarCloud - requires: - - test - - ui + # - sonarcloud: + # context: SonarCloud + # requires: + # - test + # - ui - e2e: requires: - build diff --git a/.github/workflows/ci-checks.yaml b/.github/workflows/ci-checks.yaml new file mode 100644 index 0000000000000..9855fbb6e8e88 --- /dev/null +++ b/.github/workflows/ci-checks.yaml @@ -0,0 +1,396 @@ +name: CI checks + +on: + push: + branches: + - 'master' + pull_request: + branches: + - 'master' + +env: + TEST_TOOLS_TAG: v0.2.0 + DOCKER_ARGS: null + +jobs: + ############################################################################# + # The build job is responsible for a complete build of all Go units in the + # codebase. It also ensures Gopkg.lock is up-to-date with Gopkg.toml and the + # dependencies. It sets up the vendor and build caches, so must be run before + # all other jobs. + ############################################################################# + build: + name: Build codebase + runs-on: ubuntu-latest + env: + GOPATH: ${{ github.workspace }} + DOCKER_ARGS: null + steps: + - name: Pull required images + run: docker pull argoproj/argocd-test-tools:$TEST_TOOLS_TAG + + - name: Checkout code + uses: actions/checkout@v2 + with: + path: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - run: mkdir -p $HOME/.cache/go-build + + - name: Restore dependency cache + uses: actions/cache@v1 + with: + path: ${{ github.workspace }}/src/github.com/argoproj/argo-cd/vendor + key: ${{ runner.os }}-go-dep-v2-${{ hashFiles('**/Gopkg.lock') }} + + - name: Ensure Gopkg.lock is in sync with Gopkg.toml + run: make dep-check + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Synchronize vendor dependencies + run: make dep + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Restore any build cache for this PR + uses: actions/cache@v1 + with: + path: /home/runner/.cache/go-build + key: ${{ runner.os }}-go-build-v2-${{ github.ref }} + + - name: Build the codebase + run: make build + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + codegen: + name: Run codegen + runs-on: ubuntu-latest + needs: + - build + + env: + GOPATH: /home/runner/work/argo-cd/argo-cd + DOCKER_ARGS: null + + steps: + - name: Pull required images + run: docker pull argoproj/argocd-test-tools:$TEST_TOOLS_TAG + + - name: Checkout code + uses: actions/checkout@v2 + with: + path: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Restore dependency cache + id: cache-dependencies + uses: actions/cache@v1 + with: + path: ${{ github.workspace }}/src/github.com/argoproj/argo-cd/vendor + key: ${{ runner.os }}-go-dep-v2-${{ hashFiles('**/Gopkg.lock') }} + + - name: Restore any build cache for this PR + id: cache-build-cache + uses: actions/cache@v1 + with: + path: /home/runner/.cache/go-build + key: ${{ runner.os }}-go-build-v2-${{ github.ref }} + + - name: Run codegen + run: make codegen + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Ensure nothing has changed + run: | + set -xo pipefail + # This makes sure you ran `make pre-commit` before you pushed. + # We exclude the Swagger resources; CircleCI doesn't generate them correctly. + # When this fails, it will, create a patch file you can apply locally to fix it. + # To troubleshoot builds: https://argoproj.github.io/argo-cd/developer-guide/ci/ + git diff --exit-code -- . ':!Gopkg.lock' ':!assets/swagger.json' | tee codegen.patch + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + test: + name: Run unit tests + runs-on: ubuntu-latest + needs: + - build + env: + GOPATH: ${{ github.workspace }} + DOCKER_ARGS: null + GOCACHE: /home/runner/.cache/go-build + + steps: + - name: Pull required images + run: docker pull argoproj/argocd-test-tools:$TEST_TOOLS_TAG + + - name: Checkout code + uses: actions/checkout@v2 + with: + path: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Switch to new branch + run: | + git switch -c temporal-pr-branch + git status + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Fetch complete history for blame information + run: | + git fetch --prune --no-tags --depth=1 origin +refs/heads/*:refs/remotes/origin/* + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Restore dependency cache + id: cache-dependencies + uses: actions/cache@v1 + with: + path: ${{ github.workspace }}/src/github.com/argoproj/argo-cd/vendor + key: ${{ runner.os }}-go-dep-v2-${{ hashFiles('**/Gopkg.lock') }} + + - name: Restore any build cache for this PR + id: cache-build-cache + uses: actions/cache@v1 + with: + path: ${{ env.GOCACHE }} + key: ${{ runner.os }}-go-build-v2-${{ github.ref }} + + - name: Show cache directory + run: ls -la + working-directory: ${{ env.GOCACHE }} + + - name: Run all unit tests + env: + ARGOCD_TEST_PARALLELISM: 8 + run: | + export PATH=$PATH:$GITHUB_WORKSPACE/src/github.com/argoproj/argo-cd/hack + make test + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Store coverage information + uses: actions/upload-artifact@v1 + with: + name: test-results + path: ${{ github.workspace }}/./src/github.com/argoproj/argo-cd/test-results + + sonarcloud: + name: Run sonarcloud analysis + needs: + - test + - ui + runs-on: ubuntu-latest + env: + GOPATH: /home/runner/work/argo-cd/argo-cd + DOCKER_ARGS: null + steps: + - name: Checkout code + uses: actions/checkout@v2 + with: + path: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + fetch-depth: 0 + + - name: Fetch complete history for blame information + run: | + git fetch --prune --no-tags origin +refs/heads/*:refs/remotes/origin/* + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Create test-results directory + run: mkdir -p $GITHUB_WORKSPACE/src/github.com/argoproj/argo-cd/test-results + + - name: Restore node dependency cache + id: cache-dependencies + uses: actions/cache@v1 + with: + path: ${{ github.workspace}}/src/github.com/argoproj/argo-cd/ui/node_modules + key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }} + + - name: Remove stray node configuration + run: | + rm -rf ui/node_modules/argo-ui/node_modules + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Restore Code coverage information + uses: actions/download-artifact@v1 + with: + name: test-results + path: ${{ github.workspace }}/src/github.com/argoproj/argo-cd/test-results + + - name: Run sonar-scanner + uses: jannfis/sonarcloud-github-action@master + with: + projectBaseDir: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + NODE_MODULES: ${{ github.workspace }}/src/github.com/argoproj/argo-cd/ui/node_modules + + lint: + needs: + - build + name: Lint codebase + runs-on: ubuntu-latest + env: + GOPATH: /home/runner/work/argo-cd/argo-cd + DOCKER_ARGS: null + steps: + - name: Pull required images + run: docker pull argoproj/argocd-test-tools:$TEST_TOOLS_TAG + + - name: Checkout code + uses: actions/checkout@v2 + with: + path: ${{ github.workspace}}/src/github.com/argoproj/argo-cd + + - name: Restore dependency cache + id: cache-dependencies + uses: actions/cache@v1 + with: + path: ${{ github.workspace}}/src/github.com/argoproj/argo-cd/vendor + key: ${{ runner.os }}-go-dep-v2-${{ hashFiles('**/Gopkg.lock') }} + + - name: Restore any build cache for this PR + id: cache-build-cache + uses: actions/cache@v1 + with: + path: /home/runner/.cache/go-build + key: ${{ runner.os }}-go-build-v2-${{ github.ref }} + + - name: Run golangci-lint + run: make lint ARGOCD_LINT_GOGC=100 + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Check that nothing has changed + run: | + gDiff=$(git diff) + if test "$gDiff" != ""; then + echo "################################################################################" + echo "golangci-lint has detected & fixed changes. Please fix them in your local repo," + echo "commit the changes and push them to re-trigger the check." + echo "################################################################################" + git diff + exit 1 + fi + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + test-e2e: + name: Run end-to-end tests + runs-on: ubuntu-latest + needs: + - build + env: + GOPATH: /home/runner/work/argo-cd/argo-cd + DOCKER_ARGS: null + ARGOCD_FAKE_IN_CLUSTER: "true" + ARGOCD_SSH_DATA_PATH: "/tmp/argo-e2e/app/config/ssh" + ARGOCD_TLS_DATA_PATH: "/tmp/argo-e2e/app/config/tls" + ARGOCD_E2E_K3S: "true" + ARGOCD_IN_CI: "true" + + steps: + - name: Pull required images + run: docker pull argoproj/argocd-test-tools:$TEST_TOOLS_TAG + + - name: Checkout code + uses: actions/checkout@v2 + with: + path: ${{ github.workspace}}/src/github.com/argoproj/argo-cd + + - name: Restore dependency cache + id: cache-dependencies + uses: actions/cache@v1 + with: + path: ${{ github.workspace}}/src/github.com/argoproj/argo-cd/vendor + key: ${{ runner.os }}-go-dep-v2-${{ hashFiles('**/Gopkg.lock') }} + + - name: Restore any build cache for this PR + id: cache-build-cache + uses: actions/cache@v1 + with: + path: /home/runner/.cache/go-build + key: ${{ runner.os }}-go-build-v2-${{ github.ref }} + + - name: Install K3S + env: + INSTALL_K3S_VERSION: v1.0.1 + run: | + set -x + curl -sfL https://get.k3s.io | sh - + sudo chmod -R a+rw /etc/rancher/k3s + sudo mkdir -p $HOME/.kube && sudo chown -R runner $HOME/.kube + sudo k3s kubectl config view --raw > $HOME/.kube/config + sudo chown runner $HOME/.kube/config + kubectl version + + - name: Get interface information + env: + IFACE: eth0 + run: | + set -x + ifconfig + ipaddr=$(ifconfig $IFACE |grep "inet " | awk '{print $2}') + if echo $ipaddr | grep -q 'addr:'; then + ipaddr=$(echo $ipaddr | awk -F ':' '{print $2}') + fi + echo "Using IPAddr '$ipaddr'" + test -d $HOME/.kube || mkdir -p $HOME/.kube + tempfile=$(mktemp) + kubectl config view --raw | sed -e "s/127.0.0.1:6443/${ipaddr}:6443/g" -e "s/localhost:6443/${ipaddr}:6443/g" > $tempfile + mv $tempfile $HOME/.kube/config + kubectl version + + - name: Run E2E server and wait for it being available + timeout-minutes: 30 + run: | + set -x + make start-e2e & + count=1 + until curl http://localhost:8080/healthz; do + sleep 10; + if test $count -ge 60; then + echo "Timeout" + exit 1 + fi + count=$((count+1)) + done + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Run E2E tests + timeout-minutes: 30 + env: + ARGOCD_OPTS: "--plaintext" + ARGOCD_E2E_K3S: "true" + DOCKER_ARGS: -t + DOCKER_SRCDIR: ${{ github.workspace }}/src + run: | + set -x + make test-e2e + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + ui: + runs-on: ubuntu-latest + name: Build & lint UI code + env: + DOCKER_SRCDIR: ${{ github.workspace }}/src + steps: + + - name: Pull required images + run: docker pull argoproj/argocd-test-tools:$TEST_TOOLS_TAG + + - name: Checkout code + uses: actions/checkout@v2 + with: + path: ${{ github.workspace}}/src/github.com/argoproj/argo-cd + + - name: Restore node dependency cache + id: cache-dependencies + uses: actions/cache@v1 + with: + path: ${{ github.workspace}}/src/github.com/argoproj/argo-cd/ui/node_modules + key: ${{ runner.os }}-node-dep-v2-${{ hashFiles('**/yarn.lock') }} + + - name: Update yarn dependencies + run: | + make dep-ui + if: steps.cache-dependencies.outputs.cache-hit != 'true' + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd + + - name: Test, build and lint UI code + run: | + make build-ui + working-directory: ${{ github.workspace }}/src/github.com/argoproj/argo-cd \ No newline at end of file diff --git a/Makefile b/Makefile index 5b925121c3ed4..6af9c520490be 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ GIT_COMMIT=$(shell git rev-parse HEAD) GIT_TAG=$(shell if [ -z "`git status --porcelain`" ]; then git describe --exact-match --tags HEAD 2>/dev/null; fi) GIT_TREE_STATE=$(shell if [ -z "`git status --porcelain`" ]; then echo "clean" ; else echo "dirty"; fi) PACKR_CMD=$(shell if [ "`which packr`" ]; then echo "packr"; else echo "go run vendor/github.com/gobuffalo/packr/packr/main.go"; fi) -VOLUME_MOUNT=$(shell if test "$(go env GOOS)"=="darwin"; then echo ":delegated"; elif test selinuxenabled; then echo ":Z"; else echo ""; fi) +VOLUME_MOUNT=$(shell if test "$(go env GOOS)" = "darwin"; then echo ":delegated"; elif test selinuxenabled; then echo ":Z"; else echo ""; fi) GOPATH?=$(shell if test -x `which go`; then go env GOPATH; else echo "$(HOME)/go"; fi) GOCACHE?=$(HOME)/.cache/go-build @@ -17,6 +17,9 @@ GOCACHE?=$(HOME)/.cache/go-build DOCKER_SRCDIR?=$(GOPATH)/src DOCKER_WORKDIR?=/go/src/github.com/argoproj/argo-cd +# DOCKER_ARGS should be unset when running from a non-pty device, i.e. CI +DOCKER_ARGS?=-it + ARGOCD_PROCFILE?=Procfile # Configuration for building argocd-test-tools image @@ -39,11 +42,13 @@ ARGOCD_IN_CI?=false ARGOCD_TEST_E2E?=true ARGOCD_LINT_GOGC?=20 +ARGOCD_TEST_PARALLELISM?= +ARGOCD_TEST_VERBOSE?=true # Runs any command in the argocd-test-utils container in server mode # Server mode container will start with uid 0 and drop privileges during runtime define run-in-test-server - docker run --rm -it \ + docker run --rm $(DOCKER_ARGS) \ --name argocd-test-server \ -e USER_ID=$(shell id -u) \ -e HOME=/home/user \ @@ -65,7 +70,7 @@ endef # Runs any command in the argocd-test-utils container in client mode define run-in-test-client - docker run --rm -it \ + docker run --rm $(DOCKER_ARGS) \ --name argocd-test-client \ -u $(shell id -u) \ -e HOME=/home/user \ @@ -73,6 +78,8 @@ define run-in-test-client -e ARGOCD_E2E_K3S=$(ARGOCD_E2E_K3S) \ -e GOCACHE=/tmp/go-build-cache \ -e ARGOCD_LINT_GOGC=$(ARGOCD_LINT_GOGC) \ + -e ARGOCD_TEST_PARALLELISM=$(ARGOCD_TEST_PARALLELISM) \ + -e ARGOCD_TEST_VERBOSE=$(ARGOCD_TEST_VERBOSE) \ -v ${DOCKER_SRCDIR}:/go/src${VOLUME_MOUNT} \ -v ${GOCACHE}:/tmp/go-build-cache${VOLUME_MOUNT} \ -v ${HOME}/.kube:/home/user/.kube${VOLUME_MOUNT} \ @@ -84,7 +91,7 @@ endef # define exec-in-test-server - docker exec -it -u $(shell id -u) -e ARGOCD_E2E_K3S=$(ARGOCD_E2E_K3S) argocd-test-server $(1) + docker exec $(DOCKER_ARGS) -u $(shell id -u) -e ARGOCD_E2E_K3S=$(ARGOCD_E2E_K3S) argocd-test-server $(1) endef PATH:=$(PATH):$(PWD)/hack @@ -259,7 +266,7 @@ dep-ensure-local: # Runs dep check in a container to ensure Gopkg.lock is up-to-date with dependencies .PHONY: dep-check dep-check: - $(call run-in-test-client,make dep-check-local) + $(call run-in-test-client,pwd && ls -la && make dep-check-local) # Runs dep check locally to ensure Gopkg.lock is up-to-date with dependencies .PHONY: dep-check-local @@ -296,7 +303,7 @@ lint-ui-local: .PHONY: build build: mkdir -p $(GOCACHE) - $(call run-in-test-client, make build-local) + $(call run-in-test-client,make build-local) # Build all Go code (local version) .PHONY: build-local @@ -316,9 +323,9 @@ test: .PHONY: test-local test-local: if test "$(TEST_MODULE)" = ""; then \ - ./hack/test.sh -coverprofile=coverage.out `go list ./... | grep -v 'test/e2e'`; \ + ./hack/test.sh -coverprofile=test-results/coverage.out `go list ./... | grep -v 'test/e2e'`; \ else \ - ./hack/test.sh -coverprofile=coverage.out "$(TEST_MODULE)"; \ + ./hack/test.sh -coverprofile=test-results/coverage.out "$(TEST_MODULE)"; \ fi # Run the E2E test suite. E2E test servers (see start-e2e target) must be @@ -331,7 +338,7 @@ test-e2e: .PHONY: test-e2e-local test-e2e-local: cli # NO_PROXY ensures all tests don't go out through a proxy if one is configured on the test system - NO_PROXY=* ./hack/test.sh -timeout 15m -v ./test/e2e + NO_PROXY=* ./hack/test.sh -timeout 15m -v -p 1 ./test/e2e # Spawns a shell in the test server container for debugging purposes debug-test-server: @@ -452,5 +459,16 @@ install-tools-local: dep-ui: $(call run-in-test-client,make dep-ui-local) +.PHONY: dep-ui-local dep-ui-local: - cd ui && yarn install + cd ui && yarn install --frozen-lockfile --ignore-optional --non-interactive + +.PHONY: build-ui +build-ui: + $(call run-in-test-client,make build-ui-local) + +.PHONY: build-ui-local +build-ui-local: + cd ui && yarn test + cd ui && NODE_ENV='production' yarn build + cd ui && yarn lint \ No newline at end of file diff --git a/sonar-project.properties b/sonar-project.properties index e8a64fa8b002e..365f489628636 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -13,6 +13,8 @@ sonar.sourceEncoding=UTF-8 sonar.host.url=https://sonarcloud.io +sonar.go.coverage.reportPaths=test-results/coverage.out + # Exclude following set of patterns from coverage analysis sonar.coverage.exclusions=**/*.pb.go,**/*.pb.gw.go,**/mocks/**,**/*.ts*,**/vendor/**,**/openapi_generated.go,**/*_test.go,**/*_generated*,test/**,pkg/client/**,pkg/apiclient/** diff --git a/test/e2e/app_management_test.go b/test/e2e/app_management_test.go index d49c3b769b9a2..c4e71e52d7d6b 100644 --- a/test/e2e/app_management_test.go +++ b/test/e2e/app_management_test.go @@ -495,6 +495,11 @@ func TestConfigMap(t *testing.T) { func TestFailedConversion(t *testing.T) { + // k3s does not validate at all, so this test does not work + if os.Getenv("ARGOCD_E2E_K3S") == "true" { + t.SkipNow() + } + defer func() { FailOnErr(Run("", "kubectl", "delete", "apiservice", "v1beta1.metrics.k8s.io")) }() diff --git a/test/e2e/fixture/app/consequences.go b/test/e2e/fixture/app/consequences.go index dddfc104553d9..fc0aa4e968090 100644 --- a/test/e2e/fixture/app/consequences.go +++ b/test/e2e/fixture/app/consequences.go @@ -22,7 +22,7 @@ func (c *Consequences) Expect(e Expectation) *Consequences { c.context.t.Helper() var message string var state state - timeout := time.Duration(15) * time.Second + timeout := time.Duration(30) * time.Second for start := time.Now(); time.Since(start) < timeout; time.Sleep(3 * time.Second) { state, message = e(c) switch state { diff --git a/test/e2e/fixture/app/context.go b/test/e2e/fixture/app/context.go index 019f42671a8fe..dd6468254ccdc 100644 --- a/test/e2e/fixture/app/context.go +++ b/test/e2e/fixture/app/context.go @@ -39,7 +39,7 @@ type Context struct { func Given(t *testing.T) *Context { fixture.EnsureCleanState(t) - return &Context{t: t, destServer: KubernetesInternalAPIServerAddr, repoURLType: fixture.RepoURLTypeFile, name: fixture.Name(), timeout: 10, project: "default", prune: true} + return &Context{t: t, destServer: KubernetesInternalAPIServerAddr, repoURLType: fixture.RepoURLTypeFile, name: fixture.Name(), timeout: 30, project: "default", prune: true} } func (c *Context) CustomCACertAdded() *Context {