chore(ISSUE_TEMPLATES): add issue templates & workflow

This commit is contained in:
Ly-sec
2026-05-06 15:54:08 +02:00
parent 4ac81c754e
commit bb183faa93
4 changed files with 354 additions and 0 deletions
+128
View File
@@ -0,0 +1,128 @@
name: Bug Report
description: Report a bug or regression in Noctalia
title: "[BUG] "
labels: ["bug"]
assignees: [Ly-sec, ItsLemmy]
body:
- type: checkboxes
id: submission-checklist
attributes:
label: Submission checklist
description: Please confirm the following before submitting.
options:
- label: I have searched existing issues and confirmed this is not a duplicate.
required: true
- label: I am using the latest available version of Noctalia.
required: true
- type: textarea
id: description
attributes:
label: Bug description
description: A clear and concise description of the issue.
placeholder: Describe the problem...
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to reproduce
description: Steps required to reproduce the issue.
placeholder: |
1. Open ...
2. Click ...
3. Observe ...
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
description: What did you expect to happen?
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual behavior
description: What actually happened?
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs / error output
description: |
Paste any relevant logs, terminal output, or stack traces here.
Examples:
- journalctl output
- terminal errors
- crash logs
Large outputs can be wrapped in a `<details>` block.
render: text
- type: dropdown
id: compositor
attributes:
label: Desktop environment / compositor
description: Select the compositor where the issue occurs.
options:
- Niri
- Hyprland
- Sway
- Scroll
- Labwc
- Mango
- Other
validations:
required: true
- type: dropdown
id: distribution
attributes:
label: Distribution family
description: Select the Linux distribution family where the issue occurs.
options:
- Arch-based
- Fedora-based
- Debian-based
- Gentoo-based
- NixOS
- openSUSE-based
- Void
- Other
validations:
required: true
- type: textarea
id: environment
attributes:
label: Environment information
description: |
Please provide relevant system information:
If you selected `Other` for distribution and/or compositor, please specify the exact one(s) here.
- Noctalia version or commit:
- Installation method:
- GPU:
placeholder: |
Noctalia version: main / commit hash
Installation method: AUR
GPU: AMD RX 7800 XT (amdgpu)
render: text
validations:
required: true
- type: textarea
id: additional
attributes:
label: Additional context
description: |
Add any other context, screenshots, or relevant information here.
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Noctalia Fluxer
url: https://fluxer.gg/Noctalia
about: Join the community for support, discussions, and quick help.
- name: Noctalia Docs
url: https://docs.noctalia.dev
about: Browse the documentation, guides, and frequently asked questions.
@@ -0,0 +1,92 @@
name: Feature Request
description: Suggest an improvement, new feature, or enhancement for Noctalia
title: "[FEATURE] "
labels: ["feature"]
assignees: [Ly-sec, ItsLemmy]
body:
- type: checkboxes
id: submission-checklist
attributes:
label: Submission checklist
description: Please confirm the following before submitting.
options:
- label: I have searched existing issues and confirmed this has not been requested before.
required: true
- label: I have checked existing pull requests for similar changes.
required: true
- type: dropdown
id: feature-type
attributes:
label: Feature type
description: What kind of feature or improvement is this?
options:
- UI / visual improvement
- New functionality
- Performance improvement
- Configuration / customization
- Accessibility improvement
- Developer / API improvement
- Integration support
- Documentation improvement
- Other
validations:
required: true
- type: textarea
id: summary
attributes:
label: Feature summary
description: A concise description of the feature or enhancement.
placeholder: What would you like to see added or changed?
validations:
required: true
- type: textarea
id: motivation
attributes:
label: Motivation / use case
description: |
Why would this feature be useful?
What problem does it solve or improve?
placeholder: Explain the benefit or real-world use case...
validations:
required: true
- type: textarea
id: proposed-solution
attributes:
label: Proposed solution
description: |
Describe how you think this could work.
Mockups, examples, screenshots, or references are welcome.
placeholder: Describe your idea...
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: |
Have you considered any alternative solutions or workarounds?
placeholder: Optional...
- type: textarea
id: references
attributes:
label: References / related projects
description: |
Link any related projects, concepts, screenshots, issues, or examples here.
placeholder: |
https://github.com/...
https://example.com/...
- type: textarea
id: additional
attributes:
label: Additional context
description: |
Add any additional information, screenshots, mockups, or context here.
+126
View File
@@ -0,0 +1,126 @@
name: Label Issue Metadata
on:
issues:
types: [opened, edited]
permissions:
contents: read
issues: write
jobs:
label-issue-metadata:
runs-on: ubuntu-latest
steps:
- name: Apply compositor and distribution labels from issue form
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const body = issue.body || "";
const issueNumber = issue.number;
const { owner, repo } = context.repo;
const extractValue = (heading) => {
const escapedHeading = heading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const match = body.match(new RegExp(`### ${escapedHeading}\\s*\\n+([^\\n\\r]+)`, "i"));
return match ? match[1].trim() : null;
};
const compositorValue = extractValue("Desktop environment / compositor");
const distributionValue = extractValue("Distribution family");
const compositorLabelMap = {
"Niri": "compositor:niri",
"Hyprland": "compositor:hyprland",
"Sway": "compositor:sway",
"Scroll": "compositor:scroll",
"Labwc": "compositor:labwc",
"MangoWC": "compositor:mango",
"Other": "compositor:other"
};
const distributionLabelMap = {
"Arch-based": "distro:arch-based",
"Fedora-based": "distro:fedora-based",
"Debian-based": "distro:debian-based",
"NixOS": "distro:nixos",
"openSUSE-based": "distro:opensuse",
"Gentoo-based": "distro:gentoo",
"Void-based": "distro:void",
"Other": "distro:other"
};
const mappings = [
{
kind: "compositor",
prefix: "compositor:",
selectedValue: compositorValue,
labelMap: compositorLabelMap,
description: "Issue reported for this compositor stack"
},
{
kind: "distribution",
prefix: "distro:",
selectedValue: distributionValue,
labelMap: distributionLabelMap,
description: "Issue reported for this Linux distribution family"
}
];
async function ensureLabelExists(name, description) {
try {
await github.rest.issues.getLabel({ owner, repo, name });
} catch (error) {
if (error.status !== 404) throw error;
await github.rest.issues.createLabel({
owner,
repo,
name,
color: "5319e7",
description
});
core.info(`Created missing label "${name}".`);
}
}
const existingLabels = issue.labels.map((label) => label.name);
for (const mapping of mappings) {
if (!mapping.selectedValue) {
core.info(`${mapping.kind} field not found in issue body; skipping.`);
continue;
}
const targetLabel = mapping.labelMap[mapping.selectedValue];
if (!targetLabel) {
core.info(`No ${mapping.kind} label mapping found for value: "${mapping.selectedValue}"`);
continue;
}
await ensureLabelExists(targetLabel, mapping.description);
const currentKindLabels = existingLabels.filter((name) => name.startsWith(mapping.prefix));
for (const label of currentKindLabels) {
if (label === targetLabel) continue;
try {
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: issueNumber,
name: label
});
} catch (error) {
core.info(`Could not remove label "${label}": ${error.message}`);
}
}
await github.rest.issues.addLabels({
owner,
repo,
issue_number: issueNumber,
labels: [targetLabel]
});
core.info(`Applied ${mapping.kind} label "${targetLabel}" from value "${mapping.selectedValue}".`);
}