-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
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 (#3)
Co-authored-by: Manh Cao <[email protected]>
- Loading branch information
1 parent
6b2a7f3
commit a720684
Showing
5 changed files
with
143 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"name": "Protocol Name 1", | ||
"name": "Protocol Name 1 abc", | ||
"icon": "logo.svg", | ||
"metadata": { | ||
"pt": [ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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": [ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |