Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/2232789/?format=api
{ "id": 2232789, "url": "http://patchwork.ozlabs.org/api/1.2/patches/2232789/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hi8lco6rjs.gcc.gcc-TEST.rearnsha.149.1.1@forge-stage.sourceware.org/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/1.2/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<bmm.hi8lco6rjs.gcc.gcc-TEST.rearnsha.149.1.1@forge-stage.sourceware.org>", "list_archive_url": null, "date": "2026-05-05T09:17:12", "name": "[v1,1/1] Forge: Add scaffolding for managing forge labels", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "9324c6b522ac483ee1c129028a28039a7c4ac3dc", "submitter": { "id": 92169, "url": "http://patchwork.ozlabs.org/api/1.2/people/92169/?format=api", "name": "Richard Earnshaw via Sourceware Forge", "email": "forge-bot+rearnsha@forge-stage.sourceware.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/bmm.hi8lco6rjs.gcc.gcc-TEST.rearnsha.149.1.1@forge-stage.sourceware.org/mbox/", "series": [ { "id": 502793, "url": "http://patchwork.ozlabs.org/api/1.2/series/502793/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=502793", "date": "2026-05-05T09:17:11", "name": "WIP: Forge: Add scaffolding for managing forge labels", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/502793/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2232789/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2232789/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)", "sourceware.org; dmarc=none (p=none dis=none)\n header.from=forge-stage.sourceware.org", "sourceware.org;\n spf=pass smtp.mailfrom=forge-stage.sourceware.org", "server2.sourceware.org;\n arc=none smtp.remote-ip=38.145.34.39" ], "Received": [ "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g8tLL3v6Gz1y04\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 05 May 2026 19:21:30 +1000 (AEST)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 8414A4BA79BB\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 5 May 2026 09:21:28 +0000 (GMT)", "from forge-stage.sourceware.org (vm08.sourceware.org [38.145.34.39])\n by sourceware.org (Postfix) with ESMTPS id 267634BA7994\n for <gcc-patches@gcc.gnu.org>; Tue, 5 May 2026 09:18:11 +0000 (GMT)", "from forge-stage.sourceware.org (localhost [IPv6:::1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256)\n (No client certificate requested)\n by forge-stage.sourceware.org (Postfix) with ESMTPS id AB12742C44;\n Tue, 05 May 2026 09:18:10 +0000 (UTC)" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org 8414A4BA79BB", "OpenDKIM Filter v2.11.0 sourceware.org 267634BA7994" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 267634BA7994", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 267634BA7994", "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777972691; cv=none;\n b=mTWWPlzN4vPX64V9hw5OIWuUeUal9GoSAKZxGJMnfoK3IRYa4KC2iMxsQPi6dFELyxP2Nnnx9zJLL+P+b3jZkbYghX4+lsDcfK5YiEzraSTRaathh+d+SlTdqfU9yR8MfOE7WzKKnfOD2sih3hTMJruz849Pi0+9Nl64o60QQI8=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777972691; c=relaxed/simple;\n bh=n0YCe44XbHo9wSmb5+McHQBWl99vBAss85ogw8dY4jM=;\n h=From:Date:Subject:To:Message-ID;\n b=IszdjE16T5HtQeyCZ6uHZwV+vkGRI11I4qazAAyWCgXmg4/dooiDLPYKZl2Mnoy893snRYk0BM8stjAF723c0Sb4AxNskdFLHfeMGpzJozKh5E/PDR56wx52Bcsu73bRyQoVE0Q1P69II94bjE7bdhux2Wv/zFlFurq5i1m5rnA=", "ARC-Authentication-Results": "i=1; server2.sourceware.org", "From": "Richard Earnshaw via Sourceware Forge\n <forge-bot+rearnsha@forge-stage.sourceware.org>", "Date": "Tue, 05 May 2026 09:17:12 +0000", "Subject": "[PATCH v1 1/1] Forge: Add scaffolding for managing forge labels", "To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>", "Cc": "claudio.bantaloukas@arm.com", "Message-ID": "\n <bmm.hi8lco6rjs.gcc.gcc-TEST.rearnsha.149.1.1@forge-stage.sourceware.org>", "X-Mailer": "batrachomyomachia", "X-Requested-Reviewer": "rdfm", "X-Pull-Request-Organization": "gcc", "X-Pull-Request-Repository": "gcc-TEST", "X-Pull-Request": "https://forge.sourceware.org/gcc/gcc-TEST/pulls/149", "References": "\n <bmm.hi8lco6rjs.gcc.gcc-TEST.rearnsha.149.1.0@forge-stage.sourceware.org>", "In-Reply-To": "\n <bmm.hi8lco6rjs.gcc.gcc-TEST.rearnsha.149.1.0@forge-stage.sourceware.org>", "X-Patch-URL": "\n https://forge.sourceware.org/rearnsha/gcc-TEST/commit/59109ed260b8a6064ba8c5a41335d3caf6ee82b6", "X-BeenThere": "gcc-patches@gcc.gnu.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>", "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>", "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>", "Reply-To": "gcc-patches mailing list <gcc-patches@gcc.gnu.org>,\n claudio.bantaloukas@arm.com, rearnsha@arm.com", "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org" }, "content": "From: Richard Earnshaw <rearnsha@arm.com>\n\nAdd some scaffolding for managing labels used by the forge. This\npatch handles some general infrastructure to read a 'database' of\nlabels, an initial set of lables and a script to manage the list of\nlabels on the forge instance. It makes use of the forge's REST API to\nautomate the process, thus making it simple for a user with\nappropriate privilages to update the list with minimal effort.\n\nThe classify.py script takes a list of file paths and applies the\nmatch rules, printing out the labels that would apply to each filename.\nYou can see the effects by running\n (cd $GCC_SRC_BASE; find . -type f -print) | ./classify.py\n\nI expect a future patch to use the matching data to automatically\nlabel merge requests with the relevant labels as part of the initial\ntriaging process.\n\ncontrib/ChangeLog:\n\n\t* forge/forgelabels.py: New file.\n\t* forge/labels.yaml: New file.\n\t* forge/update-labels.py: New file.\n\t* forge/classify.py: New file.\n---\n contrib/forge/classify.py | 88 ++++\n contrib/forge/forgelabels.py | 201 +++++++\n contrib/forge/labels.yaml | 926 +++++++++++++++++++++++++++++++++\n contrib/forge/update-labels.py | 151 ++++++\n 4 files changed, 1366 insertions(+)\n create mode 100755 contrib/forge/classify.py\n create mode 100755 contrib/forge/forgelabels.py\n create mode 100644 contrib/forge/labels.yaml\n create mode 100755 contrib/forge/update-labels.py", "diff": "diff --git a/contrib/forge/classify.py b/contrib/forge/classify.py\nnew file mode 100755\nindex 000000000000..da77c9c72390\n--- /dev/null\n+++ b/contrib/forge/classify.py\n@@ -0,0 +1,88 @@\n+#!/usr/bin/env python3\n+\n+# Map files in the GCC source tree to forge labels.\n+\n+# Copyright (C) 2026 Free Software Foundation, Inc.\n+#\n+# This file is part of GCC.\n+#\n+# GCC is free software; you can redistribute it and/or modify it under\n+# the terms of the GNU General Public License as published by the Free\n+# Software Foundation; either version 3, or (at your option) any later\n+# version.\n+#\n+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+# WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n+# for more details.\n+#\n+# You should have received a copy of the GNU General Public License\n+# along with GCC; see the file COPYING3. If not see\n+# <http://www.gnu.org/licenses/>.\n+\n+# Note, this file requires python 3.10 or later.\n+\n+import re\n+import sys\n+import forgelabels\n+\n+labels_file = 'labels'\n+\n+class classifier:\n+ def __init__ (self, groups):\n+ self.file_class = []\n+ self.bz_class = []\n+ for g in groups:\n+ if not g.match_defaults or g.match_defaults.mclass != \"file\":\n+ continue\n+ for l in g.labels:\n+ if l.match:\n+ self.file_class.append (self._file_entry (l.match,\n+ l.full_name))\n+\n+ def map_to_labels (self, name):\n+ labels = []\n+ priority = 100\n+ for fc in self.file_class:\n+ if fc['pattern'].match (name):\n+ if fc['priority'] < priority:\n+ priority = fc['priority']\n+ labels = [fc['label']]\n+ elif fc['priority'] == priority:\n+ labels.append (fc['label'])\n+\n+ return labels\n+\n+ def _file_entry (self, match, label):\n+ priority = match.priority\n+\n+ d = dict()\n+ try:\n+ d['pattern'] = re.compile (match.file2re ())\n+ except Exception as e:\n+ # Re-raise the exception with some additional context\n+ raise Exception (f\"{label}: {str (e)}\")\n+\n+ d['priority'] = priority\n+ d['label'] = label\n+ return d\n+\n+def load ():\n+ \"\"\"\n+ Main entry point to initialize the classifier\n+ \"\"\"\n+ return classifier (forgelabels.load ())\n+\n+def main ():\n+ \"\"\"\n+ Entry point for testing the classifier.\n+ Use it with something like:\n+ (cd srcroot; find . -type f -print) | ./classify.py\n+ \"\"\"\n+ my_classifier = load ()\n+ for f in sys.stdin.readlines ():\n+ labels = my_classifier.map_to_labels (f[1:].strip ('\\n'))\n+ print (f\"{f.strip ('\\n')}: {labels}\")\n+\n+if __name__ == \"__main__\":\n+ main ()\ndiff --git a/contrib/forge/forgelabels.py b/contrib/forge/forgelabels.py\nnew file mode 100755\nindex 000000000000..b4b42ba0feb4\n--- /dev/null\n+++ b/contrib/forge/forgelabels.py\n@@ -0,0 +1,201 @@\n+#! /usr/bin/env python3\n+\n+# Read the list of label data for a forgejo instance of GCC\n+\n+# Copyright (C) 2026 Free Software Foundation, Inc.\n+#\n+# This file is part of GCC.\n+#\n+# GCC is free software; you can redistribute it and/or modify it under\n+# the terms of the GNU General Public License as published by the Free\n+# Software Foundation; either version 3, or (at your option) any later\n+# version.\n+#\n+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+# WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n+# for more details.\n+#\n+# You should have received a copy of the GNU General Public License\n+# along with GCC; see the file COPYING3. If not see\n+# <http://www.gnu.org/licenses/>.\n+\n+# Variables needed by the script. Can be overridden by setting the\n+# same name in the environment\n+\n+import yaml\n+\n+# Prefer the libYAML implementations if available. Fall back to the\n+# pure python versions as a backup.\n+try:\n+ from yaml import CLoader as Loader, CDumper as Dumper\n+except:\n+ from yaml import Loader, Dumper\n+\n+labels_file = \"labels.yaml\"\n+\n+class match_defaults:\n+ def __init__(self, md_data):\n+ self.mclass = 'file'\n+ if 'class' in md_data:\n+ if (md_data['class'] == \"file\"\n+ or md_data['class'] == \"BZ\"):\n+ self.mclass = md_data['class']\n+ else:\n+ raise Exception (\"Unsupported match class: {md_data['class']}\")\n+\n+ # todo: Add BZ class support\n+\n+class label_match:\n+ def __init__(self, lm_data):\n+ self.file = None\n+ self.priority = 1\n+ if 'file' in lm_data:\n+ self.file = lm_data['file']\n+ if 'priority' in lm_data:\n+ self.priority = lm_data['priority']\n+ # todo: Add BZ match support\n+\n+ def file2re(self):\n+ \"\"\"\n+ Convert the extended glob file entry to a standard regular expression.\n+\n+ Supported features:\n+ ^/ at the start of an entry anchors to the root of the file tree.\n+ \\<char> passes <char> through to the RE compiler, without any of\n+ the interpretations below.\n+ /**/ matches an arbitrary depth of directories.\n+ * matches any character except '/'.\n+ + matches the literal '+'.\n+ . matches the literal '.'.\n+ (...|...[|...]+) match any of the alternatives.\n+ \"\"\"\n+ if not self.file:\n+ raise Exception (\"Match rule lacks a 'file' entry\")\n+ template = self.file\n+ pos = 0\n+ depth = 0\n+ last_char = None\n+ pattern = r''\n+ length = len (template)\n+ if template[pos] == '^':\n+ pattern += r'^'\n+ pos += 1\n+ # Don't update last char\n+ else:\n+ pattern += r'.*/'\n+\n+ while pos < length:\n+ if template[pos] == '\\\\' and pos + 1 < length:\n+ pos += 1\n+ pattern += template[pos]\n+ # '*' is mapped to '[^/]*' unless the following characters are\n+ # also '*/', in which case we match '(.*/)*'\n+ elif template[pos] == '*':\n+ if pos + 2 < length and template[:3] == '**/':\n+ pattern += r'(:?.*/)*'\n+ pos += 1\n+ else:\n+ pattern += r'[^/]*'\n+ elif template[pos] == '+':\n+ pattern += r'\\+'\n+ elif template[pos] == '(':\n+ # We don't need any groups from the regex.\n+ pattern += r'(?:'\n+ depth += 1\n+ elif template[pos] == ')':\n+ pattern += r')'\n+ depth -= 1\n+ if depth < 0:\n+ raise Exception ('Invalid template: ' + template)\n+ elif template[pos] == '.':\n+ pattern += r'\\.'\n+ elif template[pos] == '/':\n+ pattern += r'/'\n+ if (depth > 0\n+ and pos + 1 < length \n+ and (template[pos + 1] == '|'\n+ or template[pos + 1] == ')')):\n+ # We expect '/|' (or '/)' to appear at the end of\n+ # an alternative and to mean anything in any\n+ # subdirectory matched. But we may need to match\n+ # files in the alternative, so add an explicit\n+ # '.*'.\n+ pattern += r'.*'\n+ else:\n+ pattern += template[pos]\n+ last_char = template[pos]\n+ pos += 1\n+\n+ if depth != 0:\n+ raise Exception ('Invalid template: ' + template)\n+ if last_char != '/':\n+ pattern += '$'\n+\n+ return pattern\n+\n+class label:\n+ def __init__(self, l_data, group):\n+ self.name = None\n+ self.full_name = None\n+ self.desc = None\n+ self.match = None\n+ self.color_val = None\n+ self.group = group\n+ if 'name' in l_data:\n+ self.name = l_data['name']\n+ self.full_name = group.group + '/' + self.name\n+ else:\n+ raise Exception (f\"Missing label name (in group '{group.group}').\")\n+ if 'description' in l_data:\n+ self.desc = l_data['description']\n+ if 'match' in l_data:\n+ self.match = label_match(l_data['match'])\n+ def color(self):\n+ if self.color_val:\n+ return self.color_val\n+ return self.group.color\n+\n+class group:\n+ def __init__(self, gr_data):\n+ # defaults\n+ self.exclusive = False\n+ self.color = \"#ff0000\" # Red\n+ self.match_defaults = None\n+ self.labels = []\n+\n+ if 'group' in gr_data:\n+ self.group = gr_data['group']\n+ else:\n+ raise Exception ('All groups must specify their name')\n+ if 'color' in gr_data:\n+ self.color = gr_data['color']\n+ if 'exclusive' in gr_data:\n+ self.exclusive = gr_data['exclusive']\n+ if 'match_defaults' in gr_data:\n+ self.match_defaults = match_defaults(gr_data['match_defaults'])\n+ if 'labels' in gr_data:\n+ for l in gr_data['labels']:\n+ self.labels.append(label(l, self))\n+ else:\n+ raise Exception (f\"Group {self.group} must contain at least one label\")\n+\n+def load():\n+ with open(labels_file) as f:\n+ groups = []\n+ data = yaml.load (f, Loader=Loader)\n+\n+ try:\n+ for g in data['label_data']:\n+ groups.append(group(g))\n+\n+ except Exception as e:\n+ raise e\n+ return\n+ return groups\n+\n+def main():\n+ print (load())\n+\n+if __name__ == \"__main__\":\n+ main()\ndiff --git a/contrib/forge/labels.yaml b/contrib/forge/labels.yaml\nnew file mode 100644\nindex 000000000000..4abe4779b975\n--- /dev/null\n+++ b/contrib/forge/labels.yaml\n@@ -0,0 +1,926 @@\n+# Provisional list of labels for the gcc forge:\n+#\n+# Copyright (C) 2026 Free Software Foundation, Inc.\n+#\n+# This file is part of GCC.\n+#\n+# GCC is free software; you can redistribute it and/or modify it under\n+# the terms of the GNU General Public License as published by the Free\n+# Software Foundation; either version 3, or (at your option) any later\n+# version.\n+#\n+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+# WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n+# for more details.\n+#\n+# You should have received a copy of the GNU General Public License\n+# along with GCC; see the file COPYING3. If not see\n+# <http://www.gnu.org/licenses/>.\n+\n+# Tags are not exclusive unless otherwise stated.\n+\n+# Note, *** indicates that this matches a strict category, but perhaps\n+# we shouldn't permit these in labels.\n+\n+# Format of this file:\n+#\n+# We currently recognize three classes matching rule for auto-applying\n+# labels: BZ, file and none.\n+# The matching rules are inherrited up the data scopes with the inner\n+# most rule taking precedence. If no rule can be found, then the\n+# default rule of 'none' is applied.\n+# - BZ\n+# If the patch cover letter references a Bugzilla ticket, the ticket\n+# number will be looked up in the Bugzilla database and the\n+# appropriate data used to apply the relevant label.\n+# - file\n+# The extended glob patterns are matched against the files modified\n+# and the label is attached if the pattern matches and no higher\n+# priority matches exist. The default priority for a match is 1\n+# - none\n+# Can be used to disable a label from being selected by matching\n+# when a default class would otherwise be inherrited.\n+\n+\n+label_data: \n+ # Bug reports\n+ # All of these labels are expected to be automatically scraped from\n+ # the primary (first-referenced) bugzilla entry that is identified\n+ # from the cover text of a patch. Note that they will not be\n+ # automatically updated if the bugzilla entry is changed after the\n+ # pull request has been created.\n+ - group: Bug\n+ # Labels relating to bugs with a 'regression' marker in the\n+ # bug summary.\n+ exclusive: false\n+ color: \"bd0000\"\n+ labels:\n+ - name: Regression\n+ description: \"The referenced Bugzilla ticket is a regression\"\n+ match:\n+ class: BZ\n+ field: summary\n+ value: \"imatch(\\\\[[^\\\\]]*regression\\\\])\"\n+ - group: Bug/Importance\n+ exclusive: true\n+ color: \"f06d00\"\n+ match_defaults:\n+ class: BZ\n+ field: importance\n+ labels:\n+ - name: \"P1\"\n+ description: \"The Bugzilla ticket has priority P1\"\n+ match:\n+ value: \"== 'P1'\"\n+ - name: \"P2\"\n+ description: \"The Bugzilla ticket has priority P2\"\n+ match:\n+ value: \"== 'P2'\"\n+ - name: \"P3\"\n+ description: \"The Bugzilla ticket has priority P3\"\n+ match:\n+ value: \"== 'P3'\"\n+ - name: \"P4\"\n+ description: \"The Bugzilla ticket has priority P4\"\n+ match:\n+ value: \"== 'P4'\"\n+ - name: \"P5\"\n+ description: \"The Bugzilla ticket has priority P5\"\n+ match:\n+ value: \"== 'P5'\"\n+ # Labels relating to bugs with a specific component. The final\n+ # part of the label should be a string match for the component\n+ # field of the BZ entry.\n+ - group: \"Bug/Component\"\n+ exclusive: true\n+ color: \"fbca04\"\n+ match_defaults:\n+ class: BZ\n+ field: component\n+ label_name: true\n+ labels:\n+ - name: \"ada\"\n+ description: \"The Bugzilla component is 'ada'\"\n+ - name: \"algol68\"\n+ description: \"The Bugzilla component is 'algol68'\"\n+ - name: \"analyzer\"\n+ description: \"The Bugzilla component is 'analyzer'\"\n+ - name: \"boehm-gc\"\n+ description: \"The Bugzilla component is 'boehm-gc'\"\n+ - name: \"bootstrap\"\n+ description: \"The Bugzilla component is 'bootstrap'\"\n+ - name: \"c\"\n+ description: \"The Bugzilla component is 'c'\"\n+ - name: \"c++\"\n+ description: \"The Bugzilla component is 'c++'\"\n+ - name: \"cobol\"\n+ description: \"The Bugzilla component is 'cobol'\"\n+ - name: \"d\"\n+ description: \"The Bugzilla component is 'd'\"\n+ - name: \"debug\"\n+ description: \"The Bugzilla component is 'debug'\"\n+ - name: \"demangler\"\n+ description: \"The Bugzilla component is 'demangler'\"\n+ - name: \"diagnostics\"\n+ description: \"The Bugzilla component is 'diagnostics'\"\n+ - name: \"driver\"\n+ description: \"The Bugzilla component is 'driver'\"\n+ - name: \"fortran\"\n+ description: \"The Bugzilla component is 'fortran'\"\n+ - name: \"gcov-profile\"\n+ description: \"The Bugzilla component is 'gcov-profile'\"\n+ - name: \"go\"\n+ description: \"The Bugzilla component is 'go'\"\n+ - name: \"ipa\"\n+ description: \"The Bugzilla component is 'ipa'\"\n+ - name: \"jit\"\n+ description: \"The Bugzilla component is 'jit'\"\n+ - name: \"libbacktrace\"\n+ description: \"The Bugzilla component is 'libbacktrace'\"\n+ - name: \"libcc1\"\n+ description: \"The Bugzilla component is 'libcc1'\"\n+ - name: \"libffi\"\n+ description: \"The Bugzilla component is 'libffi'\"\n+ - name: \"libfortran\"\n+ description: \"The Bugzilla component is 'libfortran'\"\n+ - name: \"libgcc\"\n+ description: \"The Bugzilla component is 'libgcc'\"\n+ - name: \"libgdiagnostics\"\n+ description: \"The Bugzilla component is 'libdiagnostics'\"\n+ - name: \"libgomp\"\n+ description: \"The Bugzilla component is 'libgomp'\"\n+ - name: \"libitm\"\n+ description: \"The Bugzilla component is 'libitm'\"\n+ - name: \"libobjc\"\n+ description: \"The Bugzilla component is 'libobjc'\"\n+ - name: \"libquadmath\"\n+ description: \"The Bugzilla component is 'libquadmath'\"\n+ - name: \"libstdc++\"\n+ description: \"The Bugzilla component is 'libstdc++'\"\n+ - name: \"lto\"\n+ description: \"The Bugzilla component is 'lto'\"\n+ - name: \"middle-end\"\n+ description: \"The Bugzilla component is 'middle-end'\"\n+ - name: \"modula2\"\n+ description: \"The Bugzilla component is 'modula2'\"\n+ - name: \"objc\"\n+ description: \"The Bugzilla component is 'objc'\"\n+ - name: \"other\"\n+ description: \"The Bugzilla component is 'other'\"\n+ - name: \"pch\"\n+ description: \"The Bugzilla component is 'pch'\"\n+ - name: \"pending\"\n+ description: \"The Bugzilla component is 'pending'\"\n+ - name: \"plugins\"\n+ description: \"The Bugzilla component is 'plugins'\"\n+ - name: \"preprocessor\"\n+ description: \"The Bugzilla component is 'preprocessor'\"\n+ - name: \"regression\"\n+ description: \"The Bugzilla component is 'regression'\"\n+ - name: \"rtl-optimization\"\n+ description: \"The Bugzilla component is 'rtl-optimization'\"\n+ - name: \"rust\"\n+ description: \"The Bugzilla component is 'rust'\"\n+ - name: \"sanitizer\"\n+ description: \"The Bugzilla component is 'sanitizer'\"\n+ - name: \"sarif-replay\"\n+ description: \"The Bugzilla component is 'sarif-replay'\"\n+ - name: \"target\"\n+ description: \"The Bugzilla component is 'target'\"\n+ - name: \"testsuite\"\n+ description: \"The Bugzilla component is 'testsuite'\"\n+ - name: \"translation\"\n+ description: \"The Bugzilla component is 'translation'\"\n+ - name: \"tree-optimization\"\n+ description: \"The Bugzilla component is 'tree-optimization'\"\n+ - name: \"web\"\n+ description: \"The Bugzilla component is 'web'\"\n+ # Labels relating to releases (for backporting)\n+ - group: \"Release\"\n+ exclusive: false\n+ color: \"5319e7\"\n+ labels:\n+ - name: \"GCC-13\"\n+ description: \"Consider backporting to GCC-13\"\n+ - name: \"GCC-14\"\n+ description: \"Consider backporting to GCC-14\"\n+ - name: \"GCC-15\"\n+ description: \"Consider backporting to GCC-15\"\n+ - name: \"GCC-16\"\n+ description: \"Consider backporting to GCC-16\"\n+ # Labels related to components\n+ # Note that multiple labels in this section can be applied, based on\n+ # the files modified.\n+ - group: \"General\"\n+ exclusive: false\n+ color: \"006b75\"\n+ match_defaults:\n+ class: \"file\"\n+ labels:\n+ - name: \"config\"\n+ description: \"Affects configure or autoconf scripts\"\n+ match:\n+ file: \"^/(config/|**/*.(in|ac|m4)|**/configure*)\"\n+ priority: 2\n+ - name: \"contrib\"\n+ description: \"Miscellaneous support scripts\"\n+ match:\n+ file: \"^/contrib/\"\n+ - name: \"make\"\n+ description: \"Affects Makefiles or automake\"\n+ match:\n+ file: \"(Makefile(.*)?|*.am)\"\n+ priority: 2\n+ - name: \"driver\"\n+ description: \"GCC main driver program\"\n+ match:\n+ file: \"^/gcc/gcc(-main|-ar)?.(cc|h)\"\n+ - name: \"forge\"\n+ description: \"Forge and CI infrastructure\"\n+ match:\n+ file: \"^/.(forgejo|github)/\"\n+ - name: \"unknown\"\n+ description: \"Catch-all, does not match any other category\"\n+ match:\n+ file: \"*\"\n+ priority: 10\n+ - name: \"gdbhooks\"\n+ description: \"Support for debugging GCC with GDB (gdbhooks.py)\"\n+ match:\n+ file: \"^/gcc/gdb(hooks.py|init.in)\"\n+ - name: \"docs\"\n+ description: \"Changes to the documentation\"\n+ match:\n+ file: \"(docs?/|*.texi)\"\n+ - name: \"web\"\n+ description: \"Changes to the web pages\"\n+ # No match entry!\n+\n+ # Library components\n+ - group: \"Library\"\n+ exclusive: false\n+ color: \"009800\"\n+ match_defaults:\n+ class: \"file\"\n+ labels:\n+ - name: \"libada\"\n+ description: \"Affects libada\"\n+ match:\n+ file: \"^/libada/\"\n+ - name: \"libatomic\"\n+ description: \"Affects libatomic\"\n+ match:\n+ file: \"^/libatomic/\"\n+ - name: \"libbacktrace\"\n+ description: \"Affects libbacktrace\"\n+ match:\n+ file: \"^/libbacktrace/\"\n+ - name: \"libcc1\"\n+ description: \"Affects libcc1\"\n+ match:\n+ file: \"^/libcc1/\"\n+ - name: \"libcody\"\n+ description: \"Affects libcody\"\n+ match:\n+ file: \"^/libcody/\"\n+ - name: \"libcpp\"\n+ description: \"Affects libcpp\"\n+ match:\n+ file: \"^/libcpp/\"\n+ - name: \"libdecnumber\"\n+ description: \"Affects libdecnumber\"\n+ match:\n+ file: \"^/libdecnumber/\"\n+ - name: \"libffi\"\n+ description: \"Affects libffi\"\n+ match:\n+ file: \"^/libffi/\"\n+ - name: \"libgcc\"\n+ description: \"Affects libgcc\"\n+ match:\n+ file: \"^/libgcc/\"\n+ - name: \"libgcobol\"\n+ description: \"Affects libgcobol\"\n+ match:\n+ file: \"^/libgcobol/\"\n+ - name: \"libgfortran\"\n+ description: \"Affects libgfortran\"\n+ match:\n+ file: \"^/libgfortran/\"\n+ - name: \"libgm2\"\n+ description: \"Affects libgm2\"\n+ match:\n+ file: \"^/libgm2/\"\n+ - name: \"libgo\"\n+ description: \"Affects libgo\"\n+ match:\n+ file: \"^/libgo/\"\n+ - name: \"libgomp\"\n+ description: \"Affects libgomp\"\n+ match:\n+ file: \"^/libgomp/\"\n+ - name: \"libgrust\"\n+ description: \"Affects libgrust\"\n+ match:\n+ file: \"^/libgrust/\"\n+ - name: \"libiberty\"\n+ description: \"Affects libiberty\"\n+ match:\n+ file: \"^/(include|libiberty)/\"\n+ - name: \"libitm\"\n+ description: \"Affects libitm\"\n+ match:\n+ file: \"^/libitm/\"\n+ - name: \"libobjc\"\n+ description: \"Affects libobjc\"\n+ match:\n+ file: \"^/libobjc/\"\n+ - name: \"libphobos\"\n+ description: \"Affects libphobos\"\n+ match:\n+ file: \"^/libphobos/\"\n+ - name: \"libquadmath\"\n+ description: \"Affects libquadmath\"\n+ match:\n+ file: \"^/libquadmath/\"\n+ - name: \"libsanitizer\"\n+ description: \"Affects libsanitizer\"\n+ match:\n+ file: \"^/libsanitizer/\"\n+ - name: \"libssp\"\n+ description: \"Affects libssp\"\n+ match:\n+ file: \"^/libssp/\"\n+ - name: \"libstdc++\"\n+ description: \"Affects libstdc++\"\n+ match:\n+ file: \"^/libstdc++-v3/\"\n+ - name: \"libvtv\"\n+ description: \"Affects libvtv\"\n+ match:\n+ file: \"^/libvtv/\"\n+ - name: \"zlib\"\n+ description: \"Affects zlib\"\n+ match:\n+ file: \"^/zlib/\"\n+ # CPU targets (in compiler or in libraries)\n+ - group: \"Target\"\n+ exclusive: false\n+ color: \"70c24a\"\n+ match_defaults:\n+ class: \"file\"\n+ labels:\n+ - name: \"aarch64\"\n+ description: \"Affects the aarch64 target\"\n+ match:\n+ file: \"config/aarch64/\"\n+ - name: \"alpha\"\n+ description: \"Affects the alpha target\"\n+ match:\n+ file: \"config/alpha/\"\n+ - name: \"arc\"\n+ description: \"Affects the arc target\"\n+ match:\n+ file: \"config/arc/\"\n+ - name: \"arm\"\n+ description: \"Affects the arm target\"\n+ match:\n+ file: \"config/arm/\"\n+ - name: \"avr\"\n+ description: \"Affects the avr target\"\n+ match:\n+ file: \"config/avr/\"\n+ - name: \"bfin\"\n+ description: \"Affects the bfin target\"\n+ match:\n+ file: \"config/bfin/\"\n+ - name: \"bpf\"\n+ description: \"Affects the bpf target\"\n+ match:\n+ file: \"config/bpf/\"\n+ - name: \"c6x\"\n+ description: \"Affects the c6x target\"\n+ match:\n+ file: \"config/c6x/\"\n+ - name: \"cris\"\n+ description: \"Affects the cris target\"\n+ match:\n+ file: \"config/cris/\"\n+ - name: \"csky\"\n+ description: \"Affects the csky target\"\n+ match:\n+ file: \"config/csky/\"\n+ - name: \"epiphany\"\n+ description: \"Affects the epiphany target\"\n+ match:\n+ file: \"config/epiphany/\"\n+ - name: \"fr30\"\n+ description: \"Affects the fr30 target\"\n+ match:\n+ file: \"config/fr30/\"\n+ - name: \"frv\"\n+ description: \"Affects the frv target\"\n+ match:\n+ file: \"config/frv/\"\n+ - name: \"ft32\"\n+ description: \"Affects the ft32 target\"\n+ match:\n+ file: \"config/ft32/\"\n+ - name: \"gcn\"\n+ description: \"Affects the gcn target\"\n+ match:\n+ file: \"config/gcn/\"\n+ - name: \"h8300\"\n+ description: \"Affects the h8300 target\"\n+ match:\n+ file: \"config/h8300/\"\n+ - name: \"i386\"\n+ description: \"Affects the i386 target\"\n+ match:\n+ file: \"config/i386/\"\n+ - name: \"ia64\"\n+ description: \"Affects the ia64 target\"\n+ match:\n+ file: \"config/ia64/\"\n+ - name: \"iq2000\"\n+ description: \"Affects the iq2000 target\"\n+ match:\n+ file: \"config/iq2000/\"\n+ - name: \"lm32\"\n+ description: \"Affects the lm32 target\"\n+ match:\n+ file: \"config/lm32/\"\n+ - name: \"loongarch\"\n+ description: \"Affects the loongarch target\"\n+ match:\n+ file: \"config/loongarch/\"\n+ - name: \"m32c\"\n+ description: \"Affects the m32c target\"\n+ match:\n+ file: \"config/m32c/\"\n+ - name: \"m32r\"\n+ description: \"Affects the m32r target\"\n+ match:\n+ file: \"config/m32r/\"\n+ - name: \"m68k\"\n+ description: \"Affects the m68k target\"\n+ match:\n+ file: \"config/m68k/\"\n+ - name: \"mcore\"\n+ description: \"Affects the mcore target\"\n+ match:\n+ file: \"config/mcore/\"\n+ - name: \"microblaze\"\n+ description: \"Affects the microblaze target\"\n+ match:\n+ file: \"config/microblaze/\"\n+ - name: \"mips\"\n+ description: \"Affects the mips target\"\n+ match:\n+ file: \"config/mips/\"\n+ - name: \"mmix\"\n+ description: \"Affects the mmix target\"\n+ match:\n+ file: \"config/mmix/\"\n+ - name: \"mn10300\"\n+ description: \"Affects the mn1030 target\"\n+ match:\n+ file: \"config/mn10300/\"\n+ - name: \"moxie\"\n+ description: \"Affects the moxie target\"\n+ match:\n+ file: \"config/moxie/\"\n+ - name: \"msp430\"\n+ description: \"Affects the msp430 target\"\n+ match:\n+ file: \"config/msp430/\"\n+ - name: \"nds32\"\n+ description: \"Affects the nds32 target\"\n+ match:\n+ file: \"config/nds32/\"\n+ - name: \"nvptx\"\n+ description: \"Affects the nvptx target\"\n+ match:\n+ file: \"config/nvptx/\"\n+ - name: \"or1k\"\n+ description: \"Affects the or1k target\"\n+ match:\n+ file: \"config/or1k/\"\n+ - name: \"pa\"\n+ description: \"Affects the pa target\"\n+ match:\n+ file: \"config/pa/\"\n+ - name: \"pdp11\"\n+ description: \"Affects the pdp1 target\"\n+ match:\n+ file: \"config/pdp11/\"\n+ - name: \"pru\"\n+ description: \"Affects the pru target\"\n+ match:\n+ file: \"config/pru/\"\n+ - name: \"riscv\"\n+ description: \"Affects the riscv target\"\n+ match:\n+ file: \"config/riscv/\"\n+ - name: \"rl78\"\n+ description: \"Affects the rl78 target\"\n+ match:\n+ file: \"config/rl78/\"\n+ - name: \"rs6000\"\n+ description: \"Affects the rs6000 target\"\n+ match:\n+ file: \"config/rs6000/\"\n+ - name: \"rx\"\n+ description: \"Affects the rx target\"\n+ match:\n+ file: \"config/rx/\"\n+ - name: \"s390\"\n+ description: \"Affects the s390 target\"\n+ match:\n+ file: \"config/s390/\"\n+ - name: \"sh\"\n+ description: \"Affects the sh target\"\n+ match:\n+ file: \"config/sh/\"\n+ - name: \"sparc\"\n+ description: \"Affects the sparc target\"\n+ match:\n+ file: \"config/sparc/\"\n+ - name: \"stormy16\"\n+ description: \"Affects the stormy16 target\"\n+ match:\n+ file: \"config/x?stormy16/\"\n+ - name: \"v850\"\n+ description: \"Affects the v850 target\"\n+ match:\n+ file: \"config/v850/\"\n+ - name: \"vax\"\n+ description: \"Affects the vax target\"\n+ match:\n+ file: \"config/vax/\"\n+ - name: \"visium\"\n+ description: \"Affects the visium target\"\n+ match:\n+ file: \"config/visium/\"\n+ - name: \"xtensa\"\n+ description: \"Affects the xtensa target\"\n+ match:\n+ file: \"config/xtensa/\"\n+ # Labels specific to an object file format\n+ - group: \"Obj\"\n+ exclusive: false\n+ color: \"b0ffb0\"\n+ match_defaults:\n+ class: \"file\"\n+ labels:\n+ - name: \"coff\"\n+ description: \"Target independent code related to COFF object format\"\n+ match:\n+ file: \"*coff*\"\n+ priority: 2\n+ - name: \"elf\"\n+ description: \"Target independent code related to COFF object format\"\n+ match:\n+ file: \"*elf*\"\n+ priority: 2\n+ - name: \"pe\"\n+ description: \"Target independent code related to PE-COFF object format\"\n+ # No auto-match entry.\n+ # Labels relating to a specific OS\n+ - group: \"OS\"\n+ exclusive: false\n+ color: \"b0fff9\"\n+ match_defaults:\n+ class: \"file\"\n+ labels:\n+ - name: \"aix\"\n+ description: \"Affects AIX OS\"\n+ match:\n+ file: \"rs6000/*aix*\"\n+ - name: \"android\"\n+ description: \"Affects Android OS\"\n+ match:\n+ file: \"*android*\"\n+ - name: \"cygwin\"\n+ description: \"Affects cywin or mingw OSes\"\n+ match:\n+ file: \"(config/mingw/|*(cyqwin|mingw)*)\"\n+ - name: \"darwin\"\n+ description: \"Affects Darwin OS\"\n+ match:\n+ file: \"*darwin*\"\n+ - name: \"dragonfly\"\n+ description: \"Affects Dragonfly OS\"\n+ match:\n+ file: \"*dragonfly*\"\n+ - name: \"freebsd\"\n+ description: \"Affects FreeBSD OS\"\n+ match:\n+ file: \"*freebsd*\"\n+ - name: \"hpux\"\n+ description: \"Affects HP-UX OS\"\n+ match:\n+ file: \"*hpux*\"\n+ - name: \"hurd\"\n+ description: \"Affects GNU Hurd OS\"\n+ match:\n+ file: \"*hurd*\"\n+ - name: \"linux\"\n+ description: \"Affects generic Linux OS\"\n+ match:\n+ file: \"*linux*\"\n+ priority: 2\n+ - name: \"netbsd\"\n+ description: \"Affects NetBSD OS\"\n+ match:\n+ file: \"*netbsd*\"\n+ - name: \"openbsd\"\n+ description: \"Affects OpenBSD OS\"\n+ match:\n+ file: \"*openbsd*\"\n+ - name: \"rtems\"\n+ description: \"Affects RTEMS OS\"\n+ match:\n+ file: \"*rtems*\"\n+ - name: \"solaris\"\n+ description: \"Affects Solaris OS\"\n+ match:\n+ file: \"(sol2*|*solaris*)\"\n+ - name: \"vms\"\n+ description: \"Affects VMS OS\"\n+ match:\n+ file: \"(*[^a-z])?vms*\"\n+ - name: \"vxworks\"\n+ description: \"Affects VxWorks\"\n+ match:\n+ file: \"(config/vxworks/|*vxworks*)\"\n+ - name: \"windows\"\n+ description: \"Affects Windows OS\"\n+ match:\n+ file: \"*windows*\"\n+ # Labels relating to compiler mid-end\n+ - group: \"Midend\"\n+ exclusive: false\n+ color: \"207de5\"\n+ match_defaults:\n+ class: \"file\"\n+ labels:\n+ - name: \"diagnostics\"\n+ description: \"Diagnostics framework\"\n+ match:\n+ file: \"^/gcc/(diagnostics/|text-art/|*diagnostic*|*sarif*)\"\n+ - name: \"rtl\"\n+ description: \"General RTL code\"\n+ match:\n+ file: \"^/gcc/*.(cc|c|h)\"\n+ priority: 3\n+ - name: \"reg-alloc\"\n+ description: \"Register allocation code\"\n+ match:\n+ file: \"^/gcc/*(ira|lra)*\"\n+ - name: \"tree\"\n+ description: \"General tree/gimple code\"\n+ match:\n+ file: \"^/gcc/*tree*\"\n+ priority: 2\n+ - name: \"vect\"\n+ description: \"Vectorization\"\n+ match:\n+ file: \"^/gcc/*vect*\"\n+ - name: \"cfg\"\n+ description: \"Control Flow Graph framework\"\n+ match:\n+ file: \"^/gcc/*cfg*\"\n+ - name: \"ggc\"\n+ description: \"Garbage collection\"\n+ match:\n+ file: \"^/gcc/*ggc*\"\n+ - name: \"gen\"\n+ description: \"Generator programs, eg genattr\"\n+ match:\n+ file: \"^/gcc/gen*.(cc|h)\"\n+ - name: \"ipa\"\n+ description: \"Inter Procedural Analysis framework\"\n+ match:\n+ file: \"^/gcc/ipa*\"\n+ - name: \"misc\"\n+ description: \"Miscellaneous files that doesn't fit anything else\"\n+ match:\n+ file: \"^/gcc/*\"\n+ priority: 4\n+ - name: \"lto\"\n+ description: \"Link Time Optimizer code\"\n+ match:\n+ file: \"^/gcc/(lto/|*lto*)\"\n+ - name: \"jit\"\n+ description: \"JIT (Just-In-Time) code\"\n+ match:\n+ file: \"^/gcc/jit/\"\n+ - name: \"include\"\n+ description: \"Include headers and fixincludes\"\n+ match:\n+ file: \"^/(fixincludes|gcc/ginclude)/\"\n+ - name: \"dwarf\"\n+ description: \"Dwarf debug information\"\n+ match:\n+ file: \"^/gcc/**/*dwarf*\"\n+ - name: \"debug\"\n+ description: \"Non-dwarf debug support\"\n+ match:\n+ file: \"^/gcc/*ctf*\"\n+ - name: \"gimple\"\n+ description: \"General GIMPLE support\"\n+ match:\n+ file: \"^/gcc/*gimple*\"\n+ - name: \"gcse\"\n+ description: \"RTL GCSE\"\n+ match:\n+ file: \"^/gcc/*gcse*\"\n+ - name: \"jump\"\n+ description: \"Jump and branch optimizations\"\n+ match:\n+ file: \"^/gcc/*jump*\"\n+ - name: \"i18n\"\n+ description: \"Internationalization and Localization\"\n+ match:\n+ file: \"^/gcc/(po/|intl.*)\"\n+ - name: \"gcov\"\n+ description: \"GCOV code coverage support\"\n+ match:\n+ file: \"^/gcc/gcov*\"\n+ - name: \"opts\"\n+ description: \"Option framework\"\n+ match:\n+ file: \"^/gcc/(opt*.awk|*.opt|opt[-s]*)\"\n+ - name: \"ranger\"\n+ description: \"Value range framework\"\n+ match:\n+ file: \"^/gcc/*range*\"\n+ - name: \"rtl-ssa\"\n+ description: \"RTL SSA framework\"\n+ match:\n+ file: \"^/gcc/rtl-ssa/\"\n+ - name: \"tree-ssa\"\n+ description: \"Tree SSA framework\"\n+ match:\n+ file: \"^/gcc/(tree|gimple)-ssa*\"\n+ - name: \"autofdo\"\n+ description: \"AutoFDO framework\"\n+ match:\n+ file: \"^/gcc/auto-profile*\"\n+ - name: \"combine\"\n+ description: \"Instruction Combiner\"\n+ match:\n+ file: \"^/gcc/combine*\"\n+ - name: \"reload\"\n+ description: \"Legacy reload pass (obsolete)\"\n+ match:\n+ file: \"^/gcc/reload*\"\n+ - name: \"pair-fusion\"\n+ description: \"Pair Fusion framework\"\n+ match:\n+ file: \"^/gcc/pair-fusion*\"\n+ - name: \"ivopts\"\n+ description: \"Loop IVopt framework\"\n+ match:\n+ file: \"^/gcc/*loop-iv*\"\n+ - name: \"loop\"\n+ description: \"Loop optimizations\"\n+ match:\n+ file: \"^/gcc/*loop*\"\n+ - name: \"openacc\"\n+ description: \"OpenACC framework\"\n+ # No auto-match entry\n+ - name: \"openmp\"\n+ description: \"OpenMP framework\"\n+ match:\n+ file: \"^/gcc/omp*\"\n+ - name: \"analyzer\"\n+ description: \"Static analyzer\"\n+ match:\n+ file: \"^/gcc/analyzer/\"\n+ # Labels relating to language frontends\n+ - group: \"Frontend\"\n+ exclusive: false\n+ color: \"0052cc\"\n+ match_defaults:\n+ class: \"file\"\n+ labels:\n+ - name: \"ada\"\n+ description: \"The Ada frontend\"\n+ match:\n+ file: \"^/gcc/ada/\"\n+ - name: \"algol68\"\n+ description: \"The Algol68 frontend\"\n+ match:\n+ file: \"^/gcc/algol68/\"\n+ - name: \"c\"\n+ description: \"The C frontend\"\n+ match:\n+ file: \"^/gcc/c(|-family)/\"\n+ - name: \"c++\"\n+ description: \"The C++ frontend\"\n+ match:\n+ file: \"^/gcc/c(p|-family)/\"\n+ - name: \"cobol\"\n+ description: \"The COBOL frontend\"\n+ match:\n+ file: \"^/gcc/cobol/\"\n+ - name: \"d\"\n+ description: \"The D frontend\"\n+ match:\n+ file: \"^/gcc/d/\"\n+ - name: \"fortran\"\n+ description: \"The Fortran frontend\"\n+ match:\n+ file: \"^/gcc/fortran/\"\n+ - name: \"go\"\n+ description: \"The Go frontend\"\n+ match:\n+ file: \"^/gcc/(go/|godump*)\"\n+ - name: \"m2\"\n+ description: \"The Modula-2 frontend\"\n+ match:\n+ file: \"^/gcc/m2/\"\n+ - name: \"objc\"\n+ description: \"The Objective-C/-C++ frontends\"\n+ match:\n+ file: \"^/gcc/objcp?/\"\n+ - name: \"rust\"\n+ description: \"The Rust frontend\"\n+ match:\n+ file: \"^/gcc/rust/\"\n+ # Labels relating to testsuites (probably incomplete)\n+ - group: \"Tests\"\n+ exclusive: false\n+ color: \"c544ff\"\n+ match_defaults:\n+ class: \"file\"\n+ labels:\n+ - name: \"framework\"\n+ description: \"Changes to the test framework (testsuite/lib)\"\n+ match:\n+ file: \"testsuite/lib/\"\n+ - name: \"torture\"\n+ description: \"Changes to legacy torture tests\"\n+ match:\n+ file: \"^/gcc/testsuite/*-torture/\"\n+ - name: \"target\"\n+ description: \"Changes to target-specific tests (use target/* as well)\"\n+ match:\n+ file: \"^/gcc/testsuite/*.target/\"\n+ - name: \"lang\"\n+ description: \"Changes to language-specific tests\"\n+ match:\n+ file: \"^/gcc/testsuite/(gcc|gdc|gfortran|g++|obj|go|cobol|gnat|ada|c-c++|gm2|rust)*/\"\n+ - name: \"lib\"\n+ description: \"Changes to top-level library tests (use Library/* as well)\"\n+ match:\n+ file: \"^/lib*/**/testsuite/\"\n+ - name: \"jit\"\n+ description: \"Changes to GCC's jit tests\"\n+ match:\n+ file: \"^/gcc/testsuite/jit.dg/\"\n+ - name: \"selftest\"\n+ description: \"Changes to GCC's self-tests\"\n+ match:\n+ file: \"^/gcc/testsuite/selftests/\"\n+ - name: \"diagnostics\"\n+ description: \"Changes to GCC's diagnostic framework tests\"\n+ match:\n+ file: \"^/gcc/testsuite/libgdiagnostics.dg/\"\n+ - name: \"sarif\"\n+ description: \"Changes to GCC's sarif tests\"\n+ match:\n+ file: \"^/gcc/testsuite/sarif-replay.dg/\"\n+\n+ # # Forge status labels\n+ # These have been removed for now. It's not clear how useful\n+ # these would be, given that we may have more than one runner\n+ #\n+ # # Labels for runners (exclusive)\n+ # - group: \"Runners\"\n+ # exclusive: true\n+ # color: \"f6c6c7\"\n+ # match_defaults:\n+ # class: \"none\"\n+ # labels:\n+ # - name: \"pending\"\n+ # description: \"Runner has started, but results not yet available\"\n+ # - name: \"unresolved\"\n+ # description: \"Runner failed for an unknown reason\"\n+ # - name: \"red\"\n+ # description: \"Check failed with errors, code not fit for committing\"\n+ # - name: \"amber\"\n+ # description: \"Check failed with warnings, manually inspect results\"\n+ # - name: \"green\"\n+ # description: \"Checks passed\"\n+ - group: \"Reviewed\"\n+ exclusive: true\n+ color: \"616161\"\n+ match_defaults:\n+ class: \"file\"\n+ labels:\n+ - name: Confirmed\n+ description: \"Issue has been confirmed\"\ndiff --git a/contrib/forge/update-labels.py b/contrib/forge/update-labels.py\nnew file mode 100755\nindex 000000000000..b8e81b617e43\n--- /dev/null\n+++ b/contrib/forge/update-labels.py\n@@ -0,0 +1,151 @@\n+#! /usr/bin/env python3\n+# Update the list of labels on a Forgejo instance\n+\n+# Copyright (C) 2026 Free Software Foundation, Inc.\n+#\n+# This file is part of GCC.\n+#\n+# GCC is free software; you can redistribute it and/or modify it under\n+# the terms of the GNU General Public License as published by the Free\n+# Software Foundation; either version 3, or (at your option) any later\n+# version.\n+#\n+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n+# WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n+# for more details.\n+#\n+# You should have received a copy of the GNU General Public License\n+# along with GCC; see the file COPYING3. If not see\n+# <http://www.gnu.org/licenses/>.\n+\n+# Variables needed by the script. Can be overridden by setting the\n+# same name in the environment\n+\n+PROJECT = \"gcc\"\n+REPO = \"gcc-test\"\n+FORGE = \"https://forge.sourceware.org/api/v1\"\n+\n+APIKEY = None\n+\n+import os, sys, forgelabels, urllib.request, json, getpass\n+\n+def setup():\n+ global PROJECT, REPO, FORGE, APIKEY\n+ PROJECT = os.getenv(\"PROJECT\", PROJECT)\n+ REPO = os.getenv(\"REPO\", REPO)\n+ FORGE = os.getenv(\"FORGE\", FORGE)\n+ APIKEY = getpass.getpass(prompt=\"API key: \")\n+ print (f\"Accessing {FORGE}/{PROJECT}/{REPO}.\")\n+\n+def read_existing():\n+ global FORGE, PROJECT, REPO\n+ try:\n+ url = f\"{FORGE}/repos/{PROJECT}/{REPO}/labels\"\n+ reply = urllib.request.urlopen(url)\n+ labels_list = json.loads(reply.read())\n+ except Exception as e:\n+ print (f\"Error reading label data: {e}\")\n+ sys.exit (1)\n+ return labels_list\n+\n+def add_label(l):\n+ global FORGE, PROJECT, REPO, APIKEY\n+ payload = {'name': l.full_name,\n+ 'color': l.color(),\n+ 'exclusive': l.group.exclusive,\n+ 'is_archived': False}\n+ if l.desc != None:\n+ payload['description'] = l.desc\n+ headers = {'Authorization': f\"token {APIKEY}\",\n+ 'accept': \"application/json\",\n+ 'Content-Type': \"application/json\"} \n+ try:\n+ url = f\"{FORGE}/repos/{PROJECT}/{REPO}/labels\"\n+ payload = json.dumps (payload).encode(\"utf-8\")\n+ request = urllib.request.Request (url, data = payload,\n+ headers = headers,\n+ method = 'POST')\n+ reply = urllib.request.urlopen(request)\n+ except Exception as e:\n+ print (f\"Error writing label data: {e}\")\n+ sys.exit (1)\n+ print (f\"Success: add {l.full_name}\")\n+\n+def modify_label(o, l):\n+ global FORGE, PROJECT, REPO, APIKEY\n+ payload = {'name': l.full_name,\n+ 'color': l.color(),\n+ 'exclusive': l.group.exclusive,\n+ 'is_archived': False}\n+ if l.desc != None:\n+ payload['description'] = l.desc\n+ headers = {'Authorization': f\"token {APIKEY}\",\n+ 'accept': \"application/json\",\n+ 'Content-Type': \"application/json\"} \n+ try:\n+ url = f\"{FORGE}/repos/{PROJECT}/{REPO}/labels/{o['id']}\"\n+ payload = json.dumps (payload).encode(\"utf-8\")\n+ request = urllib.request.Request (url, data = payload,\n+ headers = headers,\n+ method = 'PATCH')\n+ reply = urllib.request.urlopen(request)\n+ except Exception as e:\n+ print (f\"Error writing label data: {e}\")\n+ sys.exit (1)\n+ print (f\"Success: modify {l.full_name}\")\n+\n+def archive_label(o):\n+ global FORGE, PROJECT, REPO, APIKEY\n+ payload = {'name': o['name'],\n+ 'is_archived': True}\n+ headers = {'Authorization': f\"token {APIKEY}\",\n+ 'accept': \"application/json\",\n+ 'Content-Type': \"application/json\"} \n+ try:\n+ url = f\"{FORGE}/repos/{PROJECT}/{REPO}/labels/{o['id']}\"\n+ payload = json.dumps (payload).encode(\"utf-8\")\n+ request = urllib.request.Request (url, data = payload,\n+ headers = headers,\n+ method = 'PATCH')\n+ reply = urllib.request.urlopen(request)\n+ except Exception as e:\n+ print (f\"Error writing label data: {e}\")\n+ sys.exit (1)\n+ print (f\"Success: archive {o['name']}\")\n+\n+def main():\n+ setup()\n+ groups = forgelabels.load()\n+ oldlabels = read_existing()\n+ toadd = []\n+ tochange = []\n+\n+ for g in groups:\n+ for l in g.labels:\n+ matched = False\n+ for o in oldlabels:\n+ if o['name'] == l.full_name:\n+ if (o['is_archived']\n+ or o['color'] != l.color()\n+ or o['exclusive'] != l.group.exclusive\n+ or o['description'] != l.desc):\n+ tochange.append((o, l))\n+ matched = True\n+ o['matched'] = True\n+ break\n+ if not matched:\n+ toadd.append(l)\n+ for o in oldlabels:\n+ if not 'matched' in o and not o['is_archived']:\n+ archive_label(o)\n+ print (f\"To archive: {o['name']}\")\n+ for o, n in tochange:\n+ modify_label (o, n)\n+ for l in toadd:\n+ add_label (l)\n+\n+if __name__ == \"__main__\":\n+ main()\n+\n+ \n", "prefixes": [ "v1", "1/1" ] }