Dependency Upgrades

Guide for updating dependencies across repositories using Tidra.

When to Use This

Dependency upgrades are needed for:

  • Security vulnerabilities
  • New features
  • Performance improvements
  • Framework updates
  • End-of-support migrations

Common examples:

  • Updating internal shared libraries
  • Bumping framework versions
  • Language version updates
  • Replacing deprecated packages

What Tidra Can Do

Tidra is good for:

  • Updating version numbers in manifest files
  • Updating import statements
  • Replacing deprecated method calls
  • Updating configuration for new versions

Tidra has limitations with:

  • Running build commands (npm install, pip install) for lock file updates
  • Private dependencies requiring credentials (we're working on this)
  • Complex dependency resolution

Best fit: Dependency updates that involve code changes, not just version bumps.


Basic Pattern

1. Identify the Change

Document:

  • Which package to update
  • Current version → new version
  • Code changes needed (if any)
  • Breaking changes to handle

2. Understand Breaking Changes

Read the package's changelog:

  • What's deprecated?
  • What's removed?
  • What's changed?
  • Are there migration guides?

3. Write Your Description

Include:

  • Version update in manifest file
  • Code changes needed
  • Import changes
  • Configuration updates

Example: Update Internal Library

Goal

Update internal shared library across all services.

Description

Update @company/shared-utils from 2.x to 3.x:

1. Update package.json:
   Change "@company/shared-utils": "^2.0.0"
   To: "@company/shared-utils": "^3.0.0"

2. Update imports (breaking change in v3):
   Old: import { utils } from '@company/shared-utils'
   New: import { utils } from '@company/shared-utils/core'

3. Update method calls (renamed in v3):
   Old: utils.formatDate(date)
   New: utils.format.date(date)

   Old: utils.parseJSON(str)
   New: utils.parse.json(str)

4. Look in:
   - All .js and .ts files
   - Files that import @company/shared-utils

See migration guide: https://docs.company.com/shared-utils/v3-migration

What to Check

  • ✅ package.json version updated
  • ✅ Imports updated
  • ✅ Method calls updated
  • ✅ No remaining v2 patterns

Example: Python Library Update

Goal

Update requests library and handle breaking changes.

Description

Update requests library from 2.28.x to 2.31.x in requirements.txt:

1. Update version:
   Change: requests==2.28.2
   To: requests==2.31.0

2. Update deprecated patterns:
   Old: response.content.decode('utf-8')
   New: response.text

3. Update timeout handling (changed in 2.31):
   Old: requests.get(url, timeout=30)
   New: requests.get(url, timeout=(5, 30))  # (connect, read)

4. Look in all .py files that import requests

Note: This won't update requirements.lock - you'll need to run pip install after merging.

What to Check

  • ✅ requirements.txt updated
  • ✅ Deprecated patterns updated
  • ✅ Timeout syntax updated
  • ✅ Code still valid Python

Example: Framework Major Version

Goal

Update React from 17 to 18.

Description

Update React from 17.x to 18.x:

1. Update package.json:
   "react": "^17.0.0" → "react": "^18.2.0"
   "react-dom": "^17.0.0" → "react-dom": "^18.2.0"

2. Update root render (breaking change):
   Old pattern in index.js:
   ```javascript
   import ReactDOM from 'react-dom';
   ReactDOM.render(<App />, document.getElementById('root'));

New pattern:

import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
  1. Look for:

    • ReactDOM.render usage
    • ReactDOM.hydrate usage (change to hydrateRoot)
  2. Files to check:

    • src/index.js
    • src/index.tsx
    • Any file with ReactDOM imports

Reference: https://react.dev/blog/2022/03/08/react-18-upgrade-guide


### What to Check

- ✅ Versions updated in package.json
- ✅ Render method migrated
- ✅ Hydrate updated if present
- ✅ Imports correct

---

## Example: Language Version Update

### Goal
Update Python version from 3.9 to 3.10.

### Description

Update Python version declarations from 3.9 to 3.10:

  1. Update Dockerfile: FROM python:3.9-slim → FROM python:3.10-slim

  2. Update .python-version file: 3.9.18 → 3.10.13

  3. Update GitHub Actions workflow: python-version: '3.9' → python-version: '3.10'

  4. Update runtime.txt (if present): python-3.9 → python-3.10

  5. Update pyproject.toml (if present): requires-python = ">=3.9" → requires-python = ">=3.10"

Don't change:

  • Code that imports sys.version_info (leave those checks)
  • Documentation mentioning Python 3.9 (we'll update separately)

Note: 3.9 → 3.10 has minimal breaking changes, but test your code.


### What to Check

- ✅ All version declarations updated
- ✅ Dockerfile updated
- ✅ CI config updated
- ✅ No version checks broken

---

## Working with Lock Files

### Current Limitation

Tidra can update manifest files (package.json, requirements.txt, go.mod) but may not be able to update lock files (package-lock.json, requirements.lock, go.sum) if you have private dependencies.

### Workaround

**Option 1:** Update manually after PRs merge
```bash
cd repo
npm install  # Updates package-lock.json
git commit -am "Update lock file"
git push

Option 2: CI automation Set up CI to automatically update lock files when manifest changes.

Option 3: Wait for Tidra's credential support We're working on allowing Tidra to access private dependencies. Coming soon.


Tips for Success

Read the Changelog

Always read the package changelog before updating. Look for:

  • Breaking changes
  • Deprecations
  • Migration guides
  • New requirements

Test with Similar Repos

Update similar repos first (all Node.js, all Python, etc.). Different languages need different descriptions.

Update Related Packages

If updating React, also update react-dom. If updating Django, also update django-rest-framework. Keep ecosystem packages aligned.

Handle Multiple Versions

If some repos are on very old versions, consider:

  • Updating them separately
  • Multiple initiatives (v1 → v2, then v2 → v3)

Document Why

Include in PR description:

  • Why updating (security, features, deprecation)
  • What broke (breaking changes)
  • How to test

Common Mistakes

Just Bumping Version Numbers

Dependencies often require code changes. Don't just update the version and hope it works.

Mixing Unrelated Updates

Update one dependency at a time (or closely related ones). Don't update 10 packages in one initiative.

Forgetting Dev Dependencies

Update both runtime and dev dependencies if needed.

Not Testing

Dependency updates can break things. Always test a few repos first.


Advanced: Replacing Deprecated Package

Goal

Replace old package with new recommended one.

Description

Replace deprecated 'moment' with 'date-fns':

1. Update package.json:
   Remove: "moment": "^2.29.4"
   Add: "date-fns": "^2.30.0"

2. Update imports:
   Old: import moment from 'moment'
   New: import { format, parseISO } from 'date-fns'

3. Update common patterns:
   Old: moment().format('YYYY-MM-DD')
   New: format(new Date(), 'yyyy-MM-dd')

   Old: moment(dateString)
   New: parseISO(dateString)

   Old: moment().add(1, 'days')
   New: addDays(new Date(), 1)

4. Look in all .js and .ts files

5. Import what you need from date-fns based on usage:
   - format, parseISO (most common)
   - addDays, subDays (for date math)
   - isAfter, isBefore (for comparisons)

Reference: https://date-fns.org/docs/Getting-Started

What to Check

  • ✅ Old package removed
  • ✅ New package added
  • ✅ Imports updated
  • ✅ Method calls updated
  • ✅ All date operations work

Validation Checklist

  • Manifest file updated (package.json, requirements.txt, etc.)
  • Imports updated
  • Deprecated methods replaced
  • Breaking changes handled
  • Configuration updated
  • Code still valid syntax
  • Lock file strategy defined (manual, CI, or wait)

Next Steps