# How to Configure Runtime Versions for Node, Python, Go, Ruby, and Java in gh-aw

> Learn to configure Node, Python, Go, Ruby, and Java runtime versions in gh-aw workflows. Add a runtimes block to your YAML frontmatter for easy version management.

- Repository: [GitHub/gh-aw](https://github.com/github/gh-aw)
- Tags: how-to-guide
- Published: 2026-02-16

---

**You configure runtime versions in gh-aw by adding a `runtimes:` block to your workflow's YAML frontmatter, specifying the version and optionally a custom setup action for each language.**

The **gh-aw** compiler automatically manages runtime dependencies for your GitHub Actions workflows. When you need to pin specific versions of Node.js, Python, Go, Ruby, or Java, you can override the built-in defaults directly in your workflow file's frontmatter to configure runtime versions precisely.

## How Runtime Version Configuration Works

The compiler follows a three-phase process to resolve runtime versions. First, it **detects required runtimes** by scanning tool configurations and command usage, as implemented in [`pkg/workflow/runtime_definitions.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/runtime_definitions.go). Second, it **merges** any user-provided `runtimes:` configuration from the workflow's frontmatter with the default runtime catalog. Finally, it **generates** the appropriate setup action steps using the resolved versions.

The runtime catalog defines supported languages, default versions, and their corresponding GitHub Actions setup actions in [`pkg/workflow/runtime_definitions.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/runtime_definitions.go) (lines 11-60).

## Supported Runtimes and Default Versions

gh-aw supports five primary runtimes with the following defaults:

- **Node.js**: Version 24 using `actions/setup-node@v6`
- **Python**: Version 3.12 using `actions/setup-python@v5`
- **Go**: Version 1.25 using `actions/setup-go@v5`
- **Ruby**: Version 3.3 using `ruby/setup-ruby@v1`
- **Java**: Version 21 using `actions/setup-java@v4`

If you omit the `runtimes:` block entirely, the compiler automatically injects these default versions into your generated workflow.

## Configuring Runtime Versions in Workflow Frontmatter

You declare runtime overrides in the YAML frontmatter at the top of your workflow markdown file. The schema is defined in [`docs/src/content/docs/reference/frontmatter.md`](https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/frontmatter.md) (lines 37-60) and parsed into a typed `RuntimeConfig` struct in [`pkg/workflow/frontmatter_types.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/frontmatter_types.go) (lines 12-26).

### Basic Override for a Single Runtime

To pin a specific Node.js version, add the runtime name and version string:

```yaml
---
runtimes:
  node:
    version: "22"
---
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

```

The compiled output will use `actions/setup-node@v6` with `node-version: 22` instead of the default 24.

### Configuring Multiple Runtimes

You can specify versions for multiple languages in a single block:

```yaml
---
runtimes:
  node:
    version: "20"
  python:
    version: "3.11"
  go:
    version: "1.22"
---
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

```

The compiler generates three separate setup steps, each using the specified version.

### Using Custom Setup Actions

For enterprise environments or forked actions, override the default setup action repository and version:

```yaml
---
runtimes:
  java:
    version: "17"
    action-repo: "myorg/setup-java"
    action-version: "v2"
---
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

```

This generates a step using `myorg/setup-java@v2` instead of the default `actions/setup-java@v4`.

### Complete Runtime Configuration Example

Pin all five supported runtimes in a single workflow:

```yaml
---
name: Multi-runtime workflow
engine: copilot
runtimes:
  node:
    version: "22"
  python:
    version: "3.11"
  go:
    version: "1.22"
  ruby:
    version: "3.2"
  java:
    version: "21"
---
on:
  push:
    branches: [main]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

```

This configuration guarantees reproducible builds by locking every runtime to a specific version.

## Runtime Merge Logic and Implementation

The compiler applies user overrides through the `mergeRuntimes` function in [`pkg/workflow/tools.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/tools.go) (lines 207-238). This function combines the default runtime catalog with the user-supplied `runtimes:` map, giving precedence to user-defined values.

The typed configuration structure is defined in [`pkg/workflow/frontmatter_types.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/frontmatter_types.go) (lines 12-26), where the `RuntimeConfig` struct captures the version string and optional action overrides. When the compiler generates the final workflow in [`pkg/workflow/unified_prompt_creation.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/unified_prompt_creation.go), it references these merged configurations to emit the correct `actions/setup-*` steps with precise version pinning.

## Summary

- Configure runtime versions in gh-aw by adding a `runtimes:` block to your workflow's YAML frontmatter.
- Override defaults for Node.js, Python, Go, Ruby, and Java by specifying the `version` field for each runtime.
- Use `action-repo` and `action-version` fields to substitute custom GitHub Actions for the default setup actions.
- Default versions are defined in [`pkg/workflow/runtime_definitions.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/runtime_definitions.go) and merged with user overrides in [`pkg/workflow/tools.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/tools.go).
- The compiler automatically generates setup steps using `actions/setup-node`, `actions/setup-python`, and their counterparts based on your configuration.

## Frequently Asked Questions

### What happens if I don't specify a runtime version?

If you omit the `runtimes:` block entirely, the compiler automatically uses the default versions defined in [`pkg/workflow/runtime_definitions.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/runtime_definitions.go). For example, Node.js defaults to version 24, Python to 3.12, and Java to 21. The compiler injects the appropriate setup action with these versions during workflow generation.

### Can I use a custom GitHub Actions setup action?

Yes. In addition to specifying the `version` field, you can override the default setup action by adding `action-repo` and `action-version` fields to any runtime entry. For instance, setting `action-repo: "myorg/setup-java"` and `action-version: "v2"` directs the compiler to generate a step using your custom action instead of the default `actions/setup-java@v4`.

### How does gh-aw detect which runtimes my workflow needs?

The compiler scans your workflow file for tool configurations and command usage patterns to identify required runtimes, as implemented in [`pkg/workflow/runtime_definitions.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/runtime_definitions.go). However, you can proactively declare runtimes in the frontmatter to ensure specific versions are used, even if the automatic detection would have otherwise skipped or defaulted them differently.

### Where are the default runtime versions defined?

Default versions for Node.js, Python, Go, Ruby, and Java are stored in the static runtime catalog located at [`pkg/workflow/runtime_definitions.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/runtime_definitions.go) (lines 11-60). This file maps each runtime ID to its default version string and the corresponding GitHub Actions setup action repository. The compiler references this catalog when merging user overrides in [`pkg/workflow/tools.go`](https://github.com/github/gh-aw/blob/main/pkg/workflow/tools.go).