From f92aef4fb3ba5e147fc6c1efd8643495934b7973 Mon Sep 17 00:00:00 2001 From: "M. Chornyi" <99709299+mc-nv@users.noreply.github.com> Date: Fri, 17 Jul 2026 16:59:44 -0700 Subject: [PATCH 01/18] ci: add centralized add-spdx-license hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tools/add_spdx_header.py as a centralized pre-commit hook that migrates each source file to the two-line SPDX header the first time it is touched (maintain / migrate legacy NVIDIA BSD header / insert). Exclude .github/ from add-license so GitHub issue/PR templates keep their YAML frontmatter first. Make add-license read the LICENSE file without rewriting its copyright year — consumer repos' LICENSE files must never be modified by hooks. Requires tagging v0.2.0 after merge. Also align this repository with the shared pre-commit baseline and GitHub templates. TRI-1100 --- .github/ISSUE_TEMPLATE/bug_report.md | 24 ++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 +++ .github/pull_request_template.md | 23 ++++ .github/workflows/pre-commit.yml | 27 +--- .pre-commit-config.yaml | 45 +++--- .pre-commit-hooks.yaml | 38 ++---- tools/add_copyright.py | 38 +----- tools/add_spdx_header.py | 159 ++++++++++++++++++++++ 8 files changed, 267 insertions(+), 107 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/pull_request_template.md create mode 100755 tools/add_spdx_header.py diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..df06a0e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,24 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Description** +A clear and concise description of what the bug is. + +**Triton Information** +What version of Triton are you using? + +Are you using the Triton container or did you build it yourself? + +**To Reproduce** +Steps to reproduce the behavior. + +Describe the models (framework, inputs, outputs), ideally include the model configuration file (if using an ensemble include the model configuration file for that as well). + +**Expected behavior** +A clear and concise description of what you expected to happen. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..2671e4e --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,23 @@ + + +#### What does the PR do? + + +#### Related Issues / PRs + + +#### Test plan + + +#### Caveats + + +#### Checklist +- [ ] PR title follows `: ` (conventional commit — enforced by the `conventional-pre-commit` hook) +- [ ] I ran `pre-commit install && pre-commit run --all-files` locally and it passes +- [ ] Copyright header is correct on all changed files +- [ ] External contributors: I have read the [Contribution guidelines](../CONTRIBUTING.md) and signed the [Contributor License Agreement](https://github.com/NVIDIA/triton-inference-server/blob/master/Triton-CCLA-v1.pdf) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 4dbce6b..e52c546 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -1,28 +1,5 @@ -# Copyright 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of NVIDIA CORPORATION nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# SPDX-FileCopyrightText: Copyright (c) 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause name: pre-commit diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 95efd68..31a22ec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,28 +1,7 @@ -# Copyright 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of NVIDIA CORPORATION nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# SPDX-FileCopyrightText: Copyright (c) 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause + +default_install_hook_types: [pre-commit, commit-msg] repos: - repo: https://github.com/PyCQA/isort @@ -54,6 +33,15 @@ repos: additional_dependencies: [tomli] args: ["--toml", "pyproject.toml"] exclude: (?x)^(.*stemmer.*|.*stop_words.*|^CHANGELOG.md$) +# Validates commit messages against the Conventional Commits format +# (<commit_type>: <title>). Replaces the manual commit-type checklist that +# used to live in the PR template. +- repo: https://github.com/compilerla/conventional-pre-commit + rev: v4.4.0 + hooks: + - id: conventional-pre-commit + stages: [commit-msg] + args: [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] # More details about these pre-commit hooks here: # https://pre-commit.com/hooks.html - repo: https://github.com/pre-commit/pre-commit-hooks @@ -73,6 +61,11 @@ repos: - id: trailing-whitespace - repo: https://github.com/triton-inference-server/developer_tools - rev: v0.1.0 + rev: v0.2.0 hooks: - id: add-license + # Incremental SPDX-header adoption: migrates each source file to the + # two-line SPDX header the first time it is touched. pre-commit runs hooks + # only on the files staged in a commit, so this rolls SPDX out gradually + # as files change. + - id: add-spdx-license diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index cb55ba6..7aad914 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,28 +1,5 @@ -# Copyright 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of NVIDIA CORPORATION nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause - id: add-license name: Add License @@ -31,3 +8,14 @@ stages: [pre-commit] verbose: true require_serial: true + # GitHub issue/PR templates must start with YAML frontmatter; keep + # license headers out of them. + exclude: ^\.github/ +- id: add-spdx-license + name: Add SPDX License Header + entry: tools/add_spdx_header.py + language: script + files: \.(py|pyi|sh|bash|yaml|yml|cc|cpp|cxx|h|hpp|cu|cuh)$ + stages: [pre-commit] + verbose: true + require_serial: true diff --git a/tools/add_copyright.py b/tools/add_copyright.py index 4e911eb..a3bccce 100755 --- a/tools/add_copyright.py +++ b/tools/add_copyright.py @@ -1,29 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of NVIDIA CORPORATION nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause import argparse import os import re @@ -90,15 +67,14 @@ def update_copyright_year( f.write(updated_content) -def update_and_get_license(license_path: Optional[str] = None) -> str: +def get_license(license_path: Optional[str] = None) -> str: """ - Updates the copyright year in the LICENSE file if necessary and then - returns its contents. + Returns the contents of the LICENSE file. - Note: LICENSE file maintains a year range if it has an older starting year. + Note: The LICENSE file itself is never modified by this hook; its + copyright year is maintained manually by each repository. """ license_path = license_path or get_license_path() - update_copyright_year(license_path) with open(license_path, "r") as license_file: return license_file.read() @@ -106,7 +82,7 @@ def update_and_get_license(license_path: Optional[str] = None) -> str: def load_license_text() -> None: global LICENSE_TEXT - LICENSE_TEXT = update_and_get_license() + LICENSE_TEXT = get_license() # diff --git a/tools/add_spdx_header.py b/tools/add_spdx_header.py new file mode 100755 index 0000000..70b1fd2 --- /dev/null +++ b/tools/add_spdx_header.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +# SPDX-FileCopyrightText: Copyright (c) 2018-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause + +"""Insert / maintain / migrate to an SPDX license header on source files. + +Pre-commit hook that adopts the two-line SPDX header on every file it is run +against. Because pre-commit runs hooks on the files staged in a commit, scoping +this hook by file type (rather than by directory) migrates each source file to +SPDX *the first time it is touched* -- a low-risk, incremental rollout. + +The header uses a copyright *year range*, mirroring the repo convention (the +``LICENSE`` file and ``add_copyright.py`` use ``<start>-<current>``):: + + # SPDX-FileCopyrightText: Copyright (c) 2018-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + # SPDX-License-Identifier: BSD-3-Clause + +Per file, the hook does exactly one of: + +* **Maintain** -- already SPDX: bump the copyright end year to the current year. +* **Migrate** -- carries the legacy long-form NVIDIA BSD header: replace that + whole block in place with the two SPDX lines, preserving the comment style + (``#`` or ``//``), the shebang, and the block's start year. +* **Insert** -- no NVIDIA header: add the SPDX header (after a shebang if any). + +Idempotent, and coexists with ``add_copyright.py`` (which runs first and only +maintains the copyright year on the legacy/SPDX string it recognizes). +""" + +import os +import re +import sys +from datetime import datetime + +# Centralized hook: runs with cwd = consumer repo root, so resolve +# the LICENSE of the repository being committed to, not this one. +LICENSE_PATH = os.path.join(os.getcwd(), "LICENSE") +CURRENT_YEAR = str(datetime.now().year) + +_SPDX_MARKER = "SPDX-License-Identifier" +_LICENSE_ID = "BSD-3-Clause" + +# Start year of the project-wide LICENSE (used only when inserting into a file +# that has no NVIDIA copyright at all). +_LICENSE_YEAR_PAT = re.compile(r"Copyright \(c\) (\d{4})(?:-\d{4})?, NVIDIA") +# Existing SPDX copyright line (for year maintenance). +_SPDX_YEAR_PAT = re.compile( + r"(SPDX-FileCopyrightText: Copyright \(c\) )(\d{4})(?:-\d{4})?(, NVIDIA)" +) +# First line of a legacy long-form NVIDIA BSD header (captures comment prefix + +# start year). The block ends at the standard BSD "SUCH DAMAGE" line. +_LEGACY_COPY_PAT = re.compile( + r"^(#|//) ?Copyright(?: \(c\))? (\d{4})(?:-\d{4})?,? NVIDIA CORPORATION" +) +_LEGACY_END_MARK = "POSSIBILITY OF SUCH DAMAGE" + +_CPP_EXTS = (".cc", ".cpp", ".cxx", ".h", ".hpp", ".cu", ".cuh") + + +def _year_range(start): + return start if start == CURRENT_YEAR else "{}-{}".format(start, CURRENT_YEAR) + + +def _license_start_year(): + try: + with open(LICENSE_PATH, "r", encoding="utf-8") as f: + match = _LICENSE_YEAR_PAT.search(f.read()) + if match: + return match.group(1) + except OSError: + # LICENSE not readable here; fall through to the current-year default. + pass + return CURRENT_YEAR + + +def _spdx_lines(prefix, years): + return ( + "{p} SPDX-FileCopyrightText: Copyright (c) {y}, NVIDIA CORPORATION " + "& AFFILIATES. All rights reserved.\n" + "{p} SPDX-License-Identifier: {lic}\n".format( + p=prefix, y=years, lic=_LICENSE_ID + ) + ) + + +def _maintain(content): + def _bump(match): + return match.group(1) + _year_range(match.group(2)) + match.group(3) + + return _SPDX_YEAR_PAT.sub(_bump, content) + + +def _migrate_legacy(content): + """Replace a legacy long-form NVIDIA BSD header with the SPDX lines. Returns + the new content, or None if no legacy header is found.""" + lines = content.splitlines(keepends=True) + start = prefix = start_year = None + for i, line in enumerate(lines): + match = _LEGACY_COPY_PAT.match(line) + if match: + start, prefix, start_year = i, match.group(1), match.group(2) + break + if start is None: + return None + end = None + for j in range(start, len(lines)): + if _LEGACY_END_MARK in lines[j]: + end = j + break + if end is None: + return None + header = _spdx_lines(prefix, _year_range(start_year)) + return "".join(lines[:start]) + header + "".join(lines[end + 1 :]) + + +def _insert(path, content): + prefix = "//" if path.endswith(_CPP_EXTS) else "#" + header = _spdx_lines(prefix, _year_range(_license_start_year())) + "\n" + lines = content.splitlines(keepends=True) + if lines and lines[0].startswith("#!"): + return lines[0] + header + "".join(lines[1:]) + return header + content + + +def process(path): + """Bring ``path`` to an SPDX header (maintain/migrate/insert). Returns True if + the file was modified.""" + try: + with open(path, "r", encoding="utf-8") as f: + content = f.read() + except (OSError, UnicodeDecodeError): + return False + + if _SPDX_MARKER in content: + updated = _maintain(content) + else: + updated = _migrate_legacy(content) + if updated is None: + updated = _insert(path, content) + + if updated == content: + return False + with open(path, "w", encoding="utf-8") as f: + f.write(updated) + return True + + +def main(argv): + changed = False + for path in argv[1:]: + if process(path): + print("Updated SPDX header: {}".format(path)) + changed = True + # Non-zero exit tells pre-commit the file was modified so it re-stages. + return 1 if changed else 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) From bef38e65e6ad534dea77274a33131df6a24acb38 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Fri, 17 Jul 2026 17:59:22 -0700 Subject: [PATCH 02/18] ci: run in-tree hook versions in this repo's own pre-commit config CI here must validate the hook code being merged rather than an already-published tag; consumer repositories keep referencing rev: v0.2.0. TRI-1100 --- .pre-commit-config.yaml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 31a22ec..4ceaa41 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -60,12 +60,30 @@ repos: - id: requirements-txt-fixer - id: trailing-whitespace -- repo: https://github.com/triton-inference-server/developer_tools - rev: v0.2.0 +# This repository defines the centralized hooks; run the in-tree versions +# directly so CI validates the hook code being merged. Consumer repositories +# reference these via `repo: .../developer_tools` + `rev: v0.2.0` instead. +- repo: local hooks: - id: add-license + name: Add License + entry: tools/add_copyright.py + language: script + stages: [pre-commit] + verbose: true + require_serial: true + # GitHub issue/PR templates must start with YAML frontmatter; keep + # license headers out of them. + exclude: ^\.github/ # Incremental SPDX-header adoption: migrates each source file to the # two-line SPDX header the first time it is touched. pre-commit runs hooks # only on the files staged in a commit, so this rolls SPDX out gradually # as files change. - id: add-spdx-license + name: Add SPDX License Header + entry: tools/add_spdx_header.py + language: script + files: \.(py|pyi|sh|bash|yaml|yml|cc|cpp|cxx|h|hpp|cu|cuh)$ + stages: [pre-commit] + verbose: true + require_serial: true From 0060976e83ccac6338392bfc49883f45a74617ea Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Fri, 17 Jul 2026 18:31:54 -0700 Subject: [PATCH 03/18] chore: align SPDX copyright text with NVIDIA Legal boilerplate Legal's Copyright / License Header Guidance specifies the SPDX form without a comma after the year: SPDX-FileCopyrightText: Copyright (c) <year> NVIDIA CORPORATION & AFFILIATES. All rights reserved. Emit that form from add_spdx_header.py, keep both hooks tolerant of the legacy comma variant, and normalize the headers introduced by this change. TRI-1100 --- .github/pull_request_template.md | 2 +- .github/workflows/pre-commit.yml | 2 +- .pre-commit-config.yaml | 2 +- .pre-commit-hooks.yaml | 2 +- tools/add_copyright.py | 11 ++++++++--- tools/add_spdx_header.py | 10 +++++----- 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2671e4e..3de2b78 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,5 @@ <!-- -SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: BSD-3-Clause --> diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index e52c546..2210ecb 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2023-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: BSD-3-Clause name: pre-commit diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4ceaa41..db04008 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2023-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: BSD-3-Clause default_install_hook_types: [pre-commit, commit-msg] diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 7aad914..e6461e1 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: BSD-3-Clause - id: add-license diff --git a/tools/add_copyright.py b/tools/add_copyright.py index a3bccce..d96a78c 100755 --- a/tools/add_copyright.py +++ b/tools/add_copyright.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: BSD-3-Clause import argparse import os @@ -12,7 +12,7 @@ current_year = str(datetime.now().year) COPYRIGHT_YEAR_PAT = re.compile( - r"Copyright( \(c\))? (\d{4})?-?(\d{4}), NVIDIA CORPORATION" + r"Copyright( \(c\))? (\d{4})?-?(\d{4})(,?) NVIDIA CORPORATION" ) LICENSE_TEXT = "" @@ -58,7 +58,7 @@ def update_copyright_year( new_copyright += f"{min_year}-{current_year}" else: new_copyright += f"{current_year}" - new_copyright += ", NVIDIA CORPORATION" + new_copyright += f"{match.groups()[3]} NVIDIA CORPORATION" updated_content = COPYRIGHT_YEAR_PAT.sub(new_copyright, content) @@ -347,6 +347,11 @@ def make_copyright_text(text): make_copyright_text("(c) 2018-2023, NVIDIA CORPORATION"), make_copyright_text(f"(c) 2018-{current_year}, NVIDIA CORPORATION"), ), + # Comma-less (Legal-standard SPDX boilerplate) form is preserved: + ( + make_copyright_text("(c) 2018 NVIDIA CORPORATION"), + make_copyright_text(f"(c) 2018-{current_year} NVIDIA CORPORATION"), + ), ], ) def test_copyright_update(content, expected): diff --git a/tools/add_spdx_header.py b/tools/add_spdx_header.py index 70b1fd2..f6054da 100755 --- a/tools/add_spdx_header.py +++ b/tools/add_spdx_header.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Copyright (c) 2018-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2018-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: BSD-3-Clause """Insert / maintain / migrate to an SPDX license header on source files. @@ -12,7 +12,7 @@ The header uses a copyright *year range*, mirroring the repo convention (the ``LICENSE`` file and ``add_copyright.py`` use ``<start>-<current>``):: - # SPDX-FileCopyrightText: Copyright (c) 2018-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + # SPDX-FileCopyrightText: Copyright (c) 2018-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: BSD-3-Clause Per file, the hook does exactly one of: @@ -42,10 +42,10 @@ # Start year of the project-wide LICENSE (used only when inserting into a file # that has no NVIDIA copyright at all). -_LICENSE_YEAR_PAT = re.compile(r"Copyright \(c\) (\d{4})(?:-\d{4})?, NVIDIA") +_LICENSE_YEAR_PAT = re.compile(r"Copyright \(c\) (\d{4})(?:-\d{4})?,? NVIDIA") # Existing SPDX copyright line (for year maintenance). _SPDX_YEAR_PAT = re.compile( - r"(SPDX-FileCopyrightText: Copyright \(c\) )(\d{4})(?:-\d{4})?(, NVIDIA)" + r"(SPDX-FileCopyrightText: Copyright \(c\) )(\d{4})(?:-\d{4})?(,? NVIDIA)" ) # First line of a legacy long-form NVIDIA BSD header (captures comment prefix + # start year). The block ends at the standard BSD "SUCH DAMAGE" line. @@ -75,7 +75,7 @@ def _license_start_year(): def _spdx_lines(prefix, years): return ( - "{p} SPDX-FileCopyrightText: Copyright (c) {y}, NVIDIA CORPORATION " + "{p} SPDX-FileCopyrightText: Copyright (c) {y} NVIDIA CORPORATION " "& AFFILIATES. All rights reserved.\n" "{p} SPDX-License-Identifier: {lic}\n".format( p=prefix, y=years, lic=_LICENSE_ID From c2f2363bd70596c1c467c536facd0e3631433737 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Fri, 17 Jul 2026 22:58:22 -0700 Subject: [PATCH 04/18] ci: drop the add-spdx-license hook, keep add-license hardening Remove tools/add_spdx_header.py and its hook definition. The add-license hook keeps the two fixes: .github/ is excluded so GitHub issue/PR templates retain their YAML frontmatter first, and the consumer repo's LICENSE file is read without ever being rewritten. TRI-1100 --- .github/pull_request_template.md | 5 - .github/workflows/pre-commit.yml | 27 ++- .pre-commit-config.yaml | 43 +++-- .pre-commit-hooks.yaml | 35 ++-- ...add_copyright.cpython-312-pytest-9.1.1.pyc | Bin 0 -> 17709 bytes tools/add_copyright.py | 36 +++- tools/add_spdx_header.py | 159 ------------------ 7 files changed, 104 insertions(+), 201 deletions(-) create mode 100644 tools/__pycache__/add_copyright.cpython-312-pytest-9.1.1.pyc delete mode 100755 tools/add_spdx_header.py diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 3de2b78..a79d3bd 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,8 +1,3 @@ -<!-- -SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -SPDX-License-Identifier: BSD-3-Clause ---> - #### What does the PR do? <!-- Describe the change and the motivation behind it. --> diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 2210ecb..15d0b68 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -1,5 +1,28 @@ -# SPDX-FileCopyrightText: Copyright (c) 2023-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2023-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of NVIDIA CORPORATION nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. name: pre-commit diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index db04008..0ae189a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,28 @@ -# SPDX-FileCopyrightText: Copyright (c) 2023-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of NVIDIA CORPORATION nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. default_install_hook_types: [pre-commit, commit-msg] @@ -60,9 +83,9 @@ repos: - id: requirements-txt-fixer - id: trailing-whitespace -# This repository defines the centralized hooks; run the in-tree versions +# This repository defines the centralized hooks; run the in-tree version # directly so CI validates the hook code being merged. Consumer repositories -# reference these via `repo: .../developer_tools` + `rev: v0.2.0` instead. +# reference it via `repo: .../developer_tools` + `rev: v0.2.0` instead. - repo: local hooks: - id: add-license @@ -75,15 +98,3 @@ repos: # GitHub issue/PR templates must start with YAML frontmatter; keep # license headers out of them. exclude: ^\.github/ - # Incremental SPDX-header adoption: migrates each source file to the - # two-line SPDX header the first time it is touched. pre-commit runs hooks - # only on the files staged in a commit, so this rolls SPDX out gradually - # as files change. - - id: add-spdx-license - name: Add SPDX License Header - entry: tools/add_spdx_header.py - language: script - files: \.(py|pyi|sh|bash|yaml|yml|cc|cpp|cxx|h|hpp|cu|cuh)$ - stages: [pre-commit] - verbose: true - require_serial: true diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index e6461e1..fef4d8a 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -1,5 +1,28 @@ -# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of NVIDIA CORPORATION nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - id: add-license name: Add License @@ -11,11 +34,3 @@ # GitHub issue/PR templates must start with YAML frontmatter; keep # license headers out of them. exclude: ^\.github/ -- id: add-spdx-license - name: Add SPDX License Header - entry: tools/add_spdx_header.py - language: script - files: \.(py|pyi|sh|bash|yaml|yml|cc|cpp|cxx|h|hpp|cu|cuh)$ - stages: [pre-commit] - verbose: true - require_serial: true diff --git a/tools/__pycache__/add_copyright.cpython-312-pytest-9.1.1.pyc b/tools/__pycache__/add_copyright.cpython-312-pytest-9.1.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2311c15a5e3eec77baf6cee920357e01af3d91e GIT binary patch literal 17709 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 W18(K{6a1<l#TBh6T2aBY+5ZDrwF!Ly literal 0 HcmV?d00001 diff --git a/tools/add_copyright.py b/tools/add_copyright.py index d96a78c..c58fd81 100755 --- a/tools/add_copyright.py +++ b/tools/add_copyright.py @@ -1,6 +1,29 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of NVIDIA CORPORATION nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import os import re @@ -12,7 +35,7 @@ current_year = str(datetime.now().year) COPYRIGHT_YEAR_PAT = re.compile( - r"Copyright( \(c\))? (\d{4})?-?(\d{4})(,?) NVIDIA CORPORATION" + r"Copyright( \(c\))? (\d{4})?-?(\d{4}), NVIDIA CORPORATION" ) LICENSE_TEXT = "" @@ -58,7 +81,7 @@ def update_copyright_year( new_copyright += f"{min_year}-{current_year}" else: new_copyright += f"{current_year}" - new_copyright += f"{match.groups()[3]} NVIDIA CORPORATION" + new_copyright += ", NVIDIA CORPORATION" updated_content = COPYRIGHT_YEAR_PAT.sub(new_copyright, content) @@ -347,11 +370,6 @@ def make_copyright_text(text): make_copyright_text("(c) 2018-2023, NVIDIA CORPORATION"), make_copyright_text(f"(c) 2018-{current_year}, NVIDIA CORPORATION"), ), - # Comma-less (Legal-standard SPDX boilerplate) form is preserved: - ( - make_copyright_text("(c) 2018 NVIDIA CORPORATION"), - make_copyright_text(f"(c) 2018-{current_year} NVIDIA CORPORATION"), - ), ], ) def test_copyright_update(content, expected): diff --git a/tools/add_spdx_header.py b/tools/add_spdx_header.py deleted file mode 100755 index f6054da..0000000 --- a/tools/add_spdx_header.py +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-FileCopyrightText: Copyright (c) 2018-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: BSD-3-Clause - -"""Insert / maintain / migrate to an SPDX license header on source files. - -Pre-commit hook that adopts the two-line SPDX header on every file it is run -against. Because pre-commit runs hooks on the files staged in a commit, scoping -this hook by file type (rather than by directory) migrates each source file to -SPDX *the first time it is touched* -- a low-risk, incremental rollout. - -The header uses a copyright *year range*, mirroring the repo convention (the -``LICENSE`` file and ``add_copyright.py`` use ``<start>-<current>``):: - - # SPDX-FileCopyrightText: Copyright (c) 2018-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - # SPDX-License-Identifier: BSD-3-Clause - -Per file, the hook does exactly one of: - -* **Maintain** -- already SPDX: bump the copyright end year to the current year. -* **Migrate** -- carries the legacy long-form NVIDIA BSD header: replace that - whole block in place with the two SPDX lines, preserving the comment style - (``#`` or ``//``), the shebang, and the block's start year. -* **Insert** -- no NVIDIA header: add the SPDX header (after a shebang if any). - -Idempotent, and coexists with ``add_copyright.py`` (which runs first and only -maintains the copyright year on the legacy/SPDX string it recognizes). -""" - -import os -import re -import sys -from datetime import datetime - -# Centralized hook: runs with cwd = consumer repo root, so resolve -# the LICENSE of the repository being committed to, not this one. -LICENSE_PATH = os.path.join(os.getcwd(), "LICENSE") -CURRENT_YEAR = str(datetime.now().year) - -_SPDX_MARKER = "SPDX-License-Identifier" -_LICENSE_ID = "BSD-3-Clause" - -# Start year of the project-wide LICENSE (used only when inserting into a file -# that has no NVIDIA copyright at all). -_LICENSE_YEAR_PAT = re.compile(r"Copyright \(c\) (\d{4})(?:-\d{4})?,? NVIDIA") -# Existing SPDX copyright line (for year maintenance). -_SPDX_YEAR_PAT = re.compile( - r"(SPDX-FileCopyrightText: Copyright \(c\) )(\d{4})(?:-\d{4})?(,? NVIDIA)" -) -# First line of a legacy long-form NVIDIA BSD header (captures comment prefix + -# start year). The block ends at the standard BSD "SUCH DAMAGE" line. -_LEGACY_COPY_PAT = re.compile( - r"^(#|//) ?Copyright(?: \(c\))? (\d{4})(?:-\d{4})?,? NVIDIA CORPORATION" -) -_LEGACY_END_MARK = "POSSIBILITY OF SUCH DAMAGE" - -_CPP_EXTS = (".cc", ".cpp", ".cxx", ".h", ".hpp", ".cu", ".cuh") - - -def _year_range(start): - return start if start == CURRENT_YEAR else "{}-{}".format(start, CURRENT_YEAR) - - -def _license_start_year(): - try: - with open(LICENSE_PATH, "r", encoding="utf-8") as f: - match = _LICENSE_YEAR_PAT.search(f.read()) - if match: - return match.group(1) - except OSError: - # LICENSE not readable here; fall through to the current-year default. - pass - return CURRENT_YEAR - - -def _spdx_lines(prefix, years): - return ( - "{p} SPDX-FileCopyrightText: Copyright (c) {y} NVIDIA CORPORATION " - "& AFFILIATES. All rights reserved.\n" - "{p} SPDX-License-Identifier: {lic}\n".format( - p=prefix, y=years, lic=_LICENSE_ID - ) - ) - - -def _maintain(content): - def _bump(match): - return match.group(1) + _year_range(match.group(2)) + match.group(3) - - return _SPDX_YEAR_PAT.sub(_bump, content) - - -def _migrate_legacy(content): - """Replace a legacy long-form NVIDIA BSD header with the SPDX lines. Returns - the new content, or None if no legacy header is found.""" - lines = content.splitlines(keepends=True) - start = prefix = start_year = None - for i, line in enumerate(lines): - match = _LEGACY_COPY_PAT.match(line) - if match: - start, prefix, start_year = i, match.group(1), match.group(2) - break - if start is None: - return None - end = None - for j in range(start, len(lines)): - if _LEGACY_END_MARK in lines[j]: - end = j - break - if end is None: - return None - header = _spdx_lines(prefix, _year_range(start_year)) - return "".join(lines[:start]) + header + "".join(lines[end + 1 :]) - - -def _insert(path, content): - prefix = "//" if path.endswith(_CPP_EXTS) else "#" - header = _spdx_lines(prefix, _year_range(_license_start_year())) + "\n" - lines = content.splitlines(keepends=True) - if lines and lines[0].startswith("#!"): - return lines[0] + header + "".join(lines[1:]) - return header + content - - -def process(path): - """Bring ``path`` to an SPDX header (maintain/migrate/insert). Returns True if - the file was modified.""" - try: - with open(path, "r", encoding="utf-8") as f: - content = f.read() - except (OSError, UnicodeDecodeError): - return False - - if _SPDX_MARKER in content: - updated = _maintain(content) - else: - updated = _migrate_legacy(content) - if updated is None: - updated = _insert(path, content) - - if updated == content: - return False - with open(path, "w", encoding="utf-8") as f: - f.write(updated) - return True - - -def main(argv): - changed = False - for path in argv[1:]: - if process(path): - print("Updated SPDX header: {}".format(path)) - changed = True - # Non-zero exit tells pre-commit the file was modified so it re-stages. - return 1 if changed else 0 - - -if __name__ == "__main__": - sys.exit(main(sys.argv)) From 81c12bc6ecbde5da096686e1a392af1a952e4afd Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Fri, 17 Jul 2026 22:58:52 -0700 Subject: [PATCH 05/18] ci: drop the add-spdx-license hook, keep add-license hardening Remove tools/add_spdx_header.py and its hook definition. The add-license hook keeps the two fixes: .github/ is excluded so GitHub issue/PR templates retain their YAML frontmatter first, and the consumer repo's LICENSE file is read without ever being rewritten. TRI-1100 --- .../add_copyright.cpython-312-pytest-9.1.1.pyc | Bin 17709 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tools/__pycache__/add_copyright.cpython-312-pytest-9.1.1.pyc diff --git a/tools/__pycache__/add_copyright.cpython-312-pytest-9.1.1.pyc b/tools/__pycache__/add_copyright.cpython-312-pytest-9.1.1.pyc deleted file mode 100644 index e2311c15a5e3eec77baf6cee920357e01af3d91e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17709 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 W18(K{6a1<l#TBh6T2aBY+5ZDrwF!Ly From dd3aa7ae277e9670a910ae75b00087cac1e01dc0 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Fri, 17 Jul 2026 23:26:02 -0700 Subject: [PATCH 06/18] ci: route issue reporting to the server repository Issues for all Triton components are tracked in triton-inference-server/server; disable blank issues here and point the new-issue chooser at the server repository. TRI-1100 --- .github/ISSUE_TEMPLATE/bug_report.md | 24 ----------------------- .github/ISSUE_TEMPLATE/config.yml | 5 +++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ------------------- 3 files changed, 5 insertions(+), 44 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index df06a0e..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - -**Description** -A clear and concise description of what the bug is. - -**Triton Information** -What version of Triton are you using? - -Are you using the Triton container or did you build it yourself? - -**To Reproduce** -Steps to reproduce the behavior. - -Describe the models (framework, inputs, outputs), ideally include the model configuration file (if using an ensemble include the model configuration file for that as well). - -**Expected behavior** -A clear and concise description of what you expected to happen. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..1fb3f37 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Bug report or feature request + url: https://github.com/triton-inference-server/server/issues/new/choose + about: Please report issues for all Triton Inference Server components in the server repository. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bbcbbe7..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. From be0947794bce1dadd612fc5be5abdb7f7f15fde3 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Fri, 17 Jul 2026 23:30:49 -0700 Subject: [PATCH 07/18] ci: share the server repository's PR templates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adopt the canonical PR template set from triton-inference-server/server (default chooser plus internal/external contribution templates) so every repository presents the same PR experience. The manual "Commit Type" checkbox section is dropped — the conventional-pre-commit hook (commit-msg stage) enforces it automatically. TRI-1100 --- .../pull_request_template_external_contrib.md | 36 +++++++++++++++++++ .../pull_request_template_internal_contrib.md | 36 +++++++++++++++++++ .github/pull_request_template.md | 23 +++++------- 3 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template_external_contrib.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template_internal_contrib.md diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template_external_contrib.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template_external_contrib.md new file mode 100644 index 0000000..4a9e6b6 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template_external_contrib.md @@ -0,0 +1,36 @@ +#### What does the PR do? +<!-- Describe your pull request here. Please read the text below the line, and make sure you follow the checklist.--> + +#### Checklist +- [ ] I have read the [Contribution guidelines](#../../CONTRIBUTING.md) and signed the [Contributor License +Agreement](https://github.com/NVIDIA/triton-inference-server/blob/master/Triton-CCLA-v1.pdf) +- [ ] PR title reflects the change and is of format `<commit_type>: <Title>` +- [ ] Changes are described in the pull request. +- [ ] Related issues are referenced. +- [ ] Populated [github labels](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels) field +- [ ] Added [test plan](#test-plan) and verified test passes. +- [ ] Verified that the PR passes existing CI. +- [ ] I ran pre-commit locally (`pre-commit install, pre-commit run --all`) +- [ ] Verified copyright is correct on all changed files. +- [ ] Added _succinct_ git squash message before merging [ref](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). +- [ ] All template sections are filled out. +- [ ] Optional: Additional screenshots for behavior/output changes with before/after. + +#### Related PRs: +<!-- Related PRs from other Repositories --> + +#### Where should the reviewer start? +<!-- call out specific files that should be looked at closely --> + +#### Test plan: +<!-- list steps to verify feature works --> +<!-- were e2e tests added?--> + +#### Caveats: +<!-- any limitations or possible things missing from this PR --> + +#### Background +<!-- e.g. what led to this change being made. this is optional extra information to help the reviewer --> + +#### Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to) +- closes GitHub issue: #xxx diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template_internal_contrib.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template_internal_contrib.md new file mode 100644 index 0000000..42b1bb9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template_internal_contrib.md @@ -0,0 +1,36 @@ +#### What does the PR do? +<!-- Describe your pull request here. Please read the text below the line, and make sure you follow the checklist.--> + +#### Checklist +- [ ] PR title reflects the change and is of format `<commit_type>: <Title>` +- [ ] Changes are described in the pull request. +- [ ] Related issues are referenced. +- [ ] Populated [github labels](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels) field +- [ ] Added [test plan](#test-plan) and verified test passes. +- [ ] Verified that the PR passes existing CI. +- [ ] Verified copyright is correct on all changed files. +- [ ] Added _succinct_ git squash message before merging [ref](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). +- [ ] All template sections are filled out. +- [ ] Optional: Additional screenshots for behavior/output changes with before/after. + +#### Related PRs: +<!-- Related PRs from other Repositories --> + +#### Where should the reviewer start? +<!-- call out specific files that should be looked at closely --> + +#### Test plan: +<!-- list steps to verify --> +<!-- were e2e tests added?--> + +- CI Pipeline ID: +<!-- Only Pipeline ID and no direct link here --> + +#### Caveats: +<!-- any limitations or possible things missing from this PR --> + +#### Background +<!-- e.g. what led to this change being made. this is optional extra information to help the reviewer --> + +#### Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to) +- closes GitHub issue: #xxx diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a79d3bd..0787dcb 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,18 +1,13 @@ -#### What does the PR do? -<!-- Describe the change and the motivation behind it. --> +Thanks for submitting a PR to Triton! +Please go the the `Preview` tab above this description box and select the appropriate sub-template: -#### Related Issues / PRs -<!-- Use "Closes #xxx" / "Fixes #xxx" / "Resolves #xxx" for issues. - Link related PRs from other triton-inference-server repositories. --> +* [PR description template for Triton Engineers](?expand=1&template=pull_request_template_internal_contrib.md) +* [PR description template for External Contributors](?expand=1&template=pull_request_template_external_contrib.md) -#### Test plan -<!-- How was this change verified? List steps, tests added, or CI evidence. --> +If you already created the PR, please replace this message with one of +* [External contribution template](https://raw.githubusercontent.com/triton-inference-server/server/main/.github/PULL_REQUEST_TEMPLATE/pull_request_template_external_contrib.md) +* [Internal contribution template](https://raw.githubusercontent.com/triton-inference-server/server/main/.github/PULL_REQUEST_TEMPLATE/pull_request_template_internal_contrib.md) + +and fill it out. -#### Caveats -<!-- Optional: known limitations or follow-ups. --> -#### Checklist -- [ ] PR title follows `<commit_type>: <Title>` (conventional commit — enforced by the `conventional-pre-commit` hook) -- [ ] I ran `pre-commit install && pre-commit run --all-files` locally and it passes -- [ ] Copyright header is correct on all changed files -- [ ] External contributors: I have read the [Contribution guidelines](../CONTRIBUTING.md) and signed the [Contributor License Agreement](https://github.com/NVIDIA/triton-inference-server/blob/master/Triton-CCLA-v1.pdf) From 3c84d22a135f0dd3f4c611d258ee458d0533b358 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:46:14 -0700 Subject: [PATCH 08/18] ci: migrate the centralized add-license hook to the org .github repo The hook definition and tools/add_copyright.py move to triton-inference-server/.github (v1.0.0) so hooks, templates, and reusable workflows live under one roof. Existing consumers pinned to this repository's v0.x tags keep working - tags are immutable. Also aligns this repository with the shared baseline (conventional commit validation, modified-files pre-commit CI, org-wide templates, conventional-pr caller stub). TRI-1100 --- .github/ISSUE_TEMPLATE/config.yml | 5 - .../pull_request_template_external_contrib.md | 36 -- .../pull_request_template_internal_contrib.md | 36 -- .github/pull_request_template.md | 13 - .../workflows/conventional-pr.yml | 25 +- .pre-commit-config.yaml | 19 +- tools/add_copyright.py | 407 ------------------ 7 files changed, 19 insertions(+), 522 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template_external_contrib.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template_internal_contrib.md delete mode 100644 .github/pull_request_template.md rename .pre-commit-hooks.yaml => .github/workflows/conventional-pr.yml (76%) delete mode 100755 tools/add_copyright.py diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 1fb3f37..0000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,5 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Bug report or feature request - url: https://github.com/triton-inference-server/server/issues/new/choose - about: Please report issues for all Triton Inference Server components in the server repository. diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template_external_contrib.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template_external_contrib.md deleted file mode 100644 index 4a9e6b6..0000000 --- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template_external_contrib.md +++ /dev/null @@ -1,36 +0,0 @@ -#### What does the PR do? -<!-- Describe your pull request here. Please read the text below the line, and make sure you follow the checklist.--> - -#### Checklist -- [ ] I have read the [Contribution guidelines](#../../CONTRIBUTING.md) and signed the [Contributor License -Agreement](https://github.com/NVIDIA/triton-inference-server/blob/master/Triton-CCLA-v1.pdf) -- [ ] PR title reflects the change and is of format `<commit_type>: <Title>` -- [ ] Changes are described in the pull request. -- [ ] Related issues are referenced. -- [ ] Populated [github labels](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels) field -- [ ] Added [test plan](#test-plan) and verified test passes. -- [ ] Verified that the PR passes existing CI. -- [ ] I ran pre-commit locally (`pre-commit install, pre-commit run --all`) -- [ ] Verified copyright is correct on all changed files. -- [ ] Added _succinct_ git squash message before merging [ref](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). -- [ ] All template sections are filled out. -- [ ] Optional: Additional screenshots for behavior/output changes with before/after. - -#### Related PRs: -<!-- Related PRs from other Repositories --> - -#### Where should the reviewer start? -<!-- call out specific files that should be looked at closely --> - -#### Test plan: -<!-- list steps to verify feature works --> -<!-- were e2e tests added?--> - -#### Caveats: -<!-- any limitations or possible things missing from this PR --> - -#### Background -<!-- e.g. what led to this change being made. this is optional extra information to help the reviewer --> - -#### Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to) -- closes GitHub issue: #xxx diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template_internal_contrib.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template_internal_contrib.md deleted file mode 100644 index 42b1bb9..0000000 --- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template_internal_contrib.md +++ /dev/null @@ -1,36 +0,0 @@ -#### What does the PR do? -<!-- Describe your pull request here. Please read the text below the line, and make sure you follow the checklist.--> - -#### Checklist -- [ ] PR title reflects the change and is of format `<commit_type>: <Title>` -- [ ] Changes are described in the pull request. -- [ ] Related issues are referenced. -- [ ] Populated [github labels](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels) field -- [ ] Added [test plan](#test-plan) and verified test passes. -- [ ] Verified that the PR passes existing CI. -- [ ] Verified copyright is correct on all changed files. -- [ ] Added _succinct_ git squash message before merging [ref](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). -- [ ] All template sections are filled out. -- [ ] Optional: Additional screenshots for behavior/output changes with before/after. - -#### Related PRs: -<!-- Related PRs from other Repositories --> - -#### Where should the reviewer start? -<!-- call out specific files that should be looked at closely --> - -#### Test plan: -<!-- list steps to verify --> -<!-- were e2e tests added?--> - -- CI Pipeline ID: -<!-- Only Pipeline ID and no direct link here --> - -#### Caveats: -<!-- any limitations or possible things missing from this PR --> - -#### Background -<!-- e.g. what led to this change being made. this is optional extra information to help the reviewer --> - -#### Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to) -- closes GitHub issue: #xxx diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index 0787dcb..0000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,13 +0,0 @@ -Thanks for submitting a PR to Triton! -Please go the the `Preview` tab above this description box and select the appropriate sub-template: - -* [PR description template for Triton Engineers](?expand=1&template=pull_request_template_internal_contrib.md) -* [PR description template for External Contributors](?expand=1&template=pull_request_template_external_contrib.md) - -If you already created the PR, please replace this message with one of -* [External contribution template](https://raw.githubusercontent.com/triton-inference-server/server/main/.github/PULL_REQUEST_TEMPLATE/pull_request_template_external_contrib.md) -* [Internal contribution template](https://raw.githubusercontent.com/triton-inference-server/server/main/.github/PULL_REQUEST_TEMPLATE/pull_request_template_internal_contrib.md) - -and fill it out. - - diff --git a/.pre-commit-hooks.yaml b/.github/workflows/conventional-pr.yml similarity index 76% rename from .pre-commit-hooks.yaml rename to .github/workflows/conventional-pr.yml index fef4d8a..d96bb13 100644 --- a/.pre-commit-hooks.yaml +++ b/.github/workflows/conventional-pr.yml @@ -24,13 +24,18 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- id: add-license - name: Add License - entry: tools/add_copyright.py - language: script - stages: [pre-commit] - verbose: true - require_serial: true - # GitHub issue/PR templates must start with YAML frontmatter; keep - # license headers out of them. - exclude: ^\.github/ +# Thin caller: the logic lives in the org-wide reusable workflow, pinned by +# tag. Workflow changes ship as a new tag in the .github repository plus a +# one-line rev bump here (tags are write-once, never moved). + +name: conventional-pr + +on: + pull_request: + types: [opened, edited, synchronize, reopened] + +jobs: + conventional-pr: + permissions: + pull-requests: write + uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0ae189a..dda5e86 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -57,8 +57,8 @@ repos: args: ["--toml", "pyproject.toml"] exclude: (?x)^(.*stemmer.*|.*stop_words.*|^CHANGELOG.md$) # Validates commit messages against the Conventional Commits format -# (<commit_type>: <title>). Replaces the manual commit-type checklist that -# used to live in the PR template. +# (<commit_type>: <title>); PR titles are validated org-wide by the +# conventional-pr reusable workflow. - repo: https://github.com/compilerla/conventional-pre-commit rev: v4.4.0 hooks: @@ -83,18 +83,7 @@ repos: - id: requirements-txt-fixer - id: trailing-whitespace -# This repository defines the centralized hooks; run the in-tree version -# directly so CI validates the hook code being merged. Consumer repositories -# reference it via `repo: .../developer_tools` + `rev: v0.2.0` instead. -- repo: local +- repo: https://github.com/triton-inference-server/.github + rev: v1.0.0 hooks: - id: add-license - name: Add License - entry: tools/add_copyright.py - language: script - stages: [pre-commit] - verbose: true - require_serial: true - # GitHub issue/PR templates must start with YAML frontmatter; keep - # license headers out of them. - exclude: ^\.github/ diff --git a/tools/add_copyright.py b/tools/add_copyright.py deleted file mode 100755 index c58fd81..0000000 --- a/tools/add_copyright.py +++ /dev/null @@ -1,407 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of NVIDIA CORPORATION nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import argparse -import os -import re -import subprocess -import sys -from datetime import datetime -from typing import Callable, Dict, Optional, Sequence - -current_year = str(datetime.now().year) - -COPYRIGHT_YEAR_PAT = re.compile( - r"Copyright( \(c\))? (\d{4})?-?(\d{4}), NVIDIA CORPORATION" -) - -LICENSE_TEXT = "" - - -def get_repo_root() -> str: - try: - result = subprocess.run( - ["git", "rev-parse", "--show-toplevel"], - capture_output=True, - text=True, - check=True, - ) - return result.stdout.strip() - except (FileNotFoundError, subprocess.CalledProcessError): - return os.getcwd() - - -def get_license_path() -> str: - return os.path.join(get_repo_root(), "LICENSE") - - -def has_copyright(content: str) -> bool: - return COPYRIGHT_YEAR_PAT.search(content) - - -def update_copyright_year( - path: str, content: Optional[str] = None, disallow_range: bool = False -) -> str: - """ - Updates the copyright year in the provided file. - If the copyright is not present in the file, this function has no effect. - """ - if content is None: - with open(path, "r") as f: - content = f.read() - - match = COPYRIGHT_YEAR_PAT.search(content) - min_year = match.groups()[1] or match.groups()[2] - - new_copyright = f"Copyright{match.groups()[0] or ''} " - if min_year < current_year and not disallow_range: - new_copyright += f"{min_year}-{current_year}" - else: - new_copyright += f"{current_year}" - new_copyright += ", NVIDIA CORPORATION" - - updated_content = COPYRIGHT_YEAR_PAT.sub(new_copyright, content) - - if content != updated_content: - with open(path, "w") as f: - f.write(updated_content) - - -def get_license(license_path: Optional[str] = None) -> str: - """ - Returns the contents of the LICENSE file. - - Note: The LICENSE file itself is never modified by this hook; its - copyright year is maintained manually by each repository. - """ - license_path = license_path or get_license_path() - - with open(license_path, "r") as license_file: - return license_file.read() - - -def load_license_text() -> None: - global LICENSE_TEXT - LICENSE_TEXT = get_license() - - -# -# Header manipulation helpers -# - - -def prefix_lines(content: str, prefix: str) -> str: - # NOTE: This could have been done via `textwrap.indent`, but we're not actually indenting, - # so it seems semantically wrong to do that. - return prefix + f"\n{prefix}".join(content.splitlines()) - - -def insert_after(regex: str) -> Callable[[str, str], str]: - """ - Builds a callback that will insert a provided header after - the specified regular expression. If the expression is not - found in the file contents, the header will be inserted at the - beginning of the file. - - Args: - regex: The regular expression to match. - - Returns: - A callable that can be used as the `add_header` argument to `update_or_add_header`. - """ - - def add_header(header: str, content: str) -> str: - match = re.match(regex, content) - - if match is None: - return header + "\n" + content - - insertion_point = match.span()[-1] - - return content[:insertion_point] + f"{header}\n" + content[insertion_point:] - - return add_header - - -def update_or_add_header( - path: str, header: str, add_header: Optional[Callable[[str, str], str]] = None -): - """ - Updates in place or adds a new copyright header to the specified file. - - Args: - path: The path of the file. - header: The contents of the copyright header. - add_header: A callback that receives the copyright header and file contents and - controls how the contents of the file are updated. By default, the copyright - header is prepended to the file. - """ - with open(path, "r") as f: - content = f.read() - - if has_copyright(content): - update_copyright_year(path, content) - return - - add_header = add_header or (lambda header, content: header + "\n" + content) - - content = add_header(header, content) - - # As a sanity check, make sure we didn't accidentally add the copyright header - # twice, or add a new header when one was already present. - if content.count("Copyright (c)") != 1: - print( - f"WARNING: Something went wrong while processing: {path}!\n" - "Please check if the copyright header was included twice or wasn't added at all. " - ) - - with open(path, "w") as f: - f.write(content) - - -# Each file type requires slightly different handling when inserting the copyright -# header. For example, for C++ files, the header must be prefixed with `//` and for -# shell scripts, it must be prefixed with `#` and must be inserted *after* the shebang. -# -# This mapping stores callables that return whether a handler wants to process a specified -# file based on the path along with callables that will accept the file path and update -# it with the copyright header. -FILE_TYPE_HANDLERS: Dict[Callable[[str], bool], Callable[[str], None]] = {} - - -# -# Path matching callables -# These allow registered functions to more easily specify what kinds of -# paths they should be applied to. -# -def has_ext(exts: Sequence[str]): - def has_ext_impl(path: str): - _, ext = os.path.splitext(path) - return ext in exts - - return has_ext_impl - - -def basename_is(expected_path: str): - return lambda path: os.path.basename(path) == expected_path - - -def path_contains(expected: str): - return lambda path: expected in path - - -def any_of(*funcs: Sequence[Callable[[str], bool]]): - return lambda path: any(func(path) for func in funcs) - - -# -# File handlers for different types of files. -# Many types of files require very similar handling - those are combined where possible. -# - - -def register(match: Callable[[str], bool]): - def register_impl(func): - FILE_TYPE_HANDLERS[match] = func - return func - - return register_impl - - -@register( - any_of( - has_ext([".py", ".pyi", ".sh", ".bash", ".yaml", ".pbtxt"]), - basename_is("CMakeLists.txt"), - path_contains("Dockerfile"), - ) -) -def py_or_shell_like(path): - update_or_add_header( - path, - prefix_lines(LICENSE_TEXT, "# "), - # Insert the header *after* the shebang. - # NOTE: This could break if there is a shebang-like pattern elsewhere in the file. - # In that case, this could be edited to check only the first line of the file (after removing whitespace). - insert_after(r"#!(.*)\n"), - ) - - -@register(has_ext([".cc", ".h"])) -def cpp(path): - update_or_add_header(path, prefix_lines(LICENSE_TEXT, "// ")) - - -@register(has_ext([".tpl"])) -def tpl(path): - update_or_add_header(path, "{{/*\n" + prefix_lines(LICENSE_TEXT, "# ") + "\n*/}}") - - -@register(has_ext([".html", ".md"])) -def html_md(path): - update_or_add_header(path, "<!--\n" + prefix_lines(LICENSE_TEXT, "# ") + "\n-->") - - -@register(has_ext([".rst"])) -def rst(path): - update_or_add_header(path, prefix_lines(LICENSE_TEXT, ".. ")) - - -def add_copyrights(paths): - load_license_text() - - for path in paths: - # Special case: LICENSE file only needs year update - if os.path.basename(path) == "LICENSE": - update_copyright_year(path) - continue - - for match, handler in FILE_TYPE_HANDLERS.items(): - if match(path): - handler(path) - break - else: - print( - f"WARNING: No handler registered for file: {path}. Please add a new handler to {__file__}!" - ) - - # Don't automatically 'git add' changes for now, make it more clear which - # files were changed and have ability to see 'git diff' on them. - # Note that this means the hook will modify files and then cancel the commit, which you will then - # have to manually make again. - # subprocess.run(["git", "add"] + paths) - - print(f"Processed copyright headers for {len(paths)} file(s).") - - -def main() -> int: - parser = argparse.ArgumentParser( - description="Adds copyright headers to source files" - ) - parser.add_argument("files", nargs="*") - - args, _ = parser.parse_known_args() - - license_path = get_license_path() - if not os.path.isfile(license_path): - print(f"ERROR: LICENSE file not found at {license_path}", file=sys.stderr) - return 1 - - add_copyrights(args.files) - return 0 - - -if __name__ == "__main__": - # sys.exit is important here to avoid the test-related imports below during normal execution. - sys.exit(main()) - - -# -# Integration Tests -# -import tempfile - -import pytest - - -# Processes provided text through the copyright hook by writing it to a temporary file. -def process_text(content, extension): - with tempfile.NamedTemporaryFile("w+", suffix=extension) as f: - f.write(content) - f.flush() - - add_copyrights([f.name]) - - f.seek(0) - return f.read() - - -# We use this slightly weird hack to make sure the copyright hook does not do a text replacement -# of the parameters in the test, since they look exactly like copyright headers. -def make_copyright_text(text): - return f"Copyright {text}" - - -@pytest.mark.parametrize( - "content, expected", - [ - # Convert to range if the year that's already present is older than the current year. - ( - make_copyright_text("(c) 2018, NVIDIA CORPORATION"), - make_copyright_text(f"(c) 2018-{current_year}, NVIDIA CORPORATION"), - ), - ( - make_copyright_text("2018, NVIDIA CORPORATION"), - make_copyright_text(f"2018-{current_year}, NVIDIA CORPORATION"), - ), - # No effect if the year is current: - ( - make_copyright_text(f"(c) {current_year}, NVIDIA CORPORATION"), - make_copyright_text(f"(c) {current_year}, NVIDIA CORPORATION"), - ), - ( - make_copyright_text(f"{current_year}, NVIDIA CORPORATION"), - make_copyright_text(f"{current_year}, NVIDIA CORPORATION"), - ), - # If there is already a range, update the upper bound of the range: - ( - make_copyright_text("(c) 2018-2023, NVIDIA CORPORATION"), - make_copyright_text(f"(c) 2018-{current_year}, NVIDIA CORPORATION"), - ), - ], -) -def test_copyright_update(content, expected): - # We don't really care about the extension here - just needs to be something the hook will recognize. - assert process_text(content, ".py") == expected - - -@pytest.mark.parametrize( - "content, extension, expected", - [ - ("", ".cc", f"// {make_copyright_text(f'(c) {current_year}')}"), - ("", ".h", f"// {make_copyright_text(f'(c) {current_year}')}"), - ("", ".py", f"# {make_copyright_text(f'(c) {current_year}')}"), - ("", ".sh", f"# {make_copyright_text(f'(c) {current_year}')}"), - # Make sure copyright comes after shebangs - ( - "#!/bin/python\n", - ".py", - f"#!/bin/python\n# {make_copyright_text(f'(c) {current_year}')}", - ), - ( - "#!/bin/bash\n", - ".sh", - f"#!/bin/bash\n# {make_copyright_text(f'(c) {current_year}')}", - ), - ], -) -def test_adding_new_copyrights(content, extension, expected): - assert process_text(content, extension).startswith(expected) - - -def test_license_has_current_year(): - load_license_text() - # LICENSE file should have the current year (either as single year or end of range) - assert f"{current_year}, NVIDIA CORPORATION" in LICENSE_TEXT From 0a4de80f7299c5b604a912a1e88fa961b81ec89d Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:56:43 -0700 Subject: [PATCH 09/18] ci: bump conventional-pr workflow to v1.1.0 Org-wide label color scheme and cherry-pick detection. TRI-1100 --- .github/workflows/conventional-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml index d96bb13..0871567 100644 --- a/.github/workflows/conventional-pr.yml +++ b/.github/workflows/conventional-pr.yml @@ -38,4 +38,4 @@ jobs: conventional-pr: permissions: pull-requests: write - uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.0.0 + uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.1.0 From c263b82e1ecf637555fdd6ccaf380ac593a1b628 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:29:27 -0700 Subject: [PATCH 10/18] ci: bump conventional-pr workflow to v1.2.1 Human-readable type labels with enforced descriptions and colors. TRI-1100 --- .github/workflows/conventional-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml index 0871567..dab9232 100644 --- a/.github/workflows/conventional-pr.yml +++ b/.github/workflows/conventional-pr.yml @@ -38,4 +38,4 @@ jobs: conventional-pr: permissions: pull-requests: write - uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.1.0 + uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.2.1 From 81110a80bb7d85fc483ac669cb928c2b7bb3ffe8 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:35:53 -0700 Subject: [PATCH 11/18] ci: bump conventional-pr workflow to v1.2.2 TRI-1100 --- .github/workflows/conventional-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml index dab9232..594e1ec 100644 --- a/.github/workflows/conventional-pr.yml +++ b/.github/workflows/conventional-pr.yml @@ -38,4 +38,4 @@ jobs: conventional-pr: permissions: pull-requests: write - uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.2.1 + uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.2.2 From 53a03dd612ab2f0103c3fe7d07e4b36710f06ada Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:41:58 -0700 Subject: [PATCH 12/18] ci: bump conventional-pr workflow to v1.3.0 TRI-1100 --- .github/workflows/conventional-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml index 594e1ec..503ddca 100644 --- a/.github/workflows/conventional-pr.yml +++ b/.github/workflows/conventional-pr.yml @@ -38,4 +38,4 @@ jobs: conventional-pr: permissions: pull-requests: write - uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.2.2 + uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.3.0 From b9014e7535efd14f13bc016cf1ba335ae909fe96 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:56:08 -0700 Subject: [PATCH 13/18] ci: bump conventional-pr workflow to v1.3.1 TRI-1100 --- .github/workflows/conventional-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml index 503ddca..1866f85 100644 --- a/.github/workflows/conventional-pr.yml +++ b/.github/workflows/conventional-pr.yml @@ -38,4 +38,4 @@ jobs: conventional-pr: permissions: pull-requests: write - uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.3.0 + uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.3.1 From 9d592916123b41ab21abf5ed178bd625513dc62b Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Mon, 20 Jul 2026 16:14:55 -0700 Subject: [PATCH 14/18] ci: pin org .github hooks and workflow to the same tag (v1.3.1) TRI-1100 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dda5e86..63b6fe5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -84,6 +84,6 @@ repos: - id: trailing-whitespace - repo: https://github.com/triton-inference-server/.github - rev: v1.0.0 + rev: v1.3.1 hooks: - id: add-license From 0659fbd32eebb260f0c6bbb00cf704ac2f909e21 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Tue, 21 Jul 2026 08:15:54 -0700 Subject: [PATCH 15/18] ci: bump org .github hooks and workflow to v1.4.0 The add-license hook now fails when the LICENSE copyright year is stale. TRI-1100 --- .github/workflows/conventional-pr.yml | 2 +- .pre-commit-config.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml index 1866f85..922aaa5 100644 --- a/.github/workflows/conventional-pr.yml +++ b/.github/workflows/conventional-pr.yml @@ -38,4 +38,4 @@ jobs: conventional-pr: permissions: pull-requests: write - uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.3.1 + uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.4.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 63b6fe5..dfb695e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -84,6 +84,6 @@ repos: - id: trailing-whitespace - repo: https://github.com/triton-inference-server/.github - rev: v1.3.1 + rev: v1.4.0 hooks: - id: add-license From d13254ceff1cb1eb12aefb0b146f65a87d0d50d0 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Tue, 21 Jul 2026 08:29:26 -0700 Subject: [PATCH 16/18] ci: bump org .github hooks and workflow to v1.4.1 Workflow files are license-processed again (only templates excluded); refresh the stale copyright year this repo's pre-commit workflow carried. TRI-1100 --- .github/workflows/conventional-pr.yml | 2 +- .github/workflows/pre-commit.yml | 2 +- .pre-commit-config.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml index 922aaa5..7f6b096 100644 --- a/.github/workflows/conventional-pr.yml +++ b/.github/workflows/conventional-pr.yml @@ -38,4 +38,4 @@ jobs: conventional-pr: permissions: pull-requests: write - uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.4.0 + uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.4.1 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 15d0b68..4dbce6b 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -1,4 +1,4 @@ -# Copyright 2023-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dfb695e..836d741 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -84,6 +84,6 @@ repos: - id: trailing-whitespace - repo: https://github.com/triton-inference-server/.github - rev: v1.4.0 + rev: v1.4.1 hooks: - id: add-license From 3d8bf7a71f199ba3c5fb689840c359db1a252e16 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Tue, 21 Jul 2026 17:19:39 -0700 Subject: [PATCH 17/18] ci: bump org .github hooks and workflow to v1.4.2 Grant issues:write to the labeling job (review feedback). TRI-1100 --- .github/workflows/conventional-pr.yml | 3 ++- .pre-commit-config.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml index 7f6b096..72472a7 100644 --- a/.github/workflows/conventional-pr.yml +++ b/.github/workflows/conventional-pr.yml @@ -38,4 +38,5 @@ jobs: conventional-pr: permissions: pull-requests: write - uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.4.1 + issues: write + uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.4.2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 836d741..724cade 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -84,6 +84,6 @@ repos: - id: trailing-whitespace - repo: https://github.com/triton-inference-server/.github - rev: v1.4.1 + rev: v1.4.2 hooks: - id: add-license From c8823420faeb3ba3dd4c1e7f3a6c355a20c8a799 Mon Sep 17 00:00:00 2001 From: Misha Chornyi <99709299+mc-nv@users.noreply.github.com> Date: Wed, 22 Jul 2026 11:29:37 -0700 Subject: [PATCH 18/18] ci: harden CI workflows and configs per fleet-wide review feedback - conventional-pr stub: dual pull_request/pull_request_target triggers so fork PRs from external contributors get labeled too (the reusable workflow never checks out PR code); explicit contents:read; pinned v1.4.3. - pre-commit workflow: robust modified-files runner (null-delimited paths, deletion-only PRs handled, deleted paths filtered, no undocumented -r flag, cache keyed on config hash). - flake8 args quoted correctly (the flow-scalar form split at commas and silently reduced the select list). - hooks pinned to .github v1.4.3. TRI-1100 --- .github/workflows/conventional-pr.yml | 14 +++++++++++++- .github/workflows/pre-commit.yml | 19 ++++++++++++++----- .pre-commit-config.yaml | 4 ++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/.github/workflows/conventional-pr.yml b/.github/workflows/conventional-pr.yml index 72472a7..d3348b7 100644 --- a/.github/workflows/conventional-pr.yml +++ b/.github/workflows/conventional-pr.yml @@ -33,10 +33,22 @@ name: conventional-pr on: pull_request: types: [opened, edited, synchronize, reopened] + pull_request_target: + types: [opened, edited, synchronize, reopened] jobs: conventional-pr: + # Same-repo PRs run on the safe pull_request event; fork PRs run on + # pull_request_target so the labeling job gets a writable token (safe + # here: the reusable workflow never checks out PR code - it only reads + # PR metadata via the API and manages labels). + if: >- + (github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository) || + (github.event_name == 'pull_request_target' && + github.event.pull_request.head.repo.full_name != github.repository) permissions: pull-requests: write issues: write - uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.4.2 + contents: read + uses: triton-inference-server/.github/.github/workflows/conventional-pr.yml@v1.4.3 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 4dbce6b..cd8680b 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -32,14 +32,23 @@ on: jobs: pre-commit: runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@v5.0.0 with: fetch-depth: 2 - - name: Get modified files - id: modified-files - run: echo "modified_files=$(git diff --name-only -r HEAD^1 HEAD | xargs)" >> $GITHUB_OUTPUT - uses: actions/setup-python@v6.0.0 - - uses: pre-commit/action@v3.0.1 + - uses: actions/cache@v4 with: - extra_args: --files ${{ steps.modified-files.outputs.modified_files }} + path: ~/.cache/pre-commit + key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }} + - name: Run pre-commit on the files modified by the PR + # Null-delimited so paths with spaces survive; --no-run-if-empty + # handles deletion-only PRs; deleted paths are filtered out before + # being handed to pre-commit. + run: | + python -m pip install --quiet pre-commit + git diff --name-only -z --diff-filter=d HEAD^1 HEAD \ + | xargs -0 --no-run-if-empty \ + pre-commit run --show-diff-on-failure --color=always --files diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 724cade..e5fd080 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,7 +41,7 @@ repos: rev: 7.3.0 hooks: - id: flake8 - args: [--max-line-length=88, --select=C,E,F,W,B,B950, --extend-ignore = E203,E501] + args: ["--max-line-length=88", "--select=C,E,F,W,B,B950", "--extend-ignore=E203,E501"] types_or: [python, cython] - repo: https://github.com/pre-commit/mirrors-clang-format rev: v16.0.5 @@ -84,6 +84,6 @@ repos: - id: trailing-whitespace - repo: https://github.com/triton-inference-server/.github - rev: v1.4.2 + rev: v1.4.3 hooks: - id: add-license