[FEATURE] Add cellular network connections support #323
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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(`^\\s*(?:###\\s*)?${escapedHeading}\\s*\\r?\\n+([^\\n\\r]+)`, "im")); | |
| return match ? match[1].trim() : null; | |
| }; | |
| const compositorValue = extractValue("Compositor"); | |
| const distributionValue = extractValue("Distribution"); | |
| const compositorLabelMap = { | |
| "Niri": "niri", | |
| "Hyprland": "hyprland", | |
| "Sway": "sway", | |
| "Scroll": "scroll", | |
| "Labwc": "labwc", | |
| "Mango": "mango", | |
| "MangoWC": "mango", | |
| "Other": "compositor:other" | |
| }; | |
| const distributionLabelMap = { | |
| "Arch-based": "arch-based", | |
| "Fedora-based": "fedora-based", | |
| "Debian-based": "debian-based", | |
| "NixOS": "nixos", | |
| "openSUSE-based": "opensuse", | |
| "Gentoo-based": "gentoo", | |
| "Void": "void", | |
| "Void-based": "void", | |
| "Other": "distro:other" | |
| }; | |
| const compositorLabels = new Set(Object.values(compositorLabelMap)); | |
| const distributionLabels = new Set(Object.values(distributionLabelMap)); | |
| const mappings = [ | |
| { | |
| kind: "compositor", | |
| selectedValue: compositorValue, | |
| labelMap: compositorLabelMap, | |
| managedLabels: compositorLabels, | |
| description: "Issue reported for this compositor stack" | |
| }, | |
| { | |
| kind: "distribution", | |
| selectedValue: distributionValue, | |
| labelMap: distributionLabelMap, | |
| managedLabels: distributionLabels, | |
| 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) => mapping.managedLabels.has(name)); | |
| 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}".`); | |
| } |