From bb9171d6e3fb72977d4cabf2b87d1866d6aa4a24 Mon Sep 17 00:00:00 2001 From: Oksana Grishchenko <91597950+oksana-grishchenko@users.noreply.github.com> Date: Thu, 21 Mar 2024 13:38:54 +0200 Subject: [PATCH] EVEREST-726 RC/Release workflow (#96) EVEREST-726 release workflow --- .github/workflows/release.yml | 442 ++++++++++++++++++++++++++++++++++ Makefile | 6 + go.mod | 4 +- go.sum | 8 +- 4 files changed, 454 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..baecbaef7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,442 @@ +--- +name: Release +on: + workflow_dispatch: + inputs: + version: + description: "The RC/Release version, format: X.Y.Z-rcN for RC, X.Y.Z for releases" + required: true + +permissions: + contents: read + packages: write + checks: write + pull-requests: write + +jobs: + build: + runs-on: ubuntu-latest + env: + TOOLS_PATH: "/opt/tools/bin" + VERSION: ${{ github.event.inputs.version }} + # version in format "X.Y" which is going to be updated with each patch release + FLOATING_TAG: '' + # branch name in format "release-X.Y" + BRANCH_NAME: '' + # GitHub tag name to use for the RC/Release + GH_TAG: '' + # Shows if this workflow is triggered for RC or Release + IS_RC: 0 + ARCH: '' + OS: '' + steps: + + - name: Validate input + run: | + if [[ ! $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc[1-9][0-9]*)?$ ]]; then + echo "Wrong version format provided, please use "X.Y.Z-rcN" format for an RC or "X.Y.Z" format for a release" + exit 1 + fi + + - name: Set environment variables + run: | + floating_tag=${VERSION%.*} + echo "FLOATING_TAG=$floating_tag" >> $GITHUB_ENV + echo "BRANCH_NAME=release-$floating_tag" >> $GITHUB_ENV + echo "GH_TAG=v$VERSION" >> $GITHUB_ENV + if [[ ! $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "IS_RC=1" >> $GITHUB_ENV + fi + echo "ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')" >> $GITHUB_ENV + echo "OS=$(uname | awk '{print tolower($0)}')" >> $GITHUB_ENV + + + - name: Operator - check out + uses: actions/checkout@v4 + with: + repository: percona/everest-operator + path: everest-operator + token: ${{ secrets.ROBOT_TOKEN }} + + - name: Operator - create release branch + run: | + cd everest-operator + # Check if the branch already exists + git fetch + check_branch=$(git ls-remote --heads origin ${BRANCH_NAME}) + if [[ -z ${check_branch} ]]; then + git checkout -b $BRANCH_NAME + git push origin $BRANCH_NAME + fi + + git checkout $BRANCH_NAME + + # update version in the Makefile + sed -i "s/^VERSION ?=.*/VERSION ?= $VERSION/g" Makefile + + make init + make release + + # if there is something to commit, commit it and add the tag + if [[ -n $(git status --porcelain) ]]; then + if git tag --list | grep -q "^$GH_TAG$"; then + echo "The tag is already present in github. Please create a different RC/Release" + exit 1 + fi + + # configure userdata for commits + git config --global user.email "everest-ci@percona.com" + git config --global user.name "Everest RC CI triggered by ${{ github.actor }}" + + # commit and push the updated files + git commit -a -m "update version tag" + git push origin $BRANCH_NAME + + git tag $GH_TAG + git push origin $GH_TAG + fi + + + - name: Operator - install operator-sdk + run: | + mkdir -p $TOOLS_PATH + echo $TOOLS_PATH >> $GITHUB_PATH + + export OPERATOR_SDK_DL_URL=https://github.com/operator-framework/operator-sdk/releases/download/v1.25.2 + curl -LO ${OPERATOR_SDK_DL_URL}/operator-sdk_${OS}_${ARCH} + + gpg --keyserver keyserver.ubuntu.com --recv-keys 052996E2A20B5C7E + + curl -LO ${OPERATOR_SDK_DL_URL}/checksums.txt + curl -LO ${OPERATOR_SDK_DL_URL}/checksums.txt.asc + gpg -u "Operator SDK (release) " --verify checksums.txt.asc + + grep operator-sdk_${OS}_${ARCH} checksums.txt | sha256sum -c - + + chmod +x operator-sdk_${OS}_${ARCH} + mv operator-sdk_${OS}_${ARCH} $TOOLS_PATH/operator-sdk + + - name: Operator - build and bundle + run: | + cd everest-operator + make build manifests bundle + + + - name: Operator - setup Docker meta for everest-operator + id: operator_meta + uses: docker/metadata-action@v4 + # docker/metadata-action action looks more elegant when being triggered by a GH tag, + # however this workflow can't be triggered by a GH tag since there are some changes need to be done + # in the codebase prior putting the tag, so the action uses the raw tags + with: + images: | + percona/everest-operator,enable=${{ env.IS_RC == 0 }} + perconalab/everest-operator + tags: | + type=raw,value=${{ env.VERSION }} + type=raw,value=latest + type=raw,value=${{ env.FLOATING_TAG }},enable=${{ env.IS_RC == 0 }} + + - name: Operator - setup Docker meta for everest-operator-bundle + id: bundle_meta + uses: docker/metadata-action@v4 + with: + images: | + percona/everest-operator-bundle,enable=${{ env.IS_RC == 0 }} + perconalab/everest-operator-bundle + tags: | + type=raw,value=${{ env.VERSION }} + type=raw,value=${{ env.FLOATING_TAG }},enable=${{ env.IS_RC == 0 }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Operator - build everest-operator image + uses: docker/build-push-action@v3 + with: + context: everest-operator + push: false + tags: ${{ steps.operator_meta.outputs.tags }} + + - name: Operator - set everest-operator image to scan + id: set_operator_image + run: | + # taking the first tag to check with trivy. Since the build is the same, no need to check the rest of them + echo "::set-output name=image_to_check::$(echo "${{ steps.operator_meta.outputs.tags }}" | head -n 1)" + + - name: Operator - run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@0.12.0 + with: + image-ref: ${{ steps.set_operator_image.outputs.image_to_check }} + format: 'table' + exit-code: '1' + severity: 'CRITICAL,HIGH' + + - name: Operator - push everest-operator image + uses: docker/build-push-action@v3 + with: + context: everest-operator + push: true + tags: ${{ steps.operator_meta.outputs.tags }} + + - name: Operator - build everest-operator-bundle image + uses: docker/build-push-action@v3 + with: + context: everest-operator + push: false + tags: ${{ steps.bundle_meta.outputs.tags }} + file: everest-operator/bundle.Dockerfile + + - name: Operator - set everest-operator-bundle image to scan + id: set_operator_bundle_image + run: | + # taking the first tag to check with trivy. Since the build is the same, no need to check the rest of them + echo "::set-output name=image_to_check::$(echo "${{ steps.bundle_meta.outputs.tags }}" | head -n 1)" + + - name: Operator - Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@0.12.0 + with: + image-ref: ${{ steps.set_operator_bundle_image.outputs.image_to_check }} + format: 'table' + exit-code: '1' + severity: 'CRITICAL,HIGH' + + - name: Operator - push everest-operator-bundle image + uses: docker/build-push-action@v3 + with: + context: everest-operator + push: true + tags: ${{ steps.bundle_meta.outputs.tags }} + file: everest-operator/bundle.Dockerfile + + - name: Catalog - checkout + uses: actions/checkout@v4 + with: + repository: percona/everest-catalog + path: everest-catalog + token: ${{ secrets.ROBOT_TOKEN }} + + - name: Catalog - create release branch + run: | + cd everest-catalog + # Check if the branch already exists + git fetch + check_branch=$(git ls-remote --heads origin ${BRANCH_NAME}) + + if [[ -z ${check_branch} ]]; then + git checkout -b $BRANCH_NAME + git push origin $BRANCH_NAME + fi + git checkout $BRANCH_NAME + + # update tag refs in scripts + if [[ $env.IS_RC ]]; then + sed -i "s/perconalab\/everest-operator-bundle.*/perconalab\/everest-operator-bundle:$VERSION/g" catalog/everest-operator/veneer.yaml + sed -i "s/percona\/everest-operator-bundle.*/perconalab\/everest-operator-bundle:$VERSION/g" catalog/everest-operator/veneer.yaml + else + sed -i "s/perconalab\/everest-operator-bundle.*/percona\/everest-operator-bundle:$VERSION/g" catalog/everest-operator/veneer.yaml + sed -i "s/percona\/everest-operator-bundle.*/percona\/everest-operator-bundle:$VERSION/g" catalog/everest-operator/veneer.yaml + fi + + curl -Lo /tmp/opm https://github.com/operator-framework/operator-registry/releases/latest/download/${OS}-${ARCH}-opm + chmod +x /tmp/opm + /tmp/opm alpha render-template semver -o yaml < ./catalog/everest-operator/veneer.yaml > ./catalog/everest-operator/catalog.yaml + + # if there is something to commit, commit it and add the tag + if [[ -n $(git status --porcelain) ]]; then + if git tag --list | grep -q "^$GH_TAG$"; then + echo "The tag is already present in github. Please create a different RC/Release" + exit 1 + fi + + # configure userdata for commits + git config --global user.email "everest-ci@percona.com" + git config --global user.name "Everest RC CI triggered by ${{ github.actor }}" + + # commit and push the updated files + git commit -a -m "update version tag" + git push origin $BRANCH_NAME + + git tag $GH_TAG + git push origin $GH_TAG + fi + + + - name: Catalog - docker meta + id: catalog_meta + uses: docker/metadata-action@v4 + with: + images: | + percona/everest-catalog,enable=${{ env.IS_RC == 0 }} + perconalab/everest-catalog + tags: | + type=raw,value=${{ env.VERSION }} + type=raw,value=latest + type=raw,value=${{ env.FLOATING_TAG }},enable=${{ env.IS_RC == 0 }} + + + - name: Catalog - build image + uses: docker/build-push-action@v3 + with: + context: everest-catalog + push: false + tags: ${{ steps.catalog_meta.outputs.tags }} + file: everest-catalog/everest-catalog.Dockerfile + + - name: Catalog - set catalog image to scan + id: set_catalog_image + run: | + # taking the first tag to check with trivy. Since the build is the same, no need to check the rest of them + echo "::set-output name=image_to_check::$(echo "${{ steps.catalog_meta.outputs.tags }}" | head -n 1)" + + - name: Catalog - run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@0.12.0 + with: + image-ref: ${{ steps.set_catalog_image.outputs.image_to_check }} + format: 'table' + exit-code: '1' + severity: 'CRITICAL,HIGH' + + - name: Catalog - push image + uses: docker/build-push-action@v3 + with: + context: everest-catalog + push: true + tags: ${{ steps.catalog_meta.outputs.tags }} + file: everest-catalog/everest-catalog.Dockerfile + + - name: Everest - check out + uses: actions/checkout@v4 + with: + token: ${{ secrets.ROBOT_TOKEN }} + + - name: Everest - setup golang + uses: actions/setup-go@v5 + with: + go-version-file: './go.mod' + + - name: Everest - create and update release branch + run: | + # Check if the branch already exists + git fetch + check_branch=$(git ls-remote --heads origin ${BRANCH_NAME}) + + if [[ -z ${check_branch} ]]; then + git checkout -b $BRANCH_NAME + git push origin $BRANCH_NAME + fi + git checkout $BRANCH_NAME + + # Update deploy manifest + if [[ $env.IS_RC ]]; then + sed -i "s/perconalab\/everest.*/perconalab\/everest:$VERSION/g" deploy/quickstart-k8s.yaml + sed -i "s/percona\/percona-everest.*/perconalab\/everest:$VERSION/g" deploy/quickstart-k8s.yaml + else + sed -i "s/perconalab\/everest.*/percona\/percona-everest:$VERSION/g" deploy/quickstart-k8s.yaml + sed -i "s/percona\/percona-everest.*/percona\/percona-everest:$VERSION/g" deploy/quickstart-k8s.yaml + fi + + # Update the operator go module to reference the version tag + go get github.com/percona/everest-operator@$GH_TAG + go mod tidy + + # Change version in Makefile + sed -i "s/RELEASE_VERSION ?=.*/RELEASE_VERSION ?= v$VERSION/g" Makefile + + # if there is something to commit, commit it and add the tag + if [[ -n $(git status --porcelain) ]]; then + if git tag --list | grep -q "^$GH_TAG$"; then + echo "The tag is already present in github. Please create a different RC/Release" + exit 1 + fi + # configure userdata for commits + git config --global user.email "everest-ci@percona.com" + git config --global user.name "Everest RC CI triggered by ${{ github.actor }}" + + # commit and push the updated files + git commit -a -m "update version tag" + git push origin $BRANCH_NAME + + git tag $GH_TAG + git push origin $GH_TAG + fi + + - name: Everest UI - setup pnpm + uses: pnpm/action-setup@v3 + with: + version: 8 + + - name: Everest UI - run with Node 20 + uses: actions/setup-node@v4 + with: + node-version: 20.x + cache: 'pnpm' + cache-dependency-path: ui/pnpm-lock.yaml + + - name: Everest UI - build + run: | + cd ui + pnpm install + EVEREST_OUT_DIR=${GITHUB_WORKSPACE}/public/dist/ pnpm build + + - name: Everest - build binary + run: | + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 make build + + - name: Everest - setup docker build metadata + uses: docker/metadata-action@v5 + id: everest_meta + with: + images: | + percona/percona-everest,enable=${{ env.IS_RC == 0 }} + perconalab/everest + tags: | + type=raw,value=${{ env.VERSION }} + type=raw,value=latest + type=raw,value=${{ env.FLOATING_TAG }},enable=${{ env.IS_RC == 0 }} + + - name: Everest - build Everest image + uses: docker/build-push-action@v5 + with: + context: . + push: false + tags: ${{ steps.everest_meta.outputs.tags }} + + - name: Everest - set everest image to scan + id: set_everest_image + run: | + # taking the first tag to check with trivy. Since the build is the same, no need to check the rest of them + echo "::set-output name=image_to_check::$(echo "${{ steps.everest_meta.outputs.tags }}" | head -n 1)" + + - name: Everest - run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@0.12.0 + with: + image-ref: ${{ steps.set_everest_image.outputs.image_to_check }} + format: 'table' + exit-code: '1' + severity: 'CRITICAL,HIGH' + + - name: Everest - push Everest image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.everest_meta.outputs.tags }} + + - name: CLI - build binaries + run: | + make release-cli + + - name: CLI - create release with binaries + uses: softprops/action-gh-release@v1 + with: + draft: true + files: | + dist/* + env: + GITHUB_TOKEN: ${{ github.token }} + + diff --git a/Makefile b/Makefile index f9d0e0610..3f1a183ad 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,12 @@ release: FLAGS += -X 'github.com/percona/everest/cmd/config.TelemetryURL=https:/ release: build ## Build release version +release-cli: + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v $(LD_FLAGS_CLI) -o ./dist/everestctl-linux-amd64 ./cmd/cli + CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -v $(LD_FLAGS_CLI) -o ./dist/everestctl-linux-arm64 ./cmd/cli + CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -v $(LD_FLAGS_CLI) -o ./dist/everestctl-darwin-amd64 ./cmd/cli + CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -v $(LD_FLAGS_CLI) -o ./dist/everestctl-darwin-arm64 ./cmd/cli + CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -v $(LD_FLAGS_CLI) -o ./dist/everestctl.exe ./cmd/cli build-debug: ## Build binaries go build -tags debug -v $(LD_FLAGS_API) -o bin/everest ./cmd diff --git a/go.mod b/go.mod index 75b04d45b..e301102ef 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/oapi-codegen/runtime v1.1.1 github.com/operator-framework/api v0.22.0 github.com/operator-framework/operator-lifecycle-manager v0.26.0 - github.com/percona/everest-operator v0.6.0-dev1.0.20240320193418-5589fbee25eb + github.com/percona/everest-operator v0.6.0-dev1.0.20240321080344-5ebebf3b97ae github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.9.0 @@ -100,7 +100,7 @@ require ( github.com/montanaflynn/stats v0.6.6 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/onsi/gomega v1.31.1 // indirect + github.com/onsi/gomega v1.32.0 // indirect github.com/operator-framework/operator-registry v1.30.1 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/percona/percona-backup-mongodb v1.8.1-0.20230920143330-3b1c2e263901 // indirect diff --git a/go.sum b/go.sum index 342a0d620..37e47420c 100644 --- a/go.sum +++ b/go.sum @@ -530,8 +530,8 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= -github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= +github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= +github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= @@ -549,8 +549,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/percona/everest-operator v0.6.0-dev1.0.20240320193418-5589fbee25eb h1:6Mj1zPWQgCmETxqTTLYFdDKQiBZ/ace/hvTVvs2qasM= -github.com/percona/everest-operator v0.6.0-dev1.0.20240320193418-5589fbee25eb/go.mod h1:aVoMfYKLOxkm592jVFY+KiDxvvUx1yWnzU4Da8BssEk= +github.com/percona/everest-operator v0.6.0-dev1.0.20240321080344-5ebebf3b97ae h1:TfRQGnA1KGxk57IJyn8H54zlC6THxAAM+/lXeWd/qAE= +github.com/percona/everest-operator v0.6.0-dev1.0.20240321080344-5ebebf3b97ae/go.mod h1:/lnoyOjSuriLWBnmO7uV9YWZGM5l+pJOJ/pxur7e9qQ= github.com/percona/percona-backup-mongodb v1.8.1-0.20230920143330-3b1c2e263901 h1:BDgsZRCjEuxl2/z4yWBqB0s8d20shuIDks7/RVdZiLs= github.com/percona/percona-backup-mongodb v1.8.1-0.20230920143330-3b1c2e263901/go.mod h1:fZRCMpUqkWlLVdRKqqaj001LoVP2eo6F0ZhoMPeXDng= github.com/percona/percona-postgresql-operator v0.0.0-20231220140959-ad5eef722609 h1:+UOK4gcHrRgqjo4smgfwT7/0apF6PhAJdQIdAV4ub/M=