diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 000000000..6f4ffa9f0 --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,68 @@ +name: Benchmark + +on: + push: + branches: + - master + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + benchmark: + name: benchmark + runs-on: ubuntu-latest + environment: master_n_tags + container: + image: paritytech/node-wrk:latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: benchmarks + run: | + yarn --immutable + echo "Benchmarks for polkadot" + mkdir -p artifacts + yarn bench --log-level info --ws-url wss://rpc.polkadot.io + mv benchmarks.txt artifacts/ + + - name: upload artifacts + uses: actions/upload-artifact@v4 + with: + name: benchmarks + path: ./artifacts/ + + benchmark-publish: + name: benchmark publish + runs-on: ubuntu-latest + needs: [benchmark] + environment: master_n_tags + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ secrets.GH_APP_SAS_APP_ID }} + private-key: ${{ secrets.GH_APP_SAS_APP_KEY }} + + - name: download artifacts + uses: actions/download-artifact@v4 + with: + name: benchmarks + path: artifacts + + - name: Modify benches result for benhcmark action + run: ./scripts/ci/benchmarks/generate_benchmark_result.sh artifacts/benchmarks.txt > artifacts/benchmarks.json + + - name: Store benchmark result + uses: benchmark-action/github-action-benchmark@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 #1.20.4 + with: + tool: "customSmallerIsBetter" + output-file-path: artifacts/benchmarks.json + # Push and deploy GitHub pages branch automatically + auto-push: true + github-token: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/calc.yml b/.github/workflows/calc.yml index bcd5c2e12..6218812e1 100644 --- a/.github/workflows/calc.yml +++ b/.github/workflows/calc.yml @@ -2,9 +2,13 @@ name: calc on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true jobs: build: diff --git a/.github/workflows/pr.yml b/.github/workflows/ci.yml similarity index 64% rename from .github/workflows/pr.yml rename to .github/workflows/ci.yml index 8151bbf4f..c2d2b6e5c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,10 @@ on: branches: - master +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: lint: # The type of runner that the job will run on @@ -21,7 +25,7 @@ jobs: - name: Install Node v18 uses: actions/setup-node@v4 with: - node-version: '18.14' + node-version: "18.14" - name: Get yarn cache directory path id: yarn-cache-dir-path @@ -41,7 +45,7 @@ jobs: - name: Linter. run: yarn lint tests: - # The type of runner that the job will run on + # The type of runner that the job will run on runs-on: ubuntu-latest steps: @@ -51,7 +55,7 @@ jobs: - name: Install Node v18 uses: actions/setup-node@v4 with: - node-version: '18.14' + node-version: "18.14" - name: Get yarn cache directory path id: yarn-cache-dir-path @@ -82,7 +86,7 @@ jobs: - name: Install Node v18 uses: actions/setup-node@v4 with: - node-version: '18.14' + node-version: "18.14" - name: Get yarn cache directory path id: yarn-cache-dir-path @@ -113,7 +117,7 @@ jobs: - name: Install Node v18 uses: actions/setup-node@v4 with: - node-version: '18.14' + node-version: "18.14" - name: Get yarn cache directory path id: yarn-cache-dir-path @@ -134,11 +138,11 @@ jobs: run: yarn build:docs build-npm-release: - # This test is to make sure sidecar can release a binary without any errors. - # This script does not publish a release, but instead uses yarn to create a tarball and - # install it locally. Once installed a binary is attached to sidecars node_modules, and that - # binary is then tested against. For more in depth information reference the docs at - # `../../scripts/README.md`. + # This test is to make sure sidecar can release a binary without any errors. + # This script does not publish a release, but instead uses yarn to create a tarball and + # install it locally. Once installed a binary is attached to sidecars node_modules, and that + # binary is then tested against. For more in depth information reference the docs at + # `../../scripts/README.md`. runs-on: ubuntu-latest @@ -147,10 +151,50 @@ jobs: node-version: [18.x] steps: - - uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - - run: yarn - - run: yarn test:test-release + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + - run: yarn + - run: yarn test:test-release + + build_docker: + name: Build docker image + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Build Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: false + tags: | + docker.io/parity/substrate-api-sidecar:latest + + e2e: + name: e2e + runs-on: ubuntu-latest + container: + image: node:18 + strategy: + matrix: + include: + - chain-name: westend + chain-url: wss://westend-rpc.polkadot.io + - chain-name: kusama + chain-url: wss://apps-kusama-rpc.polkadot.io + - chain-name: polkadot + chain-url: wss://apps-rpc.polkadot.io + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: e2e tests + run: | + yarn --immutable + echo "Tests for ${{ matrix.chain-name }}" + yarn test:latest-e2e-tests --log-level info --chain ${{ matrix.chain-name }} --local ${{ matrix.chain-url }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 000000000..9045d272e --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,156 @@ +name: Deploy + +on: + push: + branches: + - master + tags: + - v* + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +#to use reusable workflow +permissions: + id-token: write + contents: read + +env: + APP: "substrate-api-sidecar" + +jobs: + set-variables: + # This workaround sets the container image for each job using 'set-variables' job output. + # env variables don't work for PR from forks, so we need to use outputs. + runs-on: ubuntu-latest + outputs: + VERSION: ${{ steps.version.outputs.VERSION }} + steps: + - name: Define version + id: version + run: | + export COMMIT_SHA=${{ github.sha }} + export COMMIT_SHA_SHORT=${COMMIT_SHA:0:8} + export REF_NAME=${{ github.ref_name }} + export REF_SLUG=${REF_NAME//\//_} + if [[ ${REF_SLUG} == "master" ]] + then + VERSION=${REF_SLUG}-${COMMIT_SHA_SHORT} + echo "VERSION=${REF_SLUG}-${COMMIT_SHA_SHORT}" >> $GITHUB_OUTPUT + else + VERSION=${REF_SLUG} + echo "VERSION=${REF_SLUG}" >> $GITHUB_OUTPUT + fi + echo "set VERSION=${VERSION}" + + build_push_docker: + name: Build docker image + runs-on: ubuntu-latest + environment: master_n_tags + needs: [set-variables] + env: + VERSION: ${{ needs.set-variables.outputs.VERSION }} + steps: + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Build Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: true + tags: | + docker.io/parity/substrate-api-sidecar:${{ env.VERSION }} + + deploy-stg-kusama: + name: Deploy Staging + runs-on: ubuntu-latest + needs: [set-variables, build_push_docker] + environment: parity-stg + env: + VERSION: ${{ needs.set-variables.outputs.VERSION }} + ARGOCD_SERVER: "argocd-stg.teleport.parity.io" + steps: + - name: Deploy to ArgoCD + uses: paritytech/argocd-deployment-action@main + with: + environment: "parity-stg" + tag: "${{ env.VERSION }}" + app_name: "substrate-api-sidecar-kusama" + app_packages: "${{ env.APP }}" + argocd_server: ${{ env.ARGOCD_SERVER }} + teleport_token: ${{ env.APP }} + teleport_app_name: "argocd-stg" + argocd_auth_token: ${{ secrets.ARGOCD_AUTH_TOKEN }} + + deploy-stg-polkadot: + name: Deploy Staging + runs-on: ubuntu-latest + needs: [set-variables, build_push_docker] + environment: parity-stg + env: + VERSION: ${{ needs.set-variables.outputs.VERSION }} + ARGOCD_SERVER: "argocd-stg.teleport.parity.io" + steps: + - name: Deploy to ArgoCD + uses: paritytech/argocd-deployment-action@main + with: + environment: "parity-stg" + tag: "${{ env.VERSION }}" + app_name: "substrate-api-sidecar-polkadot" + app_packages: "${{ env.APP }}" + argocd_server: ${{ env.ARGOCD_SERVER }} + teleport_token: ${{ env.APP }} + teleport_app_name: "argocd-stg" + argocd_auth_token: ${{ secrets.ARGOCD_AUTH_TOKEN }} + + deploy-prod-kusama: + name: Deploy Production + runs-on: ubuntu-latest + needs: [set-variables, deploy-stg-kusama] + # Deploy only if the tag is v* + if: startsWith(github.ref, 'refs/tags/v') + environment: parity-chains + env: + VERSION: ${{ needs.set-variables.outputs.VERSION }} + ARGOCD_SERVER: "argocd-chains.teleport.parity.io" + steps: + - name: Deploy to ArgoCD + uses: paritytech/argocd-deployment-action@main + with: + environment: "parity-chains" + tag: "${{ env.VERSION }}" + app_name: "substrate-api-sidecar-kusama" + app_packages: "${{ env.APP }}" + argocd_server: ${{ env.ARGOCD_SERVER }} + teleport_token: ${{ env.APP }} + teleport_app_name: "argocd-chains" + argocd_auth_token: ${{ secrets.ARGOCD_AUTH_TOKEN }} + + deploy-prod-polkadot: + name: Deploy Production + runs-on: ubuntu-latest + needs: [set-variables, deploy-stg-polkadot] + # Deploy only if the tag is v* + if: startsWith(github.ref, 'refs/tags/v') + environment: parity-chains + env: + VERSION: ${{ needs.set-variables.outputs.VERSION }} + ARGOCD_SERVER: "argocd-chains.teleport.parity.io" + steps: + - name: Deploy to ArgoCD + uses: paritytech/argocd-deployment-action@main + with: + environment: "parity-chains" + tag: "${{ env.VERSION }}" + app_name: "substrate-api-sidecar-polkadot" + app_packages: "${{ env.APP }}" + argocd_server: ${{ env.ARGOCD_SERVER }} + teleport_token: ${{ env.APP }} + teleport_app_name: "argocd-chains" + argocd_auth_token: ${{ secrets.ARGOCD_AUTH_TOKEN }} diff --git a/.github/workflows/gitspiegel-trigger.yml b/.github/workflows/gitspiegel-trigger.yml deleted file mode 100644 index dce3aaf2f..000000000 --- a/.github/workflows/gitspiegel-trigger.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: gitspiegel sync - -# This workflow doesn't do anything, it's only use is to trigger "workflow_run" -# webhook, that'll be consumed by gitspiegel -# This way, gitspiegel won't do mirroring, unless this workflow runs, -# and running the workflow is protected by GitHub - -on: - pull_request: - types: - - opened - - synchronize - - unlocked - - ready_for_review - - reopened - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - name: Do nothing - run: echo "let's go" diff --git a/.github/workflows/semantic.yml b/.github/workflows/semantic.yml index c01e94a51..2dccdfc22 100644 --- a/.github/workflows/semantic.yml +++ b/.github/workflows/semantic.yml @@ -13,11 +13,15 @@ on: - opened - edited - synchronize - + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: validate-title: permissions: - pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs + pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs name: Validate PR Title runs-on: ubuntu-latest steps: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 81efb4ad0..000000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,273 +0,0 @@ -# Gitlab-CI Workflow -# stages: -# build: -# - Runs on commits on master or tags that match the pattern v1.0, v2.1rc1 -# deploy-staging: -# - Runs on commits on master or tags that match the pattern v1.0, v2.1rc1 (continues deployment) -# deploy-production: -# - Runs on tags that match the pattern v1.0, v2.1rc1 (manual deployment) - -variables: - CONTAINER_REPO: "docker.io/parity/substrate-api-sidecar" - DOCKERFILE_DIRECTORY: "./" - CI_IMAGE: "$BUILDAH_IMAGE" # defined in group variables - BUILDAH_COMMAND: "buildah --storage-driver overlay2" - NODE_IMAGE: "node:18" - BENCHMARK_IMAGE: "paritytech/node-wrk:latest" - -default: - retry: - max: 2 - when: - - runner_system_failure - - unknown_failure - - api_failure - interruptible: true - before_script: - - |- - if [[ $CI_COMMIT_TAG =~ ^v[0-9]+\.[0-9]+.*$ ]]; then - export DOCKER_IMAGE_TAG="${CI_COMMIT_TAG}" - export BUILD_LATEST_IMAGE="true" - else - export DOCKER_IMAGE_TAG="${CI_COMMIT_SHORT_SHA}-beta" - fi - -stages: - - test - - build - - deploy-staging - - deploy-production - - benchmark - - check-benchmark - - push-benchmark - -.collect-artifacts: &collect-artifacts - artifacts: - name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}" - when: on_success - expire_in: 1 days - paths: - - ./artifacts/ - -.test-refs: &test-refs - rules: - - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs - -.test-refs-manual: &test-refs-manual - rules: - - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/ # PRs - when: manual - -.publish-refs: &publish-refs - rules: - - if: $CI_PIPELINE_SOURCE == "pipeline" - when: never - - if: $CI_PIPELINE_SOURCE == "schedule" - - if: $CI_COMMIT_REF_NAME == "master" - - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - -.dockerize: &dockerize - stage: build - image: $CI_IMAGE - tags: - - kubernetes-parity-build - -.kubernetes-env: &kubernetes-env - image: $CI_IMAGE - tags: - - kubernetes-parity-build - -.deploy-k8s: &deploy-k8s - image: quay.io/argoproj/argocd:v2.7.9 - variables: - ARGOCD_OPTS: --grpc-web --grpc-web-root-path /$DOMAIN - script: - - argocd app list - # app1 - - argocd app set $APP1 --helm-set substrate-api-sidecar.image.tag="${DOCKER_IMAGE_TAG}" - - argocd app sync $APP1 - - argocd app wait $APP1 --timeout 180 - # app2 - - argocd app set $APP2 --helm-set substrate-api-sidecar.image.tag="${DOCKER_IMAGE_TAG}" - - argocd app sync $APP2 - - argocd app wait $APP2 --timeout 180 - tags: - - kubernetes-parity-build - -.e2e-template: &e2e-template - stage: test - <<: *kubernetes-env - variables: - CI_IMAGE: $NODE_IMAGE - CHAIN_NAME: "" - CHAIN_URL: "" - script: - - yarn --immutable - - echo "Tests for ${CHAIN_URL}" - - yarn test:latest-e2e-tests --log-level info --chain ${CHAIN_NAME} --local ${CHAIN_URL} - allow_failure: true - -e2e-westend: - <<: *e2e-template - variables: - CI_IMAGE: $NODE_IMAGE - CHAIN_NAME: "westend" - CHAIN_URL: "wss://westend-rpc.polkadot.io" - -e2e-kusama: - <<: *e2e-template - variables: - CI_IMAGE: $NODE_IMAGE - CHAIN_NAME: "kusama" - CHAIN_URL: "wss://apps-kusama-rpc.polkadot.io" - -e2e-polkadot: - <<: *e2e-template - variables: - CI_IMAGE: $NODE_IMAGE - CHAIN_NAME: "polkadot" - CHAIN_URL: "wss://apps-rpc.polkadot.io" - -build-docker: - <<: *dockerize - <<: *publish-refs - script: - - echo building "$CONTAINER_REPO:$DOCKER_IMAGE_TAG" - - if [[ $BUILD_LATEST_IMAGE ]]; then - $BUILDAH_COMMAND build - --format=docker - --tag "$CONTAINER_REPO:$DOCKER_IMAGE_TAG" - --tag "$CONTAINER_REPO:latest" "$DOCKERFILE_DIRECTORY"; - else - $BUILDAH_COMMAND build - --format=docker - --tag "$CONTAINER_REPO:$DOCKER_IMAGE_TAG" "$DOCKERFILE_DIRECTORY"; - fi - - $BUILDAH_COMMAND info - - echo ${Docker_Hub_Pass_Parity} | - buildah login --username ${Docker_Hub_User_Parity} --password-stdin docker.io - - echo pushing "$CONTAINER_REPO:$DOCKER_IMAGE_TAG" - - if [[ $BUILD_LATEST_IMAGE ]]; then - $BUILDAH_COMMAND push --format=v2s2 "$CONTAINER_REPO:$DOCKER_IMAGE_TAG"; - $BUILDAH_COMMAND push --format=v2s2 "$CONTAINER_REPO:latest"; - else - $BUILDAH_COMMAND push --format=v2s2 "$CONTAINER_REPO:$DOCKER_IMAGE_TAG"; - fi - -push-docker-image-description: - stage: build - before_script: - - echo - extends: - - .kubernetes-env - variables: - CI_IMAGE: paritytech/dockerhub-description - DOCKERHUB_REPOSITORY: parity/substrate-api-sidecar - DOCKER_USERNAME: $Docker_Hub_User_Parity - DOCKER_PASSWORD: $Docker_Hub_Pass_Parity - README_FILEPATH: $CI_PROJECT_DIR/Dockerfile.README.md - SHORT_DESCRIPTION: "REST service to interact with blockchain nodes built using Substrate's FRAME framework." - rules: - - if: $CI_COMMIT_REF_NAME == "master" - changes: - - Dockerfile.README.md - script: - - cd / && sh entrypoint.sh - -# checks that dockerimage can be built without publishing -build-docker-pr: - <<: *dockerize - <<: *test-refs - script: - - echo building "$CONTAINER_REPO:$DOCKER_IMAGE_TAG" - - if [[ $BUILD_LATEST_IMAGE ]]; then - $BUILDAH_COMMAND build - --format=docker - --tag "$CONTAINER_REPO:$DOCKER_IMAGE_TAG" - --tag "$CONTAINER_REPO:latest" "$DOCKERFILE_DIRECTORY"; - else - $BUILDAH_COMMAND build - --format=docker - --tag "$CONTAINER_REPO:$DOCKER_IMAGE_TAG" "$DOCKERFILE_DIRECTORY"; - fi - - $BUILDAH_COMMAND info - -deploy-staging: - stage: deploy-staging - extends: .deploy-k8s - <<: *publish-refs - environment: - name: parity-stg - variables: - DOMAIN: parity-stg - APP1: substrate-api-sidecar-kusama - APP2: substrate-api-sidecar-polkadot - -deploy-production: - stage: deploy-production - extends: .deploy-k8s - environment: - name: parity-chains - variables: - DOMAIN: parity-chains - APP1: substrate-api-sidecar-kusama - APP2: substrate-api-sidecar-polkadot - rules: - - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - when: manual - -bench-polkadot: &bench-polkadot - stage: benchmark - <<: *kubernetes-env - <<: *collect-artifacts - <<: *publish-refs - variables: - CI_IMAGE: $BENCHMARK_IMAGE - CHAIN_NAME: "polkadot" - CHAIN_URL: "wss://rpc.polkadot.io" - script: - - yarn --immutable - - echo "Benchmarks for ${CHAIN_URL}" - - mkdir -p artifacts - - yarn bench --log-level info --ws-url ${CHAIN_URL} - - mv benchmarks.txt artifacts/ - -# manual step to run benchmarks in PR pipeline -bench-polkadot-manual-pr: - stage: benchmark - <<: *bench-polkadot - <<: *test-refs-manual - - -# temporary disabled for collecting results -# check-benchmark: -# stage: check-benchmark -# <<: *publish-refs -# <<: *kubernetes-env -# <<: *collect-artifacts -# needs: -# - job: benchmark -# artifacts: true -# variables: -# GITHUB_REPO: "paritytech/substrate-api-sidecar" -# CI_IMAGE: "paritytech/benchmarks:latest" -# THRESHOLD: 60000 -# GITHUB_TOKEN: $GITHUB_PR_TOKEN -# script: -# - export RESULT=$(cat artifacts/result.txt | grep AvgRequestTime | awk '{print $2}') -# - check_single_bench_result -g $GITHUB_REPO -# -c $THRESHOLD -# -v $RESULT - -push-benchmark: - stage: push-benchmark - <<: *publish-refs - <<: *kubernetes-env - needs: - - job: bench-polkadot - artifacts: true - variables: - PROMETHEUS_URL: "https://pushgateway.parity-build.parity.io" - CI_IMAGE: "paritytech/benchmarks:latest" - script: - - scripts/ci/benchmarks/push_benchmark_results.sh artifacts/benchmarks.txt diff --git a/scripts/ci/benchmarks/generate_benchmark_result.sh b/scripts/ci/benchmarks/generate_benchmark_result.sh new file mode 100755 index 000000000..5ae9db475 --- /dev/null +++ b/scripts/ci/benchmarks/generate_benchmark_result.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# The script parses benchmarks.txt file and creates file suitable for https://github.com/benchmark-action/github-action-benchmark +# Usage: generate_benchmark_result.sh + +RESULT_FILE=$1 + +if [ -z "${RESULT_FILE}" ] +then + echo "Usage: $0 " + exit 1 +fi + + +BENCHMARKS=$(cat ${RESULT_FILE} | grep Result | awk '{print $3}') +NBENCHMARKS=$(echo ${BENCHMARKS} | wc -w) +COUNTER=0 +echo "[" +for benchmark in ${BENCHMARKS} +do + COUNTER=$((COUNTER+1)) + # "/accounts/{accountId}/balance-info:" -> "accounts-{accountId}-balance-info" + benchmark_name=$(echo ${benchmark} | cut -d ":" -f1 | sed 's/\///' | sed 's/\//-/g' ) + result=$(cat ${RESULT_FILE} | grep -A 20 ${benchmark} | grep "Avg RequestTime(Latency)" | awk '{print $3}') + unit=${result: -2} + result_value=${result::-2} + echo " {" + echo " \"name\": \"${benchmark_name}\"," + echo " \"result\": ${result_value}," + echo " \"unit\": \"${unit}\"" + if [ $COUNTER -eq $NBENCHMARKS ] + then + echo " }" + else + echo " }," + fi +done +echo "]" \ No newline at end of file