Skip to content

Commit

Permalink
LF-12061 Run healthcheck on new network (#985)
Browse files Browse the repository at this point in the history
* Added healthCheck for new network deployment git action

* Updated healthCheckForNewNetworkDeployment github action and healthCheck script

* Changed var names

* test

* changed networks

* health check fo new network deployment action adjustments

* temp comment

* test

* test

* c

* d

* fix

* Merge branch 'main' into lf-12061-run-healthcheck-on-new-network

* removed paths

* test

* Revert back networks.json

* Added action description, eror when no networks.json file found, added confirmations

* test

* up

* test
  • Loading branch information
mirooon authored Mar 5, 2025
1 parent e4d597c commit b45e479
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 31 deletions.
112 changes: 112 additions & 0 deletions .github/workflows/healthCheckForNewNetworkDeployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: Health Check for New Network Deployment

# - designed to perform health checks for newly added networks
# - triggers on pull requests and first checks if the config/networks.json file was modified
# - validates that each new network has corresponding deployment and state configuration files
# - runs network-specific health checks
# - any required file is missing or a health check fails, the action exits with an error

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]

jobs:
check-new-network-health:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Check if config/networks.json was changed in this branch
id: check-file-change
run: |
if git diff --name-only origin/main...HEAD | grep -q "config/networks.json"; then
echo "config/networks.json has been modified in this branch"
echo "CONTINUE=true" >> $GITHUB_ENV
else
echo "No changes in config/networks.json detected in this branch"
echo "CONTINUE=false" >> $GITHUB_ENV
fi
- name: Detect Newly Added Networks
if: env.CONTINUE == 'true'
id: detect-changes
run: |
echo "Comparing config/networks.json with the previous commit..."
git fetch origin main --depth=1 || echo "No previous commit found."
if git show origin/main:config/networks.json > /dev/null 2>&1; then
OLD_NETWORKS=$(git show origin/main:config/networks.json | jq 'keys')
else
echo "❌ Error: No previous networks.json found. Expected existing network configuration."
exit 1
fi
NEW_NETWORKS=$(jq 'keys' config/networks.json)
ADDED_NETWORKS=$(jq -n --argjson old "$OLD_NETWORKS" --argjson new "$NEW_NETWORKS" '$new - $old')
echo "Added networks: $ADDED_NETWORKS"
if [[ "$ADDED_NETWORKS" == "[]" ]]; then
echo "No new networks detected."
echo "SKIP_CHECK=true" >> $GITHUB_ENV
else
echo "New networks detected: $ADDED_NETWORKS"
echo "added_networks=$(echo $ADDED_NETWORKS | jq -c .)" >> $GITHUB_ENV
fi
- name: Validate Network Deployment Files
if: env.CONTINUE == 'true' && env.SKIP_CHECK != 'true'
run: |
echo "Validating required files for new networks..."
for network in $(echo $added_networks | jq -r '.[]'); do
echo "🔍 Checking files for network: $network"
# Check if network exists in _targetState.json
if ! jq -e 'has("'"$network"'")' script/deploy/_targetState.json > /dev/null; then
echo "❌ Error: Network '$network' not found in script/deploy/_targetState.json"
exit 1
else
echo "✅ Confirmed: Network '$network' exists in script/deploy/_targetState.json"
fi
# Check if deployments/{network}.json file exists
if [[ ! -f "deployments/$network.json" ]]; then
echo "❌ Error: Missing deployment file: deployments/$network.json"
exit 1
else
echo "✅ Confirmed: Deployment file: deployments/$network.json exists"
fi
done
- name: Install Bun
if: env.CONTINUE == 'true' && env.SKIP_CHECK != 'true'
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

- name: Install Foundry (provides cast)
if: env.CONTINUE == 'true' && env.SKIP_CHECK != 'true'
uses: foundry-rs/foundry-toolchain@v1

- name: Install dependencies
if: env.CONTINUE == 'true' && env.SKIP_CHECK != 'true'
run: bun install

- name: Run Health Checks on New Networks
if: env.CONTINUE == 'true' && env.SKIP_CHECK != 'true'
run: |
echo "Running health check for new networks..."
set -e
for network in $(echo $added_networks | jq -r '.[]'); do
echo "🔍 Checking network: $network"
if bun run script/deploy/healthCheck.ts --network "$network"; then
echo "✅ $network is fine."
else
echo "❌ Health check failed for $network. Exiting..."
exit 1
fi
done
72 changes: 41 additions & 31 deletions script/deploy/healthCheck.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-nocheck
import { consola } from 'consola'
import { $, spinner } from 'zx'
import { $ } from 'zx'
import { defineCommand, runMain } from 'citty'
import * as path from 'path'
import * as fs from 'fs'
Expand All @@ -24,8 +24,6 @@ import { coreFacets, pauserWallet } from '../../config/global.json'

const SAFE_THRESHOLD = 3

const louperCmd = 'louper-cli'

const corePeriphery = [
'ERC20Proxy',
'Executor',
Expand All @@ -48,26 +46,8 @@ const main = defineCommand({
},
},
async run({ args }) {
if ((await $`${louperCmd}`.exitCode) !== 0) {
const answer = await consola.prompt(
'Louper CLI is required but not installed. Would you like to install it now?',
{
type: 'confirm',
}
)
if (answer) {
await spinner(
'Installing...',
() => $`npm install -g @mark3labs/louper-cli`
)
} else {
consola.error('Louper CLI is required to run this script')
process.exit(1)
}
}

const { network } = args
const deployedContracts = await import(
const { default: deployedContracts } = await import(
`../../deployments/${network.toLowerCase()}.json`
)
const targetStateJson = await import(
Expand Down Expand Up @@ -161,16 +141,43 @@ const main = defineCommand({

let registeredFacets: string[] = []
try {
const facetsResult =
await $`${louperCmd} inspect diamond -a ${diamondAddress} -n ${network} --json`
registeredFacets = JSON.parse(facetsResult.stdout).facets.map(
(f: { name: string }) => f.name
)
if (networksConfig[network.toLowerCase()].rpcUrl) {
const rpcUrl: string = networksConfig[network.toLowerCase()].rpcUrl
const facetsResult =
await $`cast call ${diamondAddress} "facets() returns ((address,bytes4[])[])" --rpc-url ${rpcUrl}`
const rawString = facetsResult.stdout

const jsonCompatibleString = rawString
.replace(/\(/g, '[')
.replace(/\)/g, ']')
.replace(/0x[0-9a-fA-F]+/g, '"$&"')

const onChainFacets = JSON.parse(jsonCompatibleString)

if (Array.isArray(onChainFacets)) {
// mapping on-chain facet addresses to names in config
const configFacetsByAddress = Object.fromEntries(
Object.entries(deployedContracts).map(([name, address]) => {
return [address.toLowerCase(), name]
})
)

const onChainFacetAddresses = onChainFacets.map(([address]) =>
address.toLowerCase()
)

const configuredFacetAddresses = Object.keys(configFacetsByAddress)

registeredFacets = onChainFacets.map(([address]) => {
return configFacetsByAddress[address.toLowerCase()]
})
}
} else {
throw new Error('Failed to get rpc from network config file')
}
} catch (error) {
consola.warn(
'Unable to parse louper output - skipping facet registration check'
)
consola.debug('Error:', error)
consola.warn('Unable to parse output - skipping facet registration check')
consola.warn('Error:', error)
}

for (const facet of [...coreFacets, ...nonCoreFacets]) {
Expand Down Expand Up @@ -531,6 +538,7 @@ const main = defineCommand({
finish()
} else {
logError('No dexs configured')
finish()
}
},
})
Expand Down Expand Up @@ -592,8 +600,10 @@ const checkIsDeployed = async (
const finish = () => {
if (errors.length) {
consola.error(`${errors.length} Errors found in deployment`)
process.exit(1)
} else {
consola.success('Deployment checks passed')
process.exit(0)
}
}

Expand Down

0 comments on commit b45e479

Please sign in to comment.