logos-storage-nim/.github/workflows/deploy-devnet.yml
2025-07-28 10:02:19 +00:00

176 lines
6.2 KiB
YAML

name: Deploy - Devnet
on:
workflow_dispatch:
inputs:
codex_image:
description: codexstorage/nim-codex:latest-dist-tests
required: false
type: string
workflow_call:
inputs:
codex_image:
description: codexstorage/nim-codex:latest-dist-tests
required: true
type: string
env:
CODEX_NAMESPACE: codex
TOOLS_NAMESPACE: common
KUBE_CONFIG: ${{ secrets.DEVNET_KUBE_CONFIG }}
KUBE_VERSION: v1.33.1
CODEX_IMAGE: ${{ inputs.codex_image }}
SSH_HOSTS: ${{ secrets.DEVNET_SSH_HOSTS }}
SSH_PORT: ${{ secrets.DEVNET_SSH_PORT }}
SSH_USERNAME: ${{ secrets.DEVNET_SSH_USERNAME }}
SSH_PRIVATE_KEY: ${{ secrets.DEVNET_SSH_KEY }}
jobs:
deploy-contracts:
name: Deploy contracts
runs-on: ubuntu-latest
steps:
- name: Create access token
uses: actions/create-github-app-token@v2
id: app-token
with:
app-id: ${{ secrets.DEPLOYER_APP_ID }}
private-key: ${{ secrets.DEPLOYER_PRIVATE_KEY }}
repositories: codex-contracts-eth
- name: Checkout sources
uses: actions/checkout@v4
with:
submodules: recursive
- name: Get contracts submodule ref
id: contracts
run: echo "ref=$(git rev-parse HEAD:vendor/codex-contracts-eth)" >> $GITHUB_OUTPUT
- name: Deploy smart contracts
uses: the-actions-org/workflow-dispatch@v4
with:
repo: codex-storage/codex-contracts-eth
workflow: devnet-contracts.yml
token: ${{ steps.app-token.outputs.token }}
wait-for-completion-timeout: 20m
wait-for-completion-interval: 20s
inputs: '{ "network": "codex_devnet", "contracts_ref": "${{ steps.contracts.outputs.ref }}" }'
bootstrap-nodes:
name: Bootstrap nodes
runs-on: ubuntu-latest
needs: deploy-contracts
steps:
- name: Codex Bootstrap - Update
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.DEVNET_SSH_HOSTS }}
username: ${{ secrets.DEVNET_SSH_USERNAME }}
key: ${{ secrets.DEVNET_SSH_KEY }}
port: ${{ secrets.DEVNET_SSH_PORT }}
script: /opt/codex/remote-deploy.sh ${{ env.CODEX_IMAGE }}
cluster-nodes:
name: Cluster nodes
runs-on: ubuntu-latest
needs: bootstrap-nodes
steps:
- name: Kubectl - Install ${{ env.KUBE_VERSION }}
uses: azure/setup-kubectl@v4
with:
version: ${{ env.KUBE_VERSION }}
- name: Kubectl - Kubeconfig
run: |
mkdir -p "${HOME}"/.kube
echo "${{ env.KUBE_CONFIG }}" | base64 -d > "${HOME}"/.kube/config
- name: Codex Storage - Update
run: |
for node in {1..5}; do
kubectl -n "${{ env.CODEX_NAMESPACE }}" patch statefulset codex-storage-${node} \
--patch '{"spec": {"template": {"spec":{"containers":[{"name": "codex", "image":"${{ env.CODEX_IMAGE }}"}]}}}}'
done
- name: Codex Validators - Update
run: |
for node in {1..1}; do
kubectl -n "${{ env.CODEX_NAMESPACE }}" patch statefulset codex-validator-${node} \
--patch '{"spec": {"template": {"spec":{"containers":[{"name": "codex", "image":"${{ env.CODEX_IMAGE }}"}]}}}}'
done
- name: Codex Storage - Status
run: |
WAIT=300
SECONDS=0
sleep=1
for instance in {1..5}; do
while (( SECONDS < WAIT )); do
pod=codex-storage-${instance}-1
phase=$(kubectl get pod "${pod}" -n "${{ env.CODEX_NAMESPACE }}" -o jsonpath='{.status.phase}')
if [[ "${phase}" == "Running" ]]; then
echo "Pod ${pod} is in the ${phase} state"
break
else
echo "Pod ${pod} is in the ${phase} state - Check in ${sleep} second(s) / $((WAIT - SECONDS))"
fi
sleep "${sleep}"
done
done
- name: Codex Validators - Status
run: |
WAIT=300
SECONDS=0
sleep=1
for instance in {1..1}; do
while (( SECONDS < WAIT )); do
pod=codex-validator-${instance}-1
phase=$(kubectl get pod "${pod}" -n "${{ env.CODEX_NAMESPACE }}" -o jsonpath='{.status.phase}')
if [[ "${phase}" == "Running" ]]; then
echo "Pod ${pod} is in the ${phase} state"
break
else
echo "Pod ${pod} is in the ${phase} state - Check in ${sleep} second(s) / $((WAIT - SECONDS))"
fi
sleep "${sleep}"
done
done
- name: Tools - Update
run: |
crawler_pod=$(kubectl get pod -n "${{ env.TOOLS_NAMESPACE }}" -l 'app.kubernetes.io/name=crawler' -ojsonpath='{.items[0].metadata.name}' 2>/dev/null || true)
discordbot_pod=$(kubectl get pod -n "${{ env.TOOLS_NAMESPACE }}" -l 'app=discordbot' -ojsonpath='{.items[0].metadata.name}' 2>/dev/null || true)
for pod in "${crawler_pod}" "${discordbot_pod}"; do
if [[ -n "${pod}" ]]; then
kubectl delete pod -n "${{ env.TOOLS_NAMESPACE }}" "${pod}" --grace-period=10
fi
done
- name: Tools - Status
run: |
WAIT=300
SECONDS=0
sleep=1
crawler_pod=$(kubectl get pod -n "${{ env.TOOLS_NAMESPACE }}" -l 'app.kubernetes.io/name=crawler' -ojsonpath='{.items[0].metadata.name}' 2>/dev/null || true)
discordbot_pod=$(kubectl get pod -n "${{ env.TOOLS_NAMESPACE }}" -l 'app=discordbot' -ojsonpath='{.items[0].metadata.name}' 2>/dev/null || true)
for pod in "${crawler_pod}" "${discordbot_pod}"; do
if [[ -n "${pod}" ]]; then
while (( SECONDS < WAIT )); do
phase=$(kubectl get pod "${pod}" -n "${{ env.TOOLS_NAMESPACE }}" -o jsonpath='{.status.phase}')
if [[ "${phase}" == "Running" ]]; then
echo "Pod ${pod} is in the ${phase} state"
break
else
echo "Pod ${pod} is in the ${phase} state - Check in ${sleep} second(s) / $((WAIT - SECONDS))"
fi
sleep "${sleep}"
done
fi
done