home / skills / tylercannon / agent-skills / asdf-runtime-version-updater

asdf-runtime-version-updater skill

/skills/asdf-runtime-version-updater

This skill updates language runtime versions across .tool-versions, Dockerfiles, and workflows to keep projects in sync.

npx playbooks add skill tylercannon/agent-skills --skill asdf-runtime-version-updater

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
4.5 KB
---
name: asdf-runtime-version-updater
description: "Update language runtime versions in .tool-versions files (asdf) and propagate changes to Dockerfiles, GitHub Actions workflows, and other version-referencing files. Use when: (1) updating a project's language runtime version(s), (2) synchronizing versions across .tool-versions, Dockerfiles, and CI/CD configs, or (3) migrating to a new runtime version."
---

# ASDF Runtime Version Updater

Update language runtime versions consistently across your project.

## Workflow

1. **Parse current versions** - Read `.tool-versions` to get current runtime versions
2. **Find latest version** - Run `asdf latest <runtime>` to get the latest available version
3. **Update `.tool-versions`** - Update the version in `.tool-versions`
4. **Install new version** - Run `asdf install` to install the runtime
5. **Find version references** - Search for files referencing the old version
6. **Update all references** - Update versions consistently across all files
7. **Verify project** - Install deps, build, format check, and run tests

## Version Lookup

```bash
# Get latest version for a runtime
asdf latest nodejs      # e.g., 22.13.1
asdf latest python      # e.g., 3.13.2
asdf latest ruby        # e.g., 3.4.2
asdf latest elixir      # e.g., 1.19.5-otp-28
asdf latest erlang      # e.g., 28.3.1
```

## File Patterns

### `.tool-versions` Format

```
nodejs 22.13.1
python 3.13.2
ruby 3.4.2
elixir 1.19.5-otp-28
erlang 28.3.1
```

### Dockerfile Patterns

```dockerfile
# Node.js
FROM node:22.13.1-alpine
FROM node:22-alpine

# Python
FROM python:3.13.2-slim
FROM python:3.13-slim

# Ruby
FROM ruby:3.4.2-alpine

# Elixir (often uses erlang base)
FROM elixir:1.19.5-otp-28
FROM hexpm/elixir:1.19.5-erlang-28.3.1-alpine-3.21.0
```

### Dockerfile ARG Patterns

Some Dockerfiles use `ARG` for version configuration:

```dockerfile
ARG ELIXIR_VERSION=1.19.5
ARG OTP_VERSION=28.3.1
ARG DEBIAN_VERSION=trixie-20260112-slim

ARG BUILDER_IMAGE="docker.io/hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
```

Search for these patterns:
```bash
grep -E "^ARG\s+(ELIXIR|OTP|ERLANG|NODE|PYTHON|RUBY)_VERSION=" Dockerfile*
```

### GitHub Workflows (`.github/workflows/*.yml`)

```yaml
# Node.js
- uses: actions/setup-node@v4
  with:
    node-version: '22.13.1'
    node-version-file: '.tool-versions'

# Python
- uses: actions/setup-python@v5
  with:
    python-version: '3.13.2'

# Ruby
- uses: ruby/setup-ruby@v1
  with:
    ruby-version: '3.4.2'

# Elixir
- uses: erlef/setup-beam@v1
  with:
    elixir-version: '1.19.5'
    otp-version: '28.0'
```

### GitHub Workflow Job Containers

Jobs can also specify container images directly:

```yaml
jobs:
  test:
    runs-on: ubuntu-latest
    container:
      image: hexpm/elixir:1.19.5-erlang-28.3.1-alpine-3.23.3
    
  build:
    runs-on: ubuntu-latest
    container: node:22.13.1-alpine
```

Search for these patterns:
```bash
grep -rE "^\s*(image:|container:)" .github/workflows/
```

### Other Version Files

| Runtime | Files |
|---------|-------|
| Node.js | `.nvmrc`, `.node-version`, `package.json` (engines, `@types/node`) |
| Python | `.python-version`, `pyproject.toml`, `setup.py` |
| Ruby | `.ruby-version`, `Gemfile` |

## Search Patterns

Use these patterns to find version references:

```bash
# Find version references in project
grep -r "22.13.1" .             # Specific version
grep -rE "node[:-]?22" .         # Node.js major version patterns
grep -rE "python[:-]?3\.13" .    # Python minor version patterns
```

## Example Update

**Before** (`.tool-versions`):
```
elixir 1.18.0-otp-27
erlang 27.2.4
```

**Steps**:
```bash
# Check latest versions
asdf latest elixir  # 1.19.5-otp-28
asdf latest erlang  # 28.3.1

# Update .tool-versions, then:
asdf install
```

**After** (`.tool-versions`):
```
elixir 1.19.5-otp-28
erlang 28.3.1
```

Then update all other files (Dockerfile, GitHub workflows, etc.) to match.

## Verification

After updating versions, verify the project still works:

### Elixir/Phoenix

```bash
mix deps.clean --all
mix deps.get
mix compile --warnings-as-errors
mix format --check-formatted
mix test
```

### Node.js

```bash
npm install
npm run build
npm run lint
npm test
```

### Python

```bash
pip install -e ".[dev]"
python -m build
ruff check .
pytest
```

### Ruby

```bash
bundle install
bundle exec rake build
bundle exec rubocop
bundle exec rspec
```

### Go

```bash
go mod download
go build ./...
go fmt ./...
go test ./...
```

## Resources

For detailed patterns per runtime, see [runtime-patterns.md](references/runtime-patterns.md).

Overview

This skill updates language runtime versions consistently across a repository by editing .tool-versions and propagating the new version to Dockerfiles, GitHub Actions workflows, and other version-referencing files. It automates lookup of the latest runtime versions, performs in-repo search-and-replace for common patterns, and runs project verification steps to catch regressions. The goal is a single coordinated version bump with minimal manual edits.

How this skill works

The skill reads .tool-versions to identify current runtimes and uses asdf to query the latest available versions. It updates .tool-versions and runs asdf install to provision the new runtimes. Then it searches for known filename and pattern matches (Dockerfiles, ARGs, workflow actions, .nvmrc, pyproject.toml, etc.), updates references consistently, and runs language-specific verification commands (install/build/test/lint).

When to use it

  • Bumping one or more language runtimes in a project (.tool-versions driven)
  • Synchronizing runtime versions across Dockerfiles, CI workflows, and local version files
  • Preparing a migration to a new major or minor runtime release
  • Fixing mismatched version declarations that cause CI or build errors
  • Automating bulk updates before a dependency or security upgrade

Best practices

  • Run asdf latest <runtime> to confirm target versions before changing files
  • Commit .tool-versions change first, then propagate to other files in the same PR
  • Use precise grep/regex patterns to avoid accidental replacements (major/minor anchors)
  • Run the project’s full verification steps (install, build, lint, tests) after updates
  • Update ARG-based Dockerfile variables and workflow inputs rather than only image tags

Example use cases

  • Upgrade Node.js from 22.13.1 to 22.14.x and update FROM lines, .nvmrc, and package.json engines
  • Move an Elixir project from 1.18.0-otp-27 to 1.19.5-otp-28 and update Docker ARGs and workflow job containers
  • Sync Python version in .tool-versions, GitHub Actions setup-python inputs, and pyproject.toml
  • Migrate Ruby version across .ruby-version, Gemfile, and Dockerbase images when preparing a new CI image

FAQ

Will this change every occurrence of a version string in the repo?

No. The skill targets common file patterns and uses anchored regexes to avoid broad, unsafe replacements; review suggested changes before committing.

How do I choose between exact and major-only image tags (e.g., 22.13.1 vs 22)?

Prefer exact tags for reproducible builds and major-only tags for automatic minor/patch upgrades; align Dockerfiles with your stability needs and CI policy.

What verification steps are included?

Language-specific flows are supported: install deps, build, lint/format checks, and run tests. Adjust or extend commands per project conventions.