Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions .github/workflows/changelog-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout branch
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
ref: main
fetch-depth: 0

- name: Build Changelog
id: github_tag
uses: mikepenz/release-changelog-builder-action@v3.3.1
uses: mikepenz/release-changelog-builder-action@000e44613cdb6c340ac98cb1582f99e8d3230058 # v3.3.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:
run: cat CHANGELOG.md

- name: Create or update label
uses: actions/github-script@v8
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const labelName = '${{ inputs.release-branch }}';
Expand Down Expand Up @@ -112,7 +112,7 @@ jobs:
}

- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7
with:
commit-message: "beep boop: Update changelog"
title: "Update changelog for `${{ inputs.release-branch }}`"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/cherry-pick-release-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:

jobs:
cherry-pick:
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_cherry_pick.yml@v0.63.0
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_cherry_pick.yml@8ebb3aec4c246c944a25adc7b09107cbd6a76976 # v0.63.0
secrets:
PAT: ${{ secrets.PAT }}
SLACK_WEBHOOK_ADMIN: ${{ secrets.SLACK_WEBHOOK_ADMIN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/close-inactive-issue-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ on:

jobs:
close-issues:
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_close_inactive_issue_pr.yml@v0.44.0
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_close_inactive_issue_pr.yml@9e07489b8a6bc533c8792099b012c588f4430298 # v0.44.0
8 changes: 4 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@b8d3b6e8af63cde30bdc382c0bc28114f4346c88 # v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -57,7 +57,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@b8d3b6e8af63cde30bdc382c0bc28114f4346c88 # v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
Expand All @@ -70,6 +70,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@b8d3b6e8af63cde30bdc382c0bc28114f4346c88 # v2
with:
category: "/language:${{matrix.language}}"
2 changes: 1 addition & 1 deletion .github/workflows/community-bot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
community-bot:
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_community_bot.yml@v0.54.4
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_community_bot.yml@a8006e87bff5bce54336c3e1e8571563ac70d88e # v0.54.4
with:
community_project_id: ${{ vars.COMMUNITY_PROJECT_ID }}
secrets:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/copyright-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ on:

jobs:
copyright-check:
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_copyright_check.yml@v0.54.4
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_copyright_check.yml@a8006e87bff5bce54336c3e1e8571563ac70d88e # v0.54.4
2 changes: 1 addition & 1 deletion .github/workflows/detect-secrets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ on:

jobs:
secrets-detector:
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_secrets-detector.yml@v0.74.0
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_secrets-detector.yml@859ae21dd5588c87e3bde499ddab7a3025773e8d # v0.74.0
4 changes: 2 additions & 2 deletions .github/workflows/install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:
os: [ubuntu-latest, macos-latest, ubuntu-22.04-arm]
python: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Setup Python
uses: actions/setup-python@v6
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "${{ matrix.python }}"

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ jobs:
runs-on: ubuntu-latest
needs: [format, lint, test]
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Create nightly tag
uses: actions/github-script@v8
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
// Delete existing nightly tag if it exists
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ on:

jobs:
build-docs:
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_build_docs.yml@v0.67.0
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_build_docs.yml@3ab507cd035df3ae37cce8808ed3210ff6e7062b # v0.67.0
with:
ref: ${{ inputs.github-ref }}

publish-docs:
runs-on: ubuntu-latest
needs: [build-docs]
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
repository: NVIDIA-NeMo/FW-CI-templates
ref: v0.74.0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-freeze.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ on:
default: true
jobs:
code-freeze:
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_code_freeze.yml@v1.4.2
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_code_freeze.yml@bfdb5e35067fd8cd91ce21fca4eb1072ffd7ab8c # v1.4.2
with:
library-name: NeMo Run
python-package: nemo_run
Expand Down
13 changes: 9 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,13 @@ concurrency:

jobs:
release:
if: '!cancelled()'
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@v1.4.3
if: |
!cancelled()
&& (
github.event_name != 'pull_request'
|| github.event.pull_request.head.repo.full_name == github.repository
)
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_release_library.yml@f7af92c4d1caea5a58577ce4ac5314f7de1bc5d4 # v1.4.3
with:
release-ref: ${{ inputs.release-ref || github.sha }}
python-package: nemo_run
Expand All @@ -75,14 +80,14 @@ jobs:
app-id: ${{ vars.BOT_ID }}
packaging: setuptools
gh-release-use-changelog-builder: ${{ inputs.generate-changelog || false }}
publish-docs: ${{ inputs.publish-docs || true }}
publish-docs: ${{ inputs.publish-docs == true }}
docs-target-path: nemo/run
restrict-to-admins: true
secrets: inherit # pragma: allowlist secret

release-summary:
needs: [release]
if: ${{ !cancelled() }}
if: ${{ !cancelled() && needs.release.result != 'skipped' }}
runs-on: ubuntu-latest
steps:
- name: Result
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ruff-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Install the latest version of uv
uses: astral-sh/setup-uv@v3
uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
with:
version: "latest"

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ruff-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Install the latest version of uv
uses: astral-sh/setup-uv@v3
uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
with:
version: "latest"

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/spelling.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ jobs:
name: "Spell check"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: crate-ci/typos@master
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: crate-ci/typos@3bc303c295c081add5df4a4d52a1e117f2fb2dce # master
with:
files: .
config: ./.github/workflows/config/typos.toml
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Install the latest version of uv
uses: astral-sh/setup-uv@v3
uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
with:
version: "latest"

Expand Down Expand Up @@ -48,7 +48,7 @@ jobs:
uv run -- coverage report

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@0fb7174895f61a3b6b78fc075e0cd60383518dac # v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage.xml
Expand Down
4 changes: 2 additions & 2 deletions nemo_run/run/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def __init__(
assert id, "Cannot reconstruct an experiment without id."

self._title = title
self._id = id or f"{title}_{int(time.time())}"
self._id = id or f"{title}_{time.time_ns()}"
self._enable_goodbye_message = enable_goodbye_message
self._threadpool_workers = threadpool_workers
self._skip_status_at_exit = skip_status_at_exit
Expand Down Expand Up @@ -1068,7 +1068,7 @@ def reset(self) -> "Experiment":
return self

old_id, old_exp_dir, old_launched = self._id, self._exp_dir, self._launched
self._id = f"{self._title}_{int(time.time())}"
self._id = f"{self._title}_{time.time_ns()}"
self._exp_dir = os.path.join(get_nemorun_home(), "experiments", self._title, self._id)
self._launched = False
self._live_progress = None
Expand Down
5 changes: 4 additions & 1 deletion nemo_run/run/torchx_backend/schedulers/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,11 @@ def local_logs(container: DockerContainer):
def _cancel_existing(self, app_id: str) -> None:
req = DockerJobRequest.load(app_id=app_id)
if not req:
return None
return
status = json.dumps({"id": app_id, "exit_code": "1"}) + "\n"
for container in req.containers:
status_file = Path(req.executor.job_dir) / f"status_{container.name}.out"
status_file.write_text(status)
container.delete(client=self._docker_client, id=req.id)

def close(self) -> None:
Expand Down
28 changes: 28 additions & 0 deletions test/run/test_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ def test_experiment_creation(temp_dir):
assert isinstance(exp.executor, LocalExecutor)


def test_experiment_creation_uses_nanosecond_timestamp(temp_dir):
timestamp_ns = 1_753_041_987_123_456_789

with patch("nemo_run.run.experiment.time.time_ns", return_value=timestamp_ns):
exp = Experiment("test-exp")

assert exp._id == f"test-exp_{timestamp_ns}"
assert exp._exp_dir == os.path.join(
temp_dir, "experiments", "test-exp", f"test-exp_{timestamp_ns}"
)


def test_experiment_with_custom_id(temp_dir):
"""Test creating an experiment with a custom id."""
exp = Experiment("test-exp", id="custom-id")
Expand Down Expand Up @@ -345,6 +357,22 @@ def test_reset_not_run_experiment(temp_dir):
assert reset_exp is exp # The implementation returns self now


def test_reset_uses_nanosecond_timestamp(temp_dir):
timestamp_ns = 1_753_041_987_987_654_321
exp = Experiment("test-exp", id="test-exp_original")
exp._prepare()
Path(os.path.join(exp._exp_dir, Experiment._DONE_FILE)).touch()

with patch("nemo_run.run.experiment.time.time_ns", return_value=timestamp_ns):
reset_exp = exp.reset()

assert reset_exp is exp
assert exp._id == f"test-exp_{timestamp_ns}"
assert exp._exp_dir == os.path.join(
temp_dir, "experiments", "test-exp", f"test-exp_{timestamp_ns}"
)


@patch("nemo_run.run.experiment.get_runner")
def test_experiment_from_id(mock_get_runner, temp_dir):
"""Test reconstructing an experiment from its ID."""
Expand Down
28 changes: 28 additions & 0 deletions test/run/torchx_backend/schedulers/test_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,34 @@ def test_docker_scheduler_methods(docker_scheduler):
assert hasattr(docker_scheduler, "close")


def test_cancel_existing_without_request_is_noop():
docker_scheduler = object.__new__(PersistentDockerScheduler)
docker_scheduler._DockerWorkspaceMixin__docker_client = mock.Mock()
docker_scheduler._scheduled_reqs = []

with mock.patch.object(DockerJobRequest, "load", return_value=None):
docker_scheduler._cancel_existing("app-id")


def test_cancel_existing_persists_terminal_status(tmp_path):
docker_scheduler = object.__new__(PersistentDockerScheduler)
docker_scheduler._DockerWorkspaceMixin__docker_client = mock.Mock()
docker_scheduler._scheduled_reqs = []
container = mock.Mock(name="container")
container.name = "task-1-0"
request = mock.Mock()
request.id = "app-id"
request.executor.job_dir = str(tmp_path)
request.containers = [container]

with mock.patch.object(DockerJobRequest, "load", return_value=request):
docker_scheduler._cancel_existing("app-id")

container.delete.assert_called_once_with(client=docker_scheduler._docker_client, id="app-id")
status = json.loads((tmp_path / "status_task-1-0.out").read_text())
assert status == {"id": "app-id", "exit_code": "1"}


def test_schedule(docker_scheduler, mock_app_def, docker_executor):
with (
mock.patch.object(DockerExecutor, "package") as mock_package,
Expand Down
16 changes: 16 additions & 0 deletions tests/test_release_publish_docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import re
import unittest
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parent.parent


class TestReleaseWorkflow(unittest.TestCase):
def test_publish_docs_respects_false_input(self):
workflow = REPO_ROOT / ".github" / "workflows" / "release.yml"
text = workflow.read_text()
match = re.search(r"^\s+publish-docs:\s*(.+)$", text, re.MULTILINE)
self.assertIsNotNone(match)
self.assertNotIn("|| true", match.group(1),
"publish-docs always evaluates to true; false input is ignored")

Loading