ci.yml 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. name: CI
  2. on:
  3. push:
  4. branches:
  5. - main
  6. - release-*
  7. pull_request: {}
  8. workflow_dispatch: {}
  9. env:
  10. # Common versions
  11. GOLANGCI_VERSION: 'v1.49.0'
  12. KUBERNETES_VERSION: '1.24.x'
  13. DOCKER_BUILDX_VERSION: 'v0.4.2'
  14. # Common users. We can't run a step 'if secrets.GHCR_USERNAME != ""' but we can run
  15. # a step 'if env.GHCR_USERNAME' != ""', so we copy these to succinctly test whether
  16. # credentials have been provided before trying to run steps that need them.
  17. GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }}
  18. # Sonar
  19. SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
  20. jobs:
  21. detect-noop:
  22. runs-on: ubuntu-18.04
  23. outputs:
  24. noop: ${{ steps.noop.outputs.should_skip }}
  25. steps:
  26. - name: Detect No-op Changes
  27. id: noop
  28. uses: fkirc/skip-duplicate-actions@v4.0.0
  29. with:
  30. github_token: ${{ secrets.GITHUB_TOKEN }}
  31. paths_ignore: '["**.md", "**.png", "**.jpg"]'
  32. do_not_skip: '["workflow_dispatch", "schedule", "push"]'
  33. concurrent_skipping: false
  34. lint:
  35. runs-on: ubuntu-18.04
  36. needs: detect-noop
  37. if: needs.detect-noop.outputs.noop != 'true'
  38. steps:
  39. - name: Checkout
  40. uses: actions/checkout@v3
  41. - name: Setup Go
  42. uses: actions/setup-go@v3
  43. with:
  44. go-version-file: "go.mod"
  45. - name: Find the Go Cache
  46. id: go
  47. run: |
  48. echo "::set-output name=build-cache::$(go env GOCACHE)"
  49. echo "::set-output name=mod-cache::$(go env GOMODCACHE)"
  50. - name: Cache the Go Build Cache
  51. uses: actions/cache@v3
  52. with:
  53. path: ${{ steps.go.outputs.build-cache }}
  54. key: ${{ runner.os }}-build-lint-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
  55. restore-keys: ${{ runner.os }}-build-lint-${{ github.sha }}-
  56. - name: Cache Go Dependencies
  57. uses: actions/cache@v3
  58. with:
  59. path: ${{ steps.go.outputs.mod-cache }}
  60. key: ${{ runner.os }}-pkg-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
  61. restore-keys: ${{ runner.os }}-pkg-${{ github.sha }}-
  62. # This action uses its own setup-go, which always seems to use the latest
  63. # stable version of Go. We could run 'make lint' to ensure our desired Go
  64. # version, but we prefer this action because it leaves 'annotations' (i.e.
  65. # it comments on PRs to point out linter violations).
  66. - name: Lint
  67. uses: golangci/golangci-lint-action@v3.2.0
  68. with:
  69. version: ${{ env.GOLANGCI_VERSION }}
  70. skip-pkg-cache: true
  71. skip-build-cache: true
  72. skip-go-installation: true
  73. check-diff:
  74. runs-on: ubuntu-18.04
  75. needs: detect-noop
  76. if: needs.detect-noop.outputs.noop != 'true'
  77. steps:
  78. - name: Checkout
  79. uses: actions/checkout@v3
  80. - name: Setup Go
  81. uses: actions/setup-go@v3
  82. with:
  83. go-version-file: "go.mod"
  84. - name: Find the Go Cache
  85. id: go
  86. run: |
  87. echo "::set-output name=build-cache::$(go env GOCACHE)"
  88. echo "::set-output name=mod-cache::$(go env GOMODCACHE)"
  89. - name: Cache the Go Build Cache
  90. uses: actions/cache@v3
  91. with:
  92. path: ${{ steps.go.outputs.build-cache }}
  93. key: ${{ runner.os }}-build-check-diff-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
  94. restore-keys: ${{ runner.os }}-build-check-diff-${{ github.sha }}-
  95. - name: Cache Go Dependencies
  96. uses: actions/cache@v3
  97. with:
  98. path: ${{ steps.go.outputs.mod-cache }}
  99. key: ${{ runner.os }}-pkg-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
  100. restore-keys: ${{ runner.os }}-pkg-${{ github.sha }}-
  101. # Check DIff also runs Reviewable which needs golangci-lint installed
  102. - name: Check Diff
  103. run: |
  104. wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s ${{ env.GOLANGCI_VERSION }}
  105. export PATH=$PATH:./bin
  106. make check-diff
  107. unit-tests:
  108. runs-on: ubuntu-18.04
  109. needs: detect-noop
  110. if: needs.detect-noop.outputs.noop != 'true'
  111. steps:
  112. - name: Checkout
  113. uses: actions/checkout@v3
  114. - name: Fetch History
  115. run: git fetch --prune --unshallow
  116. - name: Setup Go
  117. uses: actions/setup-go@v3
  118. with:
  119. go-version-file: "go.mod"
  120. - name: Find the Go Cache
  121. id: go
  122. run: |
  123. echo "::set-output name=build-cache::$(go env GOCACHE)"
  124. echo "::set-output name=mod-cache::$(go env GOMODCACHE)"
  125. - name: Cache the Go Build Cache
  126. uses: actions/cache@v3
  127. with:
  128. path: ${{ steps.go.outputs.build-cache }}
  129. key: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
  130. restore-keys: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-
  131. - name: Cache Go Dependencies
  132. uses: actions/cache@v3
  133. with:
  134. path: ${{ steps.go.outputs.mod-cache }}
  135. key: ${{ runner.os }}-pkg-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
  136. restore-keys: ${{ runner.os }}-pkg-${{ github.sha }}-
  137. - name: Add setup-envtest
  138. run: |
  139. go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
  140. setup-envtest use ${{env.KUBERNETES_VERSION}} -p env --os $(go env GOOS) --arch $(go env GOARCH)
  141. - name: Cache envtest binaries
  142. uses: actions/cache@v3
  143. with:
  144. path: /home/runner/.local/share/kubebuilder-envtest/
  145. key: ${{ runner.os }}-kubebuilder-${{env.KUBERNETES_VERSION}}
  146. restore-keys: ${{ runner.os }}-kubebuilder-
  147. - name: Run Unit Tests
  148. run: |
  149. export KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT=true
  150. source <(setup-envtest use ${{env.KUBERNETES_VERSION}} -p env --os $(go env GOOS) --arch $(go env GOARCH))
  151. make test
  152. publish-artifacts:
  153. runs-on: ubuntu-18.04
  154. needs: detect-noop
  155. if: needs.detect-noop.outputs.noop != 'true'
  156. permissions:
  157. id-token: write
  158. contents: read
  159. steps:
  160. - name: Setup QEMU
  161. uses: docker/setup-qemu-action@v2
  162. with:
  163. platforms: all
  164. - name: Setup Docker Buildx
  165. uses: docker/setup-buildx-action@v2
  166. with:
  167. version: ${{ env.DOCKER_BUILDX_VERSION }}
  168. install: true
  169. - name: Checkout
  170. uses: actions/checkout@v3
  171. - name: Fetch History
  172. run: git fetch --prune --unshallow
  173. - name: Setup Go
  174. uses: actions/setup-go@v3
  175. with:
  176. go-version-file: "go.mod"
  177. - name: Find the Go Cache
  178. id: go
  179. run: |
  180. echo "::set-output name=build-cache::$(go env GOCACHE)"
  181. echo "::set-output name=mod-cache::$(go env GOMODCACHE)"
  182. - name: Cache the Go Build Cache
  183. uses: actions/cache@v3
  184. with:
  185. path: ${{ steps.go.outputs.build-cache }}
  186. key: ${{ runner.os }}-build-publish-artifacts-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
  187. restore-keys: ${{ runner.os }}-build-publish-artifacts-${{ github.sha }}-
  188. - name: Cache Go Dependencies
  189. uses: actions/cache@v3
  190. with:
  191. path: ${{ steps.go.outputs.mod-cache }}
  192. key: ${{ runner.os }}-pkg-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
  193. restore-keys: ${{ runner.os }}-pkg-${{ github.sha }}-
  194. - name: Login to Docker
  195. uses: docker/login-action@v2
  196. if: env.GHCR_USERNAME != ''
  197. with:
  198. registry: ghcr.io
  199. username: ${{ secrets.GHCR_USERNAME }}
  200. password: ${{ secrets.GHCR_TOKEN }}
  201. - name: Build & Publish Artifacts
  202. if: env.GHCR_USERNAME != ''
  203. env:
  204. BUILD_ARGS: "--push --platform linux/amd64,linux/arm64"
  205. run: make docker.build
  206. - name: Get docker image tag
  207. if: env.GHCR_USERNAME != ''
  208. id: image_version
  209. run: echo "::set-output name=image::$(make docker.image)"
  210. - name: Run Trivy vulnerability scanner
  211. if: env.GHCR_USERNAME != ''
  212. uses: aquasecurity/trivy-action@master
  213. with:
  214. image-ref: '${{ steps.image_version.outputs.image }}'
  215. format: 'table'
  216. exit-code: '1'
  217. ignore-unfixed: true
  218. vuln-type: 'os,library'
  219. severity: 'CRITICAL,HIGH'
  220. - name: Promote Artifacts to main release channel
  221. if: github.ref == 'refs/heads/main' && env.GHCR_USERNAME != ''
  222. run: make docker.promote
  223. env:
  224. RELEASE_TAG: main
  225. - name: Set up crane
  226. if: github.ref == 'refs/heads/main' && env.GHCR_USERNAME != ''
  227. run: go install github.com/google/go-containerregistry/cmd/crane@v0.8.0
  228. - name: Install cosign
  229. if: github.ref == 'refs/heads/main' && env.GHCR_USERNAME != ''
  230. uses: sigstore/cosign-installer@v2.6.0
  231. - name: Sign Artifacts to main release channel
  232. if: github.ref == 'refs/heads/main' && env.GHCR_USERNAME != ''
  233. run: make docker.sign
  234. env:
  235. RELEASE_TAG: main
  236. COSIGN_EXPERIMENTAL: true