Internal precompile binaries hook#22
Internal precompile binaries hook#22BitcoinZavior wants to merge 42 commits intobitcoindevkit:mainfrom
Conversation
|
This is looking nice, added a bunch of comments/questions, and if you can run I’ll set up the signing secret later, let me know if any other maintainer setup is needed. |
README.md
Outdated
| ``` | ||
|
|
||
| `mode` controls when the precompiled path is used: | ||
| - `auto` prefers precompiled binaries when available, otherwise builds locally |
There was a problem hiding this comment.
auto is described as preferring precompiled, but the hook currently disables precompiled when rustup is present (UserOptions.defaultUsePrecompiledBinaries). Should we update this wording to reflect the rustup heuristic, or change the behavior to match the doc
There was a problem hiding this comment.
I suggest updating the wording in README.md. It now explicitly states that auto prefers local builds when the Rust toolchain (rustup) is detected; otherwise, it uses precompiled binaries.
docs/precompiled_binaries.md
Outdated
| - CI builds and uploads precompiled binaries via `.github/workflows/precompile_binaries.yml`. | ||
| - Artifacts are tagged by the crate hash and uploaded to a GitHub release. | ||
| - Each binary is signed with an Ed25519 key; the public key is embedded in `pubspec.yaml`. | ||
| - The build hook tries to download a verified binary first and falls back to a local build if needed. |
There was a problem hiding this comment.
The doc says ‘download verified binary first and fall back’; should we note that mode: always is intended to disable fallback (once that behavior is enforced), or explicitly call out the rustup heuristic for auto?
There was a problem hiding this comment.
Added a “Mode behavior” section. It clarifies that always currently falls back but is intended to fail if a verified binary isn’t present, and reiterates how never operates.
There was a problem hiding this comment.
Thanks for adding the Mode behavior section + rustup heuristic callout. One mismatch remains: docs say always falls back, but implementation now throws in always on any download/verify failure (no fallback). Can we update precompiled_binaries.md (always bullet + ‘If any step fails’ line) to reflect that always fails the build and only auto falls back?
| exitCode = 2; | ||
| return; | ||
| } | ||
| if (repository == null || repository.trim().isEmpty) { |
There was a problem hiding this comment.
--repository is required but never used in any gh release calls; should we pass --repo $repository to view/create/upload (or drop the flag if it’s not needed)?
There was a problem hiding this comment.
Forgot to call it out earlier: --repository was left unused in the release commands by mistake, but we’ve since wired it back in. This lets us rerun the tool against another repo (e.g., for testing or experimentation) without editing the workflow. In production it still defaults to the current repo, so the rest of the release flow behaves as before.
There was a problem hiding this comment.
--repository is wired for upload + asset check, but _ensureReleaseExists still calls gh release view without --repo, and gh release create arg order is wrong (--title consumes --repo, so $repository is treated as a positional asset/pattern and the command fails). (lib/src/precompiled/cli/commands/precompile_binaries.dart:394-406)
Can we:
- add
--repo repositoryto therelease viewin_ensureReleaseExists - reorder create args to
--repo repository --title "Precompiled binaries $crateHash" …?
| '--package', | ||
| cratePackage, | ||
| '--release', | ||
| '--locked', |
There was a problem hiding this comment.
We pass --locked to cargo, but there’s no committed native/Cargo.lock in this repo; cargo build --locked will fail without it. Should we add native/Cargo.lock or remove --locked?
There was a problem hiding this comment.
Lock file added and .gitignore updated to allow lock file changes.
There was a problem hiding this comment.
I still don’t see a Cargo.lock committed in native/ (maybe I’m missing it), but precompile-binaries always runs cargo with --locked (both the cargo ndk … build and cargo build paths). On a clean runner, --locked will fail if there’s no lockfile to lock against.
Should we either:
- commit
native/Cargo.lock(preferred for reproducible precompiled artifacts + stable crate hash), --or-- - drop
--locked?
| final output = AccumulatorSink<Digest>(); | ||
| final input = sha256.startChunkedConversion(output); | ||
|
|
||
| void addTextFile(File file) { |
There was a problem hiding this comment.
We concatenate lines from multiple files without a delimiter or filename marker which could (rarely) lead to hash collisions if file boundaries change. Should we consider prefixing each file with its path (or a separator) before hashing to make the hash more robust?
There was a problem hiding this comment.
That scenario is extremely rare isn't it? we would have to arrange contents to collide via a prefix/suffix shift. I believe a lightweight fix ( a separator before its contents) should be sufficient.
There was a problem hiding this comment.
Agree it’s rare, but right now we hash line contents with no delimiter / file boundary marker (and no newline between lines), so there are theoretical collisions if boundaries shift. Could we add a lightweight separator (e.g. prefix each file with its relative path + \n, and add \n between lines) before hashing?
Not blocking, but would make the crate hash strictly more robust.
I can also make a patch for this so you dont have to
|
Thanks for the review 🧡 PR updated to address review comments and to provide more info. |
| '--title', | ||
| '--repo', | ||
| repository, | ||
| 'Precompiled binaries $crateHash', |
There was a problem hiding this comment.
The args for the github release crate are misordered: --title is followed by --repo, so the title becomes --repo. The command will fail (or produce a release with the wrong metadata), aborting the whole precompile step. Title value should come immediately after --title, and --repo should be its own flag.
| '--title', | |
| '--repo', | |
| repository, | |
| 'Precompiled binaries $crateHash', | |
| '--title', 'Precompiled binaries $crateHash', | |
| '--repo', repository, |
There was a problem hiding this comment.
+1
this is the same underlying issue as the earlier --repository thread
|
|
||
| DownloadedArtifact? handleFailure(String message) { | ||
| if (requirePrecompiled) { | ||
| throw PrecompiledBinaryRequiredException(message); |
There was a problem hiding this comment.
The documentation wordings in precompiled_binaries.md says:
"always: Attempts to use precompiled binaries and falls back to local builds if download/verification fails. Future versions may disable fallback entirely for this mode."
This can be a bit misleading, because the code throws an exception when precompiled is required. Maybe we reword as:
"Throws an exception if download/verification fails: does not fall back"
great update! I resolved the threads that were addressed, and left a few open with follow-up questions. also if there's any of the things I mentioned that you just want me to patch myself on this pr im happy to do that. and then also CI is currently failing on the |
|
Thanks @reez @Johnosezele |
thanks to you for the PR! will review again when you give me the go ahead that its ready for final review |
Precompiled Binaries Feature
Resolves #20
This PR introduces a comprehensive precompiled binaries system that significantly improves the developer experience by reducing build times and providing secure, signed artifacts.
Key Features
Secure Distribution
Performance Improvements
auto,always, orneverDeveloper Experience
Configuration
Users can configure precompiled binaries in their
pubspec.yaml:Defaulting to auto which most users would want.