From dfd98db775081c234c8f4e586f34391526bc2eca Mon Sep 17 00:00:00 2001 From: Bradley Jones Date: Fri, 10 Mar 2023 14:51:07 +0000 Subject: [PATCH] feat: add automated release pipeline Signed-off-by: Bradley Jones --- .github/workflows/release.yaml | 108 +++++++++++++++++++++++++ .github/workflows/snapshot.yaml | 48 +++++++++++ .github/workflows/static-analysis.yaml | 4 +- .github/workflows/unit-test.yaml | 2 +- Makefile | 16 ++++ 5 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release.yaml create mode 100644 .github/workflows/snapshot.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..9cac8cd --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,108 @@ +name: 'Release' +on: + push: + # take no actions on push to any branch... + branches-ignore: + - '**' + # ... only act on release tags + tags: + - 'v*' + +env: + GO_VERSION: "1.19.x" + +jobs: + wait-for-checks: + runs-on: ubuntu-latest + steps: + + - uses: actions/checkout@v3 + + # we don't want to release commits that have been pushed and tagged, but not necessarily merged onto main + - name: Ensure tagged commit is on main + run: | + echo "Tag: ${GITHUB_REF##*/}" + git fetch origin main + git merge-base --is-ancestor ${GITHUB_REF##*/} origin/main && echo "${GITHUB_REF##*/} is a commit on main!" + + - name: Build snapshot artifacts + uses: fountainhead/action-wait-for-check@v1.1.0 + id: snapshot + with: + token: ${{ secrets.GITHUB_TOKEN }} + # This check name is defined as the github actions job name (in .github/workflows/snapshot.yaml) + checkName: "Build-Snapshot-Artifacts" + ref: ${{ github.event.pull_request.head.sha || github.sha }} + + - name: Check static analysis + uses: fountainhead/action-wait-for-check@v1.1.0 + id: static-analysis + with: + token: ${{ secrets.GITHUB_TOKEN }} + # This check name is defined as the github actions job name (in .github/workflows/static-analysis.yaml) + checkName: "Static-Analysis (1.19.x, ubuntu-latest)" + ref: ${{ github.event.pull_request.head.sha || github.sha }} + + - name: Check unit test results + uses: fountainhead/action-wait-for-check@v1.1.0 + id: tests-unit + with: + token: ${{ secrets.GITHUB_TOKEN }} + # This check name is defined as the github actions job name (in .github/workflows/unit-test.yaml) + checkName: "Unit-Tests (1.19.x, ubuntu-latest)" + ref: ${{ github.event.pull_request.head.sha || github.sha }} + + - name: Quality gate + if: steps.static-analysis.outputs.conclusion != 'success' || steps.tests-unit.outputs.conclusion != 'success' || steps.snapshot.outputs.conclusion != 'success' || steps.acceptance-helm-1-13-12.outputs.conclusion != 'success' || steps.acceptance-helm-1-18-0.outputs.conclusion != 'success' + run: | + echo "Static-Analysis Status : ${{ steps.static-analysis.outputs.conclusion }}" + echo "Unit Test Status : ${{ steps.tests-unit.outputs.conclusion }}" + echo "Build Snapshot Artifacts Status: ${{ steps.snapshot.outputs.conclusion }}" + false + + release: + needs: [ wait-for-checks ] + runs-on: ubuntu-latest + steps: + + - uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} + + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Restore bootstrap cache + id: cache + uses: actions/cache@v2 + with: + path: | + ~/go/pkg/mod + ${{ github.workspace }}/.tmp + key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('Makefile') }}-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('Makefile') }}- + ${{ runner.os }}-go-${{ env.GO_VERSION }}- + + - name: Bootstrap dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: make ci-bootstrap + + - name: Login to Docker Hub + id: docker-login + run: | + echo "${DOCKER_PASS}" | docker login -u "${DOCKER_USER}" --password-stdin + env: + DOCKER_USER: ${{ secrets.TOOLBOX_DOCKER_USER }} + DOCKER_PASS: ${{ secrets.TOOLBOX_DOCKER_PASS }} + + - name: Build snapshot artifacts + run: make release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/upload-artifact@v2 + with: + name: artifacts + path: dist/**/* diff --git a/.github/workflows/snapshot.yaml b/.github/workflows/snapshot.yaml new file mode 100644 index 0000000..6da0ae5 --- /dev/null +++ b/.github/workflows/snapshot.yaml @@ -0,0 +1,48 @@ +name: 'Snapshot' +on: + workflow_dispatch: + push: + # ... only act on pushes to main + branches: + - main + # ... do not act on release tags + tags-ignore: + - v* + +env: + GO_VERSION: "1.19.x" + +jobs: + Build-Snapshot-Artifacts: + runs-on: ubuntu-latest + steps: + + - uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} + + - uses: actions/checkout@v3 + + - name: Restore bootstrap cache + id: cache + uses: actions/cache@v2 + with: + path: | + ~/go/pkg/mod + ${{ github.workspace }}/.tmp + key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}-${{ hashFiles('Makefile') }} + restore-keys: | + ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}- + ${{ runner.os }}-go-${{ env.GO_VERSION }}- + + - name: Bootstrap dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: make ci-bootstrap + + - name: Build snapshot artifacts + run: make snapshot + + - uses: actions/upload-artifact@v2 + with: + name: artifacts + path: snapshot/**/* diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index b9b6dcf..bc4a67e 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -11,11 +11,11 @@ jobs: platform: [ubuntu-latest] runs-on: ${{ matrix.platform }} steps: - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v3 with: go-version: ${{ matrix.go-version }} - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Restore bootstrap cache id: bootstrap-cache diff --git a/.github/workflows/unit-test.yaml b/.github/workflows/unit-test.yaml index a24a851..1a9b001 100644 --- a/.github/workflows/unit-test.yaml +++ b/.github/workflows/unit-test.yaml @@ -16,7 +16,7 @@ jobs: with: go-version: ${{ matrix.go-version }} - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Restore bootstrap cache id: bootstrap-cache diff --git a/Makefile b/Makefile index 425815f..ca5d277 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ SUCCESS := $(BOLD)$(GREEN) # ci dependency versions GOLANG_CI_VERSION = v1.50.1 GOSIMPORTS_VERSION = v0.3.4 +GORELEASER_VERSION = v1.16.0 ## Build variables ifeq "$(strip $(VERSION))" "" @@ -57,10 +58,15 @@ bootstrap-tools: $(TEMPDIR) $(call title,Boostrapping tools) curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TEMPDIR)/ $(GOLANG_CI_VERSION) GOBIN="$(realpath $(TEMPDIR))" go install github.com/rinchsan/gosimports/cmd/gosimports@$(GOSIMPORTS_VERSION) + GOBIN="$(abspath $(TEMPDIR))" go install github.com/goreleaser/goreleaser@$(GORELEASER_VERSION) .PHONY: bootstrap bootstrap: bootstrap-go bootstrap-tools ## Download and install all go dependencies (+ prep tooling in the ./tmp dir) +.PHONY: ci-bootstrap +ci-bootstrap: bootstrap + sudo apt update && sudo apt install -y bc jq + .PHONY: static-analysis static-analysis: lint @@ -95,3 +101,13 @@ unit: ## Run unit tests (with coverage) @go tool cover -func $(COVER_REPORT) | grep total | awk '{print substr($$3, 1, length($$3)-1)}' > $(COVER_TOTAL) @echo "Coverage: $$(cat $(COVER_TOTAL))" @if [ $$(echo "$$(cat $(COVER_TOTAL)) >= $(COVERAGE_THRESHOLD)" | bc -l) -ne 1 ]; then echo "$(RED)$(BOLD)Failed coverage quality gate (> $(COVERAGE_THRESHOLD)%)$(RESET)" && false; fi + +.PHONY: snapshot +snapshot: ## Build a snapshot binaries and docker images + $(call title,Building snapshot binary) + $(TEMPDIR)/goreleaser release --skip-publish --clean --snapshot --config .goreleaser.yaml + +.PHONY: release +release: ## Publish release binaries and docker images + $(call title, release binary) + $(TEMPDIR)/goreleaser release --clean --config .goreleaser.yaml