Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
ca9f8f0
move
terrykong Nov 20, 2025
af18c36
wip
terrykong Nov 21, 2025
0f1354e
version fix
terrykong Nov 21, 2025
951c47b
token
terrykong Nov 21, 2025
465adca
robust renovate_app_id
terrykong Nov 21, 2025
b7d282d
successful, but trying to create pr
terrykong Nov 21, 2025
0ce4d98
ignore fact that repo can be fork and also simplify into one pr
terrykong Nov 21, 2025
166f995
try to fix fork
terrykong Nov 21, 2025
0c6901e
[Renovate]: migrate config .github/renovate.json
renovate-bot Nov 21, 2025
6ec02d2
Merge pull request #3 from terrykong/renovate/migrate-config
terrykong Nov 21, 2025
c284119
attempt to group but also fix issues
terrykong Nov 21, 2025
e2f2fa5
try consolidating the logs
terrykong Nov 21, 2025
274767b
consolidated pr
terrykong Nov 21, 2025
2f11198
try to fix
terrykong Nov 22, 2025
97b6f99
try restricting dependency list
terrykong Nov 22, 2025
e538481
try to fix
terrykong Nov 24, 2025
6a14f68
pre-commit
terrykong Nov 24, 2025
355987b
add uv
terrykong Nov 24, 2025
ccef319
pre-clone repo with unshallowed submodules for Renovate
terrykong Nov 24, 2025
73e77d4
fix: add safe.directory for pre-cloned repo
terrykong Nov 24, 2025
69c9d97
fix: use 777 permissions and move gitconfig to /tmp
terrykong Nov 24, 2025
4eb360a
fix(renovate): use docker-user root and pass GIT_CONFIG_GLOBAL env var
terrykong Nov 24, 2025
5ab4f01
fix(renovate): use docker-cmd-file to set git safe.directory
terrykong Nov 24, 2025
d2629d4
fix(renovate): disable uv manager to prevent artifact update race con…
terrykong Nov 24, 2025
7366674
fix(renovate): disable uv manager via packageRules instead of top-lev…
terrykong Nov 24, 2025
debbc06
fix(sync): use bracket counting to find list end instead of regex
terrykong Nov 24, 2025
4cd8141
fix(renovate): remove incorrect workspace check that skipped uv lock
terrykong Nov 25, 2025
8bceb6f
fix(deps): update Automodel to main, remove torch/ray from Renovate a…
terrykong Nov 25, 2025
8654ac4
fix(renovate): change group name to force new branch after closed PRs
terrykong Nov 25, 2025
c0bbd39
fix(renovate): add recreateClosed to allow recreating PRs after closes
terrykong Nov 25, 2025
8b7d59a
fix(renovate): use recreateWhen instead of deprecated recreateClosed
terrykong Nov 25, 2025
67f21bc
fix(renovate): remove schedule restriction to allow anytime updates
terrykong Nov 25, 2025
eaa98ef
fix(renovate): remove transformers from allowlist (conflicts with nem…
terrykong Nov 25, 2025
88b258d
Unpin torch version to let vllm dictate
terrykong Nov 25, 2025
84feb20
Temp hack: override timm==1.0.16 to work around submodule conflict
terrykong Nov 25, 2025
e1ed02a
Disable pep621 auto lock file updates - let postUpgradeTasks handle it
terrykong Nov 25, 2025
a435420
Add NRL_AUTO_SYNC_DEPS env var for Renovate auto-sync
terrykong Nov 25, 2025
4ad700e
Set NRL_AUTO_SYNC_DEPS in renovate_cmd.sh wrapper
terrykong Nov 25, 2025
d9abfa6
Add customEnvVariables for NRL_AUTO_SYNC_DEPS in renovate.json
terrykong Nov 25, 2025
2b654d7
Add workflow_dispatch inputs for Docker updates and force run
terrykong Nov 25, 2025
4029d21
Use jq instead of sed for JSON modification
terrykong Nov 25, 2025
c043992
Remove unused dry_run input
terrykong Nov 25, 2025
758c06a
Add dockerfile disable rule to renovate.json
terrykong Nov 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions .github/RENOVATE_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# Renovate Setup Documentation

This repository uses [Renovate](https://docs.renovatebot.com/) to automatically update dependencies, including git submodules and Python packages managed in `pyproject.toml`.

## What Renovate Does

Renovate automatically:
1. **Updates git submodules** by tracking the configured branches
2. **Updates a small allowlist of Python dependencies** in `pyproject.toml`:
- `vllm`, `torch`, and `ray` for the core training stack
- `transformer-engine` and `flash-attn` for xformers compatibility
- `transformers` so we can track upstream releases
- _Everything else is frozen unless explicitly requested._
Comment on lines +9 to +13
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat .github/renovate.json | head -100

Repository: NVIDIA-NeMo/RL

Length of output: 2409


🏁 Script executed:

rg -n "torch|ray" .github/renovate.json -B 2 -A 2

Repository: NVIDIA-NeMo/RL

Length of output: 40


🏁 Script executed:

rg -n "matchPackageNames|matchPackagePatterns" .github/renovate.json -A 10

Repository: NVIDIA-NeMo/RL

Length of output: 953


Fix documentation to match actual Renovate configuration.

The documentation incorrectly lists the allowlist. The actual renovate.json only allows updates for vllm, transformer-engine, and flash-attn. The mentioned packages torch, ray, and transformers are not in the allowlist and should be removed from the documentation (lines 10-13).

🤖 Prompt for AI Agents
In @.github/RENOVATE_SETUP.md around lines 9 - 13, The README list of allowed
Python dependencies is out of sync with the actual Renovate config: update the
bullet list in RENOVATE_SETUP.md to match renovate.json by removing torch, ray,
and transformers and leaving only vllm, transformer-engine, and flash-attn;
ensure the surrounding text still states that everything else is frozen unless
explicitly requested and that the documented allowlist matches the renovate.json
entries.

3. **Syncs `3rdparty/*/setup.py` files** with their corresponding submodule dependencies
4. **Regenerates `uv.lock`** after dependency updates
5. **Pre-clones git submodules with full history** so Renovate can checkout new commits (works around `shallow=true` in `.gitmodules`)
6. **Creates a single PR** that automatically triggers the full CI pipeline (`cicd-main.yml`)

## Setup Requirements

You need to set up authentication for Renovate. Choose one of the following options:

### Option 1: Personal Access Token (PAT) - Quick Start

**This is the easiest way to get started:**

1. Create a GitHub Personal Access Token (PAT):
- Go to GitHub Settings → Developer settings → Personal access tokens → Tokens (classic)
- Click "Generate new token (classic)"
- Give it a descriptive name (e.g., "Renovate Bot")
- Select scopes:
- ✅ `repo` (Full control of private repositories)
- ✅ `workflow` (Update GitHub Action workflows - required for github-actions manager)
- Click "Generate token" and copy it

2. Add the token as a repository secret:
- Go to your repository → Settings → Secrets and variables → Actions
- Click "New repository secret"
- Name: `RENOVATE_TOKEN`
- Value: Paste your PAT
- Click "Add secret"

3. You're done! The workflow will use the PAT automatically.

### Option 2: GitHub App (Recommended for Organizations)

**Better for rate limits and security, but requires more setup:**

1. Create a GitHub App:
- Go to Organization Settings → Developer settings → GitHub Apps → New GitHub App
- Or use an existing Renovate GitHub App

2. Configure the app with these permissions:
- Repository permissions:
- Contents: Read & Write
- Pull requests: Read & Write
- Workflows: Read & Write (if using github-actions manager)
- Metadata: Read-only

3. Install the app on your repository

4. Add these secrets to your repository:
- `RENOVATE_APP_ID`: The app ID (found on the app's settings page)
- `RENOVATE_APP_PRIVATE_KEY`: The app's private key (PEM format)

5. The workflow will automatically detect and use the GitHub App token

### 2. Grant Workflow Permissions

Ensure the Renovate workflow has permission to:
- Create and update pull requests
- Read and write to the repository
- Access secrets

This can be configured in: `Settings` → `Actions` → `General` → `Workflow permissions`

## Configuration Files

### `.github/renovate.json`
Main configuration file that defines:
- Update schedule (daily during business hours PST)
- Package grouping rules
- Branch naming conventions
- PR labels (`dependencies`, `CI:L2`)

### `.github/workflows/renovate.yml`
GitHub Actions workflow that:
- Runs daily at 9 AM UTC (1 AM PST / 2 AM PDT)
- Can be manually triggered with `workflow_dispatch`
- Sets up the environment (Python, uv)
- Executes Renovate with proper credentials

### `.github/scripts/sync_submodule_dependencies.py`
Python script that:
- Reads dependencies from `3rdparty/*/pyproject.toml` files in submodules
- Updates `CACHED_DEPENDENCIES` in corresponding `setup.py` files
- Ensures consistency between submodule requirements and wrapper packages

### `.github/scripts/renovate_post_update.sh`
Bash script that runs after Renovate updates dependencies:
1. Syncs submodule dependencies to setup.py files
2. Runs `uv lock` to regenerate the lock file
3. Stages changes for commit

## Manual Workflow Trigger

You can manually trigger Renovate at any time:

1. Go to `Actions` → `Renovate` in GitHub
2. Click `Run workflow`
3. Optional parameters:
- **Log level**: Set to `debug` for verbose output
- **Dry run**: Enable to preview changes without creating PRs

## Update Strategy

Renovate now produces **one consolidated PR at a time**:

| Branch prefix | Contents | Notes |
|---------------|----------|-------|
| `renovate/allowlist-…` | Git submodules, Docker/GitHub Action updates, and the allowlisted Python packages above | Runs on the configured weekday schedule; no other dependencies are touched until explicitly re-enabled. Renovate's built-in vulnerability PRs are disabled so everything funnels through this branch. |

## Debug vs. Production Settings

- `prHourlyLimit` is currently `0` **only while debugging** so Renovate can recreate PRs immediately. Set it back to `1` once we're satisfied with the configuration to avoid noisy PR bursts.
- `prConcurrentLimit` stays at `1` to preserve the "one PR at a time" contract; raise it temporarily if you ever need parallel testing.

## CI Integration

When Renovate creates a PR:
1. The PR is automatically labeled with `CI:L2` to trigger full CI testing
2. `cicd-main.yml` runs the complete test suite
3. All L2 tests must pass before the PR can be merged
4. The lock file and setup.py changes are included in the PR

## Troubleshooting

### Renovate workflow fails
- Check that secrets `RENOVATE_APP_ID` and `RENOVATE_APP_PRIVATE_KEY` are set
- Verify the GitHub App is installed on the repository
- Check workflow logs for specific error messages

### Dependencies not syncing
- Ensure submodules are properly initialized
- Check `.github/scripts/sync_submodule_dependencies.py` logs
- Verify that submodule `pyproject.toml` files exist and are valid

### uv lock fails
- Ensure `uv` version in workflow matches project requirements
- Check for dependency conflicts in the update
- Review the post-update script logs

### PRs not triggering CI
- Verify PR has the `CI:L2` label
- Check `cicd-main.yml` configuration
- Ensure PR is targeting the `main` branch

## Customization

To modify Renovate behavior:
1. Edit `.github/renovate.json` for scheduling, grouping, or update rules
2. Update `.github/workflows/renovate.yml` for workflow settings
3. Modify `.github/scripts/renovate_post_update.sh` for custom post-update logic

## Testing Changes

Before committing Renovate config changes:
1. Use the workflow's dry-run mode to test
2. Check the Renovate logs for validation errors
3. Test the post-update script locally:
```bash
.github/scripts/renovate_post_update.sh
```

## References

- [Renovate Documentation](https://docs.renovatebot.com/)
- [Renovate Configuration Options](https://docs.renovatebot.com/configuration-options/)
- [GitHub Action for Renovate](https://github.com/renovatebot/github-action)

119 changes: 119 additions & 0 deletions .github/renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:best-practices",
":dependencyDashboard"
],
"timezone": "America/Los_Angeles",
"cloneSubmodules": true,
"customEnvVariables": {
"NRL_AUTO_SYNC_DEPS": "1"
},
"prConcurrentLimit": 1,
"prHourlyLimit": 0,
"semanticCommits": "disabled",
"commitMessagePrefix": "[Renovate]",
"branchPrefix": "renovate/",
"labels": [
"dependencies",
"CI:L2"
],
"assignees": [],
"reviewers": [],
"postUpgradeTasks": {
"commands": [
".github/scripts/renovate_post_update.sh"
],
"fileFilters": [
"uv.lock",
"3rdparty/**/setup.py"
],
"executionMode": "update"
},
"packageRules": [
{
"description": "Disable Python dependency updates unless explicitly allowlisted",
"matchManagers": [
"pep621"
],
"enabled": false
},
{
"description": "Allowlisted training stack dependencies (from initial requirements)",
"matchManagers": [
"pep621"
],
"matchPackageNames": [
"vllm",
"transformer-engine",
"flash-attn"
],
"enabled": true
},
{
"description": "Disable Python version updates (pyenv, github-actions python)",
"matchManagers": [
"pyenv"
],
"enabled": false
},
{
"description": "Disable Python runtime version updates in GitHub Actions",
"matchPackageNames": [
"python"
],
"matchManagers": [
"github-actions"
],
"enabled": false
},
{
"description": "Disable alternate Python managers that duplicate pep621 coverage",
"matchManagers": [
"pip_setup",
"poetry",
"pixi",
"uv"
],
"enabled": false
},
{
"description": "Disable Docker base image updates by default (enable manually when needed)",
"matchManagers": [
"dockerfile"
],
"enabled": false
},
{
"description": "Group every allowed update into a single PR",
"matchPackagePatterns": [
"*"
],
"groupName": "dependency updates",
"additionalBranchPrefix": "deps-",
"separateMajorMinor": false,
"separateMultipleMajor": false
}
],
"git-submodules": {
"enabled": true
},
"pep621": {
"enabled": true,
"fileMatch": ["(^|/)pyproject\\.toml$"],
"updateLockFiles": false
},
"lockFileMaintenance": {
"enabled": false
},
"vulnerabilityAlerts": {
"enabled": false
},
"osvVulnerabilityAlerts": false,
"rangeStrategy": "bump",
"platformAutomerge": false,
"rebaseWhen": "behind-base-branch",
"recreateWhen": "always",
"forkProcessing": "enabled",
"includeForks": true
}
14 changes: 14 additions & 0 deletions .github/scripts/renovate_cmd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash
# Custom Renovate command that configures git safe.directory before running renovate
# This is needed because the pre-cloned repo is owned by a different user than the container user
Comment on lines +1 to +3
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add the NVIDIA copyright header.

As per coding guidelines, shell scripts (excluding tests) require the NVIDIA copyright header at the top.

Proposed fix
 #!/bin/bash
+# Copyright (c) 2025, NVIDIA CORPORATION.  All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 # Custom Renovate command that configures git safe.directory before running renovate
 # This is needed because the pre-cloned repo is owned by a different user than the container user
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#!/bin/bash
# Custom Renovate command that configures git safe.directory before running renovate
# This is needed because the pre-cloned repo is owned by a different user than the container user
#!/bin/bash
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Custom Renovate command that configures git safe.directory before running renovate
# This is needed because the pre-cloned repo is owned by a different user than the container user
🤖 Prompt for AI Agents
In @.github/scripts/renovate_cmd.sh around lines 1 - 3, Add the required NVIDIA
copyright header to the top of the shell script .github/scripts/renovate_cmd.sh
(above the shebang or immediately after it if policy requires the shebang first)
so the script complies with coding guidelines; update the file header in
renovate_cmd.sh to include the standard multi-line NVIDIA copyright notice used
across the repo.


# Mark all directories as safe (required for pre-cloned repos with different ownership)
git config --global --add safe.directory '*'

# Enable auto-sync of CACHED_DEPENDENCIES in 3rdparty setup.py files
# This allows submodule updates to proceed - the setup.py will use submodule deps directly
export NRL_AUTO_SYNC_DEPS=1

# Run the actual renovate command
exec renovate "$@"

77 changes: 77 additions & 0 deletions .github/scripts/renovate_post_update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/bin/bash
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(realpath "$SCRIPT_DIR/../..")"

echo "==================================="
echo "Renovate Post-Update Script"
echo "==================================="
echo ""

cd "$REPO_ROOT"

# Step 1: Sync submodule dependencies to setup.py files
echo "Step 1: Syncing submodule dependencies..."
python3 "$SCRIPT_DIR/sync_submodule_dependencies.py"
if [ $? -ne 0 ]; then
echo "ERROR: Failed to sync submodule dependencies"
exit 1
fi
echo ""

# Step 2: Run uv lock to regenerate lock file
echo "Step 2: Running uv lock..."

# Install uv if not available (needed when running inside Renovate's Docker container)
if ! command -v uv &> /dev/null; then
echo "uv not found, installing..."
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
fi

if ! command -v uv &> /dev/null; then
echo "ERROR: uv is not installed or not in PATH after installation attempt"
exit 1
fi

# Run uv lock to regenerate the lock file
# Note: Workspace members are defined in pyproject.toml [tool.uv.workspace].members
# Some members point to submodule paths (e.g., Automodel-workspace/Automodel), not the parent dir
uv lock
if [ $? -ne 0 ]; then
echo "ERROR: uv lock failed"
exit 1
fi
echo ""

# Step 3: Stage all changes for commit
echo "Step 3: Staging changes..."
git add -A 3rdparty/*/setup.py uv.lock
if [ $? -ne 0 ]; then
echo "WARNING: Failed to stage files with git add"
# Don't exit, as Renovate might handle git operations differently
fi
echo ""

echo "==================================="
echo "Post-update completed successfully"
echo "==================================="
echo ""
echo "Changed files:"
git diff --cached --name-only || git status --short || echo "(git status unavailable)"

Loading