Skip to content

Commit a62f297

Browse files
authored
Merge pull request #1303 from Mrwicks00/chore/1255-1256-1257-1258-ci-dx-improvements
chore(ci): add cargo-deny, cache Playwright, split lint job, report W…
2 parents bafdb7d + 1fd94f8 commit a62f297

5 files changed

Lines changed: 263 additions & 10 deletions

File tree

.github/workflows/contracts.yml

Lines changed: 110 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ on:
1414
permissions:
1515
contents: read
1616

17+
env:
18+
# Regression guard for the deployed contract only. Raised from the
19+
# previous 55000: that limit was never actually enforced (the old
20+
# check globbed *.wasm, so SIZE held two values and `[` aborted with
21+
# "too many arguments" — which, as an `if` condition, silently read
22+
# as false). The contract has since grown to ~87 KB. Hoisted to
23+
# workflow level so the size-report job below stays in sync with it.
24+
MAX_WASM_BYTES: "92160" # 90 KB
25+
1726
jobs:
1827
test:
1928
name: Test & Build
@@ -52,13 +61,6 @@ jobs:
5261
run: cargo build --target wasm32-unknown-unknown --release
5362

5463
- name: Check WASM size
55-
env:
56-
# Regression guard for the deployed contract only. Raised from the
57-
# previous 55000: that limit was never actually enforced (the old
58-
# check globbed *.wasm, so SIZE held two values and `[` aborted with
59-
# "too many arguments" — which, as an `if` condition, silently read
60-
# as false). The contract has since grown to ~87 KB.
61-
MAX_WASM_BYTES: "92160" # 90 KB
6264
run: |
6365
set -euo pipefail
6466
ARTIFACT=target/wasm32-unknown-unknown/release/stellar_contracts.wasm
@@ -81,3 +83,104 @@ jobs:
8183
8284
- name: Run clippy (deny warnings)
8385
run: cargo clippy --all-targets --all-features -- -D warnings
86+
87+
deny:
88+
name: License & Advisory Check
89+
runs-on: ubuntu-latest
90+
91+
steps:
92+
- name: Checkout repository
93+
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
94+
95+
- name: Run cargo-deny (licenses & advisories)
96+
uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1
97+
with:
98+
manifest-path: Dechat/stellar-contracts/Cargo.toml
99+
command: check licenses advisories bans sources
100+
101+
wasm-size-report:
102+
name: WASM Size Report
103+
runs-on: ubuntu-latest
104+
if: github.event_name == 'pull_request'
105+
106+
steps:
107+
- name: Checkout PR head
108+
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
109+
with:
110+
path: head
111+
ref: ${{ github.event.pull_request.head.sha }}
112+
113+
- name: Checkout PR base
114+
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
115+
with:
116+
path: base
117+
ref: ${{ github.event.pull_request.base.sha }}
118+
119+
- name: Set up Rust
120+
uses: dtolnay/rust-toolchain@2c7215f132e9ebf062739d9130488b56d53c060c # stable
121+
with:
122+
toolchain: stable
123+
targets: wasm32-unknown-unknown
124+
125+
- name: Cache Cargo registry & shared target dir
126+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
127+
with:
128+
path: |
129+
~/.cargo/registry
130+
~/.cargo/git
131+
.wasm-size-target
132+
key: ${{ runner.os }}-cargo-wasm-size-${{ hashFiles('head/Dechat/stellar-contracts/Cargo.lock') }}
133+
restore-keys: |
134+
${{ runner.os }}-cargo-wasm-size-
135+
136+
- name: Build head WASM
137+
working-directory: head/Dechat/stellar-contracts
138+
# --lib only: this crate also has src/bin/deploy_fiat_bridge_futurenet.rs,
139+
# which compiles to its own .wasm and would collide with a glob match.
140+
run: cargo build --target wasm32-unknown-unknown --release --lib
141+
env:
142+
CARGO_TARGET_DIR: ${{ github.workspace }}/.wasm-size-target
143+
144+
- name: Record head size
145+
id: head_size
146+
run: |
147+
SIZE=$(wc -c < "${{ github.workspace }}/.wasm-size-target/wasm32-unknown-unknown/release/stellar_contracts.wasm" | tr -d '[:space:]')
148+
echo "size=$SIZE" >> "$GITHUB_OUTPUT"
149+
150+
- name: Build base WASM
151+
working-directory: base/Dechat/stellar-contracts
152+
run: cargo build --target wasm32-unknown-unknown --release --lib
153+
env:
154+
CARGO_TARGET_DIR: ${{ github.workspace }}/.wasm-size-target
155+
156+
- name: Record base size
157+
id: base_size
158+
run: |
159+
SIZE=$(wc -c < "${{ github.workspace }}/.wasm-size-target/wasm32-unknown-unknown/release/stellar_contracts.wasm" | tr -d '[:space:]')
160+
echo "size=$SIZE" >> "$GITHUB_OUTPUT"
161+
162+
- name: Write size report
163+
run: |
164+
cat > wasm-size-report.json <<EOF
165+
{
166+
"pr_number": ${{ github.event.pull_request.number }},
167+
"base_sha": "${{ github.event.pull_request.base.sha }}",
168+
"head_sha": "${{ github.event.pull_request.head.sha }}",
169+
"base_size": ${{ steps.base_size.outputs.size }},
170+
"head_size": ${{ steps.head_size.outputs.size }},
171+
"limit": ${{ env.MAX_WASM_BYTES }}
172+
}
173+
EOF
174+
175+
# PRs from forks get a read-only GITHUB_TOKEN under the `pull_request`
176+
# event, so this job can't post a comment directly. The report is
177+
# handed off as an artifact to wasm-size-comment.yml, which runs via
178+
# `workflow_run` in the base repo's context (write-capable token) and
179+
# only ever reads this JSON — it never checks out or executes PR code,
180+
# so it stays safe from a malicious PR's build script.
181+
- name: Upload size report artifact
182+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
183+
with:
184+
name: wasm-size-report
185+
path: wasm-size-report.json
186+
retention-days: 7

.github/workflows/frontend.yml

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ permissions:
1515
contents: read
1616

1717
jobs:
18-
build:
19-
name: Build & Type Check
18+
lint:
19+
name: Lint & Type Check
2020
runs-on: ubuntu-latest
2121

2222
defaults:
@@ -48,6 +48,33 @@ jobs:
4848
- name: Lint
4949
run: pnpm lint
5050

51+
build:
52+
name: Build & Test
53+
runs-on: ubuntu-latest
54+
55+
defaults:
56+
run:
57+
working-directory: Dechat/dex_with_fiat_frontend
58+
59+
steps:
60+
- name: Checkout repository
61+
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
62+
63+
- name: Install pnpm
64+
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
65+
with:
66+
version: 8
67+
68+
- name: Set up Node.js
69+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
70+
with:
71+
node-version: "24"
72+
cache: "pnpm"
73+
cache-dependency-path: Dechat/dex_with_fiat_frontend/pnpm-lock.yaml
74+
75+
- name: Install dependencies
76+
run: pnpm install
77+
5178
- name: Build
5279
run: pnpm build
5380
env:
@@ -88,7 +115,7 @@ jobs:
88115
e2e:
89116
name: Playwright E2E Tests
90117
runs-on: ubuntu-latest
91-
needs: build
118+
needs: [build, lint]
92119

93120
defaults:
94121
run:
@@ -113,9 +140,21 @@ jobs:
113140
- name: Install dependencies
114141
run: pnpm install
115142

143+
- name: Cache Playwright browsers
144+
id: playwright-cache
145+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
146+
with:
147+
path: ~/.cache/ms-playwright
148+
key: playwright-${{ runner.os }}-${{ hashFiles('Dechat/dex_with_fiat_frontend/pnpm-lock.yaml') }}
149+
116150
- name: Install Playwright browsers
151+
if: steps.playwright-cache.outputs.cache-hit != 'true'
117152
run: pnpm exec playwright install --with-deps chromium firefox webkit
118153

154+
- name: Install Playwright OS dependencies
155+
if: steps.playwright-cache.outputs.cache-hit == 'true'
156+
run: pnpm exec playwright install-deps chromium firefox webkit
157+
119158
- name: Build for E2E
120159
run: pnpm build
121160
env:
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: WASM Size Comment
2+
3+
# Runs in the base repo's context (not the PR head's), so it gets a
4+
# write-capable GITHUB_TOKEN even for PRs from forks. It never checks out
5+
# or executes any code from the PR — it only downloads the small JSON
6+
# artifact produced by the `wasm-size-report` job in contracts.yml and
7+
# posts/updates a PR comment from it.
8+
on:
9+
workflow_run:
10+
workflows: ["Smart Contract CI"]
11+
types: [completed]
12+
13+
permissions:
14+
contents: read
15+
pull-requests: write
16+
17+
jobs:
18+
comment:
19+
name: Post size comment
20+
runs-on: ubuntu-latest
21+
if: github.event.workflow_run.event == 'pull_request'
22+
23+
steps:
24+
- name: Download size report artifact
25+
id: download
26+
continue-on-error: true
27+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
28+
with:
29+
name: wasm-size-report
30+
run-id: ${{ github.event.workflow_run.id }}
31+
github-token: ${{ secrets.GITHUB_TOKEN }}
32+
33+
- name: Post or update comment
34+
if: steps.download.outcome == 'success'
35+
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
36+
with:
37+
script: |
38+
const fs = require('fs');
39+
const report = JSON.parse(fs.readFileSync('wasm-size-report.json', 'utf8'));
40+
41+
const delta = report.head_size - report.base_size;
42+
const deltaStr = `${delta > 0 ? '+' : ''}${delta.toLocaleString()} bytes`;
43+
const pct = ((report.head_size / report.limit) * 100).toFixed(1);
44+
const marker = '<!-- wasm-size-report -->';
45+
46+
const body = [
47+
marker,
48+
'### Contract WASM size report',
49+
'',
50+
'| | Bytes |',
51+
'|---|---|',
52+
`| Base (\`${report.base_sha.slice(0, 7)}\`) | ${report.base_size.toLocaleString()} |`,
53+
`| Head (\`${report.head_sha.slice(0, 7)}\`) | ${report.head_size.toLocaleString()} |`,
54+
`| Delta | ${deltaStr} |`,
55+
`| Budget used | ${pct}% of ${report.limit.toLocaleString()} bytes |`,
56+
].join('\n');
57+
58+
const { owner, repo } = context.repo;
59+
const issue_number = report.pr_number;
60+
61+
const comments = await github.rest.issues.listComments({ owner, repo, issue_number });
62+
const existing = comments.data.find((c) => c.body.includes(marker));
63+
64+
if (existing) {
65+
await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body });
66+
} else {
67+
await github.rest.issues.createComment({ owner, repo, issue_number, body });
68+
}

Dechat/stellar-contracts/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "stellar-contracts"
33
version = "0.1.0"
44
edition = "2021"
5+
publish = false
56

67
[lib]
78
crate-type = ["cdylib"]

Dechat/stellar-contracts/deny.toml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
[graph]
2+
all-features = false
3+
no-default-features = false
4+
5+
[output]
6+
feature-depth = 1
7+
8+
[advisories]
9+
ignore = [
10+
# Transitive deps of soroban-sdk 25.3.0 (via soroban-env-host -> ark-*).
11+
# No soroban-sdk release drops these yet; re-evaluate on the next SDK bump.
12+
{ id = "RUSTSEC-2024-0388", reason = "derivative is unmaintained; pulled in transitively by soroban-env-host's arkworks deps, no upstream fix available" },
13+
{ id = "RUSTSEC-2024-0436", reason = "paste is unmaintained; pulled in transitively by soroban-env-host/soroban-wasmi, no upstream fix available" },
14+
{ crate = "spin@0.9.8", reason = "yanked version pinned transitively by soroban-wasmi via soroban-sdk 25.3.0; not a direct dependency, upgrade tracked with the next SDK bump" },
15+
]
16+
17+
[licenses]
18+
allow = [
19+
"MIT",
20+
"Apache-2.0",
21+
"Apache-2.0 WITH LLVM-exception",
22+
"BSD-1-Clause",
23+
"BSD-2-Clause",
24+
"BSD-3-Clause",
25+
"Unicode-3.0",
26+
"Unlicense",
27+
"Zlib",
28+
]
29+
confidence-threshold = 0.8
30+
31+
[licenses.private]
32+
ignore = true
33+
34+
[bans]
35+
multiple-versions = "warn"
36+
wildcards = "allow"
37+
highlight = "all"
38+
39+
[sources]
40+
unknown-registry = "deny"
41+
unknown-git = "deny"
42+
allow-registry = ["https://github.com/rust-lang/crates.io-index"]

0 commit comments

Comments
 (0)