From 21655cb56f75419fb0ad90b761084e94237a6d8b Mon Sep 17 00:00:00 2001 From: zyy17 Date: Thu, 3 Aug 2023 17:11:39 +0800 Subject: [PATCH] ci: add nightly build workflow (#2089) --- .../actions/build-greptime-images/action.yml | 16 + .github/actions/build-images/action.yml | 6 + .github/scripts/create-version.sh | 17 +- .github/workflows/nightly-build.yml | 305 ++++++++++++++++++ 4 files changed, 341 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/nightly-build.yml diff --git a/.github/actions/build-greptime-images/action.yml b/.github/actions/build-greptime-images/action.yml index b4eaba302d..31bccc5296 100644 --- a/.github/actions/build-greptime-images/action.yml +++ b/.github/actions/build-greptime-images/action.yml @@ -32,6 +32,10 @@ inputs: platforms: description: The supported platforms to build the image required: true + push-latest-tag: + description: Whether to push the latest tag + required: false + default: 'true' runs: using: composite steps: @@ -76,7 +80,19 @@ runs: rm -rf arm64 && \ mv ${{ inputs.arm64-artifact-name }} arm64 + - name: Build and push images(without latest) for amd64 and arm64 + if: ${{ inputs.push-latest-tag == 'false' }} + uses: docker/build-push-action@v3 + with: + context: . + file: ${{ inputs.docker-file }} + push: true + platforms: ${{ inputs.platforms }} + tags: | + ${{ inputs.image-registry }}/${{ inputs.image-namespace }}/${{ inputs.image-name }}:${{ inputs.image-tag }} + - name: Build and push images for amd64 and arm64 + if: ${{ inputs.push-latest-tag == 'true' }} uses: docker/build-push-action@v3 with: context: . diff --git a/.github/actions/build-images/action.yml b/.github/actions/build-images/action.yml index 4405e5c6b7..dc63d15eba 100644 --- a/.github/actions/build-images/action.yml +++ b/.github/actions/build-images/action.yml @@ -16,6 +16,10 @@ inputs: version: description: Version of the artifact required: true + push-latest-tag: + description: Whether to push the latest tag + required: false + default: 'true' runs: using: composite steps: @@ -32,6 +36,7 @@ runs: amd64-artifact-name: greptime-linux-amd64-pyo3-${{ inputs.version }} arm64-artifact-name: greptime-linux-arm64-pyo3-${{ inputs.version }} platforms: linux/amd64,linux/arm64 + push-latest-tag: ${{ inputs.push-latest-tag }} - name: Build and push centos images to dockerhub uses: ./.github/actions/build-greptime-images @@ -45,3 +50,4 @@ runs: docker-file: docker/ci/Dockerfile-centos amd64-artifact-name: greptime-linux-amd64-centos-${{ inputs.version }} platforms: linux/amd64 + push-latest-tag: ${{ inputs.push-latest-tag }} diff --git a/.github/scripts/create-version.sh b/.github/scripts/create-version.sh index 22f0dd7105..9047b0bdb9 100755 --- a/.github/scripts/create-version.sh +++ b/.github/scripts/create-version.sh @@ -3,8 +3,9 @@ set -e # - If it's a tag push release, the version is the tag name(${{ github.ref_name }}); -# - If it's a scheduled release, the version is '${{ env.NEXT_RELEASE_VERSION }}-nightly-$buildTime', like v0.2.0-nigthly-20230313; -# - If it's a manual release, the version is '${{ env.NEXT_RELEASE_VERSION }}-$(git rev-parse --short HEAD)-YYYYMMDDSS', like v0.2.0-e5b243c-2023071245; +# - If it's a scheduled release, the version is '${{ env.NEXT_RELEASE_VERSION }}-nightly-$buildTime', like 'v0.2.0-nightly-20230313'; +# - If it's a manual release, the version is '${{ env.NEXT_RELEASE_VERSION }}-$(git rev-parse --short HEAD)-YYYYMMDDSS', like 'v0.2.0-e5b243c-2023071245'; +# - If it's a nightly build, the version is 'nightly-YYYYMMDD-$(git rev-parse --short HEAD)', like 'nightly-20230712-e5b243c'. # create_version ${GIHUB_EVENT_NAME} ${NEXT_RELEASE_VERSION} ${NIGHTLY_RELEASE_PREFIX} function create_version() { # Read from envrionment variables. @@ -23,6 +24,12 @@ function create_version() { exit 1 fi + # Reuse $NEXT_RELEASE_VERSION to identify whether it's a nightly build. + if [ "$NEXT_RELEASE_VERSION" = dev ]; then + echo "$NIGHTLY_RELEASE_PREFIX-$(date "+%Y%m%d")-$(git rev-parse --short HEAD)" + exit 0 + fi + # Note: Only output 'version=xxx' to stdout when everything is ok, so that it can be used in GitHub Actions Outputs. if [ "$GITHUB_EVENT_NAME" = push ]; then if [ -z "$GITHUB_REF_NAME" ]; then @@ -40,5 +47,9 @@ function create_version() { fi } -# You can run as: GITHUB_EVENT_NAME=push NEXT_RELEASE_VERSION=v0.4.0 NIGHTLY_RELEASE_PREFIX=nigthly GITHUB_REF_NAME=v0.3.0 ./create-version.sh +# You can run as following examples: +# GITHUB_EVENT_NAME=push NEXT_RELEASE_VERSION=v0.4.0 NIGHTLY_RELEASE_PREFIX=nigtly GITHUB_REF_NAME=v0.3.0 ./create-version.sh +# GITHUB_EVENT_NAME=workflow_dispatch NEXT_RELEASE_VERSION=v0.4.0 NIGHTLY_RELEASE_PREFIX=nigtly ./create-version.sh +# GITHUB_EVENT_NAME=schedule NEXT_RELEASE_VERSION=v0.4.0 NIGHTLY_RELEASE_PREFIX=nigtly ./create-version.sh +# GITHUB_EVENT_NAME=schedule NEXT_RELEASE_VERSION=dev NIGHTLY_RELEASE_PREFIX=nigtly ./create-version.sh create_version diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml new file mode 100644 index 0000000000..9e456bf1fc --- /dev/null +++ b/.github/workflows/nightly-build.yml @@ -0,0 +1,305 @@ +# Nightly build only do the following things: +# 1. Run integration tests; +# 2. Build binaries and images for linux-amd64 and linux-arm64 platform; +name: GreptimeDB Nightly build + +on: + schedule: + # Trigger at 00:00(UTC) on every day-of-week from Monday through Friday. + - cron: '0 0 * * 1-5' + workflow_dispatch: # Allows you to run this workflow manually. + inputs: + linux_amd64_runner: + type: choice + description: The runner uses to build linux-amd64 artifacts + default: ec2-c6i.2xlarge-amd64 + options: + - ubuntu-latest + - ubuntu-latest-8-cores + - ubuntu-latest-16-cores + - ubuntu-latest-32-cores + - ubuntu-latest-64-cores + - ec2-c6i.xlarge-amd64 # 4C8G + - ec2-c6i.2xlarge-amd64 # 8C16G + - ec2-c6i.4xlarge-amd64 # 16C32G + - ec2-c6i.8xlarge-amd64 # 32C64G + - ec2-c6i.16xlarge-amd64 # 64C128G + linux_arm64_runner: + type: choice + description: The runner uses to build linux-arm64 artifacts + default: ec2-c6g.2xlarge-arm64 + options: + - ec2-c6g.xlarge-arm64 # 4C8G + - ec2-c6g.2xlarge-arm64 # 8C16G + - ec2-c6g.4xlarge-arm64 # 16C32G + - ec2-c6g.8xlarge-arm64 # 32C64G + - ec2-c6g.16xlarge-arm64 # 64C128G + skip_test: + description: Do not run integration tests during the build + type: boolean + default: true + build_linux_amd64_artifacts: + type: boolean + description: Build linux-amd64 artifacts + required: false + default: false + build_linux_arm64_artifacts: + type: boolean + description: Build linux-arm64 artifacts + required: false + default: false + release_images: + type: boolean + description: Build and push images to DockerHub and ACR + required: false + default: false + +# Use env variables to control all the release process. +env: + CARGO_PROFILE: nightly + + # Controls whether to run tests, include unit-test, integration-test and sqlness. + DISABLE_RUN_TESTS: ${{ inputs.skip_test || vars.DEFAULT_SKIP_TEST }} + + # Always use 'dev' to indicate it's the nightly build. + NEXT_RELEASE_VERSION: dev + +jobs: + allocate-runners: + name: Allocate runners + if: ${{ github.repository == 'GreptimeTeam/greptimedb' }} + runs-on: ubuntu-latest + outputs: + linux-amd64-runner: ${{ steps.start-linux-amd64-runner.outputs.label }} + linux-arm64-runner: ${{ steps.start-linux-arm64-runner.outputs.label }} + + # The following EC2 resource id will be used for resource releasing. + linux-amd64-ec2-runner-label: ${{ steps.start-linux-amd64-runner.outputs.label }} + linux-amd64-ec2-runner-instance-id: ${{ steps.start-linux-amd64-runner.outputs.ec2-instance-id }} + linux-arm64-ec2-runner-label: ${{ steps.start-linux-arm64-runner.outputs.label }} + linux-arm64-ec2-runner-instance-id: ${{ steps.start-linux-arm64-runner.outputs.ec2-instance-id }} + + # The 'version' use as the global tag name of the release workflow. + version: ${{ steps.create-version.outputs.version }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Create version + id: create-version + run: | + echo "version=$(./.github/scripts/create-version.sh)" >> $GITHUB_OUTPUT + env: + GITHUB_EVENT_NAME: ${{ github.event_name }} + GITHUB_REF_NAME: ${{ github.ref_name }} + NEXT_RELEASE_VERSION: ${{ env.NEXT_RELEASE_VERSION }} + NIGHTLY_RELEASE_PREFIX: ${{ env.NIGHTLY_RELEASE_PREFIX }} + + - name: Allocate linux-amd64 runner + if: ${{ inputs.build_linux_amd64_artifacts || github.event_name == 'schedule' }} + uses: ./.github/actions/start-runner + id: start-linux-amd64-runner + with: + runner: ${{ inputs.linux_amd64_runner || vars.DEFAULT_AMD64_RUNNER }} + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ vars.EC2_RUNNER_REGION }} + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + image-id: ${{ vars.EC2_RUNNER_LINUX_AMD64_IMAGE_ID }} + security-group-id: ${{ vars.EC2_RUNNER_SECURITY_GROUP_ID }} + subnet-id: ${{ vars.EC2_RUNNER_SUBNET_ID }} + + - name: Allocate linux-arm64 runner + if: ${{ inputs.build_linux_arm64_artifacts || github.event_name == 'schedule' }} + uses: ./.github/actions/start-runner + id: start-linux-arm64-runner + with: + runner: ${{ inputs.linux_arm64_runner || vars.DEFAULT_ARM64_RUNNER }} + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ vars.EC2_RUNNER_REGION }} + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + image-id: ${{ vars.EC2_RUNNER_LINUX_ARM64_IMAGE_ID }} + security-group-id: ${{ vars.EC2_RUNNER_SECURITY_GROUP_ID }} + subnet-id: ${{ vars.EC2_RUNNER_SUBNET_ID }} + + build-linux-amd64-artifacts: + name: Build linux-amd64 artifacts + if: ${{ inputs.build_linux_amd64_artifacts || github.event_name == 'schedule' }} + needs: [ + allocate-runners, + ] + runs-on: ${{ needs.allocate-runners.outputs.linux-amd64-runner }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: ./.github/actions/build-linux-artifacts + with: + arch: amd64 + cargo-profile: ${{ env.CARGO_PROFILE }} + version: ${{ needs.allocate-runners.outputs.version }} + disable-run-tests: ${{ env.DISABLE_RUN_TESTS }} + release-to-s3-bucket: ${{ vars.AWS_RELEASE_BUCKET }} + aws-access-key-id: ${{ secrets.AWS_CN_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_CN_SECRET_ACCESS_KEY }} + aws-region: ${{ vars.AWS_RELEASE_BUCKET_REGION }} + + build-linux-arm64-artifacts: + name: Build linux-arm64 artifacts + if: ${{ inputs.build_linux_arm64_artifacts || github.event_name == 'schedule' }} + needs: [ + allocate-runners, + ] + runs-on: ${{ needs.allocate-runners.outputs.linux-arm64-runner }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: ./.github/actions/build-linux-artifacts + with: + arch: arm64 + cargo-profile: ${{ env.CARGO_PROFILE }} + version: ${{ needs.allocate-runners.outputs.version }} + disable-run-tests: ${{ env.DISABLE_RUN_TESTS }} + release-to-s3-bucket: ${{ vars.AWS_RELEASE_BUCKET }} + aws-access-key-id: ${{ secrets.AWS_CN_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_CN_SECRET_ACCESS_KEY }} + aws-region: ${{ vars.AWS_RELEASE_BUCKET_REGION }} + + release-images-to-dockerhub: + name: Build and push images to DockerHub + if: ${{ inputs.release_images || github.event_name == 'schedule' }} + needs: [ + allocate-runners, + build-linux-amd64-artifacts, + build-linux-arm64-artifacts, + ] + runs-on: ubuntu-latest + outputs: + nightly-build-result: ${{ steps.set-nightly-build-result.outputs.nightly-build-result }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Build and push images to dockerhub + uses: ./.github/actions/build-images + with: + image-registry: docker.io + image-namespace: ${{ vars.IMAGE_NAMESPACE }} + image-registry-username: ${{ secrets.DOCKERHUB_USERNAME }} + image-registry-password: ${{ secrets.DOCKERHUB_TOKEN }} + version: ${{ needs.allocate-runners.outputs.version }} + push-latest-tag: false # Don't push the latest tag to registry. + + - name: Set nightly build result + id: set-nightly-build-result + run: | + echo "nightly-build-result=success" >> $GITHUB_OUTPUT + + release-images-to-acr: + name: Build and push images to ACR + if: ${{ inputs.release_images || github.event_name == 'schedule' }} + needs: [ + allocate-runners, + build-linux-amd64-artifacts, + build-linux-arm64-artifacts, + ] + runs-on: ubuntu-latest + # When we push to ACR, it's easy to fail due to some unknown network issues. + # However, we don't want to fail the whole workflow because of this. + # The ACR have daily sync with DockerHub, so don't worry about the image not being updated. + continue-on-error: true + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Build and push images to ACR + uses: ./.github/actions/build-images + with: + image-registry: ${{ vars.ACR_IMAGE_REGISTRY }} + image-namespace: ${{ vars.IMAGE_NAMESPACE }} + image-registry-username: ${{ secrets.ALICLOUD_USERNAME }} + image-registry-password: ${{ secrets.ALICLOUD_PASSWORD }} + version: ${{ needs.allocate-runners.outputs.version }} + push-latest-tag: false # Don't push the latest tag to registry. + + stop-linux-amd64-runner: # It's always run as the last job in the workflow to make sure that the runner is released. + name: Stop linux-amd64 runner + # Only run this job when the runner is allocated. + if: ${{ always() }} + runs-on: ubuntu-latest + needs: [ + allocate-runners, + build-linux-amd64-artifacts, + ] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Stop EC2 runner + uses: ./.github/actions/stop-runner + with: + label: ${{ needs.allocate-runners.outputs.linux-amd64-ec2-runner-label }} + ec2-instance-id: ${{ needs.allocate-runners.outputs.linux-amd64-ec2-runner-instance-id }} + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ vars.EC2_RUNNER_REGION }} + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + stop-linux-arm64-runner: # It's always run as the last job in the workflow to make sure that the runner is released. + name: Stop linux-arm64 runner + # Only run this job when the runner is allocated. + if: ${{ always() }} + runs-on: ubuntu-latest + needs: [ + allocate-runners, + build-linux-arm64-artifacts, + ] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Stop EC2 runner + uses: ./.github/actions/stop-runner + with: + label: ${{ needs.allocate-runners.outputs.linux-arm64-ec2-runner-label }} + ec2-instance-id: ${{ needs.allocate-runners.outputs.linux-arm64-ec2-runner-instance-id }} + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ vars.EC2_RUNNER_REGION }} + github-token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + + notification: + if: ${{ always() }} # Not requiring successful dependent jobs, always run. + name: Send notification to Greptime team + needs: [ + release-images-to-dockerhub + ] + runs-on: ubuntu-latest + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_DEVELOP_CHANNEL }} + steps: + - name: Notifiy nightly build successful result + uses: slackapi/slack-github-action@v1.23.0 + if: ${{ needs.release-images-to-dockerhub.outputs.nightly-build-result == 'success' }} + with: + payload: | + {"text": "GreptimeDB nightly build successful"} + + - name: Notifiy nightly build failed result + uses: slackapi/slack-github-action@v1.23.0 + if: ${{ needs.release-images-to-dockerhub.outputs.nightly-build-result != 'success' }} + with: + payload: | + {"text": "GreptimeDB nightly build failed, please check 'https://github.com/GreptimeTeam/greptimedb/actions/workflows/nightly-build.yaml'"}