mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-01-02 13:33:10 +00:00
ci: auto deploy codex on devnet (#1302)
This commit is contained in:
parent
6cf99e255c
commit
8cd10edb69
175
.github/workflows/deploy-devnet.yml
vendored
Normal file
175
.github/workflows/deploy-devnet.yml
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
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
|
||||
16
.github/workflows/docker-dist-tests.yml
vendored
16
.github/workflows/docker-dist-tests.yml
vendored
@ -13,6 +13,7 @@ on:
|
||||
- '.github/**'
|
||||
- '!.github/workflows/docker-dist-tests.yml'
|
||||
- '!.github/workflows/docker-reusable.yml'
|
||||
- '!.github/workflows/deploy-devnet.yml'
|
||||
- 'docker/**'
|
||||
- '!docker/codex.Dockerfile'
|
||||
- '!docker/docker-entrypoint.sh'
|
||||
@ -23,6 +24,11 @@ on:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
deploy_devnet:
|
||||
description: Deploy Devnet
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
|
||||
jobs:
|
||||
@ -40,6 +46,7 @@ jobs:
|
||||
run: |
|
||||
hash=$(git rev-parse --short HEAD:vendor/codex-contracts-eth)
|
||||
echo "hash=$hash" >> $GITHUB_OUTPUT
|
||||
|
||||
build-and-push:
|
||||
name: Build and Push
|
||||
uses: ./.github/workflows/docker-reusable.yml
|
||||
@ -53,3 +60,12 @@ jobs:
|
||||
contract_image: "codexstorage/codex-contracts-eth:sha-${{ needs.get-contracts-hash.outputs.hash }}-dist-tests"
|
||||
run_release_tests: ${{ inputs.run_release_tests }}
|
||||
secrets: inherit
|
||||
|
||||
deploy-devnet:
|
||||
name: Deploy Devnet
|
||||
uses: ./.github/workflows/deploy-devnet.yml
|
||||
needs: build-and-push
|
||||
if: ${{ inputs.deploy_devnet || github.event_name == 'push' && github.ref_name == github.event.repository.default_branch }}
|
||||
with:
|
||||
codex_image: ${{ needs.build-and-push.outputs.codex_image }}
|
||||
secrets: inherit
|
||||
|
||||
50
.github/workflows/docker-reusable.yml
vendored
50
.github/workflows/docker-reusable.yml
vendored
@ -68,6 +68,10 @@ on:
|
||||
description: Specifies compatible smart contract image
|
||||
required: false
|
||||
type: string
|
||||
outputs:
|
||||
codex_image:
|
||||
description: Codex Docker image tag
|
||||
value: ${{ jobs.publish.outputs.codex_image }}
|
||||
|
||||
|
||||
env:
|
||||
@ -91,15 +95,16 @@ env:
|
||||
|
||||
|
||||
jobs:
|
||||
# Compute variables
|
||||
compute:
|
||||
name: Compute build ID
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
build_id: ${{ steps.build_id.outputs.build_id }}
|
||||
steps:
|
||||
- name: Generate unique build id
|
||||
id: build_id
|
||||
run: echo "build_id=$(openssl rand -hex 5)" >> $GITHUB_OUTPUT
|
||||
name: Compute build ID
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
build_id: ${{ steps.build_id.outputs.build_id }}
|
||||
steps:
|
||||
- name: Generate unique build id
|
||||
id: build_id
|
||||
run: echo "build_id=$(openssl rand -hex 5)" >> $GITHUB_OUTPUT
|
||||
|
||||
# Build platform specific image
|
||||
build:
|
||||
@ -134,7 +139,7 @@ jobs:
|
||||
run: |
|
||||
# Create contract label for compatible contract image if specified
|
||||
if [[ -n "${{ env.CONTRACT_IMAGE }}" ]]; then
|
||||
echo "CONTRACT_LABEL=storage.codex.nim-codex.blockchain-image=${{ env.CONTRACT_IMAGE }}" >>$GITHUB_ENV
|
||||
echo "CONTRACT_LABEL=storage.codex.nim-codex.blockchain-image=${{ env.CONTRACT_IMAGE }}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Docker - Meta
|
||||
@ -189,35 +194,35 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.meta.outputs.version }}
|
||||
codex_image: ${{ steps.image_tag.outputs.codex_image }}
|
||||
needs: [build, compute]
|
||||
steps:
|
||||
|
||||
- name: Docker - Variables
|
||||
run: |
|
||||
# Adjust custom suffix when set and
|
||||
# Adjust custom suffix when set
|
||||
if [[ -n "${{ env.TAG_SUFFIX }}" ]]; then
|
||||
echo "TAG_SUFFIX=-${{ env.TAG_SUFFIX }}" >>$GITHUB_ENV
|
||||
echo "TAG_SUFFIX=-${{ env.TAG_SUFFIX }}" >> $GITHUB_ENV
|
||||
fi
|
||||
# Disable SHA tags on tagged release
|
||||
if [[ ${{ startsWith(github.ref, 'refs/tags/') }} == "true" ]]; then
|
||||
echo "TAG_SHA=false" >>$GITHUB_ENV
|
||||
echo "TAG_SHA=false" >> $GITHUB_ENV
|
||||
fi
|
||||
# Handle latest and latest-custom using raw
|
||||
if [[ ${{ env.TAG_SHA }} == "false" ]]; then
|
||||
echo "TAG_LATEST=false" >>$GITHUB_ENV
|
||||
echo "TAG_RAW=true" >>$GITHUB_ENV
|
||||
echo "TAG_LATEST=false" >> $GITHUB_ENV
|
||||
echo "TAG_RAW=true" >> $GITHUB_ENV
|
||||
if [[ -z "${{ env.TAG_SUFFIX }}" ]]; then
|
||||
echo "TAG_RAW_VALUE=latest" >>$GITHUB_ENV
|
||||
echo "TAG_RAW_VALUE=latest" >> $GITHUB_ENV
|
||||
else
|
||||
echo "TAG_RAW_VALUE=latest-{{ env.TAG_SUFFIX }}" >>$GITHUB_ENV
|
||||
echo "TAG_RAW_VALUE=latest-{{ env.TAG_SUFFIX }}" >> $GITHUB_ENV
|
||||
fi
|
||||
else
|
||||
echo "TAG_RAW=false" >>$GITHUB_ENV
|
||||
echo "TAG_RAW=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
# Create contract label for compatible contract image if specified
|
||||
if [[ -n "${{ env.CONTRACT_IMAGE }}" ]]; then
|
||||
echo "CONTRACT_LABEL=storage.codex.nim-codex.blockchain-image=${{ env.CONTRACT_IMAGE }}" >>$GITHUB_ENV
|
||||
echo "CONTRACT_LABEL=storage.codex.nim-codex.blockchain-image=${{ env.CONTRACT_IMAGE }}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Docker - Download digests
|
||||
@ -257,9 +262,12 @@ jobs:
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
$(printf '${{ env.DOCKER_REPO }}@sha256:%s ' *)
|
||||
|
||||
- name: Docker - Image tag
|
||||
id: image_tag
|
||||
run: echo "codex_image=${{ env.DOCKER_REPO }}:${{ steps.meta.outputs.version }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Docker - Inspect image
|
||||
run: |
|
||||
docker buildx imagetools inspect ${{ env.DOCKER_REPO }}:${{ steps.meta.outputs.version }}
|
||||
run: docker buildx imagetools inspect ${{ steps.image_tag.outputs.codex_image }}
|
||||
|
||||
|
||||
# Compute Tests inputs
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user