Skip to content

Commit b20b135

Browse files
committed
chore(lint): add a lint to generate a json file with all enum, struct and upgrade information hashed
1 parent db18fca commit b20b135

33 files changed

+7390
-103
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# On PR: when snapshot files are modified, generates a diff report between
2+
# the base branch and the PR snapshots, then posts it as a PR comment.
3+
# Helps reviewers understand what versioned types changed.
4+
name: backward_compat_pr_change_report
5+
6+
on:
7+
pull_request:
8+
paths:
9+
- 'utils/tfhe-lints/snapshots/lint_enum_snapshots_*.json'
10+
11+
permissions:
12+
contents: read
13+
14+
concurrency:
15+
group: ${{ github.workflow }}-${{ github.head_ref }}
16+
cancel-in-progress: true
17+
18+
jobs:
19+
change-report:
20+
name: backward_compat_pr_change_report/change-report
21+
runs-on: ubuntu-latest
22+
permissions:
23+
pull-requests: write # To send and modify message in the PR
24+
steps:
25+
- name: Checkout PR head
26+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
27+
with:
28+
persist-credentials: 'false'
29+
path: head
30+
31+
- name: Checkout base branch
32+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
33+
with:
34+
persist-credentials: 'false'
35+
ref: ${{ github.event.pull_request.base.sha }}
36+
path: base
37+
38+
- name: Generate diff report
39+
id: report
40+
run: |
41+
cd head && make backward_snapshot_report \
42+
BASE_SNAPSHOT_DIR=../base/utils/tfhe-lints/snapshots \
43+
HEAD_SNAPSHOT_DIR=utils/tfhe-lints/snapshots \
44+
OUTPUT_FILE=../report.md
45+
46+
if [ -s report.md ]; then
47+
echo "has_report=true" >> "$GITHUB_OUTPUT"
48+
else
49+
echo "has_report=false" >> "$GITHUB_OUTPUT"
50+
fi
51+
52+
- name: Find existing comment
53+
id: find-comment
54+
uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.1.0
55+
with:
56+
issue-number: ${{ github.event.pull_request.number }}
57+
body-includes: '**Backward-compat snapshot:'
58+
59+
- name: Comment on PR
60+
if: steps.report.outputs.has_report == 'true'
61+
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
62+
with:
63+
comment-id: ${{ steps.find-comment.outputs.comment-id }}
64+
issue-number: ${{ github.event.pull_request.number }}
65+
body-path: report.md
66+
edit-mode: replace
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Generates snapshots from code and diffs against committed base files.
2+
# Ensures snapshots are up to date on PRs and catches stale ones on main.
3+
name: backward_compat_snapshot_consistency
4+
5+
env:
6+
CARGO_TERM_COLOR: always
7+
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
8+
RUST_BACKTRACE: "full"
9+
RUST_MIN_STACK: "8388608"
10+
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
11+
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
12+
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
13+
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
14+
SLACKIFY_MARKDOWN: true
15+
16+
on:
17+
workflow_dispatch:
18+
pull_request:
19+
push:
20+
branches:
21+
- main
22+
23+
permissions:
24+
contents: read
25+
26+
jobs:
27+
snapshot-consistency:
28+
name: backward_compat_snapshot_consistency/snapshot-consistency
29+
runs-on: ubuntu-latest
30+
concurrency:
31+
group: ${{ github.workflow }}-${{ github.head_ref || github.sha }}
32+
cancel-in-progress: ${{ github.event_name != 'push' }}
33+
steps:
34+
- name: Checkout tfhe-rs
35+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
36+
with:
37+
persist-credentials: 'false'
38+
39+
- name: Generate snapshots from current code
40+
run: make backward_snapshot_head
41+
42+
- name: Check snapshot consistency
43+
run: ./scripts/check_snapshot_consistency.sh
44+
45+
- name: Slack Notification
46+
if: ${{ failure() || (cancelled() && github.event_name == 'push') }}
47+
continue-on-error: true
48+
uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661
49+
env:
50+
SLACK_COLOR: ${{ job.status }}
51+
SLACK_MESSAGE: >-
52+
Backward compatibility snapshot consistency check: ${{ job.status }}.
53+
Snapshots may be outdated — run `make backward_snapshot_base` and commit.
54+
[See details](${{ env.ACTION_RUN_URL }})

.linelint.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ ignore:
99
- tfhe/web_wasm_parallel_tests/dist
1010
- keys
1111
- coverage
12-
- utils/tfhe-lints/tests/*/main.stderr
12+
- utils/tfhe-lints/**/main.stderr
13+
- utils/tfhe-lints/**/*.json
1314
- utils/tfhe-backward-compat-data/**/*.ron # ron files are autogenerated
1415

1516
rules:

Cargo.toml

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
[workspace]
22
resolver = "3"
33
members = [
4+
"apps/test-vectors",
5+
"backends/tfhe-cuda-backend",
6+
"backends/tfhe-hpu-backend",
7+
"backends/zk-cuda-backend",
8+
"mockups/tfhe-hpu-mockup",
9+
"tasks",
10+
"tests",
411
"tfhe",
512
"tfhe-benchmark",
13+
"tfhe-csprng",
614
"tfhe-fft",
715
"tfhe-ntt",
816
"tfhe-zk-pok",
9-
"tasks",
10-
"tfhe-csprng",
11-
"backends/tfhe-cuda-backend",
12-
"backends/zk-cuda-backend",
13-
"backends/tfhe-hpu-backend",
14-
"utils/tfhe-versionable",
15-
"utils/tfhe-versionable-derive",
17+
"utils/param_dedup",
18+
"utils/tfhe-backward-compat-checker",
1619
"utils/tfhe-backward-compat-data",
1720
"utils/tfhe-backward-compat-data/crates/add_new_version",
18-
"utils/param_dedup",
21+
"utils/tfhe-versionable",
22+
"utils/tfhe-versionable-derive",
1923
"utils/wasm-par-mq",
20-
"utils/wasm-par-mq/web_tests",
2124
"utils/wasm-par-mq/examples/msm",
22-
"tests",
23-
"mockups/tfhe-hpu-mockup",
24-
"apps/test-vectors",
25+
"utils/wasm-par-mq/web_tests",
2526
]
2627

2728
exclude = ["utils/tfhe-lints", "apps/trivium"]
@@ -74,7 +75,10 @@ lto = "off"
7475
debug-assertions = false
7576

7677
[workspace.metadata.dylint]
77-
libraries = [{ path = "utils/tfhe-lints" }]
78+
libraries = [
79+
{ path = "utils/tfhe-lints/lints" },
80+
{ path = "utils/tfhe-lints/snapshot" },
81+
]
7882

7983
[profile.debug_lto_off]
8084
inherits = "dev"

Makefile

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ ZIZMOR_VERSION=1.22.0
3939
# copy paste the command in the terminal and change them if required without forgetting the flags
4040
export RUSTFLAGS?=-C target-cpu=native
4141

42+
include utils/tfhe-lints/Makefile
43+
4244
ifeq ($(GEN_KEY_CACHE_MULTI_BIT_ONLY),TRUE)
4345
MULTI_BIT_ONLY=--multi-bit-only
4446
else
@@ -170,10 +172,6 @@ install_tarpaulin:
170172
cargo install cargo-tarpaulin --locked || \
171173
( echo "Unable to install cargo tarpaulin, unknown error." && exit 1 )
172174

173-
.PHONY: install_cargo_dylint # Install custom tfhe-rs lints
174-
install_cargo_dylint:
175-
cargo install --locked cargo-dylint dylint-link
176-
177175
.PHONY: install_cargo_audit # Check dependencies
178176
install_cargo_audit:
179177
cargo install --locked cargo-audit
@@ -537,12 +535,6 @@ clippy_versionable: install_rs_check_toolchain
537535
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy --all-targets \
538536
-p tfhe-versionable -- --no-deps -D warnings
539537

540-
.PHONY: clippy_tfhe_lints # Run clippy lints on tfhe-lints
541-
clippy_tfhe_lints: install_cargo_dylint # the toolchain is selected with toolchain.toml
542-
cd utils/tfhe-lints && \
543-
rustup toolchain install && \
544-
cargo clippy --all-targets -- --no-deps -D warnings
545-
546538
.PHONY: clippy_param_dedup # Run clippy lints on param_dedup tool
547539
clippy_param_dedup: install_rs_check_toolchain
548540
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy --all-targets \
@@ -608,19 +600,10 @@ check_rust_bindings_did_not_change:
608600
( echo "Generated bindings have changed! Please run 'git add backends/tfhe-cuda-backend/src/bindings.rs' \
609601
and commit the changes." && exit 1 )
610602

611-
612-
.PHONY: tfhe_lints # Run custom tfhe-rs lints
613-
tfhe_lints: install_cargo_dylint
614-
RUSTFLAGS="$(RUSTFLAGS) -Dwarnings" cargo dylint --all -p tfhe --no-deps -- \
615-
--features=boolean,shortint,integer,strings,zk-pok
616-
RUSTFLAGS="$(RUSTFLAGS) -Dwarnings" cargo dylint --all -p tfhe-zk-pok --no-deps -- \
617-
--features=experimental
618-
619603
.PHONY: audit_dependencies # Run cargo audit to check vulnerable dependencies
620604
audit_dependencies: install_cargo_audit
621605
cargo audit
622606

623-
624607
.PHONY: build_core # Build core_crypto without experimental features
625608
build_core:
626609
RUSTFLAGS="$(RUSTFLAGS)" cargo build --profile $(CARGO_PROFILE) \
@@ -1241,12 +1224,6 @@ test_versionable:
12411224
RUSTFLAGS="$(RUSTFLAGS)" cargo test --profile $(CARGO_PROFILE) \
12421225
--all-targets -p tfhe-versionable
12431226

1244-
.PHONY: test_tfhe_lints # Run test on tfhe-lints
1245-
test_tfhe_lints: install_cargo_dylint
1246-
cd utils/tfhe-lints && \
1247-
rustup toolchain install && \
1248-
cargo test
1249-
12501227
# The backward compat data folder holds historical binary data but also rust code to generate and load them.
12511228
.PHONY: gen_backward_compat_data # Re-generate backward compatibility data
12521229
gen_backward_compat_data:
@@ -2367,4 +2344,11 @@ bench_ntt: install_rs_check_toolchain
23672344

23682345
.PHONY: help # Generate list of targets with descriptions
23692346
help:
2370-
@grep '^\.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1\t\2/' | expand -t30 | sort
2347+
@for f in Makefile $$(grep '^include ' Makefile | awk '{print $$2}'); do \
2348+
matches=$$(grep '^\.PHONY: .* #' "$$f" || true); \
2349+
if [ -n "$$matches" ]; then \
2350+
echo ""; \
2351+
echo "--- $$f ---"; \
2352+
echo "$$matches" | sed 's/\.PHONY: \(.*\) # \(.*\)/\1\t\2/' | expand -t30 | sort; \
2353+
fi \
2354+
done
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env bash
2+
# Check that committed base snapshots match freshly generated head snapshots.
3+
# Expects `make backward_snapshot_head` to have been run beforehand.
4+
# Exits 1 if any mismatch is found.
5+
6+
set -euo pipefail
7+
8+
SNAPSHOT_DIR="utils/tfhe-lints/snapshots"
9+
10+
mismatch=0
11+
12+
head_count=$(find "${SNAPSHOT_DIR}/head" -name 'lint_enum_snapshots_*.json' | wc -l)
13+
base_count=$(find "${SNAPSHOT_DIR}" -maxdepth 1 -name 'lint_enum_snapshots_*.json' | wc -l)
14+
15+
if [ "$head_count" -ne "$base_count" ]; then
16+
echo "::error::File count mismatch: $base_count base file(s) vs $head_count head file(s)"
17+
mismatch=1
18+
fi
19+
20+
# Check each head file has a matching base file with identical content
21+
for head_file in "${SNAPSHOT_DIR}"/head/lint_enum_snapshots_*.json; do
22+
base_name=$(basename "$head_file")
23+
base_file="${SNAPSHOT_DIR}/${base_name}"
24+
if [ ! -f "$base_file" ]; then
25+
echo "::error::Missing base snapshot: $base_file"
26+
mismatch=1
27+
continue
28+
fi
29+
if ! diff -q "$base_file" "$head_file" >/dev/null 2>&1; then
30+
echo "::error::Snapshot mismatch: $base_name"
31+
diff "$base_file" "$head_file" || true
32+
mismatch=1
33+
fi
34+
done
35+
36+
# Check each base file has a matching head file
37+
for base_file in "${SNAPSHOT_DIR}"/lint_enum_snapshots_*.json; do
38+
base_name=$(basename "$base_file")
39+
head_file="${SNAPSHOT_DIR}/head/${base_name}"
40+
if [ ! -f "$head_file" ]; then
41+
echo "::error::Stale base snapshot (no matching head): $base_file"
42+
mismatch=1
43+
fi
44+
done
45+
46+
if [ "$mismatch" -ne 0 ]; then
47+
echo "::error::Snapshots are inconsistent — run 'make backward_snapshot_base' and commit."
48+
exit 1
49+
fi
50+
51+
echo "All snapshots are consistent."
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "tfhe-backward-compat-checker"
3+
version = "0.1.0"
4+
edition = "2024"
5+
rust-version.workspace = true
6+
7+
[dependencies]
8+
clap = { workspace = true }
9+
serde = { workspace = true, features = ["derive"] }
10+
serde_json = "1"

0 commit comments

Comments
 (0)