diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c50e392c5..84c9638c76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,8 @@ on: - 'examples/**' - 'examples-of-custom-resources/**' - '**.md' + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' pull_request: branches: - master @@ -29,11 +31,9 @@ defaults: shell: bash env: - DOCKER_BUILDKIT: 1 K8S_VERSION: 1.22.1 K8S_TIMEOUT: 75s HELM_CHART_DIR: deployments/helm-chart - HELM_CHART_VERSION: 0.0.0-edge GIT_NAME: NGINX Kubernetes Team GIT_MAIL: kubernetes@nginx.com @@ -43,7 +43,6 @@ jobs: name: Checks and variables runs-on: ubuntu-20.04 outputs: - sha_short: ${{ steps.vars.outputs.sha }} go_version: ${{ steps.vars.outputs.go_version }} go_path: ${{ steps.go.outputs.go_path }} steps: @@ -56,7 +55,6 @@ jobs: - name: Output Variables id: vars run: | - echo "::set-output name=sha::$(echo ${GITHUB_SHA} | cut -c1-7)" echo "::set-output name=go_version::$(grep "go 1." go.mod | cut -d " " -f 2)" - name: Setup Golang Environment uses: actions/setup-go@v2 @@ -113,63 +111,10 @@ jobs: - name: Run Tests run: go test ./... - build-image-scan: - name: Build and scan Docker images - runs-on: ubuntu-20.04 - needs: [binary, checks] - strategy: - matrix: - image: [debian, alpine, opentracing, ubi] - ubi_version: ["8"] - include: - - image: ubi - ubi_version: 7 - steps: - - name: Checkout Repository - uses: actions/checkout@v2 - - name: Fetch Cached Artifacts - uses: actions/cache@v2 - with: - path: ${{ github.workspace }}/dist - key: nginx-ingress-${{ github.run_id }}-${{ github.run_number }}-single - - name: Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Build ${{ matrix.image }} Container - uses: docker/build-push-action@v2 - with: - file: build/Dockerfile - context: '.' - # Disable cache until https://github.com/docker/buildx/issues/681 is fixed - # cache-from: type=gha - # cache-to: type=gha,mode=max - target: goreleaser - tags: docker.io/nginx/nginx-ingress:${{ matrix.image }}-${{ github.sha }} - load: true - pull: true - build-args: | - BUILD_OS=${{ matrix.image }} - UBI_VERSION=${{ matrix.ubi_version }} - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - image-ref: 'docker.io/nginx/nginx-ingress:${{ matrix.image }}-${{ github.sha }}' - format: 'template' - template: '@/contrib/sarif.tpl' - output: 'trivy-results-${{ matrix.image }}.sarif' - ignore-unfixed: 'true' - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v1 - with: - sarif_file: 'trivy-results-${{ matrix.image }}.sarif' - - name: Upload Scan Results - uses: actions/upload-artifact@v2 - with: - name: 'trivy-results-${{ matrix.image }}.sarif' - path: 'trivy-results-${{ matrix.image }}.sarif' - if: always() - setup-matrix: + name: Setup Matrix for Smoke Tests runs-on: ubuntu-20.04 + needs: [binary, unit-tests] outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: @@ -181,16 +126,15 @@ jobs: {\"image\": \"alpine\", \"marker\":\"vsr\"}, \ {\"image\": \"opentracing\", \"marker\": \"vs\"}, \ {\"image\": \"ubi\", \"marker\": \"ts\"}, \ - {\"image\": \"debian\", \"marker\": \"policies\"}], \ - \"k8s\": [\"${{env.K8S_VERSION}}\"]}" + {\"image\": \"debian\", \"marker\": \"policies\"}]}" else - echo "::set-output name=matrix::{\"k8s\": [\"1.19.11\", \"1.20.7\", \"1.21.2\", \"1.22.1\"], \"images\": [{\"image\": \"debian\"}]}" + echo "::set-output name=matrix::{\"k8s\": [\"1.19.11\", \"1.20.7\", \"1.21.2\", \"1.22.1\"]}" fi smoke-tests: name: Smoke Tests runs-on: ubuntu-20.04 - needs: [checks, binary, build-image-scan, unit-tests, setup-matrix] + needs: setup-matrix strategy: matrix: ${{ fromJSON(needs.setup-matrix.outputs.matrix) }} steps: @@ -200,9 +144,9 @@ jobs: id: smoke-tests uses: ./.github/actions/smoke-tests with: - image: ${{ matrix.images.image }} - marker: ${{ matrix.images.marker }} - k8s-version: ${{ matrix.k8s }} + image: ${{ matrix.images.image != '' && matrix.images.image || 'debian' }} + marker: ${{ matrix.images.marker != '' && matrix.images.marker || '""' }} + k8s-version: ${{ matrix.k8s != '' && matrix.k8s || env.K8S_VERSION }} - name: Upload Test Results uses: actions/upload-artifact@v2 with: @@ -213,7 +157,7 @@ jobs: helm-tests: name: Helm Tests runs-on: ubuntu-20.04 - needs: [binary, build-image-scan, unit-tests] + needs: [binary, unit-tests] env: NGINX_HTTP_PORT: 8080 NGINX_HTTPS_PORT: 8443 @@ -268,11 +212,10 @@ jobs: run: | . tests/ci-files/helm-http-test.sh ${{ env.HELM_TEST_RETRIES }} ${{ env.NGINX_HTTPS_PORT }} ${{ env.HELM_HTTP_POSTFIX }} - binaries-release: - name: Build Binaries for release + build-binaries: + name: Build Binaries runs-on: ubuntu-20.04 - needs: [checks, smoke-tests, helm-tests] - if: github.event_name != 'pull_request' + needs: [checks, smoke-tests] steps: - name: Checkout Repository uses: actions/checkout@v2 @@ -286,7 +229,7 @@ jobs: uses: goreleaser/goreleaser-action@v2 with: version: latest - args: build --snapshot --rm-dist --id kubernetes-ingress + args: build --rm-dist --id kubernetes-ingress ${{ github.event_name == 'pull_request' && '--single-target' || '' }} ${{ !startsWith(github.ref, 'refs/tags/') && '--snapshot' || '' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GOPATH: ${{ needs.check.outputs.go_path }} @@ -296,11 +239,10 @@ jobs: path: ${{ github.workspace }}/dist key: nginx-ingress-${{ github.run_id }}-${{ github.run_number }}-multi - release-docker: - name: Release Images + build-docker: + name: Build Docker Images runs-on: ubuntu-20.04 - needs: [checks, binaries-release] - if: github.event_name != 'pull_request' + needs: build-binaries strategy: matrix: include: @@ -321,10 +263,6 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 - - name: Output Variables - id: commit - run: | - echo "::set-output name=tag::$(git describe --tags --abbrev=0)" - name: Fetch Cached Artifacts uses: actions/cache@v2 with: @@ -334,6 +272,7 @@ jobs: uses: docker/setup-qemu-action@v1 with: platforms: arm,arm64,ppc64le,s390x + if: github.event_name != 'pull_request' - name: Docker Buildx uses: docker/setup-buildx-action@v1 - name: DockerHub Login @@ -341,19 +280,35 @@ jobs: with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + if: github.event_name != 'pull_request' - name: Docker meta id: meta uses: docker/metadata-action@v3 with: images: nginx/nginx-ingress + flavor: suffix=${{ matrix.suffix }} tags: | - type=edge,suffix=${{ matrix.suffix }} - type=schedule,suffix=${{ matrix.suffix }} + type=edge + type=ref,event=pr + type=schedule + type=semver,pattern={{version}} labels: | - org.opencontainers.image.title=NGINX Ingress Controller for Kubernetes + org.opencontainers.image.description=NGINX Ingress Controller for Kubernetes org.opencontainers.image.documentation=https://docs.nginx.com/nginx-ingress-controller org.opencontainers.image.vendor=NGINX Inc - - name: Push to Dockerhub + - name: Output Variables + id: var + run: | + version=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + if ${{ startsWith(github.ref, 'refs/tags/') }}; then + ic_version=v$version + else + tag=$(git describe --tags --abbrev=0) + sha_short=$(echo ${{ github.sha }} | cut -c1-7) + ic_version=$tag-$version-$sha_short + fi + echo "::set-output name=ic_version::$ic_version" + - name: Build Docker images (and push to Dockerhub if not a PR) uses: docker/build-push-action@v2 with: file: build/Dockerfile @@ -364,38 +319,70 @@ jobs: target: goreleaser tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - platforms: ${{ matrix.platforms }} + platforms: ${{ github.event_name != 'pull_request' && matrix.platforms || '' }} + load: ${{ github.event_name == 'pull_request' }} + push: ${{ github.event_name != 'pull_request' }} pull: true - push: true build-args: | BUILD_OS=${{ matrix.type }} - IC_VERSION=${{ steps.commit.outputs.tag }}-SNAPSHOT-${{ needs.checks.outputs.sha_short }} + IC_VERSION=${{ steps.var.outputs.ic_version }} + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: nginx/nginx-ingress:${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results-${{ matrix.type }}.sarif' + ignore-unfixed: 'true' + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results-${{ matrix.type }}.sarif' + - name: Upload Scan Results + uses: actions/upload-artifact@v2 + with: + name: 'trivy-results-${{ matrix.type }}.sarif' + path: 'trivy-results-${{ matrix.type }}.sarif' + if: always() package-helm: name: Package Helm Chart runs-on: ubuntu-20.04 - needs: release-docker - if: github.event_name == 'push' && github.ref == 'refs/heads/master' + needs: [build-docker, helm-tests] + outputs: + version: ${{ steps.var.outputs.helm_version }} + type: ${{ steps.var.outputs.helm_type }} + if: github.event_name == 'push' steps: - name: Checkout Repository uses: actions/checkout@v2 - - name: Lint + - name: Output Variables + id: var run: | - helm lint ${{ env.HELM_CHART_DIR }} || true + if ${{ startsWith(github.ref, 'refs/tags/') }}; then + helm_version="$(helm show chart ${{ env.HELM_CHART_DIR }} | grep 'version:' | cut -d ' ' -f 2)" + helm_type="stable" + else + helm_version="0.0.0-edge" + helm_type="edge" + fi + echo "::set-output name=helm_version::$helm_version" + echo "::set-output name=helm_type::$helm_type" + - name: Lint + run: helm lint ${{ env.HELM_CHART_DIR }} - name: Package - run: | - helm package --version ${{ env.HELM_CHART_VERSION }} ${{ env.HELM_CHART_DIR }} + run: helm package --version ${{ steps.var.outputs.helm_version }} ${{ env.HELM_CHART_DIR }} - name: Upload Chart uses: actions/upload-artifact@v2 with: name: helm-chart - path: ${{ github.workspace }}/nginx-ingress-${{ env.HELM_CHART_VERSION }}.tgz + path: ${{ github.workspace }}/nginx-ingress-${{ steps.var.outputs.helm_version }}.tgz release-helm: name: Release Helm Chart runs-on: ubuntu-20.04 needs: package-helm - if: github.event_name == 'push' && github.ref == 'refs/heads/master' + if: github.event_name == 'push' steps: - name: Checkout Repository uses: actions/checkout@v2 @@ -404,16 +391,29 @@ jobs: fetch-depth: 1 token: ${{ secrets.NGINX_PAT }} - name: Remove previous Chart - run: rm -f ${{ github.workspace }}/edge/nginx-ingress-${{ env.HELM_CHART_VERSION }}.tgz + run: rm -f ${{ github.workspace }}/${{ needs.package-helm.outputs.type }}/nginx-ingress-${{ needs.package-helm.outputs.version }}.tgz - name: Retrieve latest Helm Chart uses: actions/download-artifact@v2 with: name: helm-chart - path: ${{ github.workspace }}/edge + path: ${{ github.workspace }}/${{ needs.package-helm.outputs.type }} - name: Push Helm Chart run: | - helm repo index edge --url https://helm.nginx.com/edge + helm repo index ${{ needs.package-helm.outputs.type }} --url https://helm.nginx.com/${{ needs.package-helm.outputs.type }} git add -A git -c user.name='${{ env.GIT_NAME }}' -c user.email='${{ env.GIT_MAIL }}' \ - commit -m "NGINX Ingress Controller - Edge Release (latest)" + commit -m "NGINX Ingress Controller - Release ${{ needs.package-helm.outputs.type }} ${{ needs.package-helm.outputs.version }}" git push -u origin master + + publish-release-notes: + name: Publish Release Notes + runs-on: ubuntu-20.04 + needs: release-helm + if: ${{ startsWith(github.ref, 'refs/tags/') }} + steps: + - name: Publish Release Notes + uses: release-drafter/release-drafter@v5 + with: + publish: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/notifications.yml b/.github/workflows/notifications.yml index e16948485f..fac4dd05aa 100644 --- a/.github/workflows/notifications.yml +++ b/.github/workflows/notifications.yml @@ -8,7 +8,6 @@ on: - "CodeQL" - "Fossa" - "Lint" - - "Release" - "Update Docker Images" types: - completed @@ -19,8 +18,18 @@ jobs: if: ${{ github.event.workflow_run.conclusion == 'failure' }} steps: - name: Output Variables + continue-on-error: true id: vars - run: echo "::set-output name=sha::$(echo ${GITHUB_SHA} | cut -c1-7)" + run: | + suite_id=$(curl -sS -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }} | jq '.check_suite_id') + event=$(curl -sS -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }} | jq -r '.event') + name=$(curl -sS -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${{ github.repository }}/check-suites/$suite_id/check-runs | jq -r '[.check_runs[] | select(.conclusion=="failure")][0].name') + url=$(curl -sS -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${{ github.repository }}/check-suites/$suite_id/check-runs | jq -r '[.check_runs[] | select(.conclusion=="failure")][0].html_url') + + echo "::set-output name=name::$name" + echo "::set-output name=url::$url" + echo "::set-output name=event::$event" + - name: Send Notification uses: 8398a7/action-slack@v3 with: @@ -31,16 +40,16 @@ jobs: icon_emoji: ':octocat:', mention: 'channel', attachments: [{ - title: '[${{ github.event.repository.full_name }}] ${{ github.event.workflow.name }} pipeline has failed', + title: '[${{ github.event.repository.full_name }}] ${{ github.event.workflow.name }} pipeline has failed (${{ steps.vars.outputs.event }})', color: 'danger', fields: [{ - title: 'Commit Hash', - value: '', + title: 'Commit', + value: '', short: true }, { - title: 'Commit Message', - value: `${{ github.event.workflow_run.head_commit.message }}`, + title: 'Job failed', + value: `<${{ steps.vars.outputs.url }}|${{ steps.vars.outputs.name }}>`, short: true }, { diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 8741abf165..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,181 +0,0 @@ -name: Release - -on: - push: - tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - -defaults: - run: - shell: bash - -env: - DOCKER_BUILDKIT: 1 - HELM_CHART_DIR: deployments/helm-chart - GIT_NAME: NGINX Kubernetes Team - GIT_MAIL: kubernetes@nginx.com - -jobs: - - binary: - name: Build Binary - runs-on: ubuntu-20.04 - outputs: - version: ${{ steps.commit.outputs.version }} - helmChartVersion: ${{ steps.commit.outputs.helmChartVersion }} - steps: - - name: Checkout Repository - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Output Variables - id: commit - run: | - echo "::set-output name=version::${GITHUB_REF#refs/tags/v}" - echo "::set-output name=helmChartVersion::$(helm show chart ${{ env.HELM_CHART_DIR }} | grep 'version:' | cut -d ' ' -f 2)" - - name: Determine Go version from go.mod - run: echo "GO_VERSION=$(grep "go 1." go.mod | cut -d " " -f 2)" >> $GITHUB_ENV - - name: Setup Golang Environment - uses: actions/setup-go@v2 - with: - go-version: ${{ env.GO_VERSION }} - - name: Determine GOPATH - run: echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV - - name: Build binaries - uses: goreleaser/goreleaser-action@v2 - with: - version: latest - args: release --rm-dist --skip-publish - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GOPATH: ${{ env.GOPATH }} - - name: Store Artifacts in Cache - uses: actions/cache@v2 - with: - path: ${{ github.workspace }}/dist - key: nginx-ingress-${{ github.run_id }}-${{ github.run_number }} - - release-docker: - name: Release Images - runs-on: ubuntu-20.04 - needs: [binary] - strategy: - matrix: - include: - - tags: | - nginx/nginx-ingress:${{ needs.binary.outputs.version }} - nginx/nginx-ingress:latest - type: debian - platforms: linux/arm,linux/arm64,linux/amd64,linux/ppc64le,linux/s390x - - tags: | - nginx/nginx-ingress:${{ needs.binary.outputs.version }}-alpine - nginx/nginx-ingress:alpine - type: alpine - platforms: linux/arm,linux/arm64,linux/amd64,linux/ppc64le,linux/s390x - - tags: | - nginx/nginx-ingress:${{ needs.binary.outputs.version }}-ubi - nginx/nginx-ingress:ubi - type: ubi - platforms: linux/arm64,linux/amd64 - steps: - - name: Checkout Repository - uses: actions/checkout@v2 - - name: Output Variables - id: commit - run: | - echo "::set-output name=date::$(date -u +"%Y-%m-%dT%H:%M:%SZ")" - - name: Fetch Cached Artifacts - uses: actions/cache@v2 - with: - path: ${{ github.workspace }}/dist - key: nginx-ingress-${{ github.run_id }}-${{ github.run_number }} - - name: Setup QEMU - uses: docker/setup-qemu-action@v1 - with: - platforms: arm,arm64,ppc64le,s390x - - name: Docker Buildx - uses: docker/setup-buildx-action@v1 - with: - driver-opts: network=host - - name: Cache Docker layers for ${{ matrix.image }} - uses: actions/cache@v2 - with: - path: /tmp/.buildx-${{ matrix.image }}-cache - key: ${{ runner.os }}-buildx-${{ matrix.image }}-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx-${{ matrix.image }}- - - name: DockerHub Login - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Push to Dockerhub - uses: docker/build-push-action@v2 - with: - file: build/Dockerfile - context: '.' - cache-to: type=local,dest=/tmp/.buildx-${{ matrix.image }}-cache - target: goreleaser - tags: ${{ matrix.tags }} - platforms: ${{ matrix.platforms }} - push: true - build-args: | - BUILD_OS=${{ matrix.type }} - IC_VERSION=${GITHUB_REF#refs/tags/} - DATE=${{ steps.commit.outputs.date }} - GIT_COMMIT=${{ github.sha }} - - package-helm: - name: Package Helm Chart - runs-on: ubuntu-20.04 - needs: [binary, release-docker] - steps: - - name: Checkout Repository - uses: actions/checkout@v2 - - name: Lint - run: helm lint ${{ env.HELM_CHART_DIR }} - - name: Package - run: helm package --version ${{ needs.binary.outputs.helmChartVersion }} ${{ env.HELM_CHART_DIR }} - - name: Upload Chart - uses: actions/upload-artifact@v2 - with: - name: helm-chart - path: ${{ github.workspace }}/nginx-ingress-${{ needs.binary.outputs.helmChartVersion }}.tgz - - release-helm: - name: Release Helm Chart - runs-on: ubuntu-20.04 - needs: [binary, release-docker, package-helm] - steps: - - name: Checkout Repository - uses: actions/checkout@v2 - with: - repository: nginxinc/helm-charts - fetch-depth: 1 - token: ${{ secrets.NGINX_PAT }} - - name: Remove previous Chart - run: rm -f ${{ github.workspace }}/stable/nginx-ingress-${{ needs.binary.outputs.helmChartVersion }}.tgz - - name: Retrieve latest Helm Chart - uses: actions/download-artifact@v2 - with: - name: helm-chart - path: ${{ github.workspace }}/stable - - name: Push Helm Chart - run: | - helm repo index stable --url https://helm.nginx.com/stable - git add -A - git -c user.name='${{ env.GIT_NAME }}' -c user.email='${{ env.GIT_MAIL }}' \ - commit -m "NGINX Ingress Controller - Release ${{ needs.binary.outputs.version }}" - git push -u origin master - - publish-release-notes: - name: Publish Release Notes - runs-on: ubuntu-20.04 - needs: [release-helm] - steps: - - name: Publish Release Notes - uses: release-drafter/release-drafter@v5 - with: - publish: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/tests/Makefile b/tests/Makefile index 0e148c1723..54ad9c7f27 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -29,7 +29,7 @@ run-tests-in-kind: .PHONY: create-kind-cluster create-kind-cluster: - $(eval K8S_VERSION=$(shell grep "K8S_VERSION:" ../.github/workflows/edge.yml | awk -F" " '{print $$2}')) + $(eval K8S_VERSION=$(shell grep "K8S_VERSION:" ../.github/workflows/ci.yml | awk -F" " '{print $$2}')) kind create cluster --image kindest/node:v$(K8S_VERSION) kind export kubeconfig --kubeconfig $(KIND_KUBE_CONFIG_FOLDER)/config