Skip to content

Commit 4801d02

Browse files
Display difference in tx-cost outputs as a comment on PRs (#1703)
This adds a simple diff calculation to the PR comment, just like the present "Transaction costs" comment we get, but instead a diff between the PR and the master branch. Positive numbers are bad - it means the cost/size/etc got larger with the introduction of the PR. These are coloured black. Negative numbers are good - it means a reduction in size/cost/etc, so these are coloured green. Values that are the same between PR and branch are simply listed as `-`; i.e. unchanged. > [!note] > It seems that some differences are expected _even when nothing relevant has changed_, as in this PR itself. So some care will need to be taken in learning how to interpret these numbers, as we see them develop over furture PRs.
2 parents d8c0a49 + 90f61d4 commit 4801d02

File tree

3 files changed

+169
-0
lines changed

3 files changed

+169
-0
lines changed

.github/workflows/ci-nix.yaml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ jobs:
288288
path: |
289289
./*.pdf
290290
291+
291292
documentation:
292293
name: Documentation
293294
needs: [haddock,benchmarks,build-test,build-specification]
@@ -359,3 +360,81 @@ jobs:
359360
run: |
360361
yarn
361362
yarn build-dev
363+
364+
365+
# Compute the cost difference between this branch and master.
366+
tx-cost-diff:
367+
name: Compute cost differences
368+
runs-on: ubuntu-latest
369+
# Only run on PR
370+
if: github.event_name == 'pull_request'
371+
steps:
372+
- name: "Checkout the PR as the 'new' source"
373+
uses: actions/checkout@v4
374+
with:
375+
path: ./new
376+
ref: ${{ github.event.pull_request.head.sha }}
377+
378+
- name: "Checkout `master` as the 'old' source"
379+
uses: actions/checkout@v4
380+
with:
381+
path: ./old
382+
ref: master
383+
384+
- name: ❄ Prepare nix
385+
uses: cachix/install-nix-action@v30
386+
with:
387+
extra_nix_config: |
388+
accept-flake-config = true
389+
log-lines = 1000
390+
391+
- name: ❄ Cachix cache of nix derivations
392+
uses: cachix/cachix-action@v15
393+
with:
394+
name: cardano-scaling
395+
authToken: '${{ secrets.CACHIX_CARDANO_SCALING_AUTH_TOKEN }}'
396+
397+
- name: Set up and use the "ci" devShell
398+
uses: nicknovitski/nix-develop@v1
399+
with:
400+
arguments: "./new#costDifferences"
401+
402+
- name: "Compute costs on both old and new"
403+
run: |
404+
nix run ./new/#tx-cost >new.md
405+
nix run ./old/#tx-cost >old.md
406+
407+
- name: "Compute the difference markdown"
408+
run: |
409+
# Convert to HTML, as that's the easiest way to read the markdown
410+
# tables via pandas (!!!)
411+
pandoc -i new.md -o new.html
412+
pandoc -i old.md -o old.html
413+
414+
cat new.md | grep '##' >new-headers.txt
415+
cat old.md | grep '##' >old-headers.txt
416+
417+
# Stop if the heading columns aren't the same.
418+
cmp old-headers.txt new-headers.txt
419+
420+
# Run the diff script; note that it's located in the "new" folder.
421+
./new/.github/workflows/cost-differences/diff.py \
422+
old-headers.txt \
423+
old.html \
424+
new.html >diff.md
425+
426+
- name: 🔎 Find Comment
427+
uses: peter-evans/find-comment@v3
428+
id: find-comment
429+
with:
430+
issue-number: ${{ github.event.pull_request.number }}
431+
comment-author: 'github-actions[bot]'
432+
body-includes: Transaction cost differences
433+
434+
- name: ✏ Create or update comment
435+
uses: peter-evans/create-or-update-comment@v4
436+
with:
437+
comment-id: ${{ steps.find-comment.outputs.comment-id }}
438+
edit-mode: replace
439+
issue-number: ${{ github.event.pull_request.number }}
440+
body-file: diff.md
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#! /usr/bin/env python
2+
3+
import pandas as pd
4+
import argparse
5+
6+
parser = argparse.ArgumentParser()
7+
parser.add_argument("header_file", type=str)
8+
parser.add_argument("old_file", type=str)
9+
parser.add_argument("new_file", type=str)
10+
args = parser.parse_args()
11+
12+
with open(args.header_file, "r") as f:
13+
headers = [ l[3:].strip() for l in f.readlines() ]
14+
15+
base = pd.read_html(args.old_file, flavor="html5lib")
16+
branch = pd.read_html(args.new_file, flavor="html5lib")
17+
18+
def script_size(df):
19+
return df.drop(columns=["Hash"]).set_index("Name")
20+
21+
def parties(df):
22+
return df.set_index("Parties")
23+
24+
def utxo(df):
25+
return df.set_index("UTxO")
26+
27+
def compare_to_md(f, old, new):
28+
# New should be better, so we compare to that.
29+
df = f(new) - f(old)
30+
31+
# Don't keep what we couldn't compare.
32+
df = df.dropna()
33+
34+
# Round everything to 2 decimals
35+
df = df.round(2)
36+
37+
# Add colour
38+
def update_colour(x):
39+
if x == 0:
40+
return "-"
41+
42+
if type(x) is object:
43+
return x
44+
45+
if x > 0:
46+
return f"+{x}"
47+
else:
48+
return f"$${{\\color{{green}}{x:.2f}}}$$"
49+
50+
df = df.map(update_colour)
51+
52+
return df.to_markdown()
53+
54+
print("Transaction cost differences")
55+
56+
# First is the script size
57+
58+
print(f"## {headers[0]}")
59+
print("")
60+
print( compare_to_md( script_size, base[1], branch[1]) )
61+
62+
# Then Init,
63+
print("")
64+
print(f"## {headers[1]}")
65+
print("")
66+
print( compare_to_md(parties, base[2], branch[2]) )
67+
68+
# Then Commit is different; it doesn't have a "Parties" column
69+
70+
print("")
71+
print(f"## {headers[2]}")
72+
print("")
73+
print( compare_to_md(utxo, base[3], branch[3]) )
74+
75+
# The remaining are all the same as Init.
76+
for i in range(4, 9 + 1):
77+
print("")
78+
print(f"## {headers[i - 1]}")
79+
print("")
80+
print( compare_to_md(parties, base[i], branch[i]) )

nix/hydra/shell.nix

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,15 @@ let
150150
];
151151
};
152152

153+
# Shell for computing tx-cost-differences
154+
costDifferencesShell = pkgs.mkShell {
155+
name = "tx-cost-differences-shell";
156+
buildInputs = [
157+
pkgs.pandoc
158+
(pkgs.python3.withPackages (ps: with ps; [ pandas html5lib beautifulsoup4 tabulate ]))
159+
];
160+
};
161+
153162
# If you want to modify `Python` code add `libtmux` and pyyaml to the
154163
# `buildInputs` then enter it and then run `Python` module directly so you
155164
# have fast devel cycle.
@@ -165,4 +174,5 @@ in
165174
exes = exeShell;
166175
demo = demoShell;
167176
ci = ciShell;
177+
costDifferences = costDifferencesShell;
168178
}

0 commit comments

Comments
 (0)