name: CI on: pull_request: types: [opened, synchronize, reopened] push: branches: - "*" tags: - "*" env: GOPROXY: https://proxy.golang.org,direct GO111MODULE: on tf_version: "1.3.0" tf_init_cli_options: "-input=false" tf_validation_cli_options: "" tf_plan_cli_options: "-lock=false -input=false" tf_apply_cli_options: "-auto-approve -input=false" jobs: tests: env: GOPATH: ${{ github.workspace }} GOBIN: ${{ github.workspace }}/bin runs-on: ubuntu-latest defaults: run: working-directory: ${{ env.GOPATH }}/src/XDPoSChain strategy: matrix: include: - name: A-B tests script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[a-b].*") - name: C-[a-m] tests script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/c[a-m].*") - name: C-[n-o] tests script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/c[n-o].*") - name: C-[p-z] tests script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/c[p-z].*") - name: D-I tests script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[d-i].*") - name: J-N tests script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[j-n].*") - name: O-S tests script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[o-s].*") - name: T-Z tests script: go run build/ci.go test -coverage $(go list ./... | grep "github.com/XinFinOrg/XDPoSChain/[t-z].*") steps: - name: Check out code uses: actions/checkout@v4 with: path: ${{ env.GOPATH }}/src/XDPoSChain # Cache build tools to avoid downloading them each time - uses: actions/cache@v4 with: path: ${{ env.GOPATH }}/src/XDPoSChain/build/cache key: ${{ runner.os }}-build-tools-cache-${{ hashFiles('**/build/checksums.txt') }} - name: Set up Go uses: actions/setup-go@v5 with: cache: false go-version: "1.25.x" - name: Check gofmt run: | unformatted=$(git ls-files '*.go' | xargs -r gofmt -l) if [ -n "$unformatted" ]; then echo "Unformatted files:" echo "$unformatted" exit 1 fi echo "All Go files are properly formatted." - name: Check go mod tidy run: | set -euo pipefail go mod tidy -diff 2>&1 | sed '/^go: downloading/d' echo "go.mod and go.sum are tidy." - name: Validate generated files run: | go run build/ci.go generate - name: Run tests run: ${{ matrix.script }} env: GO111MODULE: auto tag_build: runs-on: ubuntu-latest needs: tests if: startsWith(github.ref, 'refs/tags/') steps: - uses: actions/checkout@v4 - name: Login to Docker Hub run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - name: Build Docker image run: docker build --build-arg GIT_COMMIT=${GITHUB_SHA} -t xinfinorg/xdposchain:${GITHUB_REF#refs/tags/} -f cicd/Dockerfile . - name: Push Docker image run: docker push xinfinorg/xdposchain:${GITHUB_REF#refs/tags/} devnet_build_push: runs-on: ubuntu-latest if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') needs: tests outputs: output1: ${{ steps.docker.outputs.image_name }} steps: - uses: actions/checkout@v4 - name: Login to Docker Hub run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - name: Build and Push Docker images id: docker run: | git_hash=$(git rev-parse --short "$GITHUB_SHA") image_name=xinfinorg/devnet:dev-upgrade-${git_hash} docker pull xinfinorg/devnet:latest docker tag xinfinorg/devnet:latest xinfinorg/devnet:previous docker rmi xinfinorg/devnet:latest docker build --build-arg GIT_COMMIT=${GITHUB_SHA} -t xinfinorg/devnet:latest -f cicd/Dockerfile . docker tag xinfinorg/devnet:latest $image_name docker push $image_name docker push xinfinorg/devnet:latest docker push xinfinorg/devnet:previous echo "image_name=$image_name" echo "image_name=$image_name" >> "$GITHUB_OUTPUT" devnet_k8_apply: runs-on: ubuntu-latest if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') needs: devnet_build_push steps: - uses: actions/checkout@v4 - name: Set up kubectl uses: azure/setup-kubectl@v4 with: version: "v1.19.11" - name: Apply new image version to Kubernetes deployments run: | mkdir -p $HOME/.kube echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config chmod 600 $HOME/.kube/config git_hash=$(git rev-parse --short "$GITHUB_SHA") masternodes=$(kubectl get deployment -o json | jq -r '.items[] | select(.metadata.name | test("^masternode[0-9]")) | .metadata.name' | sort) rpcs=$(kubectl get deployment -o json| jq -r '.items[] | select(.metadata.name | test("rpc")) | "\(.metadata.name)"') echo "Masternodes: $masternodes" echo "RPCs: $rpcs" # Skip masternode1 through masternode25, update the rest. readarray -t mn_array <<< "$masternodes" total=${#mn_array[@]} echo "Total masternode deployments: $total, skipping masternode1..masternode25" for name in "${mn_array[@]}"; do if [[ $name =~ ^masternode[0-9] ]]; then num=${name#masternode} num=${num%%-*} if [[ $num =~ ^[0-9]+$ ]] && (( num >= 1 && num <= 25 )); then echo "Skipping deployment: $name" continue fi fi echo "Updating deployment: $name" kubectl set image "deployment/$name" "$name=xinfinorg/devnet:dev-upgrade-${git_hash}" || true done while read -r name; do kubectl set image deployment/$name $name=xinfinorg/devnet:dev-upgrade-${git_hash} || true done <<< "$rpcs" devnet_send_notification: runs-on: ubuntu-latest needs: devnet_k8_apply if: github.ref == 'refs/heads/dev-upgrade' && !startsWith(github.ref, 'refs/tags/') steps: - uses: actions/checkout@v4 - name: Send deployment notification env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} SLACK_WEBHOOK: ${{ secrets.SLACK_DEPLOYMENT_WEBHOOK_URL }} REPO: ${{ github.repository }} run: | # Look up the merged PR that contains this commit PR_JSON=$(curl -s -H "Authorization: Bearer ${GH_TOKEN}" \ "https://api.github.com/repos/${REPO}/commits/${GITHUB_SHA}/pulls") PR_NUMBER=$(echo "$PR_JSON" | jq -r '.[0].number // empty') PR_URL=$(echo "$PR_JSON" | jq -r '.[0].html_url // empty') if [ -n "$PR_NUMBER" ]; then PR_LINE="Merged PR: <${PR_URL}|#${PR_NUMBER}>" else PR_LINE="Commit: " fi curl -X POST -H 'Content-type: application/json' \ --data "$(jq -n \ --arg pr_line "$PR_LINE" \ --arg sha "$GITHUB_SHA" \ '{ "text": ":rocket: Deployment: devnet", "blocks": [ { "type": "header", "text": {"type": "plain_text", "text": ":rocket: Deployment: devnet"} }, { "type": "section", "text": {"type": "mrkdwn", "text": ("Service: *xdc*\nEnvironment: *devnet*\nVersion: `" + $sha + "`\n" + $pr_line)} } ] }')" \ "$SLACK_WEBHOOK"