Skip to content

Commit b7e141c

Browse files
committed
fix(elixir): include actual NIF checksums in Hex package
- Replace checksum generator script with placeholder map - CI now generates checksums before Hex publish - Fixes "precompiled NIF file does not exist in checksum file" error
1 parent f3557e8 commit b7e141c

File tree

4 files changed

+18
-105
lines changed

4 files changed

+18
-105
lines changed

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ repos:
3636

3737
# Python: ruff (linting + formatting) + mypy (type checking)
3838
- repo: https://github.com/astral-sh/ruff-pre-commit
39-
rev: v0.14.10
39+
rev: v0.14.11
4040
hooks:
4141
- id: ruff
4242
args: [--fix]
@@ -60,15 +60,15 @@ repos:
6060
args: ["--workspace", "--all-features", "--all-targets", "--", "-D", "warnings", "-A", "clippy::collapsible_if"]
6161

6262
- repo: https://github.com/EmbarkStudios/cargo-deny
63-
rev: 0.18.9
63+
rev: 0.19.0
6464
hooks:
6565
- id: cargo-deny
6666
args: ["check"]
6767
files: ^(Cargo\.toml|Cargo\.lock|crates/.*/Cargo\.toml|tools/.*/Cargo\.toml|e2e/rust/Cargo\.toml|packages/ruby/ext/kreuzberg_rb/native/Cargo\.toml|deny\.toml)$
6868

6969
# Node.js/TypeScript: biome (formatting + linting)
7070
- repo: https://github.com/biomejs/pre-commit
71-
rev: v2.3.10
71+
rev: v2.3.11
7272
hooks:
7373
- id: biome-check
7474
files: ^(crates/kreuzberg-node|crates/kreuzberg-wasm|tools/benchmark-visualizer)/

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
- Eliminates manual download and configuration steps
2020
- Security hardened: semver validation, path traversal protection, decompression bomb prevention, HTTP timeout
2121

22+
### Fixed
23+
24+
#### Elixir
25+
- **Precompiled NIF checksums**: Fixed Hex package publishing to include actual SHA256 checksums instead of generator script
26+
- Added `mix rustler_precompiled.download` step to CI before Hex publish
27+
- Users can now install kreuzberg from Hex without compilation errors
28+
- Fixes "precompiled NIF file does not exist in the checksum file" error
29+
2230
---
2331

2432
## [4.0.4] - 2026-01-13

Taskfile.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ includes:
5656
vars:
5757
RUST_LOG: info
5858

59-
6059
tasks:
6160
setup:
6261
desc: "Install all dependencies and initialize project. Idempotent - safe to re-run anytime."
@@ -114,7 +113,6 @@ tasks:
114113
- task: php:test
115114
- task: elixir:test
116115

117-
118116
check:
119117
desc: Run all linting and formatting checks via prek
120118
cmds:
@@ -143,6 +141,8 @@ tasks:
143141
- task: php:update
144142
- echo "Updating Elixir dependencies..."
145143
- task: elixir:update
144+
- echo "Updating prek dependencies..."
145+
- prek autoupdate
146146
- echo "All dependencies updated"
147147

148148
clean:
Lines changed: 5 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,5 @@
1-
defmodule RustlerPrecompiled.ChecksumGenerator do
2-
@moduledoc """
3-
Generates checksums for precompiled NIFs downloaded from GitHub releases.
4-
5-
This script is used during the release process to generate SHA256 checksums
6-
for all platform-specific binaries. The checksums are used by rustler_precompiled
7-
to verify the integrity of downloaded binaries.
8-
9-
Usage:
10-
mix run checksum-Elixir.exs
11-
"""
12-
13-
def generate do
14-
version = Mix.Project.config()[:version]
15-
base_url = "https://github.com/kreuzberg-dev/kreuzberg/releases/download/v#{version}"
16-
17-
targets = [
18-
"aarch64-apple-darwin",
19-
"x86_64-apple-darwin",
20-
"x86_64-unknown-linux-gnu",
21-
"x86_64-unknown-linux-musl",
22-
"aarch64-unknown-linux-gnu",
23-
"aarch64-unknown-linux-musl",
24-
"x86_64-pc-windows-msvc",
25-
"x86_64-pc-windows-gnu"
26-
]
27-
28-
nif_versions = ["2.16", "2.17"]
29-
30-
IO.puts("Generating checksums for Kreuzberg v#{version}\n")
31-
IO.puts("Base URL: #{base_url}\n")
32-
33-
checksums =
34-
for target <- targets,
35-
nif_version <- nif_versions do
36-
ext = if String.contains?(target, "windows"), do: "dll", else: "so"
37-
filename = "libkreuzberg_rustler-v#{version}-nif-#{nif_version}-#{target}.#{ext}.tar.gz"
38-
url = "#{base_url}/#{filename}"
39-
40-
case download_and_checksum(url, filename) do
41-
{:ok, checksum} ->
42-
IO.puts("✓ #{filename}: #{checksum}")
43-
{filename, checksum}
44-
45-
{:error, reason} ->
46-
IO.puts("✗ #{filename}: #{reason}")
47-
nil
48-
end
49-
end
50-
|> Enum.reject(&is_nil/1)
51-
|> Map.new()
52-
53-
if Enum.empty?(checksums) do
54-
IO.puts("\n⚠ Warning: No checksums generated!")
55-
IO.puts("Make sure binaries are published to GitHub releases first.")
56-
else
57-
write_checksum_file(checksums)
58-
IO.puts("\n✓ Checksums written to checksum-Elixir.exs")
59-
IO.puts("Total files: #{map_size(checksums)}")
60-
end
61-
end
62-
63-
defp download_and_checksum(url, filename) do
64-
cache_dir = Path.join([System.tmp_dir!(), "kreuzberg-checksums"])
65-
File.mkdir_p!(cache_dir)
66-
local_path = Path.join(cache_dir, filename)
67-
68-
# Try to download the file
69-
case System.cmd("curl", ["-fsSL", "-o", local_path, url], stderr_to_stdout: true) do
70-
{_, 0} ->
71-
# Calculate SHA256
72-
case System.cmd("shasum", ["-a", "256", local_path]) do
73-
{output, 0} ->
74-
[checksum | _] = String.split(output)
75-
{:ok, String.trim(checksum)}
76-
77-
{error, _} ->
78-
{:error, "Failed to calculate checksum: #{error}"}
79-
end
80-
81-
{error, _} ->
82-
{:error, "Download failed: #{String.slice(error, 0..100)}"}
83-
end
84-
end
85-
86-
defp write_checksum_file(checksums) do
87-
content = """
88-
%{
89-
#{Enum.map_join(checksums, ",\n", fn {filename, hash} ->
90-
" \"#{filename}\" => \"sha256:#{hash}\""
91-
end)}
92-
}
93-
"""
94-
95-
File.write!("checksum-Elixir.exs", content)
96-
end
97-
end
98-
99-
# Run the generator
100-
RustlerPrecompiled.ChecksumGenerator.generate()
1+
%{
2+
# This file is populated by CI during the release process.
3+
# It contains SHA256 checksums for precompiled NIF binaries.
4+
# Run `mix rustler_precompiled.download Kreuzberg.Native --all --print` to regenerate.
5+
}

0 commit comments

Comments
 (0)