diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-11 20:24:55 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-11 20:28:08 +0000 |
| commit | 8acee2bfcba948f4b5a88709a047e6468394ca88 (patch) | |
| tree | bb453bc3ac970f343e02c3bcea8c4092191f350b /docs/how-to | |
| parent | af12eb7baa949bc40155c837741bfd597fd0764e (diff) | |
docs: add guide for updating git dependencies in Cargo
- Add new how-to guide covering hash updates for git dependencies
- Applies to any git dependency (e.g., nostr-sdk fork)
- Add critical note in AGENTS.md linking to this guide
- Emphasize that hash updates in both flake.nix and nix/module.nix are MANDATORY
Diffstat (limited to 'docs/how-to')
| -rw-r--r-- | docs/how-to/update-git-dependencies.md | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/docs/how-to/update-git-dependencies.md b/docs/how-to/update-git-dependencies.md new file mode 100644 index 0000000..ef21eac --- /dev/null +++ b/docs/how-to/update-git-dependencies.md | |||
| @@ -0,0 +1,192 @@ | |||
| 1 | # How to Update Git Dependencies in Cargo | ||
| 2 | |||
| 3 | ngit-grasp uses git dependencies (such as our fork of nostr-sdk) instead of crates.io releases. When updating any git dependency, you need to update the hash in both the Nix build files. | ||
| 4 | |||
| 5 | ## Prerequisites | ||
| 6 | |||
| 7 | - Access to update `Cargo.toml` and `Cargo.lock` | ||
| 8 | - Nix installed locally | ||
| 9 | |||
| 10 | ## Steps | ||
| 11 | |||
| 12 | ### 1. Update Cargo.toml and Cargo.lock | ||
| 13 | |||
| 14 | Update the git dependency in `Cargo.toml` (change the git URL, branch, rev, or tag): | ||
| 15 | |||
| 16 | ```toml | ||
| 17 | [dependencies] | ||
| 18 | some-crate = { git = "https://github.com/user/repo", branch = "main" } | ||
| 19 | ``` | ||
| 20 | |||
| 21 | Then update `Cargo.lock`: | ||
| 22 | |||
| 23 | ```bash | ||
| 24 | cargo update -p some-crate | ||
| 25 | ``` | ||
| 26 | |||
| 27 | ### 2. Try Building with Nix | ||
| 28 | |||
| 29 | ```bash | ||
| 30 | nix build .#default | ||
| 31 | ``` | ||
| 32 | |||
| 33 | This will **fail** with an error like: | ||
| 34 | |||
| 35 | ``` | ||
| 36 | error: hash mismatch in fixed-output derivation '/nix/store/...-some-crate-0.1.0': | ||
| 37 | specified: sha256-DwcWmwxNUQRR32E3hqbm7PNkGdK8LB3sGtH1Zfrkigk= | ||
| 38 | got: sha256-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX= | ||
| 39 | ``` | ||
| 40 | |||
| 41 | ### 3. Copy the Correct Hash | ||
| 42 | |||
| 43 | The hash in the "got:" line is the **correct** hash you need. It's already in SRI format (base64 with `sha256-` prefix). | ||
| 44 | |||
| 45 | ### 4. Update Both Nix Files | ||
| 46 | |||
| 47 | You must update the hash in **BOTH** files: | ||
| 48 | |||
| 49 | #### `flake.nix`: | ||
| 50 | ```nix | ||
| 51 | cargoLock = { | ||
| 52 | lockFile = ./Cargo.lock; | ||
| 53 | outputHashes = { | ||
| 54 | "some-crate-0.1.0" = "sha256-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX="; # ← Update this | ||
| 55 | }; | ||
| 56 | }; | ||
| 57 | ``` | ||
| 58 | |||
| 59 | #### `nix/module.nix`: | ||
| 60 | ```nix | ||
| 61 | cargoLock = { | ||
| 62 | lockFile = ../Cargo.lock; | ||
| 63 | outputHashes = { | ||
| 64 | "some-crate-0.1.0" = "sha256-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX="; # ← Update this | ||
| 65 | }; | ||
| 66 | }; | ||
| 67 | ``` | ||
| 68 | |||
| 69 | **⚠️ CRITICAL:** Both hashes must match exactly! | ||
| 70 | |||
| 71 | **Note:** The key format is `"crate-name-version"` as it appears in `Cargo.lock`. Check your `Cargo.lock` to find the exact string: | ||
| 72 | |||
| 73 | ```toml | ||
| 74 | [[package]] | ||
| 75 | name = "some-crate" | ||
| 76 | version = "0.1.0" | ||
| 77 | source = "git+https://github.com/user/repo?branch=main#abc123" | ||
| 78 | ``` | ||
| 79 | |||
| 80 | Use `"some-crate-0.1.0"` as the key. | ||
| 81 | |||
| 82 | ### 5. Verify the Build | ||
| 83 | |||
| 84 | ```bash | ||
| 85 | nix build .#default | ||
| 86 | ``` | ||
| 87 | |||
| 88 | Should complete successfully without hash errors. | ||
| 89 | |||
| 90 | ### 6. Test Locally | ||
| 91 | |||
| 92 | ```bash | ||
| 93 | nix develop | ||
| 94 | cargo test | ||
| 95 | ``` | ||
| 96 | |||
| 97 | Verify all tests still pass with the updated dependency. | ||
| 98 | |||
| 99 | ## Common Mistakes | ||
| 100 | |||
| 101 | ### ❌ Using base32 Format | ||
| 102 | |||
| 103 | ```nix | ||
| 104 | # WRONG - this is base32 Nix hash format: | ||
| 105 | "sha256-02cawkx6bxfi3bn1sb5ws8cn9wzcwsk8cdv1vx8h8lad1jdic1qg" | ||
| 106 | ``` | ||
| 107 | |||
| 108 | Modern Nix requires SRI format (base64): | ||
| 109 | |||
| 110 | ```nix | ||
| 111 | # CORRECT - SRI format with base64 and = padding: | ||
| 112 | "sha256-DwcWmwxNUQRR32E3hqbm7PNkGdK8LB3sGtH1Zfrkigk=" | ||
| 113 | ``` | ||
| 114 | |||
| 115 | ### ❌ Forgetting to Update Both Files | ||
| 116 | |||
| 117 | If you only update `flake.nix` OR `nix/module.nix`, the NixOS module deployment will fail because they both build the package independently. | ||
| 118 | |||
| 119 | ### ❌ Converting Hashes Manually | ||
| 120 | |||
| 121 | Don't try to convert hashes yourself. Always use the hash Nix provides in the error message - it's already in the correct format. | ||
| 122 | |||
| 123 | ### ❌ Wrong Key Format in outputHashes | ||
| 124 | |||
| 125 | The key must match exactly what appears in `Cargo.lock`: | ||
| 126 | |||
| 127 | ```toml | ||
| 128 | # From Cargo.lock: | ||
| 129 | [[package]] | ||
| 130 | name = "nostr" | ||
| 131 | version = "0.44.1" | ||
| 132 | |||
| 133 | # Use in flake.nix/module.nix: | ||
| 134 | "nostr-0.44.1" = "sha256-..." # ✅ Correct | ||
| 135 | "nostr" = "sha256-..." # ❌ Wrong | ||
| 136 | ``` | ||
| 137 | |||
| 138 | ## Background | ||
| 139 | |||
| 140 | The `outputHashes` field is needed because we use git dependencies instead of crates.io releases. Nix requires fixed-output derivations to have known hashes for reproducibility. | ||
| 141 | |||
| 142 | When the git repository changes (new commits, different branch/tag, etc.), the hash changes. Nix compares the expected hash (in our files) with the actual hash (computed from the source) and fails if they don't match. | ||
| 143 | |||
| 144 | This is a **security feature** - it prevents supply chain attacks by ensuring you get exactly the code you expect. | ||
| 145 | |||
| 146 | ## Examples | ||
| 147 | |||
| 148 | ### Example 1: Updating nostr-sdk fork | ||
| 149 | |||
| 150 | ```bash | ||
| 151 | # 1. Update to newer commit | ||
| 152 | cd /path/to/ngit-grasp | ||
| 153 | cargo update -p nostr | ||
| 154 | |||
| 155 | # 2. Try to build with Nix (will fail with hash) | ||
| 156 | nix build .#default | ||
| 157 | |||
| 158 | # 3. Copy the hash from error message | ||
| 159 | # got: sha256-ABC123...= | ||
| 160 | |||
| 161 | # 4. Update both files: | ||
| 162 | # flake.nix and nix/module.nix | ||
| 163 | "nostr-0.44.1" = "sha256-ABC123...="; | ||
| 164 | |||
| 165 | # 5. Build again | ||
| 166 | nix build .#default | ||
| 167 | ``` | ||
| 168 | |||
| 169 | ### Example 2: Adding new git dependency | ||
| 170 | |||
| 171 | ```bash | ||
| 172 | # 1. Add to Cargo.toml | ||
| 173 | [dependencies] | ||
| 174 | new-crate = { git = "https://github.com/user/repo", tag = "v1.0" } | ||
| 175 | |||
| 176 | # 2. Update Cargo.lock | ||
| 177 | cargo update -p new-crate | ||
| 178 | |||
| 179 | # 3. Try to build (will fail) | ||
| 180 | nix build .#default | ||
| 181 | |||
| 182 | # 4. Add to both flake.nix and nix/module.nix: | ||
| 183 | outputHashes = { | ||
| 184 | "nostr-0.44.1" = "sha256-..."; | ||
| 185 | "new-crate-1.0.0" = "sha256-..."; # ← Add from error message | ||
| 186 | }; | ||
| 187 | ``` | ||
| 188 | |||
| 189 | ## See Also | ||
| 190 | |||
| 191 | - [Nix Manual: Cargo.lock Hash](https://nixos.org/manual/nixpkgs/stable/#rust-cargo-lock-hash) | ||
| 192 | - [SRI Hash Format](https://www.w3.org/TR/SRI/) | ||