-
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.
- Loading branch information
Manh Cao
authored and
Manh Cao
committed
Sep 16, 2024
1 parent
6b2a7f3
commit 4fe5526
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,41 @@ | ||
name: Validate configuration files | ||
|
||
on: | ||
push: | ||
branches: | ||
- '**' | ||
|
||
jobs: | ||
merge_json_files: | ||
runs-on: ubuntu-latest | ||
|
||
if: github.ref != 'refs/heads/main' | ||
|
||
steps: | ||
- name: Checkout HEAD (current branch) | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 1 # Fetch only the latest commit of the current branch | ||
|
||
- name: Save HEAD commit SHA | ||
id: head | ||
run: echo "HEAD_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV | ||
|
||
- name: Checkout main branch | ||
run: | | ||
git fetch origin main --depth=1 # Fetch only the latest commit of main | ||
git checkout FETCH_HEAD | ||
echo "MAIN_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: Calculate changed folders | ||
run: | | ||
echo "CHANGED_FOLDERS=$$(git diff --name-only $MAIN_SHA $HEAD_SHA -- 'protocols/*' | grep '^protocols/' | xargs -L1 dirname | sed 's|protocols/||' | sort -u)" >> $GITHUB_ENV | ||
- name: Validate | ||
run: | | ||
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,99 @@ | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
|
||
const CHANGED_PROTOCOLS = process.env.CHANGED_PROTOCOLS; | ||
|
||
function isValidEthereumAddress(address) { | ||
const ethereumAddressPattern = /^0x[a-fA-F0-9]{40}$/; | ||
return ethereumAddressPattern.test(address); | ||
} | ||
|
||
async function main() { | ||
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)); | ||
} | ||
|
||
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() |