Files
pezkuwi-wallet-utils/.github/workflows/code-quality.yml
T
SatoshiQaziMuhammed 9aacf5cdf8 Publish root 2: root keys move to three dedicated holders (#84)
signed/root.2.json carries the root drafted in docs/root-signing/proposals (threshold 2 of
3 new sr25519 holders, five years, targets key unchanged) with two signatures from the
previous root's keys and two from the new ones, all valid under the "substrate" context
that installed wallets check. Wallets already follow signed/root.N.json, so they move to
the new root on their next config refresh.

The consumed proposal is removed; the CI check runs with no proposals present.
2026-11-05 05:14:37 +04:00

204 lines
6.3 KiB
YAML

name: Code Quality
on:
push:
branches: [main]
pull_request:
branches: [main]
# Weekly, so a signature running out shows here a month before the wallet stops trusting it.
schedule:
- cron: '0 7 * * 1'
# Read-only token: Code Quality never writes through GITHUB_TOKEN.
permissions:
contents: read
jobs:
python-lint:
name: Python Lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install ruff
run: pip install ruff
- name: Run ruff linter
run: ruff check scripts/
continue-on-error: true
- name: Run ruff formatter check
run: ruff format --check scripts/
continue-on-error: true
json-validation:
name: JSON Validation
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Validate JSON files
run: |
ERRORS=0
echo "Validating chain config JSON files..."
for f in chains/v22/android/chains.json chains/v22/chains.json chains/v22/chains_dev.json pezkuwi-overlay/chains/pezkuwi-chains.json; do
if [ -f "$f" ]; then
if python3 -m json.tool "$f" > /dev/null 2>&1; then
echo " $f: valid"
else
echo "::error file=$f::Invalid JSON: $f"
ERRORS=$((ERRORS + 1))
fi
fi
done
exit $ERRORS
signed-config:
name: Signed Config
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install cryptography
run: pip install cryptography
# The wallet refuses a config file whose sha256 signed/targets.json does not give, so
# a change that was not re-signed must not reach master.
- name: Targets signed and matching every served file
run: python3 scripts/signed_config.py check
# A wallet that never fell back to its light client has no saved state, so its first fallback
# starts from this checkpoint; refreshed specifications reach wallets through the signed config.
- name: Light client checkpoint not stale
run: python3 scripts/light_client_specs.py --relay-rpc https://zagros-rpc.pezkuwichain.io --check-age 60
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '22'
# A wallet that finds a root it cannot verify stops refreshing its config, so every published
# signed/root.N.json is checked here exactly as installed wallets check it.
- name: Root chain verifies as installed wallets check it
run: |
npm ci --prefix scripts/root --ignore-scripts --no-audit --no-fund
shopt -s nullglob
node scripts/root/verify_root.mjs docs/root-signing/proposals/*.json
chain-integrity:
name: Chain Config Integrity
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
# Refuses the regressions this repo has already had: assets declared that do not
# exist on chain, sufficiency left undeclared, assets served from a working
# branch, and a published fixture drifting from its source.
- name: Pezkuwi integrity
run: python3 scripts/check_pezkuwi_integrity.py
- name: Verify Pezkuwi chains are present
run: |
CHAINS_FILE="chains/v22/android/chains.json"
if [ ! -f "$CHAINS_FILE" ]; then
echo "::error::$CHAINS_FILE not found"
exit 1
fi
ERRORS=0
# Pezkuwi Relay
if ! python3 -c "import json; chains=json.load(open('$CHAINS_FILE')); assert any(c['chainId'].startswith('1aa94987') for c in chains), 'Missing Pezkuwi Relay'"; then
echo "::error::Pezkuwi Relay chain missing from $CHAINS_FILE"
ERRORS=$((ERRORS + 1))
else
echo "Pezkuwi Relay: present"
fi
# Pezkuwi Asset Hub
if ! python3 -c "import json; chains=json.load(open('$CHAINS_FILE')); assert any(c['chainId'].startswith('e7c15092') for c in chains), 'Missing Asset Hub'"; then
echo "::error::Pezkuwi Asset Hub missing from $CHAINS_FILE"
ERRORS=$((ERRORS + 1))
else
echo "Pezkuwi Asset Hub: present"
fi
# Pezkuwi People
if ! python3 -c "import json; chains=json.load(open('$CHAINS_FILE')); assert any(c['chainId'].startswith('69a8d025') for c in chains), 'Missing People Chain'"; then
echo "::error::Pezkuwi People chain missing from $CHAINS_FILE"
ERRORS=$((ERRORS + 1))
else
echo "Pezkuwi People: present"
fi
# Verify Pezkuwi chains are first in array
FIRST_CHAIN=$(python3 -c "import json; print(json.load(open('$CHAINS_FILE'))[0]['chainId'][:8])")
if [ "$FIRST_CHAIN" != "1aa94987" ]; then
echo "::warning::Pezkuwi Relay is not the first chain (found: $FIRST_CHAIN)"
else
echo "Pezkuwi Relay is first chain: OK"
fi
exit $ERRORS
sync-script-test:
name: Sync Script Dry Run
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Run sync script
run: python3 scripts/sync_from_nova.py
- name: Verify output was generated
run: |
if [ ! -f "chains/v22/android/chains.json" ]; then
echo "::error::Sync script failed to generate chains/v22/android/chains.json"
exit 1
fi
COUNT=$(python3 -c "import json; print(len(json.load(open('chains/v22/android/chains.json'))))")
echo "Generated $COUNT chains"
if [ "$COUNT" -lt 4 ]; then
echo "::error::Expected at least 4 chains, got $COUNT"
exit 1
fi