|
| 1 | +--- |
| 2 | +name: update-dependencies |
| 3 | +description: Guide for updating project dependencies using the update-dependencies.sh automation script. Automates the cargo update workflow including branch creation, commit, push, and optional PR creation. Use when updating dependencies, running cargo update, or automating the dependency lifecycle. Triggers on "update dependencies", "cargo update", "update deps", "bump dependencies", or "run dependency update". |
| 4 | +metadata: |
| 5 | + author: torrust |
| 6 | + version: "1.0" |
| 7 | +--- |
| 8 | + |
| 9 | +# Updating Dependencies |
| 10 | + |
| 11 | +This skill guides you through updating project dependencies using the `scripts/update-dependencies.sh` automation script, which handles the complete dependency update workflow from branch creation to PR submission. |
| 12 | + |
| 13 | +## Quick Reference |
| 14 | + |
| 15 | +```bash |
| 16 | +# Simple update (no issue) |
| 17 | +./scripts/update-dependencies.sh \ |
| 18 | + --branch update-dependencies \ |
| 19 | + --push-remote {fork-remote} \ |
| 20 | + --create-pr |
| 21 | + |
| 22 | +# Complex update with issue |
| 23 | +./scripts/update-dependencies.sh \ |
| 24 | + --branch {issue-number}-update-dependencies \ |
| 25 | + --push-remote {fork-remote} \ |
| 26 | + --create-pr |
| 27 | +``` |
| 28 | + |
| 29 | +## Workflow Overview |
| 30 | + |
| 31 | +The `update-dependencies.sh` script automates the following steps: |
| 32 | + |
| 33 | +1. Ensures a clean working tree (no uncommitted changes) |
| 34 | +2. Fetches and fast-forwards the base branch from upstream |
| 35 | +3. Creates a feature branch with the specified name |
| 36 | +4. Runs `cargo update` and captures the full output |
| 37 | +5. Exits early if no `Cargo.lock` changes are produced |
| 38 | +6. Optionally runs `./scripts/pre-commit.sh` (default: enabled) |
| 39 | +7. **Commits** the `Cargo.lock` changes with full `cargo update` output in commit body |
| 40 | +8. **Pushes** the branch to the fork remote |
| 41 | +9. **Creates a PR** on GitHub (optional, default: disabled) |
| 42 | + |
| 43 | +## Usage |
| 44 | + |
| 45 | +### Basic Invocation |
| 46 | + |
| 47 | +```bash |
| 48 | +./scripts/update-dependencies.sh \ |
| 49 | + --branch update-dependencies \ |
| 50 | + --push-remote {fork-remote} |
| 51 | +``` |
| 52 | + |
| 53 | +### With PR Creation |
| 54 | + |
| 55 | +```bash |
| 56 | +./scripts/update-dependencies.sh \ |
| 57 | + --branch update-dependencies \ |
| 58 | + --push-remote {fork-remote} \ |
| 59 | + --create-pr |
| 60 | +``` |
| 61 | + |
| 62 | +### Signing Commits |
| 63 | + |
| 64 | +Commits are **always signed** with `git commit -S` (GPG signing is mandatory): |
| 65 | + |
| 66 | +```bash |
| 67 | +./scripts/update-dependencies.sh \ |
| 68 | + --branch update-dependencies \ |
| 69 | + --push-remote {fork-remote} |
| 70 | +``` |
| 71 | + |
| 72 | +Unsigned commits are not permitted in this workflow. |
| 73 | + |
| 74 | +### Skipping Pre-Commit Checks |
| 75 | + |
| 76 | +Pre-commit checks are run by default. Skip them if needed (not recommended): |
| 77 | + |
| 78 | +```bash |
| 79 | +./scripts/update-dependencies.sh \ |
| 80 | + --branch update-dependencies \ |
| 81 | + --push-remote {fork-remote} \ |
| 82 | + --skip-pre-commit |
| 83 | +``` |
| 84 | + |
| 85 | +### Deleting Existing Branch |
| 86 | + |
| 87 | +If a branch with the same name already exists, delete it first: |
| 88 | + |
| 89 | +```bash |
| 90 | +./scripts/update-dependencies.sh \ |
| 91 | + --branch update-dependencies \ |
| 92 | + --push-remote {fork-remote} \ |
| 93 | + --delete-existing-branch |
| 94 | +``` |
| 95 | + |
| 96 | +## All Options |
| 97 | + |
| 98 | +```bash |
| 99 | +./scripts/update-dependencies.sh --help |
| 100 | +``` |
| 101 | + |
| 102 | +| Option | Default | Description | |
| 103 | +| -------------------------- | ---------------------------- | ------------------------------------------------------ | |
| 104 | +| `--branch` | **required** | Feature branch name (e.g., `123-update-deps`) | |
| 105 | +| `--base-branch` | `main` | Target branch for merge base | |
| 106 | +| `--base-remote` | Auto-detected | Remote for base branch (prefers `torrust` → `origin`) | |
| 107 | +| `--push-remote` | Auto-detected | Remote to push the branch to | |
| 108 | +| `--repo` | Auto-detected | GitHub repo slug (owner/repo) | |
| 109 | +| `--commit-title` | `chore: update dependencies` | First line of commit message | |
| 110 | +| `--pr-title` | `chore: update dependencies` | Pull request title | |
| 111 | +| `--skip-pre-commit` | disabled | Skip `./scripts/pre-commit.sh` after update | |
| 112 | +| `--create-pr` | disabled | Create a PR after pushing | |
| 113 | +| `--delete-existing-branch` | disabled | Delete the branch locally and remotely before starting | |
| 114 | +| `--help` | — | Show full usage and all options | |
| 115 | + |
| 116 | +## When to Create an Issue |
| 117 | + |
| 118 | +- **Simple updates**: Just running `cargo update` with no special handling → **No issue needed**, use branch name `update-dependencies` |
| 119 | +- **Complex updates**: Dependency updates requiring additional changes (migrations, API updates, refactoring) → **Create an issue** and use branch name `{issue-number}-update-dependencies` |
| 120 | + |
| 121 | +This keeps the issue tracker focused on substantial work while allowing for routine maintenance tasks without issue clutter. |
| 122 | + |
| 123 | +## Step-by-Step Example (Simple Update) |
| 124 | + |
| 125 | +### 1. Run the Script (No Issue) |
| 126 | + |
| 127 | +```bash |
| 128 | +./scripts/update-dependencies.sh \ |
| 129 | + --branch update-dependencies \ |
| 130 | + --push-remote {fork-remote} \ |
| 131 | + --create-pr |
| 132 | +``` |
| 133 | + |
| 134 | +## Step-by-Step Example (Complex Update with Issue) |
| 135 | + |
| 136 | +### 1. Create an Issue |
| 137 | + |
| 138 | +```bash |
| 139 | +gh issue create \ |
| 140 | + --title "chore: update dependencies and migrate to new API" \ |
| 141 | + --body "Update dependencies and handle breaking changes in async library." |
| 142 | +``` |
| 143 | + |
| 144 | +Note the issue number (e.g., `#456`). |
| 145 | + |
| 146 | +### 2. Run the Script |
| 147 | + |
| 148 | +```bash |
| 149 | +./scripts/update-dependencies.sh \ |
| 150 | + --branch {issue-number}-update-dependencies \ |
| 151 | + --push-remote {fork-remote} \ |
| 152 | + --create-pr |
| 153 | +``` |
| 154 | + |
| 155 | +### 3. Observe the Output |
| 156 | + |
| 157 | +The script will: |
| 158 | + |
| 159 | +- Fetch the latest `main` from `torrust` remote |
| 160 | +- Create branch `456-update-dependencies` |
| 161 | +- Run `cargo update` and show the output |
| 162 | +- If dependencies changed: run pre-commit, commit with full output, push, create PR |
| 163 | +- If no changes: clean up branch and exit (no-op, which is fine) |
| 164 | + |
| 165 | +### 4. Review and Merge |
| 166 | + |
| 167 | +- Visit the PR created by the script (URL printed to stdout) |
| 168 | +- Review the `cargo update` output in the commit body |
| 169 | +- Let CI checks pass |
| 170 | +- Merge when ready |
| 171 | + |
| 172 | +## Commit Message Format |
| 173 | + |
| 174 | +The script generates commit messages in this format: |
| 175 | + |
| 176 | +```text |
| 177 | +chore: update dependencies |
| 178 | +
|
| 179 | +[Full cargo update output] |
| 180 | +
|
| 181 | +- run `cargo update` |
| 182 | +- commit the resulting `Cargo.lock` changes |
| 183 | +``` |
| 184 | + |
| 185 | +The full `cargo update` output is included in the commit body for traceability. Example: |
| 186 | + |
| 187 | +```text |
| 188 | + Updating crates.io index |
| 189 | + Locking 14 packages to latest compatible versions |
| 190 | + Updating hyper-rustls from 0.27.7 to 0.27.8 |
| 191 | + ... |
| 192 | +``` |
| 193 | + |
| 194 | +## Pre-Commit Checks |
| 195 | + |
| 196 | +Before committing, the script optionally runs `./scripts/pre-commit.sh` (enabled by default), which verifies: |
| 197 | + |
| 198 | +1. **Unused dependencies**: `cargo machete` |
| 199 | +2. **All linters**: markdown, YAML, TOML, spelling, Clippy, rustfmt, shellcheck |
| 200 | +3. **Tests**: `cargo test` |
| 201 | +4. **Documentation**: `cargo doc --no-deps` |
| 202 | +5. **E2E infrastructure tests**: provisioning and destruction |
| 203 | +6. **E2E deployment tests**: full workflow |
| 204 | + |
| 205 | +If pre-commit fails, the script exits before committing. Fix issues and run the script again. |
| 206 | + |
| 207 | +### Skip Pre-Commit (Not Recommended) |
| 208 | + |
| 209 | +```bash |
| 210 | +./scripts/update-dependencies.sh \ |
| 211 | + --branch {issue-number}-update-dependencies \ |
| 212 | + --push-remote {fork-remote} \ |
| 213 | + --skip-pre-commit |
| 214 | +``` |
| 215 | + |
| 216 | +## When Dependencies Don't Change |
| 217 | + |
| 218 | +If `cargo update` produces no changes to `Cargo.lock`, the script will: |
| 219 | + |
| 220 | +1. Print: `No dependency changes were produced by cargo update` |
| 221 | +2. Clean up the feature branch (delete it locally) |
| 222 | +3. Exit cleanly with code 0 (success) |
| 223 | + |
| 224 | +This is **not an error** — it means all dependencies are at their latest compatible versions. |
| 225 | + |
| 226 | +## Troubleshooting |
| 227 | + |
| 228 | +### Error: Working tree has unstaged changes |
| 229 | + |
| 230 | +The script requires a clean working tree. Stage or remove all uncommitted changes: |
| 231 | + |
| 232 | +```bash |
| 233 | +git status # See what's uncommitted |
| 234 | +git add <files> # Stage changes |
| 235 | +git commit -m "..." # Or commit them |
| 236 | +git stash # Or stash them |
| 237 | +``` |
| 238 | + |
| 239 | +Then retry the script. |
| 240 | + |
| 241 | +### Error: Branch already exists |
| 242 | + |
| 243 | +The branch exists either locally or on the remote: |
| 244 | + |
| 245 | +```bash |
| 246 | +# Option 1: Use a different branch name |
| 247 | +./scripts/update-dependencies.sh \ |
| 248 | + --branch {issue-number}-update-dependencies-retry \ |
| 249 | + --push-remote {fork-remote} |
| 250 | + |
| 251 | +# Option 2: Delete the existing branch first |
| 252 | +./scripts/update-dependencies.sh \ |
| 253 | + --branch {issue-number}-update-dependencies \ |
| 254 | + --push-remote {fork-remote} \ |
| 255 | + --delete-existing-branch |
| 256 | +``` |
| 257 | + |
| 258 | +### Commit Signing Failures |
| 259 | + |
| 260 | +GPG signing is mandatory. If commit signing fails: |
| 261 | + |
| 262 | +```bash |
| 263 | +# Check GPG setup |
| 264 | +gpg --list-keys |
| 265 | + |
| 266 | +# Fix GPG configuration, then retry |
| 267 | +gh auth logout && gh auth login # Re-authenticate if needed |
| 268 | +``` |
| 269 | + |
| 270 | +Ensure GPG is properly configured before running the script. Unsigned commits are not permitted. |
| 271 | + |
| 272 | +### PR Creation Fails |
| 273 | + |
| 274 | +Ensure `gh` CLI is authenticated: |
| 275 | + |
| 276 | +```bash |
| 277 | +gh auth status # Check authentication |
| 278 | +gh auth login # Log in if needed |
| 279 | +``` |
| 280 | + |
| 281 | +Then retry with `--create-pr`. |
| 282 | + |
| 283 | +## After Merge |
| 284 | + |
| 285 | +Once the PR is merged to `main`: |
| 286 | + |
| 287 | +1. The updated `Cargo.lock` is now in the base branch |
| 288 | +2. All future branches will build with the new dependencies |
| 289 | +3. Repeat the workflow for the next update cycle (typically monthly or as needed) |
| 290 | + |
| 291 | +## Integration with CI |
| 292 | + |
| 293 | +When the PR is created, GitHub Actions will automatically run: |
| 294 | + |
| 295 | +- All linters (stable + nightly) |
| 296 | +- Full test suite |
| 297 | +- E2E infrastructure tests |
| 298 | +- E2E deployment tests |
| 299 | +- Coverage analysis |
| 300 | + |
| 301 | +All checks must pass before merging. |
| 302 | + |
| 303 | +## Best Practices |
| 304 | + |
| 305 | +- **Run regularly**: Update dependencies monthly or quarterly |
| 306 | +- **Always sign commits**: Use GPG signing (default behavior) for audit trails |
| 307 | +- **Review the output**: Check the commit message to see which packages were updated |
| 308 | +- **Run pre-commit**: Never skip this step (use default behavior) |
| 309 | +- **Use issue numbers**: Prefix branch names with issue numbers (`--branch {issue}-update-dependencies`) |
| 310 | +- **One branch per run**: Each run creates one branch and optionally one PR |
| 311 | +- **Wait for CI**: Never merge until all checks pass |
| 312 | + |
| 313 | +## See Also |
| 314 | + |
| 315 | +- [Committing Changes](../../git-workflow/commit-changes/skill.md) — General commit workflow |
| 316 | +- [Creating Feature Branches](../../git-workflow/create-feature-branch/skill.md) — Branch naming conventions |
| 317 | +- [Pre-Commit Checks](../../git-workflow/run-pre-commit-checks/skill.md) — Understanding the 6-step verification process |
0 commit comments