-
Notifications
You must be signed in to change notification settings - Fork 839
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add check runtimes
GH Workflow
#2252
Changes from all commits
6fe21bd
161a95a
e30758d
b56efc0
77e4df2
c629af5
f80df90
cce30a2
ea67b85
5d152da
835a850
8df34b6
6e57a10
91a2350
d278483
5b8e168
e48ef6b
c7df359
0f5459a
6bd97b6
fa2c5cb
caf6164
5d96ef2
d894084
e5712dd
f9cf4bf
48ec36d
3b6bbce
59c0bc1
19ae3b7
932fb54
3a7d9cd
cbf79df
0a195f0
7fbbb03
9b7dfba
910361e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"pallets": { | ||
"1": { | ||
"constants": { | ||
"EpochDuration": { | ||
"value": [ 88, 2, 0, 0, 0, 0, 0, 0 ]} | ||
} | ||
}, | ||
|
||
"2": { | ||
"constants": { | ||
"MinimumPeriod": { | ||
"value": [ 184, 11, 0, 0, 0, 0, 0, 0 ]} | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"pallets": { | ||
"1": { | ||
"constants": { | ||
"EpochDuration": { | ||
"value": [ 88, 2, 0, 0, 0, 0, 0, 0 ]} | ||
} | ||
}, | ||
|
||
"2": { | ||
"constants": { | ||
"MinimumPeriod": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it detect typos in the constant names? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the spec contains:
and the metadata :
It will not detect a typo but it will not find |
||
"value": [ 184, 11, 0, 0, 0, 0, 0, 0 ]} | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#!/usr/bin/env python3 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should put this into the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes indeed, I would create a followup PR for the fellowship runtimes. |
||
|
||
import json | ||
import sys | ||
import logging | ||
import os | ||
|
||
|
||
def check_constant(spec_pallet_id, spec_pallet_value, meta_constant): | ||
""" | ||
Check a single constant | ||
|
||
:param spec_pallet_id: | ||
:param spec_pallet_value: | ||
:param meta_constant: | ||
:return: | ||
""" | ||
if meta_constant['name'] == list(spec_pallet_value.keys())[0]: | ||
constant = meta_constant['name'] | ||
res = list(spec_pallet_value.values())[0]["value"] == meta_constant["value"] | ||
|
||
logging.debug(f" Checking pallet:{spec_pallet_id}/constants/{constant}") | ||
logging.debug(f" spec_pallet_value: {spec_pallet_value}") | ||
logging.debug(f" meta_constant: {meta_constant}") | ||
logging.info(f"pallet:{spec_pallet_id}/constants/{constant} -> {res}") | ||
return res | ||
else: | ||
# logging.warning(f" Skipping pallet:{spec_pallet_id}/constants/{meta_constant['name']}") | ||
pass | ||
|
||
|
||
def check_pallet(metadata, spec_pallet): | ||
""" | ||
Check one pallet | ||
|
||
:param metadata: | ||
:param spec_pallet_id: | ||
:param spec_pallet_value: | ||
:return: | ||
""" | ||
|
||
spec_pallet_id, spec_pallet_value = spec_pallet | ||
logging.debug(f"Pallet: {spec_pallet_id}") | ||
|
||
metadata_pallets = metadata["pallets"] | ||
metadata_pallet = metadata_pallets[spec_pallet_id] | ||
|
||
res = map(lambda meta_constant_value: check_constant( | ||
spec_pallet_id, spec_pallet_value["constants"], meta_constant_value), | ||
metadata_pallet["constants"].values()) | ||
res = list(filter(lambda item: item is not None, res)) | ||
return all(res) | ||
|
||
|
||
def check_pallets(metadata, specs): | ||
""" | ||
CHeck all pallets | ||
|
||
:param metadata: | ||
:param specs: | ||
:return: | ||
""" | ||
|
||
res = list(map(lambda spec_pallet: check_pallet(metadata, spec_pallet), | ||
specs['pallets'].items())) | ||
res = list(filter(lambda item: item is not None, res)) | ||
return all(res) | ||
|
||
|
||
def check_metadata(metadata, specs): | ||
""" | ||
Check metadata (json) against a list of expectations | ||
|
||
:param metadata: Metadata in JSON format | ||
:param expectation: Expectations | ||
:return: Bool | ||
""" | ||
|
||
res = check_pallets(metadata, specs) | ||
return res | ||
|
||
|
||
def help(): | ||
""" Show some simple help """ | ||
|
||
print(f"You must pass 2 args, you passed {len(sys.argv) - 1}") | ||
print("Sample call:") | ||
print("check-runtime.py <metadata.json> <specs.json>") | ||
|
||
|
||
def load_json(file): | ||
""" Load json from a file """ | ||
|
||
f = open(file) | ||
return json.load(f) | ||
|
||
|
||
def main(): | ||
LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper() | ||
logging.basicConfig(level=LOGLEVEL) | ||
|
||
if len(sys.argv) != 3: | ||
help() | ||
exit(1) | ||
|
||
metadata_file = sys.argv[1] | ||
specs_file = sys.argv[2] | ||
print(f"Checking metadata from: {metadata_file} with specs from: {specs_file}") | ||
|
||
metadata = load_json(metadata_file) | ||
specs = load_json(specs_file) | ||
|
||
res = check_metadata(metadata, specs) | ||
|
||
if res: | ||
logging.info(f"OK") | ||
exit(0) | ||
else: | ||
print("") | ||
logging.info(f"Some errors were found, run again with LOGLEVEL=debug") | ||
exit(1) | ||
|
||
if __name__ == "__main__": | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
name: Check Runtimes Specs | ||
# This GH Workflow fetches the runtimes available in a release. | ||
# It then compares their metadata with reference specs located under | ||
# .github/runtime_specs. | ||
|
||
on: | ||
workflow_dispatch: | ||
inputs: | ||
release_id: | ||
description: | | ||
Release ID. | ||
You can find it using the command: | ||
curl -s \ | ||
-H "Authorization: Bearer ${GITHUB_TOKEN}" https://api.github.com/repos/paritytech/polkadot-sdk/releases | \ | ||
jq '.[] | { name: .name, id: .id }' | ||
required: true | ||
type: string | ||
|
||
# This trigger unfortunately does not work as expected. | ||
# https://github.com/orgs/community/discussions/47794 | ||
# release: | ||
# types: [edited] | ||
|
||
env: | ||
RUNTIME_SPECS_DIR: .github/runtime_specs | ||
DATA_DIR: runtimes | ||
RELEASE_ID: ${{ inputs.release_id }} | ||
REPO: ${{ github.repository }} | ||
|
||
jobs: | ||
find-specs: | ||
name: Fetch runtime specs | ||
outputs: | ||
specs: ${{ steps.get-list.outputs.specs }} | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout the repo | ||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||
|
||
- name: Get list | ||
id: get-list | ||
run: | | ||
lst=$(ls $RUNTIME_SPECS_DIR/*.json | xargs -I{} basename "{}" .json | jq -R .| jq -sc .) | ||
echo "Found: $lst" | ||
echo "specs=$lst" >> $GITHUB_OUTPUT | ||
|
||
check-runtimes: | ||
name: Check runtime specs | ||
runs-on: ubuntu-latest | ||
needs: | ||
- find-specs | ||
|
||
strategy: | ||
matrix: | ||
specs: ${{ fromJSON(needs.find-specs.outputs.specs) }} | ||
|
||
steps: | ||
- name: Checkout the repo | ||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 | ||
|
||
- name: Fetch release artifacts based on release id | ||
env: | ||
OUTPUT_DIR: ${{ env.DATA_DIR }} | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
run: | | ||
. ./.github/scripts/common/lib.sh | ||
fetch_release_artifacts | ||
|
||
- name: Install tooling | ||
env: | ||
SUBWASM_VERSION: v0.20.0 | ||
DL_BASE_URL: https://github.com/chevdor/subwasm/releases/download | ||
run: | | ||
wget $DL_BASE_URL/$SUBWASM_VERSION/subwasm_linux_amd64_$SUBWASM_VERSION.deb \ | ||
-O subwasm.deb | ||
sudo dpkg -i subwasm.deb | ||
subwasm --version | ||
|
||
- name: Extract metadata JSON for ${{ matrix.specs }} | ||
env: | ||
RUNTIME: ${{ matrix.specs }} | ||
run: | | ||
WASM=$(ls ${DATA_DIR}/${RUNTIME}*.wasm) | ||
echo "WASM=$WASM" | ||
subwasm show --json "$WASM" > "${DATA_DIR}/${RUNTIME}.json" | ||
|
||
- name: Check specs for ${{ matrix.specs }} | ||
id: build | ||
env: | ||
RUNTIME: ${{ matrix.specs }} | ||
LOGLEVEL: info | ||
run: | | ||
python --version | ||
.github/scripts/check-runtime.py "${DATA_DIR}/${RUNTIME}.json" "${RUNTIME_SPECS_DIR}/${RUNTIME}.json" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we go by pallet name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this first version, I kept things simple and I am not interpreting the specs. This is why they must match 100% the format of the actuall metadata.
That could be improvement in the future but I would rather get started simple to have this check in place asap.
The benefit of the current option as well is that we can pretty much use the current metadata as spec, that would be may too strict but it works as a starting point.