Skip to content

Commit bf6b107

Browse files
committed
Merge branch 'codex/pr16158-rewrite/01-encoder-foundations' of github.com:NVIDIA-NeMo/Speech into codex/pr16158-rewrite/01-encoder-foundations
2 parents 63b23a3 + 55587b3 commit bf6b107

1,684 files changed

Lines changed: 13077 additions & 2500 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.flake8.other

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ select =
66
F401, # 'x' imported but unused
77
E741, # ambiguous variable name 'l'
88
F821, # undefined name 'x'
9-
E266, # too many leading '#' for block comment
9+
E266, # too many leading '#' for block comment
10+
# Package initializers intentionally re-export public APIs.
11+
per-file-ignores =
12+
__init__.py: F401

.flake8.speech

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ select =
77
E741, # ambiguous variable name 'l'
88
F821, # undefined name 'x'
99
E266, # too many leading '#' for block comment
10+
# Package initializers intentionally re-export public APIs.
11+
per-file-ignores =
12+
__init__.py: F401

.github/actions/test-template/action.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# Copyright (c) 2025, NVIDIA CORPORATION.
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES.
2+
# SPDX-License-Identifier: Apache-2.0
23
#
34
# Licensed under the Apache License, Version 2.0 (the "License");
45
# you may not use this file except in compliance with the License.

.github/scripts/notify.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# Copyright (c) 2025, NVIDIA CORPORATION.
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES.
2+
# SPDX-License-Identifier: Apache-2.0
23
#
34
# Licensed under the Apache License, Version 2.0 (the "License");
45
# you may not use this file except in compliance with the License.
Lines changed: 16 additions & 226 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
23
#
34
# Licensed under the Apache License, Version 2.0 (the "License");
45
# you may not use this file except in compliance with the License.
@@ -16,238 +17,27 @@ name: Approve Test Queue
1617

1718
on:
1819
schedule:
19-
- cron: '*/5 * * * *' # Runs every 5 minutes
20+
- cron: "*/5 * * * *"
2021
# Scheduled events can be delayed, so refill released queue slots immediately.
2122
workflow_run:
2223
workflows: ["CICD NeMo"]
2324
types: [completed]
24-
workflow_dispatch: # Allows manual triggering
25+
workflow_dispatch:
2526

2627
concurrency:
2728
group: approve-test-queue
2829
cancel-in-progress: false
2930

3031
jobs:
31-
approve-queue:
32-
runs-on: ubuntu-latest
33-
environment: main
34-
steps:
35-
- name: Checkout repository
36-
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
37-
38-
- name: Set up Python
39-
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
40-
with:
41-
python-version: "3.12"
42-
43-
- name: Install dependencies
44-
run: |
45-
python -m pip install --upgrade pip
46-
pip install requests
47-
48-
- name: Approve waiting deployments
49-
env:
50-
GITHUB_TOKEN: ${{ secrets.PAT }}
51-
MAX_CONCURRENCY: ${{ vars.MAX_CONCURRENCY || 1 }}
52-
run: |
53-
python - <<EOF
54-
import os
55-
import requests
56-
57-
58-
# GitHub API configuration
59-
GITHUB_TOKEN = os.environ["GITHUB_TOKEN"]
60-
REPO = os.environ["GITHUB_REPOSITORY"]
61-
MAX_CONCURRENCY = int(os.environ["MAX_CONCURRENCY"])
62-
API_BASE = f"https://api.github.com/repos/{REPO}"
63-
64-
# Headers for GitHub API
65-
headers = {
66-
"Authorization": f"token {GITHUB_TOKEN}",
67-
"Accept": "application/vnd.github.v3+json",
68-
"X-GitHub-Api-Version": "2022-11-28",
69-
}
70-
71-
def make_request(endpoint, method="GET", data=None, allow_no_pending_deployments=False):
72-
"""Make a request to the GitHub API with error handling."""
73-
url = f"{API_BASE}/{endpoint}"
74-
try:
75-
if method == "GET":
76-
response = requests.get(url, headers=headers)
77-
else:
78-
response = requests.post(url, headers=headers, json=data)
79-
response.raise_for_status()
80-
response_json = response.json()
81-
if hasattr(response, "links") and "actions/runs?status" in endpoint:
82-
response_json["next"] = response.links.get("next", {}).get("url")
83-
84-
return response_json
85-
except requests.exceptions.HTTPError as e:
86-
if (
87-
allow_no_pending_deployments
88-
and e.response is not None
89-
and e.response.status_code == 422
90-
):
91-
try:
92-
response_json = e.response.json()
93-
except ValueError:
94-
response_json = {}
95-
if "No pending deployment requests to approve or reject" in str(response_json.get("errors", "")):
96-
print(f"No pending deployment requests remain for {endpoint}; skipping")
97-
return {"skipped": True, "reason": "no_pending_deployments"}
98-
99-
print(f"Error making request to {endpoint}: {str(e)}")
100-
if e.response is not None:
101-
print(f"Response: {e.response.text}")
102-
return None
103-
except requests.exceptions.RequestException as e:
104-
print(f"Error making request to {endpoint}: {str(e)}")
105-
if e.response is not None:
106-
print(f"Response: {e.response.text}")
107-
return None
108-
109-
110-
def get_workflow_runs(status):
111-
"""Get all workflow runs for a given status."""
112-
all_results = []
113-
endpoint = f"actions/runs?status={status}"
114-
while endpoint:
115-
response = make_request(endpoint)
116-
if not response:
117-
break
118-
119-
all_results.extend(response.get("workflow_runs", []))
120-
endpoint = None
121-
next_url = response.get("next")
122-
if next_url:
123-
endpoint = f"actions/runs?{next_url.split('?')[1]}"
124-
125-
return all_results
126-
127-
128-
def filter_cicd_runs(workflow_runs):
129-
"""Keep only CICD workflow runs."""
130-
return [run for run in workflow_runs if run.get("name") == "CICD NeMo"]
131-
132-
133-
def print_workflow_run_details(label, workflow_runs):
134-
"""Print the runs that are counted against concurrency."""
135-
if not workflow_runs:
136-
print(f"{label}: none")
137-
return
138-
139-
print(f"{label}:")
140-
for run in workflow_runs:
141-
print(
142-
" "
143-
f"id={run.get('id')} "
144-
f"status={run.get('status')} "
145-
f"branch={run.get('head_branch')} "
146-
f"title={run.get('display_title')}"
147-
)
148-
149-
150-
# Get current running and queued workflows
151-
print("Fetching workflow runs...")
152-
queued_workflow_runs = filter_cicd_runs(get_workflow_runs("queued"))
153-
in_progress_workflow_runs = filter_cicd_runs(get_workflow_runs("in_progress"))
154-
print_workflow_run_details("Queued CICD workflows counted against concurrency", queued_workflow_runs)
155-
print_workflow_run_details("Running CICD workflows counted against concurrency", in_progress_workflow_runs)
156-
157-
# Count running and queued workflows
158-
queued_workflows = len(queued_workflow_runs)
159-
in_progress_workflows = len(in_progress_workflow_runs)
160-
161-
total_workflows = queued_workflows + in_progress_workflows
162-
print(f"Current queued workflows: {queued_workflows}")
163-
print(f"Current running workflows: {in_progress_workflows}")
164-
print(f"Total workflows: {total_workflows}")
165-
print(f"Max concurrency: {MAX_CONCURRENCY}")
166-
167-
if total_workflows >= MAX_CONCURRENCY:
168-
print("Maximum concurrency reached, no new approvals will be made")
169-
exit(0)
170-
171-
# Get waiting CI workflows for test environment
172-
print("Fetching deployments...")
173-
pending_workflows = filter_cicd_runs(get_workflow_runs("waiting"))
174-
175-
# Sort deployments by creation date (oldest first)
176-
print("Sorting workflows...")
177-
pending_workflows = sorted(pending_workflows, key=lambda x: x.get("created_at", ""))
178-
179-
# Process each deployment
180-
print("Processing ...")
181-
for workflow in pending_workflows:
182-
if total_workflows >= MAX_CONCURRENCY:
183-
print("Maximum concurrency reached, stopping approvals")
184-
break
185-
186-
workflow_id = workflow.get("id")
187-
workflow_name = workflow.get("display_title") or workflow.get("name") or "<unknown>"
188-
if not workflow_id:
189-
print(f"Skipping workflow without a run id: {workflow_name}")
190-
continue
191-
print(f"Approving workflow {workflow_name} with Run Id: {workflow_id}")
192-
193-
deployment_url = f"actions/runs/{workflow_id}/pending_deployments"
194-
pending_deployments = make_request(deployment_url)
195-
if not pending_deployments:
196-
print(f"No pending deployments found for workflow {workflow_name}; skipping")
197-
continue
198-
199-
environment_ids = []
200-
environment_names = []
201-
for deployment in pending_deployments:
202-
environment = deployment.get("environment") or {}
203-
environment_id = environment.get("id")
204-
environment_name = environment.get("name") or "<unknown>"
205-
if not environment_id:
206-
print(f"Skipping deployment without an environment id for workflow {workflow_name}")
207-
continue
208-
209-
environment_ids.append(environment_id)
210-
environment_names.append(environment_name)
211-
212-
if not environment_ids:
213-
print(f"No pending deployments with environment ids found for workflow {workflow_name}")
214-
exit(1)
215-
216-
# Approve the deployment
217-
status_data = {
218-
"environment_ids": environment_ids,
219-
"state": "approved",
220-
"comment": "Automatically approved by queue manager"
221-
}
222-
result = make_request(
223-
deployment_url,
224-
method="POST",
225-
data=status_data,
226-
allow_no_pending_deployments=True,
227-
)
228-
229-
if result is None:
230-
print(f"Failed to approve environments {environment_names} for workflow {workflow_name}")
231-
exit(1)
232-
if isinstance(result, dict) and result.get("skipped"):
233-
continue
234-
235-
total_workflows += 1
236-
237-
EOF
238-
notify:
239-
if: failure()
240-
runs-on: ubuntu-latest
241-
needs: [approve-queue]
242-
steps:
243-
- name: Notify
244-
env:
245-
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
246-
SLACK_WEBHOOK_ADMIN: <!subteam^${{ secrets.SLACK_WEBHOOK_ADMIN }}>
247-
GITHUB_RUN_ID: ${{ github.run_id }}
248-
GITHUB_REPOSITORY: ${{ github.repository }}
249-
run: |
250-
curl -X POST \
251-
-H 'Content-type: application/json' \
252-
--data "{\"text\":\":robot_joy: <https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}|Test-queue-approval-bot workflow> failed. Please review manually.\n\ncc ${SLACK_WEBHOOK_ADMIN}\"}" \
253-
$SLACK_WEBHOOK
32+
approve-test-queue:
33+
if: github.repository == 'NVIDIA-NeMo/Speech'
34+
uses: NVIDIA-NeMo/FW-CI-templates/.github/workflows/_test_approval_queue.yml@f07495d7a01aad5578a407db8e0c4f4e395375f6 # v1.9.1
35+
with:
36+
workflow_name: CICD NeMo
37+
max_concurrency_internal: ${{ fromJSON(vars.MAX_CONCURRENCY || '1') }}
38+
max_concurrency_external: ${{ fromJSON(vars.MAX_CONCURRENCY || '1') }}
39+
secrets:
40+
PAT: ${{ secrets.PAT }}
41+
NVIDIA_MANAGEMENT_ORG_PAT: ${{ secrets.NVIDIA_MANAGEMENT_ORG_PAT }}
42+
SLACK_CI_CHANNEL_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
43+
SLACK_TEAM_GROUP_ID: ${{ secrets.SLACK_WEBHOOK_ADMIN }}

.github/workflows/cicd-main-speech.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# Copyright (c) 2025, NVIDIA CORPORATION.
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES.
2+
# SPDX-License-Identifier: Apache-2.0
23
#
34
# Licensed under the Apache License, Version 2.0 (the "License");
45
# you may not use this file except in compliance with the License.

.github/workflows/cicd-main-unit-tests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# Copyright (c) 2025, NVIDIA CORPORATION.
1+
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES.
2+
# SPDX-License-Identifier: Apache-2.0
23
#
34
# Licensed under the Apache License, Version 2.0 (the "License");
45
# you may not use this file except in compliance with the License.

0 commit comments

Comments
 (0)