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

Compare artifact sizes #1046

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 38 additions & 0 deletions .github/workflows/compare_sizes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Compare contract sizes with master

on:
issue_comment:
types:
- created

jobs:
generate_report:
runs-on: ubuntu-latest
if: ${{ github.event.comment.body == '/compare'}}
steps:
- name: Generate report
id: report
run: |
echo "::set-output name=REPORT::$(scripts/compare_sizes.py)"
- name: Submit report
if: ${{ success() }}
uses: actions/github-script@v4
with:
script: |
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: ${{ steps.report.outputs.REPORT }},
});
- name: Notify about failure
if: ${{ failure() }}
uses: actions/github-script@v4
with:
script: |
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: 'Failed to generate size comparison report! See the failed CI job for more details.',
});
20 changes: 20 additions & 0 deletions .github/workflows/hi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Greet
on:
issue_comment
# types:
# - created
jobs:
generate_report:
runs-on: ubuntu-latest
steps:
- name: Respond
run: echo "howdy"
# uses: actions/github-script@v4
# with:
# script: |
# github.issues.createComment({
# issue_number: context.issue.number,
# owner: context.repo.owner,
# repo: context.repo.repo,
# body: "howdy",
# });
6 changes: 0 additions & 6 deletions examples/adder/res/.gitignore

This file was deleted.

167 changes: 0 additions & 167 deletions examples/adder/res/adder_abi.json

This file was deleted.

11 changes: 7 additions & 4 deletions examples/build_docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ NAME="$1"
pushd $(dirname ${BASH_SOURCE[0]})
cd ../

SOURCE_HASH="$(echo $(pwd) | md5sum | awk '{print $1;}')"
CONT_NAME="build_${NAME}_$SOURCE_HASH"

# Pick the correct tag to pull from Docker Hub based on OS architecture
_warning="
${YELLOW}WARNING${NC}: You are building smart contracts using ARM64. The resulting artifacts will
Expand All @@ -26,19 +29,19 @@ else
TAG="latest-amd64"
fi

if docker ps -a --format '{{.Names}}' | grep -Eq "^build_${NAME}\$"; then
if docker ps -a --format '{{.Names}}' | grep -Eq "^$CONT_NAME\$"; then
echo "Container exists"
else
docker create \
--mount type=bind,source=$(pwd),target=/host \
--cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
--name=build_"$NAME" \
--name="$CONT_NAME" \
-w /host/examples/"$NAME" \
-e RUSTFLAGS='-C link-arg=-s' \
-e CARGO_TARGET_DIR='/host/docker-target' \
-it nearprotocol/contract-builder:"$TAG" \
/bin/bash
fi

docker start build_"$NAME"
docker exec build_"$NAME" /bin/bash -c "./build.sh"
docker start "$CONT_NAME"
docker exec "$CONT_NAME" /bin/bash -c "./build.sh"
86 changes: 86 additions & 0 deletions scripts/compare_sizes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env python3

# Requires:
# `pip install GitPython`
import os
import tempfile
import glob
from git import Repo

this_file = os.path.abspath(os.path.realpath(__file__))
project_root = os.path.dirname(os.path.dirname(this_file))

def common_entries(*dcts):
if not dcts:
return
for i in set(dcts[0]).intersection(*dcts[1:]):
yield (i,) + tuple(d[i] for d in dcts)

def compare_sizes(old, new):
def fmt(name, old, new):
return name + " | " + str(old) + " | " + str(new)

return "".join(*map(fmt, common_entries(old, new)))

def list_dirs(path):
entries = map(lambda p: os.path.join(path, p), os.listdir(path))
return filter(os.path.isdir, entries)

class ProjectInstance:
def __init__(self, root_dir):
self.root_dir = root_dir

def examples_dir(self):
return os.path.join(self.root_dir, "examples")

def build_artifacts(self):
import subprocess

return subprocess.run(os.path.join(self.examples_dir(), "build_all_docker.sh"), stdout = subprocess.DEVNULL)

def sizes(self):
self.build_artifacts()

artifact_paths = glob.glob(self.examples_dir() + '/*/res/*.wasm')
return {os.path.basename(path):os.stat(path).st_size for path in artifact_paths}

cur_branch = ProjectInstance(project_root)
repo = Repo(project_root)

def report(master, this_branch):
def diff(old, new):
diff = (new - old)/old

res = "{0:+.0%}".format(diff)
if diff < -.1:
res = f"<div class=\"good\">{res}</div>"
elif diff > .1:
res = f"<div class=\"bad\">{res}</div>"

return res

header = """<style>.good{color:Green;}</style>
<style>.bad{color:Red;}</style>

# Contract size report

Sizes are given in bytes.

| contract | master | this branch | difference |
| - | - | - | - |"""

combined = [(name,master,branch,diff(master, branch)) for name, master, branch in common_entries(master, this_branch)]
rows = [f"| {name} | {old} | {new} | {diff} |" for name, old, new, diff in combined]

return "\n".join([header, *rows])

try:
with tempfile.TemporaryDirectory() as tempdir:
repo.git.worktree("add", tempdir, "master")
master = ProjectInstance(tempdir)

master_sizes = master.sizes()
cur_sizes = cur_branch.sizes()
print(report(master_sizes, cur_sizes))
finally:
repo.git.worktree("prune")
Loading