feat(cargo-wdk): add --signtool-args passthrough to customize driver signing#699
feat(cargo-wdk): add --signtool-args passthrough to customize driver signing#699svasista-ms wants to merge 14 commits into
--signtool-args passthrough to customize driver signing#699Conversation
There was a problem hiding this comment.
Pull request overview
Adds a cargo wdk build --signtool-args passthrough so driver signing can be customized (certificate selection, digest, timestamping, extra operands), and adjusts packaging to stage artifacts in a fresh directory and assemble the final package folder last—preventing stale signing artifacts from persisting across rebuilds.
Changes:
- Add
--signtool-argsto the CLI and plumb it through tosigntool signinvocation. - Rework packaging to build in a clean per-build staging directory and rename into the final package folder at the end (fixes stale cert artifact scenarios).
- Expand integration/unit tests and documentation to cover the new signing behavior and staging semantics.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/cargo-wdk/tests/build_command_test.rs | Adds regression + functional integration tests for staging behavior and --signtool-args. |
| crates/cargo-wdk/src/providers/mod.rs | Extends filesystem error enum to cover directory removal failures. |
| crates/cargo-wdk/src/providers/fs.rs | Adds remove_dir_all wrapper to the FS provider for testable directory cleanup. |
| crates/cargo-wdk/src/cli.rs | Introduces --signtool-args and validates signing flag combinations via TryFrom<&BuildArgs> for SignMode. |
| crates/cargo-wdk/src/actions/build/tests.rs | Updates build action unit test expectations for staging-dir + final assembly flow and new SignMode shape. |
| crates/cargo-wdk/src/actions/build/package_task.rs | Implements staging directory flow, package folder assembly, signtool argument tokenization + passthrough, and updates signing behavior. |
| crates/cargo-wdk/src/actions/build/mod.rs | Adjusts BuildAction to clone SignMode (now contains owned data). |
| crates/cargo-wdk/README.md | Documents --signtool-args, quoting/tokenization rules, and updated signing/staging semantics. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #699 +/- ##
==========================================
+ Coverage 79.93% 80.87% +0.93%
==========================================
Files 26 26
Lines 5633 5923 +290
Branches 5633 5923 +290
==========================================
+ Hits 4503 4790 +287
Misses 1002 1002
- Partials 128 131 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
|
||
| /// Builds a `clap::Error` with the given message, rendered with the standard | ||
| /// `cargo wdk build` usage for a consistent CLI experience. | ||
| fn build_error(message: impl std::fmt::Display) -> clap::Error { |
There was a problem hiding this comment.
nit: we could inline this at call site, no need of a separate function
There was a problem hiding this comment.
Yes, it was inline initially. But I added the function because ArgumentConflict error can be constructed from multiple places (2 in try_from for SignMode). Once args for all tools are added we could use anyhow to construct CLI errors.
|
|
||
| /// Arguments to `signtool sign` for signing the driver binary and catalog file. | ||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub struct SigntoolArgs(pub Vec<String>); |
There was a problem hiding this comment.
Move this declaration to the top to keep all arg type declarations at one place.
| .expect("args parse"); | ||
| let err = SignMode::try_from(&args).expect_err("should be rejected"); | ||
| assert!( | ||
| err.to_string().contains("`--sign-mode=off`"), |
There was a problem hiding this comment.
- use the exact message for assertion
`--signtool-args` cannot be used with `--sign-mode=off`.
- Can we not match exactly and avoid using contains?
There was a problem hiding this comment.
Fixed ✅, using the full message for assertion 👍
| } | ||
|
|
||
| #[test] | ||
| fn build_off_mode_maps_to_off() { |
There was a problem hiding this comment.
| fn build_off_mode_maps_to_off() { | |
| fn build_sign_mode_off_maps_correctly() { |
| let err = parse_build_args(&["--signtool-args", "/n \"CN=Contoso"]) | ||
| .expect_err("unterminated quote should be rejected"); | ||
| assert!( | ||
| err.to_string().contains("unterminated"), |
There was a problem hiding this comment.
Try and use exact message assertion
Similar suggestion as this: https://github.com/microsoft/windows-drivers-rs/pull/699/changes#r3579259207
| } | ||
|
|
||
| #[test] | ||
| fn build_signtool_args_with_verify_signature_maps_both() { |
There was a problem hiding this comment.
| fn build_signtool_args_with_verify_signature_maps_both() { | |
| fn build_verify_signature_works_with_signtool_args() { |
| @@ -304,25 +402,119 @@ mod tests { | |||
|
|
|||
| #[test] | |||
| fn build_rejects_verify_signature_when_sign_mode_is_off() { | |||
There was a problem hiding this comment.
As we have multiple tests for build sub command, We should move all the build tests to a submodule here and avoid using build as prefix for each test.
There was a problem hiding this comment.
Done ✅ , moved to a separate mod
| Driver Signing: | ||
| --signtool-args <ARGS> Additional arguments forwarded verbatim to | ||
| `signtool sign`, as a single quoted string | ||
| (e.g. `--signtool-args "/fd SHA256 /f cert.pfx"`) | ||
|
|
Adds
--signtool-argspassthrough so driver signing can be customized (certificate selection, digest algorithm, timestamping, extra file operands).When
--signtool-argsis omitted,cargo-wdksigns with the auto-generated WDR test certificate and default switches.When
--signtool-argsis provided, the caller owns the fullsigntool signoption set except thesignverb and the trailing file operand (spplied bycargo-wdk). Supplying it with--sign-mode=offis rejected.Packaging removes any existing
<target>/<profile>/<name>_packagefolder at the start of each build and recreates it, so stale signing artifacts (e.g. aWDRLocalTestCert.cerfrom a previous--sign-mode=testbuild) don't persist across rebuilds.Screenshots
Resolves #605