upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/docs/how-to/update-git-dependencies.md
blob: ef21eac119d6eabfba4696d2f8d9672bfc7447fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# How to Update Git Dependencies in Cargo

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.

## Prerequisites

- Access to update `Cargo.toml` and `Cargo.lock`
- Nix installed locally

## Steps

### 1. Update Cargo.toml and Cargo.lock

Update the git dependency in `Cargo.toml` (change the git URL, branch, rev, or tag):

```toml
[dependencies]
some-crate = { git = "https://github.com/user/repo", branch = "main" }
```

Then update `Cargo.lock`:

```bash
cargo update -p some-crate
```

### 2. Try Building with Nix

```bash
nix build .#default
```

This will **fail** with an error like:

```
error: hash mismatch in fixed-output derivation '/nix/store/...-some-crate-0.1.0':
  specified: sha256-DwcWmwxNUQRR32E3hqbm7PNkGdK8LB3sGtH1Zfrkigk=
  got:      sha256-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
```

### 3. Copy the Correct Hash

The hash in the "got:" line is the **correct** hash you need. It's already in SRI format (base64 with `sha256-` prefix).

### 4. Update Both Nix Files

You must update the hash in **BOTH** files:

#### `flake.nix`:
```nix
cargoLock = {
  lockFile = ./Cargo.lock;
  outputHashes = {
    "some-crate-0.1.0" = "sha256-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=";  # ← Update this
  };
};
```

#### `nix/module.nix`:
```nix
cargoLock = {
  lockFile = ../Cargo.lock;
  outputHashes = {
    "some-crate-0.1.0" = "sha256-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=";  # ← Update this
  };
};
```

**⚠️ CRITICAL:** Both hashes must match exactly!

**Note:** The key format is `"crate-name-version"` as it appears in `Cargo.lock`. Check your `Cargo.lock` to find the exact string:

```toml
[[package]]
name = "some-crate"
version = "0.1.0"
source = "git+https://github.com/user/repo?branch=main#abc123"
```

Use `"some-crate-0.1.0"` as the key.

### 5. Verify the Build

```bash
nix build .#default
```

Should complete successfully without hash errors.

### 6. Test Locally

```bash
nix develop
cargo test
```

Verify all tests still pass with the updated dependency.

## Common Mistakes

### ❌ Using base32 Format

```nix
# WRONG - this is base32 Nix hash format:
"sha256-02cawkx6bxfi3bn1sb5ws8cn9wzcwsk8cdv1vx8h8lad1jdic1qg"
```

Modern Nix requires SRI format (base64):

```nix
# CORRECT - SRI format with base64 and = padding:
"sha256-DwcWmwxNUQRR32E3hqbm7PNkGdK8LB3sGtH1Zfrkigk="
```

### ❌ Forgetting to Update Both Files

If you only update `flake.nix` OR `nix/module.nix`, the NixOS module deployment will fail because they both build the package independently.

### ❌ Converting Hashes Manually

Don't try to convert hashes yourself. Always use the hash Nix provides in the error message - it's already in the correct format.

### ❌ Wrong Key Format in outputHashes

The key must match exactly what appears in `Cargo.lock`:

```toml
# From Cargo.lock:
[[package]]
name = "nostr"
version = "0.44.1"

# Use in flake.nix/module.nix:
"nostr-0.44.1" = "sha256-..."  # ✅ Correct
"nostr" = "sha256-..."          # ❌ Wrong
```

## Background

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.

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.

This is a **security feature** - it prevents supply chain attacks by ensuring you get exactly the code you expect.

## Examples

### Example 1: Updating nostr-sdk fork

```bash
# 1. Update to newer commit
cd /path/to/ngit-grasp
cargo update -p nostr

# 2. Try to build with Nix (will fail with hash)
nix build .#default

# 3. Copy the hash from error message
# got: sha256-ABC123...=

# 4. Update both files:
# flake.nix and nix/module.nix
"nostr-0.44.1" = "sha256-ABC123...=";

# 5. Build again
nix build .#default
```

### Example 2: Adding new git dependency

```bash
# 1. Add to Cargo.toml
[dependencies]
new-crate = { git = "https://github.com/user/repo", tag = "v1.0" }

# 2. Update Cargo.lock
cargo update -p new-crate

# 3. Try to build (will fail)
nix build .#default

# 4. Add to both flake.nix and nix/module.nix:
outputHashes = {
  "nostr-0.44.1" = "sha256-...";
  "new-crate-1.0.0" = "sha256-...";  # ← Add from error message
};
```

## See Also

- [Nix Manual: Cargo.lock Hash](https://nixos.org/manual/nixpkgs/stable/#rust-cargo-lock-hash)
- [SRI Hash Format](https://www.w3.org/TR/SRI/)