Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
init verify schema github action
Browse files Browse the repository at this point in the history
Manh Cao authored and Manh Cao committed Sep 17, 2024
1 parent 6b2a7f3 commit 3334831
Showing 5 changed files with 143 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/combine-config.yml
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ jobs:
git config --global user.name "$GIT_USERNAME"
git config --global user.email "$GIT_EMAIL"
git add config.json
git commit -m "Merge JSON files"
git diff-index --quiet HEAD || git commit -m "Merge JSON files"
git push
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39 changes: 39 additions & 0 deletions .github/workflows/validate-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Validate configuration files

on:
push:
branches:
- '**'

jobs:
validate_json_files:
runs-on: ubuntu-latest

if: github.ref != 'refs/heads/main'

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main

- name: Checkout main branch
run: |
echo "MAIN_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
- name: Checkout repository
uses: actions/checkout@v4

- name: Save HEAD commit SHA
run: |
echo "HEAD_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '20' # Or your preferred version

- name: Validate JSON files
run: |
CHANGED_PROTOCOLS=$(git diff --name-only $HEAD_SHA $MAIN_SHA -- 'protocols/*' | grep '^protocols/' | xargs -L1 dirname | sed 's|protocols/||' | sort -u)
CHANGED_PROTOCOLS=$CHANGED_PROTOCOLS node validate-config.js
3 changes: 1 addition & 2 deletions protocols/protocol-name-1/config.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{
"name": "Protocol Name 1",
"name": "Protocol Name 1 abc",
"icon": "logo.svg",
"metadata": {
"pt": [
{
"chainId": 1,
"address": "0x332a8ee60edff0a11cf3994b1b846bbc27d3dcd6",
"integrationUrl": "https://www.pendle.magpiexyz.io/stake",
"description": "hello it's pt"
}
],
2 changes: 1 addition & 1 deletion protocols/protocol-name-2/config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "Protocol Name 2",
"name": "Protocol Name 2 abc",
"icon": "logo.jpeg",
"metadata": {
"pt": [
101 changes: 101 additions & 0 deletions validate-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
const fs = require('fs');
const path = require('path');

function isValidEthereumAddress(address) {
const ethereumAddressPattern = /^0x[a-fA-F0-9]{40}$/;
return ethereumAddressPattern.test(address);
}

async function main() {
const CHANGED_PROTOCOLS = process.env.CHANGED_PROTOCOLS;

if (!CHANGED_PROTOCOLS) {
console.log('No changed protocols');
return;
}

const protocols = CHANGED_PROTOCOLS.split('\n');

console.log('Currently validating protocols:', protocols);

protocols.forEach((protocol) => validateConfig(protocol));

console.log('Everything is fine.....')
}

function validateConfig(protocol) {
const protocolsPath = path.join(__dirname, 'protocols');
const configPath = path.join(protocolsPath, protocol, 'config.json');

if (!fs.existsSync(configPath)) {
throw new Error(`protocol ${protocol}: config.json not found`);
}

const protocolConfigStr = fs.readFileSync(configPath, 'utf8');
const protocolConfig = JSON.parse(protocolConfigStr);

if (typeof protocolConfig !== 'object'){
throw new Error(`protocol ${protocol}: config is not an object`);
}

const {name, icon, metadata} = protocolConfig;

if (!mustBeNonEmptyString(name)) {
throw new Error(`protocol ${protocol}: invalid field 'name'`);
}

if (!mustBeNonEmptyString(icon)) {
throw new Error(`protocol ${protocol}: invalid field 'icon'`);
}

if (typeof metadata !== 'object') {
throw new Error(`protocol ${protocol}: invalid field 'metadata'`);
}

const iconPath = path.join(protocolsPath, protocol, icon);
if (!fs.existsSync(iconPath)) {
throw new Error(`protocol ${protocol}: icon path not found for protocol ${icon}`);
}

const {pt, yt, lp} = metadata;
checkMetadataField(pt, protocol, 'pt');
checkMetadataField(yt, protocol, 'yt');
checkMetadataField(lp, protocol, 'lp');
}

function mustBeNonEmptyString(str) {
return typeof str === 'string' && str.trim() !== '';
}

function checkMetadataField(data, protocol, field) {
if (data === null || data === undefined) {
return;
}

if (!Array.isArray(data)) {
throw new Error(`protocol ${protocol}: metadata ${field} must be an array`)
}

for (let index = 0; index < data.length; index ++) {
const item = data[index];
const {chainId, address, description, integrationUrl} = item;

if (typeof chainId !== 'number') {
throw new Error(`protocol ${protocol}: metadata ${field} invalid 'chainId' field at index ${index}`);
}

if (!mustBeNonEmptyString(address) || !isValidEthereumAddress(address)) {
throw new Error(`protocol ${protocol}: metadata ${field} invalid 'address' field at index ${index}`);
}

if (!mustBeNonEmptyString(description)) {
throw new Error(`protocol ${protocol}: metadata ${field} invalid 'description' field at index ${index}`);
}

if (!mustBeNonEmptyString(integrationUrl)) {
throw new Error(`protocol ${protocol}: metadata ${field} invalid 'integrationUrl' field at index ${index}`);
}
}
}

void main()

0 comments on commit 3334831

Please sign in to comment.