git.delta.rocks / unique-network / refs/commits / ec8104e0af89

difftreelog

Merge pull request #983 from UniqueNetwork/ci/baedeker-node-only

Yaroslav Bolyukin2023-09-05parents: #98753ec #1a650ec.patch.diff
in: master
Move node-only CI to baedeker

14 files changed

added.baedeker/node-only.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/.baedeker/node-only.jsonnet
@@ -0,0 +1,43 @@
+local
+m = import 'baedeker-library/mixin/spec.libsonnet',
+;
+
+local relay = {
+	name: 'relay',
+	bin: 'bin/polkadot',
+	validatorIdAssignment: 'staking',
+	spec: {Genesis:{
+		chain: 'rococo-local',
+		modify:: m.genericRelay($),
+	}},
+	nodes: {
+		[name]: {
+			bin: $.bin,
+			wantedKeys: 'relay',
+		},
+		for name in ['alice', 'bob', 'charlie', 'dave', 'eve']
+	},
+};
+
+local unique = {
+	name: 'unique',
+	bin: 'bin/unique',
+	paraId: 1001,
+	spec: {Genesis:{
+		modify:: m.genericPara($),
+	}},
+	nodes: {
+		[name]: {
+			bin: $.bin,
+			wantedKeys: 'para',
+		},
+		for name in ['alice', 'bob']
+	},
+};
+
+relay + {
+	parachains: {
+		[para.name]: para,
+		for para in [unique]
+	},
+}
modified.baedeker/xcm-opal.jsonnetdiffbeforeafterboth
--- a/.baedeker/xcm-opal.jsonnet
+++ b/.baedeker/xcm-opal.jsonnet
@@ -2,12 +2,14 @@
 m = import 'baedeker-library/mixin/spec.libsonnet',
 ;
 
+function(relay_spec)
+
 local relay = {
 	name: 'relay',
 	bin: 'bin/polkadot',
 	validatorIdAssignment: 'staking',
 	spec: {Genesis:{
-		chain: 'westend-local',
+		chain: relay_spec,
 		modify:: m.genericRelay($, hrmp = [
 			[$.parachains.opal.paraId, $.parachains.westmint.paraId, 8, 512],
 			[$.parachains.westmint.paraId, $.parachains.opal.paraId, 8, 512],
modified.baedeker/xcm-quartz.jsonnetdiffbeforeafterboth
--- a/.baedeker/xcm-quartz.jsonnet
+++ b/.baedeker/xcm-quartz.jsonnet
@@ -2,12 +2,14 @@
 m = import 'baedeker-library/mixin/spec.libsonnet',
 ;
 
+function(relay_spec)
+
 local relay = {
 	name: 'relay',
 	bin: 'bin/polkadot',
 	validatorIdAssignment: 'staking',
 	spec: {Genesis:{
-		chain: 'westend-local',
+		chain: relay_spec,
 		modify:: m.genericRelay($, hrmp = std.join([], [
 			[[$.parachains[a].paraId, $.parachains[b].paraId, 8, 512], [$.parachains[b].paraId, $.parachains[a].paraId, 8, 512]],
 			for [a, b] in [
@@ -113,7 +115,6 @@
 		[name]: {
 			bin: $.bin,
 			wantedKeys: 'para',
-			legacyRpc: true,
 		},
 		for name in ['alice', 'bob']
 	},
modified.baedeker/xcm-unique.jsonnetdiffbeforeafterboth
--- a/.baedeker/xcm-unique.jsonnet
+++ b/.baedeker/xcm-unique.jsonnet
@@ -2,12 +2,14 @@
 m = import 'baedeker-library/mixin/spec.libsonnet',
 ;
 
+function(relay_spec)
+
 local relay = {
 	name: 'relay',
 	bin: 'bin/polkadot',
 	validatorIdAssignment: 'staking',
 	spec: {Genesis:{
-		chain: 'westend-local',
+		chain: relay_spec,
 		modify:: m.genericRelay($, hrmp = std.join([], [
 			[[$.parachains[a].paraId, $.parachains[b].paraId, 8, 512], [$.parachains[b].paraId, $.parachains[a].paraId, 8, 512]],
 			for [a, b] in [
deleted.docker/Dockerfile-parachain-node-only.j2diffbeforeafterboth
before · .docker/Dockerfile-parachain-node-only.j2
1# ===== Rust builder =====2FROM uniquenetwork/services:latest as rust-builder3ENV CARGO_HOME="/cargo-home"4ENV PATH="/cargo-home/bin:$PATH"5ENV TZ=UTC67RUN rustup toolchain uninstall $(rustup toolchain list) && \8    rustup toolchain install {{ RUST_TOOLCHAIN }} && \9    rustup default {{ RUST_TOOLCHAIN }} && \10    rustup target list --installed && \11    rustup show12RUN rustup target add wasm32-unknown-unknown --toolchain {{ RUST_TOOLCHAIN }}1314RUN mkdir /unique_parachain15WORKDIR /unique_parachain161718# ===== BUILD current version ======19FROM rust-builder as builder-unique-current2021ARG PROFILE=release2223WORKDIR /unique_parachain2425RUN git clone -b {{ MAINNET_BRANCH }} https://github.com/UniqueNetwork/unique-chain.git . && \26    cargo build --features={{ NETWORK }}-runtime --$PROFILE2728# ===== BUILD target version ======29FROM rust-builder as builder-unique-target3031ARG PROFILE=release3233COPY . /unique_parachain34WORKDIR /unique_parachain3536RUN cargo build --features={{ NETWORK }}-runtime --$PROFILE3738# ===== RUN ======3940FROM ubuntu:22.044142RUN apt-get -y update && \43    apt-get -y install curl git && \44    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash && \45    export NVM_DIR="$HOME/.nvm" && \46    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \47    nvm install v16.16.0 && \48    nvm use v16.16.04950RUN git clone https://github.com/uniquenetwork/polkadot-launch -b {{ POLKADOT_LAUNCH_BRANCH }}5152COPY --from=builder-unique-current /unique_parachain/target/release/unique-collator /unique-chain/current/release/5354COPY --from=builder-unique-target /unique_parachain/target/release/unique-collator /unique-chain/target/release/55COPY --from=builder-unique-target /unique_parachain/target/release/wbuild/{{ WASM_NAME }}-runtime/{{ WASM_NAME }}_runtime.compact.compressed.wasm /unique-chain/target/release/wbuild/{{ WASM_NAME }}-runtime/{{ WASM_NAME }}_runtime.compact.compressed.wasm56COPY --from=builder-unique-target /unique_parachain/.docker/forkless-config/launch-config-node-only.json /polkadot-launch/launch-config.json5758COPY --from=uniquenetwork/builder-polkadot:{{ POLKADOT_BUILD_BRANCH }} /unique_parachain/polkadot/target/release/polkadot /polkadot/target/release/59COPY --from=uniquenetwork/builder-polkadot:{{ POLKADOT_BUILD_BRANCH }} /unique_parachain/polkadot/target/release/wbuild/westend-runtime/westend_runtime.compact.compressed.wasm /polkadot/target/release/wbuild/westend-runtime/westend_runtime.compact.compressed.wasm60COPY --from=uniquenetwork/builder-polkadot:{{ POLKADOT_BUILD_BRANCH }} /unique_parachain/polkadot/target/release/wbuild/rococo-runtime/rococo_runtime.compact.compressed.wasm /polkadot/target/release/wbuild/rococo-runtime/rococo_runtime.compact.compressed.wasm6162CMD export NVM_DIR="$HOME/.nvm" && \63    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \64    cd /polkadot-launch && \65    npm install --global yarn && \66    yarn install && \67    yarn start launch-config.json --test-upgrade-parachains -w -n
added.docker/Dockerfile-unique-releasediffbeforeafterboth
--- /dev/null
+++ b/.docker/Dockerfile-unique-release
@@ -0,0 +1,49 @@
+# ===== Rust builder =====
+FROM ubuntu:22.04 as rust-builder
+LABEL maintainer="Unique.Network"
+
+ENV CARGO_HOME="/cargo-home"
+ENV PATH="/cargo-home/bin:$PATH"
+ENV TZ=UTC
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+RUN apt-get update && \
+    apt-get install -y curl cmake pkg-config libssl-dev git clang llvm libudev-dev protobuf-compiler && \
+    apt-get clean && \
+    rm -r /var/lib/apt/lists/*
+
+RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain none
+
+ARG RUST_TOOLCHAIN
+RUN echo "Using Rust '$RUST_TOOLCHAIN'" && \
+    rustup toolchain install $RUST_TOOLCHAIN && \
+    rustup target add wasm32-unknown-unknown --toolchain ${RUST_TOOLCHAIN} && \
+    rustup default $RUST_TOOLCHAIN && \
+    rustup target list --installed && \
+    rustup show
+
+RUN mkdir /unique_parachain
+WORKDIR /unique_parachain
+
+# ===== BUILD POLKADOT =====
+FROM rust-builder as builder-polkadot-bin
+
+WORKDIR /unique_parachain
+
+ARG UNIQUE_VERSION
+RUN git clone -b "$UNIQUE_VERSION" --depth 1 https://github.com/uniquenetwork/unique-chain.git
+
+ARG RUNTIME_FEATURES
+RUN --mount=type=cache,target=/cargo-home/registry \
+    --mount=type=cache,target=/cargo-home/git \
+    --mount=type=cache,target=/unique_parachain/polkadot/target \
+    cd unique-chain && \
+    CARGO_INCREMENTAL=0 cargo build --release --features="$RUNTIME_FEATURES" --locked && \
+    mv ./target/release/unique-collator /unique_parachain/unique-chain/
+
+# ===== BIN ======
+
+FROM ubuntu:22.04 as builder-polkadot
+
+COPY --from=builder-polkadot-bin /unique_parachain/unique-chain/unique-collator /bin/unique-collator
+ENTRYPOINT ["/bin/unique-collator"]
deleted.docker/docker-compose.node-only.j2diffbeforeafterboth
--- a/.docker/docker-compose.node-only.j2
+++ /dev/null
@@ -1,16 +0,0 @@
-version: "3.5"
-
-services:
-  node-only:
-    image: uniquenetwork/ci-node-only-local:{{ NETWORK }}-{{ BUILD_TAG }}
-    container_name: node-only
-    expose:
-      - 9944
-      - 9945
-      - 9933
-      - 9844
-    ports:
-      - 127.0.0.1:9944:9944
-      - 127.0.0.1:9945:9945
-      - 127.0.0.1:9933:9933
-      - 127.0.0.1:9844:9844
added.github/actions/buildContainer/action.ymldiffbeforeafterboth
--- /dev/null
+++ b/.github/actions/buildContainer/action.yml
@@ -0,0 +1,59 @@
+name: Build or pull container
+description: ''
+inputs:
+  container:
+    description: Which name to fetch/push
+    required: true
+  tag:
+    description: Which tag to fetch/push
+    required: true
+  context:
+    description: Container context
+    required: true
+    default: "."
+  dockerfile:
+    description: Path to dockerfile (relative to context)
+    required: true
+  args:
+    description: Docker build extra args
+    default: ''
+  dockerhub_username:
+    description: Secret
+  dockerhub_token:
+    description: Secret
+outputs:
+  name:
+    description: Full container name
+    value: ${{ steps.ensure.outputs.name }}
+runs:
+  using: "composite"
+  steps:
+    - name: Ensure have ${{ inputs.container }}:${{ inputs.tag }}
+      id: ensure
+      run: |
+        echo "Wanted container: ${{ inputs.container }}:${{ inputs.tag }}"
+
+        TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${{ inputs.dockerhub_username }}'", "password": "'${{ inputs.dockerhub_token }}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)
+
+        # Get TAGS from DOCKERHUB
+        TAGS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/${{ inputs.container }}/tags/?page_size=100 | jq -r '."results"[]["name"]' || echo "")
+
+        echo "Available tags:"
+        echo "$TAGS"
+
+        # Check correct version POLKADOT and build it if it doesn't exist in POLKADOT TAGS
+        if [[ ${TAGS[*]} =~ (^|[[:space:]])"${{ inputs.tag }}"($|[[:space:]]) ]]; then
+          echo "Repository has needed version, pulling";
+          docker pull ${{ inputs.container }}:${{ inputs.tag }}
+        else
+          echo "Repository had no needed version, so build it";
+          cd "${{ inputs.context }}" && docker build --file "${{ inputs.dockerfile }}" \
+            $BUILD_ARGS --tag ${{ inputs.container }}:${{ inputs.tag }} \
+            .
+          echo "Push built version to the repository";
+          docker push ${{ inputs.container }}:${{ inputs.tag }} || true
+        fi
+        echo "name=${{ inputs.container }}:${{ inputs.tag }}" >> $GITHUB_OUTPUT
+      env:
+        BUILD_ARGS: ${{ inputs.args }}
+      shell: bash
modified.github/actions/prepare/action.ymldiffbeforeafterboth
--- a/.github/actions/prepare/action.yml
+++ b/.github/actions/prepare/action.yml
@@ -14,7 +14,16 @@
       shell: bash  
       run: |  
         echo "LAST_COMMIT_SHA=${GITHUB_SHA}" >> ${GITHUB_ENV}
-    - name: Set build SHA
+    - name: Run find-and-replace to remove slashes from branch name
+      uses: mad9000/actions-find-and-replace-string@4
+      id: ref_slug
+      with:
+        source: ${{ github.head_ref }}
+        find: '/'
+        replace: '-'
+    - name: Set BUILD_SHA, REF_SLUG
       shell: bash
       run: |
         echo "BUILD_SHA=${LAST_COMMIT_SHA:0:8}" >> $GITHUB_ENV
+        echo "REF_SLUG=${{ steps.ref_slug.outputs.value }}" >> $GITHUB_ENV
+
modified.github/workflows/node-only-update.ymldiffbeforeafterboth
--- a/.github/workflows/node-only-update.yml
+++ b/.github/workflows/node-only-update.yml
@@ -37,11 +37,10 @@
         id: create_matrix
         with:
           matrix: |
-            network {opal}, wasm_name {opal}, mainnet_branch {${{ env.OPAL_MAINNET_BRANCH }}}, relay_branch {${{ env.UNIQUEWEST_MAINNET_BRANCH }}}
-            network {sapphire}, wasm_name {quartz}, mainnet_branch {${{ env.SAPPHIRE_MAINNET_BRANCH }}}, relay_branch {${{ env.UNIQUEEAST_MAINNET_BRANCH }}}
-            network {quartz}, wasm_name {quartz}, mainnet_branch {${{ env.QUARTZ_MAINNET_BRANCH }}}, relay_branch {${{ env.KUSAMA_MAINNET_BRANCH }}}
-            network {unique}, wasm_name {unique}, mainnet_branch {${{ env.UNIQUE_MAINNET_BRANCH }}}, relay_branch {${{ env.POLKADOT_MAINNET_BRANCH }}}
-
+            network {opal}, mainnet_branch {${{ env.OPAL_MAINNET_BRANCH }}}, relay_branch {${{ env.UNIQUEWEST_MAINNET_BRANCH }}}, runtime_features {opal-runtime}
+            network {sapphire}, mainnet_branch {${{ env.SAPPHIRE_MAINNET_BRANCH }}}, relay_branch {${{ env.UNIQUEEAST_MAINNET_BRANCH }}}, runtime_features {sapphire-runtime}
+            network {quartz}, mainnet_branch {${{ env.QUARTZ_MAINNET_BRANCH }}}, relay_branch {${{ env.KUSAMA_MAINNET_BRANCH }}}, runtime_features {quartz-runtime}
+            network {unique}, mainnet_branch {${{ env.UNIQUE_MAINNET_BRANCH }}}, relay_branch {${{ env.POLKADOT_MAINNET_BRANCH }}}, runtime_features {unique-runtime}
 
   node-only-update-build:
 
@@ -79,293 +78,137 @@
 
       - name: Read .env file
         uses: xom9ikk/dotenv@v2
-
-      # Build main image for NODE-ONLY-UPDATE
-      - name: Generate ENV related extend Dockerfile file
-        uses: cuchi/jinja2-action@v1.2.0
-        with:
-          template: .docker/Dockerfile-parachain-node-only.j2
-          output_file: .docker/Dockerfile-parachain-node-only.${{ matrix.network }}.yml
-          variables: |
-            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
-            NETWORK=${{ matrix.network }}
-            MAINNET_BRANCH=${{ matrix.mainnet_branch }}
-            POLKADOT_LAUNCH_BRANCH=${{ env.POLKADOT_LAUNCH_BRANCH }}
-            WASM_NAME=${{ matrix.wasm_name }}
-            POLKADOT_BUILD_BRANCH=${{ matrix.relay_branch }}
-
-      - name: Show build configuration
-        run: cat .docker/Dockerfile-parachain-node-only.${{ matrix.network }}.yml
-
-      - name: Generate launch-config.json
-        uses: cuchi/jinja2-action@v1.2.0
-        with:
-          template: .docker/forkless-config/launch-config-forkless-nodata.j2
-          output_file: .docker/forkless-config/launch-config-node-only.json
-          variables: |
-            WASM_NAME=${{ matrix.wasm_name }}
-            RELAY_CHAIN_TYPE=${{ env.RELAY_CHAIN_TYPE }}
-
-      - name: Show launch-config-forkless configuration
-        run: cat .docker/forkless-config/launch-config-node-only.json
-
-      - name: Run find-and-replace to remove slashes from branch name
-        uses: mad9000/actions-find-and-replace-string@4
-        id: branchname
-        with:
-          source: ${{ github.head_ref }}
-          find: '/'
-          replace: '-'
 
-      - name: Set build SHA
-        shell: bash
-        run: |
-          echo "BUILD_SHA=${LAST_COMMIT_SHA:0:8}" >> $GITHUB_ENV
-
-      - name: Build the stack
-        run: cd .docker/ && docker build --no-cache --file ./Dockerfile-parachain-node-only.${{ matrix.network }}.yml --tag uniquenetwork/ci-node-only-local:${{ matrix.network }}-${{ steps.branchname.outputs.value }}-$BUILD_SHA ../
-
       - name: Log in to Docker Hub
         uses: docker/login-action@v2.1.0
         with:
           username: ${{ secrets.CORE_DOCKERHUB_USERNAME }}
           password: ${{ secrets.CORE_DOCKERHUB_TOKEN }}
-
-      - name: Push docker image version
-        run: docker push uniquenetwork/ci-node-only-local:${{ matrix.network }}-${{ steps.branchname.outputs.value }}-$BUILD_SHA
-
-      - name: Remove builder cache
-        if: always()                   # run this step always
-        run: |
-          docker builder prune -f
-          docker system prune -f          
-
-
-  node-only-update-tests:
-    needs: [prepare-execution-matrix, node-only-update-build]
-    # The type of runner that the job will run on
-    runs-on: [self-hosted-ci, large]
-
-    timeout-minutes: 2880
-
-    name: ${{ matrix.network }}-tests
-
-    continue-on-error: true         #Do not stop testing of matrix runs failed.  As it decided during PR review - it required 50/50& Let's check it with false.
-
-    strategy:
-      matrix:
-        include: ${{fromJson(needs.prepare-execution-matrix.outputs.matrix)}}
 
-    steps:
-      - name: Skip if pull request is in Draft
-        if: github.event.pull_request.draft == true
-        run: exit 1
-
-      - name: Clean Workspace
-        uses: AutoModality/action-clean@v1.1.0
-
-      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
-      - uses: actions/checkout@v3.1.0
-        with:
-          ref: ${{ github.head_ref }}  #Checking out head commit
-
-      - name: Prepare
-        uses: ./.github/actions/prepare
-
-      - name: Set build SHA
-        shell: bash
-        run: |
-          echo "BUILD_SHA=${LAST_COMMIT_SHA:0:8}" >> $GITHUB_ENV
-
-      - name: Run find-and-replace to remove slashes from branch name
-        uses: mad9000/actions-find-and-replace-string@4
-        id: branchname
-        with:
-          source: ${{ github.head_ref }}
-          find: '/'
-          replace: '-'
-
-      - name: Read .env file
-        uses: xom9ikk/dotenv@v2
-
-      - name: Generate ENV related extend file for docker-compose
+      - name: Generate ENV related extend Dockerfile file for POLKADOT
         uses: cuchi/jinja2-action@v1.2.0
         with:
-          template: .docker/docker-compose.node-only.j2
-          output_file: .docker/docker-compose.node-only.${{ matrix.network }}.yml
+          template: .docker/Dockerfile-polkadot.j2
+          output_file: .docker/Dockerfile-polkadot.${{ matrix.relay_branch }}.yml
           variables: |
-            NETWORK=${{ matrix.network }}
-            BUILD_TAG=${{ steps.branchname.outputs.value }}-$BUILD_SHA
-
-      - name: Show build configuration
-        run: cat .docker/docker-compose.node-only.${{ matrix.network }}.yml
-
-      - name: Log in to Docker Hub
-        uses: docker/login-action@v2.1.0
+            RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
+            POLKADOT_BUILD_BRANCH=${{ matrix.relay_branch }}
+      - name: Prepare polkadot
+        uses: ./.github/actions/buildContainer
+        id: polkadot
         with:
-          username: ${{ secrets.CORE_DOCKERHUB_USERNAME }}
-          password: ${{ secrets.CORE_DOCKERHUB_TOKEN }}
+          container: uniquenetwork/builder-polkadot
+          tag: ${{ matrix.relay_branch }}
+          context: .docker
+          dockerfile: Dockerfile-polkadot.${{ matrix.relay_branch }}.yml
+          dockerhub_username: ${{ secrets.CORE_DOCKERHUB_USERNAME }}
+          dockerhub_token: ${{ secrets.CORE_DOCKERHUB_TOKEN }}
 
-      - name: Build the stack
-        run: docker-compose -f ".docker/docker-compose.node-only.${{ matrix.network }}.yml" up -d --remove-orphans --force-recreate --timeout 300
+      - name: Prepare mainnet
+        uses: ./.github/actions/buildContainer
+        id: mainnet
+        with:
+          container: uniquenetwork/ci-node-only-${{ matrix.network }}
+          tag: ${{ matrix.mainnet_branch }}
+          context: .docker
+          dockerfile: Dockerfile-unique-release
+          args: |
+            --build-arg RUNTIME_FEATURES=${{ matrix.runtime_features }}
+            --build-arg RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
+            --build-arg UNIQUE_VERSION=${{ matrix.mainnet_branch }}
+          dockerhub_username: ${{ secrets.CORE_DOCKERHUB_USERNAME }}
+          dockerhub_token: ${{ secrets.CORE_DOCKERHUB_TOKEN }}
 
-      #  🚀 POLKADOT LAUNCH COMPLETE 🚀
-      - name: Check if docker logs consist messages related to testing of Node Parachain Upgrade.
-        if: success()
-        run: |
-          counter=160
-          function check_container_status {
-                docker inspect -f {{.State.Running}} node-only
-          }
-          function do_docker_logs {
-                docker logs --details node-only  2>&1
-          }
-          function is_started {
-                if [ "$(check_container_status)" == "true" ]; then
-                        echo "Container: node-only RUNNING";
-                        echo "Check Docker logs"
-                        DOCKER_LOGS=$(do_docker_logs)
-                        if [[ ${DOCKER_LOGS} = *"POLKADOT LAUNCH COMPLETE"* ]];then
-                                echo "🚀 POLKADOT LAUNCH COMPLETE 🚀"
-                                return 0
-                        else
-                                echo "Message not found in logs output, repeating..."
-                                return 1
-                        fi
-                else
-                        echo "Container node-only NOT RUNNING"
-                        echo "Halting all future checks"
-                        exit 1
-                fi
-          echo "something goes wrong"
-          exit 1
-          }
-          while ! is_started; do
-                echo "Waiting for special message in log files "
-                sleep 30s
-                counter=$(( $counter - 1 ))
-                echo "Counter: $counter"
-                if [ "$counter" -gt "0" ]; then
-                         continue
-                else
-                         break
-                fi
-          done
-          echo "Halting script"
-          exit 0
-        shell: bash
+      - name: Prepare latest
+        uses: ./.github/actions/buildContainer
+        id: latest
+        with:
+          container: uniquenetwork/ci-node-only-${{ matrix.network }}
+          tag: ${{ env.REF_SLUG }}-${{ env.BUILD_SHA }}
+          context: .
+          dockerfile: .docker/Dockerfile-unique
+          args: |
+            --build-arg RUNTIME_FEATURES=${{ matrix.runtime_features }}
+            --build-arg RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }}
+          dockerhub_username: ${{ secrets.CORE_DOCKERHUB_USERNAME }}
+          dockerhub_token: ${{ secrets.CORE_DOCKERHUB_TOKEN }}
 
       - name: Checkout at '${{ matrix.mainnet_branch }}' branch
         uses: actions/checkout@master
         with:
-          ref: ${{ matrix.mainnet_branch }}  #Checking out head commit
+          ref: ${{ github.head_ref }}
+          # ref: ${{ matrix.mainnet_branch }}  #Checking out head commit
           path: ${{ matrix.mainnet_branch }}
 
       - uses: actions/setup-node@v3.5.1
         with:
           node-version: 16
 
+      - name: Install baedeker
+        uses: UniqueNetwork/baedeker-action/setup@built
+
+      - name: Setup library
+        run: mkdir -p .baedeker/vendor/ && git clone https://github.com/UniqueNetwork/baedeker-library .baedeker/vendor/baedeker-library
+
+      - name: Start network
+        uses: UniqueNetwork/baedeker-action@built
+        id: bdk
+        with:
+          jpath: |
+            .baedeker/vendor
+          tla-str: |
+            relay_spec=westend-local
+          inputs: |
+            .baedeker/node-only.jsonnet
+            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/polkadot':{dockerImage:'${{ steps.polkadot.outputs.name }}'}})
+            ephemeral:snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'${{ steps.mainnet.outputs.name }}'}}, extra_node_mixin = {legacyRpc: true})
+
       - name: Run Parallel tests before Node Parachain upgrade
         working-directory: ${{ matrix.mainnet_branch }}/tests
         if: success() || failure()
         run: |
-          yarn install
+          yarn
           yarn add mochawesome
           ./scripts/wait_for_first_block.sh
           echo "Ready to start tests"
           NOW=$(date +%s) && yarn testParallel --reporter mochawesome --reporter-options reportFilename=test-parallel-${NOW}
         env:
-          RPC_URL: http://127.0.0.1:9944/
+          RPC_URL: ${{ env.RELAY_UNIQUE_HTTP_URL }}
 
       - name: Run Sequential tests before Node Parachain upgrade
         if: success() || failure()
         working-directory: ${{ matrix.mainnet_branch }}/tests
         run: NOW=$(date +%s) && yarn testSequential --reporter mochawesome --reporter-options reportFilename=test-sequential-${NOW}
         env:
-          RPC_URL: http://127.0.0.1:9944/
+          RPC_URL: ${{ env.RELAY_UNIQUE_HTTP_URL }}
 
-      - name: Send SIGUSR1 to polkadot-launch process
+      - name: "Reconcile: only one old node"
         if: success() || failure()
-        run: |
-          #Get PID of polkadot-launch
-          ContainerID=$(docker ps -aqf "name=node-only")
-          PID=$(docker exec node-only pidof 'polkadot-launch')
-          sleep 30s
-          echo -e "\n"
-          echo -e "Restart polkadot-launch process: $PID\n"
-          docker exec node-only kill -SIGUSR1 ${PID}
-          echo "SIGUSR1 sent to Polkadot-launch PID: $PID"
-          sleep 60s
-          echo -e "Show logs of node-only container.\n"
-          docker logs ${ContainerID}
-
-      - name: Get chain logs in case of docker image crashed after Polkadot Launch restart
-        if: failure()                   # run this step only at failure
-        run: |
-          docker exec node-only tail -n 1000 /polkadot-launch/9944.log
-          docker exec node-only tail -n 1000 /polkadot-launch/9945.log
-          docker exec node-only tail -n 1000 /polkadot-launch/alice.log
+        uses: UniqueNetwork/baedeker-action/reconcile@built
+        with:
+          baedeker: ${{ steps.bdk.baedeker }}
+          # Chain should always be built with the mainnet spec, this we first set binary for all nodes expect one, then set mainnet binary for the last node, and then force chainspec to be still generated from mainnet
+          inputs: |
+            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'${{ steps.latest.outputs.name }}'}}, leave = 1, for_chain = false)
+            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'${{ steps.mainnet.outputs.name }}'}}, extra_node_mixin = {legacyRpc: true}, for_chain = false)
+            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'${{ steps.mainnet.outputs.name }}'}})
 
-      - name: copy chain log files from container to the host
+      - name: Ensure network is alive
         if: success() || failure()    # run this step even if previous step failed
         run: |
-          mkdir -p /tmp/node-only-update
-          docker cp node-only:/polkadot-launch/9944.log /tmp/node-only-update/
-          docker cp node-only:/polkadot-launch/9945.log /tmp/node-only-update/
-          docker cp node-only:/polkadot-launch/alice.log /tmp/node-only-update/
+          ./tests/scripts/wait_for_first_block.sh
+        env:
+          RPC_URL: ${{ env.RELAY_UNIQUE_HTTP_URL }}
 
-      - name: Upload chain log files
+      - name: "Reconcile: all nodes are updated"
         if: success() || failure()
-        uses: actions/upload-artifact@v3
+        uses: UniqueNetwork/baedeker-action/reconcile@built
         with:
-          name: node-only-update-chain-logs
-          path: /tmp/node-only-update/
-          if-no-files-found: warn
-
-      - name: Check if docker logs consist messages related to testing of Node Parachain Upgrade.
-        if: success()
-        run: |
-          counter=160
-          function check_container_status {
-                docker inspect -f {{.State.Running}} node-only
-          }
-          function do_docker_logs {
-                docker logs --details node-only  2>&1
-          }
-          function is_started {
-                if [ "$(check_container_status)" == "true" ]; then
-                        echo "Container: node-only RUNNING";
-                        echo "Check Docker logs"
-                        DOCKER_LOGS=$(do_docker_logs)
-                        if [[ ${DOCKER_LOGS} = *"All parachain collators restarted with the new binaries."* ]];then
-                                echo "🌗 All parachain collators restarted with the new binaries."
-                                return 0
-                        else
-                                echo "Message not found in logs output, repeating..."
-                                return 1
-                        fi
-                else
-                        echo "Container node-only NOT RUNNING"
-                        echo "Halting all future checks"
-                        exit 1
-                fi
-          echo "something goes wrong"
-          exit 1
-          }
-          while ! is_started; do
-                echo "Waiting for special message in log files "
-                sleep 30s
-                counter=$(( $counter - 1 ))
-                echo "Counter: $counter"
-                if [ "$counter" -gt "0" ]; then
-                         continue
-                else
-                         break
-                fi
-          done
-          echo "Halting script"
-          exit 0
-        shell: bash
+          baedeker: ${{ steps.bdk.baedeker }}
+          # Chain should always be built with the mainnet spec, this we first set binary for all nodes, and then force chainspec to be still generated from mainnet
+          inputs: |
+            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'${{ steps.latest.outputs.name }}'}}, for_chain = false)
+            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'${{ steps.mainnet.outputs.name }}'}})
 
       - name: Run Parallel tests after Node Parachain upgrade
         working-directory: ${{ matrix.mainnet_branch }}/tests
@@ -377,27 +220,16 @@
           echo "Ready to start tests"
           NOW=$(date +%s) && yarn testParallel --reporter mochawesome --reporter-options reportFilename=test-parallel-${NOW}
         env:
-          RPC_URL: http://127.0.0.1:9944/
+          RPC_URL: ${{ env.RELAY_UNIQUE_HTTP_URL }}
 
       - name: Run Sequential tests after Node Parachain upgrade
         if: success() || failure()
         working-directory: ${{ matrix.mainnet_branch }}/tests
         run: NOW=$(date +%s) && yarn testSequential --reporter mochawesome --reporter-options reportFilename=test-sequential-${NOW}
         env:
-          RPC_URL: http://127.0.0.1:9944/
-
-      - name: Stop running containers
-        if: always()                   # run this step always
-        run: docker-compose -f ".docker/docker-compose.node-only.${{ matrix.network }}.yml" down
+          RPC_URL: ${{ env.RELAY_UNIQUE_HTTP_URL }}
 
       - name: Remove builder cache
         if: always()                   # run this step always
         run: |
-          docker builder prune -f -a
           docker system prune -f
-          docker image prune -f -a
-
-      - name: Remove repo at the end
-        if: always()                   # run this step always
-        run: |
-          ls -ls ./
modified.github/workflows/xcm.ymldiffbeforeafterboth
--- a/.github/workflows/xcm.yml
+++ b/.github/workflows/xcm.yml
@@ -284,25 +284,16 @@
             fi
         shell: bash
 
-
-      - name: Run find-and-replace to remove slashes from branch name
-        uses: mad9000/actions-find-and-replace-string@4
-        id: branchname
-        with:
-          source: ${{ github.head_ref }}
-          find: '/'
-          replace: '-'
-
       - name: Build unique-chain
         run: |
           docker build --file .docker/Dockerfile-unique \
             --build-arg RUNTIME_FEATURES=${{ matrix.runtime_features }} \
             --build-arg RUST_TOOLCHAIN=${{ env.RUST_TOOLCHAIN }} \
-            --tag uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ steps.branchname.outputs.value }}-${{ env.BUILD_SHA }} \
+            --tag uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ env.REF_SLUG }}-${{ env.BUILD_SHA }} \
             .
 
       - name: Push docker image version
-        run: docker push uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ steps.branchname.outputs.value }}-${{ env.BUILD_SHA }}
+        run: docker push uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ env.REF_SLUG }}-${{ env.BUILD_SHA }}
 
       - uses: actions/setup-node@v3.5.1
         with:
@@ -320,10 +311,12 @@
         with:
           jpath: |
             .baedeker/vendor
+          tla-str: |
+            relay_spec=westend-local
           inputs: |
             .baedeker/xcm-${{ matrix.network }}.jsonnet
             snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/polkadot':{dockerImage:'uniquenetwork/builder-polkadot:${{ matrix.relay_branch }}'}})
-            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ steps.branchname.outputs.value }}-${{ env.BUILD_SHA }}'}})
+            snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'uniquenetwork/ci-xcm-local:${{ matrix.network }}-${{ env.REF_SLUG }}-${{ env.BUILD_SHA }}'}})
             snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/acala':{dockerImage:'uniquenetwork/builder-acala:${{ matrix.acala_version }}'}})
             snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/moonbeam':{dockerImage:'uniquenetwork/builder-moonbeam:${{ matrix.moonbeam_version }}'}})
             snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/cumulus':{dockerImage:'uniquenetwork/builder-cumulus:${{ matrix.cumulus_version }}'}})
modifiedtests/scripts/wait_for_first_block.shdiffbeforeafterboth
--- a/tests/scripts/wait_for_first_block.sh
+++ b/tests/scripts/wait_for_first_block.sh
@@ -4,24 +4,40 @@
 
 . $DIR/functions.sh
 
-function is_started {
+last_block_id=0
+block_id=0
+function get_block {
 	block_id_hex=$(do_rpc chain_getHeader | jq -r .result.number)
 	block_id=$((${block_id_hex}))
 	echo Id = $block_id
-	if (( $block_id > 1 )); then
+}
+
+function had_new_block {
+	last_block_id=$block_id
+	get_block
+	if (( last_block_id != 0 && block_id > last_block_id )); then
 		return 0
 	fi
 	return 1
 }
 
-while ! is_started; do
-	echo "Waiting for first block..."
+function reset_check {
+	last_block_id=0
+	block_id=0
+}
+
+while ! had_new_block; do
+	echo "Waiting for next block..."
 	sleep 12
 done
+reset_check
+
 echo "Chain is running, but lets wait for another block after a minute, to avoid startup flakiness."
-sleep 120
-while ! is_started; do
-	echo "Waiting for second block..."
+sleep 60
+
+while ! had_new_block; do
+	echo "Waiting for another block..."
 	sleep 12
 done
+
 echo "Chain is running!"
modifiedtests/src/util/globalSetup.tsdiffbeforeafterboth
--- a/tests/src/util/globalSetup.ts
+++ b/tests/src/util/globalSetup.ts
@@ -112,4 +112,8 @@
     });
 };
 
-globalSetup().catch(() => process.exit(1));
+globalSetup().catch(e => {
+  console.error('Setup error');
+  console.error(e);
+  process.exit(1)
+});
modifiedtests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth
--- a/tests/src/xcm/xcmQuartz.test.ts
+++ b/tests/src/xcm/xcmQuartz.test.ts
@@ -481,7 +481,7 @@
 
     await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
       const destination = {
-        V1: {
+        V2: {
           parents: 1,
           interior: {
             X1: {
@@ -591,7 +591,7 @@
   itSub('Should connect to Karura and send QTZ back', async ({helper}) => {
     await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
       const destination = {
-        V1: {
+        V2: {
           parents: 1,
           interior: {
             X2: [
@@ -653,7 +653,7 @@
     const [targetAccount] = await helper.arrange.createAccounts([targetAccountBalance], alice);
 
     const quartzMultilocation = {
-      V1: {
+      V2: {
         parents: 1,
         interior: {
           X1: {Parachain: QUARTZ_CHAIN},
@@ -716,7 +716,7 @@
     const [targetAccount] = await helper.arrange.createAccounts([0n], alice);
 
     const quartzMultilocation = {
-      V1: {
+      V2: {
         parents: 1,
         interior: {
           X1: {
@@ -797,7 +797,6 @@
   let quartzParachainMultilocation: any;
   let quartzAccountMultilocation: any;
   let quartzCombinedMultilocation: any;
-  let quartzCombinedMultilocationKarura: any; // TODO remove it when Karura goes V2
 
   let messageSent: any;
 
@@ -835,15 +834,6 @@
 
       quartzCombinedMultilocation = {
         V2: {
-          parents: 1,
-          interior: {
-            X2: [quartzParachainJunction, quartzAccountJunction],
-          },
-        },
-      };
-
-      quartzCombinedMultilocationKarura = {
-        V1: {
           parents: 1,
           interior: {
             X2: [quartzParachainJunction, quartzAccountJunction],
@@ -871,7 +861,7 @@
       const id = {
         Token: 'KAR',
       };
-      const destination = quartzCombinedMultilocationKarura;
+      const destination = quartzCombinedMultilocation;
       await helper.xTokens.transfer(alice, id, testAmount, destination, 'Unlimited');
 
       messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);