[bug#78354] teams: Add “codeowners” action.

Message ID 9b439e84c1b6298141f3b440b91946a012ba3adb.1746890038.git.ludo@gnu.org
State New
Headers
Series [bug#78354] teams: Add “codeowners” action. |

Commit Message

Ludovic Courtès May 10, 2025, 3:17 p.m. UTC
  * etc/teams.scm (team->codeowners-snippet, export-codeowners): New
procedures.
(main): Add “codeowners” action.
* doc/contributing.texi (Teams): Document it.

Change-Id: I601443981af374d85160833f7096d8c973873fb1
---
 doc/contributing.texi |  7 +++++++
 etc/teams.scm         | 31 +++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

Hello,

This patch enhances ‘etc/teams.scm’ so it can generate a ‘CODEOWNERS’
file.  Forgejo can read that file to direct reviews to the right people.

The result here is a 357-line file, which looks like this:

--8<---------------cut here---------------start------------->8---
gnu/packages/audio\.scm                            @guix/audio

gnu/packages/commencement\.scm                     @guix/bootstrap
gnu/packages/mes\.scm                              @guix/bootstrap

gnu/build-system/cmake\.scm                        @guix/c++
gnu/build/cmake-build-system\.scm                  @guix/c++
gnu/packages/c\.scm                                @guix/c++
gnu/packages/cmake\.scm                            @guix/c++
gnu/packages/cpp\.scm                              @guix/c++
gnu/packages/ninja\.scm                            @guix/c++
gnu/packages/valgrind\.scm                         @guix/c++
--8<---------------cut here---------------end--------------->8---

Of course we’ll have to create those teams on Codeberg so it can
be on any use.

Ludo’.


base-commit: 2e1ead7c8b449b58d571d8f16c1586b675c13ab4
  

Patch

diff --git a/doc/contributing.texi b/doc/contributing.texi
index f62939dc44..e98407edfd 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -2733,6 +2733,13 @@  Teams
 [env]$ git send-email --to=@var{ISSUE_NUMBER}@@debbugs.gnu.org -2
 @end example
 
+To generate a @file{CODEOWNERS} file, which Forgejo uses to determine
+which team or person should review changes to a given set of files, run:
+
+@example
+./etc/teams.scm codeowners > CODEOWNERS
+@end example
+
 @node Making Decisions
 @section Making Decisions
 
diff --git a/etc/teams.scm b/etc/teams.scm
index 17b5d4d1fe..5d5e104a48 100755
--- a/etc/teams.scm
+++ b/etc/teams.scm
@@ -14,6 +14,7 @@ 
 ;;; Copyright © 2022 Simon Tournier <zimon.toutoune@gmail.com>
 ;;; Copyright © 2025 Jelle Licht <jlicht@fsfe.org>
 ;;; Copyright © 2025 Cayetano Santos <csantosb@inventati.org>
+;;; Copyright © 2025 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -1016,6 +1017,34 @@  (define (patch->teams patch-file)
        (find-team-by-scope (apply diff-revisions
                                   (git-patch->revisions patch-file)))))
 
+(define (team->codeowners-snippet team)
+  (string-join (map (lambda (scope)
+                      (format #f "~50a @guix/~a"
+                              (if (regexp*? scope)
+                                  (regexp*-pattern scope)
+                                  (regexp-quote scope))
+                              (team-id team)))
+                    (team-scope team))
+               "\n"
+               'suffix))
+
+(define (export-codeowners port)
+  (let ((teams (sort-teams
+                (hash-map->list (lambda (_ value) value) %teams))))
+    (display "\
+# This -*- conf -*- file was generated by './etc/teams.scm codeowners'.
+#
+# It describes the expected reviewers for a pull request based on the
+# changed files.  Unlike what the name of the file suggests they don't
+# own the code (ownership is collective in this house!) but merely have
+# a good understanding of that area of the codebase and therefore are
+# usually suited as a reviewer.\n\n"
+             port)
+    (for-each (lambda (team)
+                (display (team->codeowners-snippet team) port)
+                (newline port))
+              teams)))
+
 
 (define (main . args)
   (match args
@@ -1049,6 +1078,8 @@  (define (main . args)
       team-names))
     (("show" . team-names)
      (list-teams team-names))
+    (("codeowners")
+     (export-codeowners (current-output-port)))
     (anything
      (format (current-error-port)
              "Usage: etc/teams.scm <command> [<args>]