From c2f2adbd02d59bec93ed43a466300c58aefc8891 Mon Sep 17 00:00:00 2001 From: Javier Bullrich Date: Mon, 10 Jun 2024 12:36:11 +0200 Subject: [PATCH] added command-sync --- .github/actions/set-up-gh/action.yml | 4 +- .github/workflows/command-sync.yml | 62 ++++++++++++++++++++++ scripts/command-utils.sh | 78 ++++++++++++++++++++++++++++ scripts/sync.sh | 74 ++++++++++++++++++++++++++ 4 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/command-sync.yml create mode 100644 scripts/command-utils.sh create mode 100755 scripts/sync.sh diff --git a/.github/actions/set-up-gh/action.yml b/.github/actions/set-up-gh/action.yml index 25efbf14fc8b..db6bfbd5008f 100644 --- a/.github/actions/set-up-gh/action.yml +++ b/.github/actions/set-up-gh/action.yml @@ -1,5 +1,5 @@ name: 'install gh' -description: 'Install the gh cli in a debian based distro.' +description: 'Install the gh cli in a debian based distro and switches to the PR branch.' inputs: pr-number: description: "Number of the PR" @@ -9,7 +9,7 @@ inputs: required: true outputs: branch: - description: 'Branch name' + description: 'Branch name for the PR' value: ${{ steps.branch.outputs.branch }} runs: using: "composite" diff --git a/.github/workflows/command-sync.yml b/.github/workflows/command-sync.yml new file mode 100644 index 000000000000..e6a248bcbd6a --- /dev/null +++ b/.github/workflows/command-sync.yml @@ -0,0 +1,62 @@ +name: Command Sync + +on: + workflow_dispatch: + inputs: + pr: + description: Number of the Pull Request + required: true + chain: + description: Chain + type: choice + required: true + options: + - westend + - rococo + sync-type: + description: Sync type + type: choice + required: true + options: + - warp + - full + - fast + - fast-unsafe + +jobs: + set-image: + runs-on: ubuntu-latest + outputs: + IMAGE: ${{ steps.set_image.outputs.IMAGE }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - id: set_image + run: cat .github/env >> $GITHUB_OUTPUT + cmd-sync: + needs: [set-image] + runs-on: ubuntu-latest + container: + image: ${{ needs.set-image.outputs.IMAGE }} + steps: + - name: Download repo + uses: actions/checkout@v4 + - name: Install gh cli + id: gh + uses: ./.github/actions/set-up-gh + with: + pr-number: ${{ inputs.pr }} + GH_TOKEN: ${{ github.token }} + - name: Run sync + run: | + "./scripts/sync.sh" --chain "${{ inputs.chain }}" --type "${{ inputs.sync-type }}" + - name: Report failure + if: ${{ failure() }} + run: gh pr comment ${{ inputs.pr }} --body "Run by @${{ github.actor }} for ${{ github.workflow }} failed. See logs here." + env: + RUN: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_TOKEN: ${{ github.token }} + - uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: cmd-action - changes + branch: ${{ steps.gh.outputs.branch }} diff --git a/scripts/command-utils.sh b/scripts/command-utils.sh new file mode 100644 index 000000000000..01d764b7e522 --- /dev/null +++ b/scripts/command-utils.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +if [ "${LOADED_UTILS_SH:-}" ]; then + return +else + export LOADED_UTILS_SH=true +fi + +die() { + if [ "${1:-}" ]; then + >&2 echo "$1" + fi + exit 1 +} + +get_arg() { + local arg_type="$1" + shift + + local is_required + case "$arg_type" in + required|required-many) + is_required=true + ;; + optional|optional-many) ;; + *) + die "Invalid is_required argument \"$2\" in get_arg" + ;; + esac + + local has_many_values + if [ "${arg_type: -6}" == "-many" ]; then + has_many_values=true + fi + + local option_arg="$1" + shift + + local args=("$@") + + unset out + out=() + + local get_next_arg + for arg in "${args[@]}"; do + if [ "${get_next_arg:-}" ]; then + out+=("$arg") + unset get_next_arg + if [ ! "${has_many_values:-}" ]; then + break + fi + # --foo=bar (get the value after '=') + elif [ "${arg:0:$(( ${#option_arg} + 1 ))}" == "$option_arg=" ]; then + out+=("${arg:$(( ${#option_arg} + 1 ))}") + if [ ! "${has_many_values:-}" ]; then + break + fi + # --foo bar (get the next argument) + elif [ "$arg" == "$option_arg" ]; then + get_next_arg=true + fi + done + + # arg list ended with --something but no argument was provided next + if [ "${get_next_arg:-}" ]; then + die "Expected argument after \"${args[-1]}"\" + fi + + if [ "${out[0]:-}" ]; then + if [ ! "${has_many_values:-}" ]; then + out="${out[0]}" + fi + elif [ "${is_required:-}" ]; then + die "Argument $option_arg is required, but was not found" + else + unset out + fi +} diff --git a/scripts/sync.sh b/scripts/sync.sh new file mode 100755 index 000000000000..b5d8a5219937 --- /dev/null +++ b/scripts/sync.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +set -eu -o pipefail + +. "$(realpath "$(dirname "${BASH_SOURCE[0]}")/command-utils.sh")" + + +# Function to check syncing status +check_syncing() { + # Send the system_health request and parse the isSyncing field + RESPONSE=$(curl -sSX POST http://127.0.0.1:9944 \ + --header 'Content-Type: application/json' \ + --data-raw '{"jsonrpc": "2.0", "method": "system_health", "params": [], "id": "1"}') + + # Check for errors in the curl command + if [ $? -ne 0 ]; then + echo "Error: Unable to send request to Polkadot node" + fi + + IS_SYNCING=$(echo $RESPONSE | jq -r '.result.isSyncing') + + # Check for errors in the jq command or missing field in the response + if [ $? -ne 0 ] || [ "$IS_SYNCING" == "null" ]; then + echo "Error: Unable to parse sync status from response" + fi + + # Return the isSyncing value + echo $IS_SYNCING +} + +main() { + get_arg required --chain "$@" + local chain="${out:-""}" + + get_arg required --type "$@" + local type="${out:-""}" + + export RUST_LOG="${RUST_LOG:-remote-ext=debug,runtime=trace}" + + cargo build --release + + cp "./target/release/polkadot" ./polkadot-bin + + # Start sync. + # "&" runs the process in the background + # "> /dev/tty" redirects the output of the process to the terminal + ./polkadot-bin --sync="$type" --chain="$chain" > "$ARTIFACTS_DIR/sync.log" 2>&1 & + + # Get the PID of process + POLKADOT_SYNC_PID=$! + + sleep 10 + + # Poll the node every 100 seconds until syncing is complete + while :; do + SYNC_STATUS="$(check_syncing)" + if [ "$SYNC_STATUS" == "true" ]; then + echo "Node is still syncing..." + sleep 100 + elif [ "$SYNC_STATUS" == "false" ]; then + echo "Node sync is complete!" + kill "$POLKADOT_SYNC_PID" # Stop the Polkadot node process once syncing is complete + exit 0 # Success + elif [[ "$SYNC_STATUS" = Error:* ]]; then + echo "$SYNC_STATUS" + exit 1 # Error + else + echo "Unknown error: $SYNC_STATUS" + exit 1 # Unknown error + fi + done +} + +main "$@"