Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: Bug report
about: Create a report to help us improve
title: '[Bug]: '
labels: ["bug", "needs-triage"]

---

<!-- _**Important Note: NVIDIA AI Enterprise customers can get support from NVIDIA Enterprise support. Please open a case [here](https://enterprise-support.nvidia.com/s/create-case)**._ -->

**Motivation**
<!-- A clear and concise description of your motivation: is this a real issue you ran into while using the product? -->

**Check here if you would like to work on this issue**
- [ ]

**Describe the bug**
<!-- A clear and concise description of what the bug is. -->

**To Reproduce**
<!-- Detailed steps to reproduce the issue. -->

**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Community Slack (#gpu-operator)
url: https://inviter.co/dsx-ai-factory
about: Chat with the GPU Operator team and community
14 changes: 14 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
name: Feature request
about: Submit a feature request
title: "[Feature]: "
labels: ["feature", "needs-triage"]
---
**Motivation**
<!-- A clear and concise description of your motivation: e.g. would this feature greatly help your use-case, and why? -->

**Check here if you would like to work on this issue**
- [ ]

**Describe the feature**
<!-- A clear and concise description of the feature request. What alternatives did you consider? What impact will this have on users? If this is related to another GitHub issue, please link it here too. -->
7 changes: 7 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Issue
<!-- Link the `accepted` issue assigned to you. See CONTRIBUTING.md#contribution-workflow -->
Fixes #

## Description

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

name: Assign

on:
issue_comment:
types: [created]

permissions: {}

jobs:
assign:
name: Assign issue from /assign comment
if: ${{ !github.event.issue.pull_request && startsWith(github.event.comment.body, '/assign') }}
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
issues: write
steps:
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const { owner, repo } = context.repo;
const { comment, issue } = context.payload;
const react = (content) =>
github.rest.reactions.createForIssueComment({ owner, repo, comment_id: comment.id, content });

const firstLine = comment.body.split(/\r?\n/, 1)[0].trim();
if (!/^\/assign(\s|$)/.test(firstLine)) {
return;
}

// Matches GitHub's own rule: assigning requires the triage role or higher.
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({
owner,
repo,
username: comment.user.login,
});
const canAssign = ['admin', 'maintain', 'write', 'triage'].includes(perm.role_name)
|| ['admin', 'write'].includes(perm.permission);
if (!canAssign) {
return react('-1');
}

const match = firstLine.match(/^\/assign(?:\s+@?([A-Za-z0-9-]+))?$/);
if (!match || !issue.labels.some((label) => label.name === 'accepted')) {
return react('confused');
}

const assignee = match[1] ?? comment.user.login;
const { data: updated } = await github.rest.issues.addAssignees({
owner,
repo,
issue_number: issue.number,
assignees: [assignee],
});
// GitHub silently skips users it cannot assign, such as people who have not commented on the issue.
if (!updated.assignees.some((a) => a.login.toLowerCase() === assignee.toLowerCase())) {
return react('confused');
}

// The PR gatekeeper accepts any assignee, so a new claimant must replace the previous ones.
// Maintainers stay assigned because the gatekeeper does not apply to them.
const previousClaimants = [];
for (const { login } of updated.assignees) {
if (login.toLowerCase() === assignee.toLowerCase()) {
continue;
}
const { data: level } = await github.rest.repos.getCollaboratorPermissionLevel({
owner,
repo,
username: login,
});
if (!['admin', 'maintain', 'write'].includes(level.permission)) {
previousClaimants.push(login);
}
}
if (previousClaimants.length > 0) {
await github.rest.issues.removeAssignees({
owner,
repo,
issue_number: issue.number,
assignees: previousClaimants,
});
}
return react('+1');
62 changes: 62 additions & 0 deletions .github/workflows/issue-state-labels.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright NVIDIA CORPORATION
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Issue State Labels

on:
issues:
types: [labeled]

permissions: {}

concurrency:
group: issue-state-${{ github.event.issue.number }}

jobs:
single-state:
name: Keep one state label per issue
if: contains(fromJSON('["needs-triage","needs-more-info","accepted"]'), github.event.label.name)
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
issues: write
steps:
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const stateLabels = ['needs-triage', 'needs-more-info', 'accepted'];
const { owner, repo } = context.repo;
const issue_number = context.payload.issue.number;
const added = context.payload.label.name;
if (!stateLabels.includes(added)) {
return;
}
const { data: labels } = await github.rest.issues.listLabelsOnIssue({ owner, repo, issue_number });
const current = labels.map((label) => label.name);
// Adding two state labels at once starts two runs; a later run must not undo an earlier one.
if (!current.includes(added)) {
return;
}
for (const name of current.filter((label) => stateLabels.includes(label) && label !== added)) {
try {
await github.rest.issues.removeLabel({ owner, repo, issue_number, name });
core.info(`Removed ${name}: ${added} replaces it.`);
} catch (error) {
if (error.status !== 404) {
throw error;
}
}
}
45 changes: 45 additions & 0 deletions .github/workflows/issue-triage.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright NVIDIA CORPORATION
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Issue Triage

on:
issues:
types: [opened]

permissions: {}

jobs:
label:
name: Label new issues for triage
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
issues: write
steps:
# Issue templates apply needs-triage, but issues created through the API skip templates.
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const stateLabels = ['needs-triage', 'needs-more-info', 'accepted'];
const labels = context.payload.issue.labels.map((label) => label.name);
if (labels.some((label) => stateLabels.includes(label))) {
return;
}
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
labels: ['needs-triage'],
});
17 changes: 16 additions & 1 deletion .github/workflows/stale.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,24 @@ jobs:
with:
stale-issue-message: 'This issue is stale because it has been open 90 days with no activity. This issue will be closed in 30 days unless new comments are made or the stale label is removed. To skip these checks, apply the "feature, enhancement or lifecycle/frozen" labels.'
stale-issue-label: 'lifecycle/stale'
exempt-issue-labels: 'lifecycle/frozen,feature,enhancement'
exempt-issue-labels: 'lifecycle/frozen,feature,enhancement,accepted'
days-before-stale: 90
close-issue-message: 'This issue was automatically closed due to inactivity.'
days-before-issue-close: 30
remove-stale-when-updated: true
operations-per-run: 300
- uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11
with:
only-issue-labels: 'needs-more-info'
# Triage policy start date.
start-date: '2026-10-27T00:00:00Z'
stale-issue-message: 'This issue has been waiting for more information for 23 days with no activity. It will be closed in 7 days unless the requested information is provided.'
stale-issue-label: 'lifecycle/stale'
exempt-issue-labels: 'lifecycle/frozen'
days-before-issue-stale: 23
close-issue-message: 'This issue was automatically closed because the requested information was not provided within 30 days.'
days-before-issue-close: 7
days-before-pr-stale: -1
days-before-pr-close: -1
remove-stale-when-updated: true
operations-per-run: 1000
11 changes: 11 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Contribution process (see `CONTRIBUTING.md`)

- For any change, an issue should exist describing the problem/proposal before implementation begins. Additionally, the contributor should be approved to work on said issue — ensure the PR is linked to an issue the contributor has been assigned to.
- Keep PR titles short and imperative.
- Issue or PR descriptions drafted with AI must be thoroughly reviewed and verified by the user before they are submitted.
- Replies to maintainers in review comments or issue discussions may not be AI generated.
- All commits must be signed off (DCO): `git commit -s`, producing a trailing
`Signed-off-by: Name <email>` line. Do not fabricate a sign-off identity — use the configured
git user's identity.
- Do not open, push to, or comment on GitHub issues/PRs without explicit user confirmation.
- Keep all changes as minimal as possible.
53 changes: 51 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,59 @@
# Contribute to the NVIDIA `go-gpuallocator` Project

Want to contribute to the NVIDIA `go-gpuallocator` Project? Awesome!
We only require you to sign your work, the below section describes this!
To file feature requests or bugs, submit an issue at https://github.com/NVIDIA/go-gpuallocator/issues. For questions, ask in the `#gpu-operator` channel in our community Slack at https://inviter.co/dsx-ai-factory.

All external contributions start with an issue. External contributors must have an accepted issue that is assigned to them before they open a pull request. See [Contribution workflow](#contribution-workflow). Contributions do not require explicit contributor license agreements (CLA), but we expect contributors to [sign](#sign-your-work) their work.

PR approval and decision-making for major changes are documented in [GOVERNANCE.md](GOVERNANCE.md).

All contributions must adhere to the [Code of Conduct](CODE_OF_CONDUCT.md).

### AI Usage
AI-assisted contributions are welcome, however, **you must understand your code**. If you can't explain what your changes do and how they interact with the greater system without the aid of AI tools, your contribution may not be accepted. AI should assist your effort, not replace it or shift the burden of understanding, testing, and reviewing onto maintainers.

The human contributor is accountable for all code, regardless of how much was AI-generated. Each contribution must name the human behind the change via a [DCO sign-off](#sign-your-work).

Maintainers may close issues and PRs that are unproductive or low-quality, without explanation, regardless of whether AI tools were used or not. If a contributor repeatedly opens unproductive issues or PRs, they may be blocked from contributing to the project because it is disruptive and disrespectful of the maintainers' time.

Below are some unacceptable usages of AI that will likely result in your contribution being closed:

- Submitting AI-generated issues or PRs without thorough review and verification
- Submitting AI-generated code that you cannot explain or answer questions about during review
- Using AI to generate replies to review comments or issue discussions
- Submitting AI-generated code that contains unnecessary refactoring or unrelated changes not scoped to the problem the PR is solving

### Contribution workflow

**To propose a new issue:** start at step 1.\
**To work on an existing issue:** skip to step 3 and [claim an `accepted` issue](https://github.com/NVIDIA/go-gpuallocator/issues?q=is%3Aopen+label%3Aaccepted+no%3Aassignee) with no assignees.

1. **Open an issue.** Use the bug report template to report a defect, or the feature request template to propose new behavior or a [major change](GOVERNANCE.md#core-decisions). Indicate if you want to work on the issue. Each new issue gets the `needs-triage` label.
2. **Wait for triage.** A maintainer reviews the issue against the [triage criteria](#triage-criteria). The maintainer then labels the issue `accepted`, `needs-more-info`, or closes it.
3. **Claim the issue.** When an issue is `accepted`, comment on it expressing interest and summarizing your proposed solution. Issue authors have priority if they indicate they would like to work on it. Other claims are first-come, first-served. A maintainer discusses your plan with you and assigns the issue to you when the plan is ready.
4. **Open a pull request.** File a pull request at https://github.com/NVIDIA/go-gpuallocator/pulls and link the issue in the description (for example, `Fixes #1234`). Maintainers close pull requests that do not link an issue assigned to the author, and pull requests that are duplicates of existing ones.

### Issue labels

Each open issue has one state label and one category label. For example, `needs-triage` and `bug` together identify a bug report that no maintainer has reviewed yet.

| Label | Type | Meaning |
| ----- | ---- | ------- |
| `needs-triage` | State | No maintainer has reviewed the issue yet. |
| `needs-more-info` | State | Maintainers are waiting for more information from the author. If the issue has no activity for 30 days, it is closed. |
| `accepted` | State | The issue is approved for work. Contributors can claim it. |
| `bug` | Category | A defect in existing behavior. |
| `feature` | Category | A request for new behavior. |

### Triage criteria

Maintainers use these questions to triage an issue:

- Is the problem clear and reproducible?
- Is the issue a duplicate, or does other work already address it?
- Does the issue fit the supported use cases and the project priorities?
- Is the proposed approach appropriate?
- Does the issue align with the product roadmap?

## Sign your work

The sign-off is a simple line at the end of the description for the patch. Your
Expand Down
7 changes: 3 additions & 4 deletions GOVERNANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ report issues, and engage in discussions.

### Routine Decisions

Routine decisions — bug fixes, minor features, documentation, dependency updates — proceed
via a PR. At least one maintainer approval is required for technical acceptance; a maintainer
then merges after verifying project requirements are met.
Routine decisions — bug fixes, minor features, documentation, dependency updates — proceed via a PR. External contributions first follow the contribution workflow referenced in [CONTRIBUTING.md](CONTRIBUTING.md), which requires maintainer approval on an issue before implementation begins.
A maintainer then approves and merges PRs after verifying project requirements are met.

### Core Decisions

Expand All @@ -68,7 +67,7 @@ considered, and the impact on existing contributors and users.
Core decisions are made by the maintainers. For contributors who want to propose and contribute
a major change, the process is as follows:

- A proposal for a major change will be submitted as an issue.
- A proposal for a major change will be submitted as a [feature request](.github/ISSUE_TEMPLATE/feature_request.md).
- The maintainers will discuss the proposal and seek feedback from the community.
- Once the discussion is concluded, maintainers will make the final decision.

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,7 @@ func main() {

## Contributions
[Read the document on contributions](CONTRIBUTING.md).
You can contribute by opening a [pull request](https://help.github.com/en/articles/about-pull-requests).
Contributions must adhere to the [Code of Conduct](CODE_OF_CONDUCT.md).

## Support and Getting Help
You can join our [community Slack](https://inviter.co/dsx-ai-factory). Your feedback is appreciated.
Loading