Skip to content
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

Merged
merged 37 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
6fe21bd
Initial draft
chevdor Nov 8, 2023
161a95a
Add workflow dispatch
chevdor Nov 8, 2023
e30758d
Fix matrix
chevdor Nov 9, 2023
b56efc0
Fix matrix
chevdor Nov 9, 2023
77e4df2
Various fixes, WIP
chevdor Nov 9, 2023
c629af5
Missing parenthesis
chevdor Nov 9, 2023
f80df90
Single line matrix
chevdor Nov 9, 2023
cce30a2
Update actions/checkout to 4.1.1
chevdor Nov 9, 2023
ea67b85
Add fetching for the runtimes from a release
chevdor Nov 9, 2023
5d152da
Typo
chevdor Nov 9, 2023
835a850
Install subwasm from deb
chevdor Nov 9, 2023
8df34b6
Fix subwasm install
chevdor Nov 9, 2023
6e57a10
Don't fetch runtimes from the chain
chevdor Nov 9, 2023
91a2350
Missing bracket
chevdor Nov 9, 2023
d278483
Typo
chevdor Nov 9, 2023
5b8e168
Fix REPO
chevdor Nov 9, 2023
e48ef6b
Fix VAR
chevdor Nov 9, 2023
c7df359
Add logs
chevdor Nov 9, 2023
0f5459a
More logs
chevdor Nov 9, 2023
6bd97b6
Fix env
chevdor Nov 9, 2023
fa2c5cb
Cleanup
chevdor Nov 9, 2023
caf6164
More logs
chevdor Nov 9, 2023
5d96ef2
Fix secret
chevdor Nov 9, 2023
d894084
Remove debugging info
chevdor Nov 9, 2023
e5712dd
Fix python script name
chevdor Nov 9, 2023
f9cf4bf
Make python script executable
chevdor Nov 9, 2023
48ec36d
Debug input args
chevdor Nov 9, 2023
3b6bbce
Fix runtime path
chevdor Nov 9, 2023
59c0bc1
Small fixes
chevdor Nov 9, 2023
19ae3b7
Fix args check
chevdor Nov 9, 2023
932fb54
Use reduced runtime
chevdor Nov 9, 2023
3a7d9cd
Add specs for westend
chevdor Nov 9, 2023
cbf79df
Remove unused Rust cache
chevdor Nov 9, 2023
0a195f0
Minor improvements, doc and cleanup
chevdor Nov 9, 2023
7fbbb03
Merge branch 'master' into wk-231108-check-runtimes
chevdor Nov 9, 2023
9b7dfba
Merge branch 'master' into wk-231108-check-runtimes
chevdor Nov 23, 2023
910361e
Merge branch 'master' into wk-231108-check-runtimes
chevdor Dec 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/runtime_specs/rococo.json
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 ]}
}
}
}
}
17 changes: 17 additions & 0 deletions .github/runtime_specs/westend.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"pallets": {
"1": {
Copy link
Member

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?

Copy link
Contributor Author

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.

"constants": {
"EpochDuration": {
"value": [ 88, 2, 0, 0, 0, 0, 0, 0 ]}
}
},

"2": {
"constants": {
"MinimumPeriod": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it detect typos in the constant names?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the spec contains:

 "2": {
        "constants": {
          "foo": { ... }

and the metadata :

 "2": {
        "constants": {
          "foobar": { ... }

It will not detect a typo but it will not find foo and fail.

"value": [ 184, 11, 0, 0, 0, 0, 0, 0 ]}
}
}
}
}
124 changes: 124 additions & 0 deletions .github/scripts/check-runtime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/env python3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should put this into the pipeline-scripts or releng-scripts repo, since it will be useful in the runtimes repo as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes indeed, I would create a followup PR for the fellowship runtimes.
I think having this script in the polkadot-sdk repo does also make sense since downstream repos will already likely depend on the polkadot-sdk repo.


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()
11 changes: 8 additions & 3 deletions .github/scripts/common/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -202,21 +202,26 @@ fetch_release_artifacts() {
echo "Release ID : $RELEASE_ID"
echo "Repo : $REPO"
echo "Binary : $BINARY"
OUTPUT_DIR=${OUTPUT_DIR:-"./release-artifacts/${BINARY}"}
echo "OUTPUT_DIR : $OUTPUT_DIR"

echo "Fetching release info..."
curl -L -s \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${REPO}/releases/${RELEASE_ID} > release.json

# Get Asset ids
echo "Extract asset ids..."
ids=($(jq -r '.assets[].id' < release.json ))
echo "Extract asset count..."
count=$(jq '.assets|length' < release.json )

# Fetch artifacts
mkdir -p "./release-artifacts/${BINARY}"
pushd "./release-artifacts/${BINARY}" > /dev/null
mkdir -p "$OUTPUT_DIR"
pushd "$OUTPUT_DIR" > /dev/null

echo "Fetching assets..."
iter=1
for id in "${ids[@]}"
do
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-and-attach-release-runtimes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Build ${{ matrix.runtime.name }} ${{ matrix.build_config.type }}
id: srtool_build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/check-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
check-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Rust Cache
uses: Swatinem/rust-cache@3cf7f8cc28d1b4e7d01e3783be10a97d55d483c8 # v2.7.1
Expand Down
94 changes: 94 additions & 0 deletions .github/workflows/check-runtimes.yml
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"