Gestire le approvazioni delle richieste di pull con CODEOWNERS

Questa guida descrive la struttura, la sintassi e l'implementazione della funzionalità CODEOWNERS, che consente di controllare in modo flessibile i requisiti di approvazione delle richieste pull.

Introduzione

La funzionalità CODEOWNERS di Secure Source Manager utilizza i file nel codebase per impostare gli approvatori a livello di file. Questa opzione offre un controllo più granulare rispetto ad altre regole dei rami perché puoi assegnare proprietari specifici a file specifici e definire insiemi indipendenti di approvatori.

La funzionalità CODEOWNERS offre le seguenti funzionalità:

  • Definisci gli utenti che possono approvare le richieste di pull per file, directory e rami.
  • Configura diversi gruppi di proprietari del codice per proteggere rami diversi.
  • Assicurati che le modifiche ai file vengano esaminate dai proprietari designati.

Abilitazione della revisione del proprietario del codice

Per attivare e applicare le regole CODEOWNERS, gli amministratori della protezione dei rami devono aggiornare le regole dei rami nelle impostazioni del repository su Richiedi revisione del proprietario del codice per le richieste pull. Seleziona questa opzione nelle impostazioni della regola di diramazione. Se questa impostazione è off, il sistema ignora i file CODEOWNERS per i merge nel ramo di destinazione. Se selezioni questa opzione, il sistema blocca i push e i merge nel ramo finché i proprietari del codice non esaminano e approvano le richieste di pull.

Posizione e precedenza del file CODEOWNERS

Secure Source Manager supporta due opzioni per definire i file CODEOWNERS:

  1. File nidificati: file CODEOWNERS in qualsiasi directory tranne nella directory .securesourcemanager. I file CODEOWNERS nidificati influiscono solo sulla propria directory (incluse le sottodirectory) e i percorsi dei file al loro interno devono essere specificati in relazione alla directory in cui si trova il file CODEOWNERS. Questo è l'approccio consigliato per la maggior parte dei casi d'uso.

  2. Singolo file dedicato: se devi distinguere il file CODEOWNERS di Secure Source Manager da altri file CODEOWNERS utilizzati da altri strumenti (ad esempio, .gitlab/CODEOWNERS), puoi utilizzare un singolo file che si trova in .securesourcemanager/CODEOWNERS nella radice del repository. Se questo file esiste, Secure Source Manager ignora tutti gli altri file CODEOWNERS nello stesso ramo, inclusi quelli nidificati. La directory .securesourcemanager viene riconosciuta solo nella radice del repository.

Interazione con richieste di pull e approvazioni

Quando viene creata una richiesta di pull o quando il ramo di origine viene aggiornato con nuovi commit, il sistema utilizza solo i file CODEOWNERS del ramo base (il ramo in cui esegui l'unione) per determinare i requisiti di approvazione. Il sistema ignora le modifiche ai file CODEOWNERS all'interno del codice di push per quella verifica.

Sintassi e struttura di CODEOWNERS

Un file CODEOWNERS è composto da commenti, righe di regole e indicatori di sezione. I commenti iniziano con # e vengono ignorati dal sistema.

Formato della linea di regola

Il formato standard per una riga di regola è:

[BRANCH_GLOB] PATH_GLOB [OWNERS...]

Dove:

  • BRANCH_GLOB: un pattern glob facoltativo che specifica a quali rami si applica la regola. Se non specifichi un glob del ramo, la regola si applica a qualsiasi ramo in cui viene archiviato il file CODEOWNERS (se il ramo ha CODEOWNERS abilitato nelle regole del ramo). Ad esempio:

    • main corrisponde solo al ramo main.
    • dev-* corrisponde ai rami che iniziano con dev-.
    • *-glob corrisponde ai rami che terminano con -glob.
    • my-*-glob corrisponde a rami come my-feat-glob.
  • PATH_GLOB: un pattern glob obbligatorio che specifica i percorsi dei file a cui si applica la regola. La sintassi di Secure Source Manager si basa sui pattern gitignore.

    • Se un pattern non contiene / o contiene solo / come carattere finale, è un glob che corrisponde a qualsiasi directory.
      • *.js corrisponde ai file JavaScript ovunque.
      • build/ corrisponde alle directory denominate build ovunque.
    • Se un pattern contiene / in un punto diverso dalla fine, viene considerato un percorso relativo alla posizione del file CODEOWNERS.
      • docs/* corrisponde ai file in docs/ rispetto al file CODEOWNERS.
      • /*.js corrisponde ai file JavaScript nella stessa directory del file CODEOWNERS, ma non ai file JavaScript nidificati.
    • Un pattern che termina con / corrisponde solo alle directory e ai relativi contenuti in modo ricorsivo. Ad esempio, build-*/ corrisponde a directory come build-app/ e build-tool/ ovunque.
    • Se utilizzi .securesourcemanager/CODEOWNERS, i percorsi sono relativi alla radice del repository.
  • OWNERS: un elenco facoltativo di indirizzi email dei proprietari, separati da spazi. Se omessa, questa regola funge da esclusione del percorso.

Proprietà specifica per filiale

Il campo facoltativo BRANCH_GLOB all'inizio di una riga della regola ti consente di implementare controlli specifici per il proprietario del codice del ramo.

  • Se non specifichi un BRANCH_GLOB all'inizio della regola, la regola si applica a tutti i rami.
  • Il sistema ignora qualsiasi riga con un glob di ramo che non corrisponde al ramo corrente.

Nozioni di base sulla sintassi

  • Interpretazione dei campi: i campi sono separati da spazi.
    • I campi contenenti @ vengono identificati come indirizzi email del proprietario.
    • Se un campo senza @ precede gli indirizzi email del proprietario, viene considerato come PATH_GLOB. Ad esempio, in *.js user@example.com, *.js è il PATH_GLOB.
    • Se due campi senza @ precedono gli indirizzi email del proprietario, il primo è BRANCH_GLOB e il secondo è PATH_GLOB. Ad esempio, in main *.js user@example.com, main è BRANCH_GLOB e *.js è PATH_GLOB.
    • La stessa logica si applica se non vengono specificati proprietari: un campo è PATH_GLOB e due campi sono BRANCH_GLOB PATH_GLOB.
  • Sintassi in stile glob: Secure Source Manager utilizza la sintassi standard in stile glob (.gitignore) per le espressioni di percorso.
  • Dettagli del carattere jolly:
    • ** corrisponde a qualsiasi sequenza di caratteri, incluso /.
    • * corrisponde a qualsiasi sequenza di caratteri, tranne /.
    • ? corrisponde a qualsiasi singolo carattere, tranne /.
  • Sensibilità alle maiuscole: i file CODEOWNERS sono sensibili alle maiuscole.
  • Identificazione del proprietario: il sistema identifica i proprietari in base all'indirizzo email. Il carattere @ distingue i campi del proprietario.
  • Negli indirizzi email del proprietario, solo space e backslash devono essere sottoposti a escape.
  • Caratteri riservati: il sistema riserva i seguenti caratteri. Devi eseguire l'escape con la barra rovesciata (\) nelle espressioni di rami e percorsi: [, ], , @, *, ?, \, {, } e !.
  • Se ** viene combinato con caratteri diversi dalla barra, il sistema lo considera un normale carattere jolly. Ad esempio, /**/*.py corrisponde a qualsiasi file Python di qualsiasi profondità, /**.py viene trattato come /*.py e corrisponde solo ai file nella directory radice.

Sezioni per più set di approvazione

L'utilizzo di [Section] raggruppa le regole in approvazioni richieste indipendenti. Questa impostazione è utile per richiedere revisioni da team distinti, ad esempio Sicurezza o QA.

  • Definizione della sezione: utilizza una riga nel formato [Section Name] (utilizza un nome in linguaggio naturale).
  • Conteggio approvazioni: una sezione può includere un suffisso facoltativo [<approverCount>] per specificare un conteggio approvazioni diverso da 1. Un conteggio di 0 indica i proprietari facoltativi. Ad esempio, puoi utilizzarlo per visualizzare gli esperti di determinati file a scopo informativo senza richiedere la loro revisione.
  • Terminazione della sezione: una sezione si applica a tutte le regole che la seguono fino all'inizio della sezione successiva.
  • Regole non sezionate: il sistema tratta le regole che vengono visualizzate prima di qualsiasi definizione di [Section] come un'unica sezione unificata, che richiede un'approvazione per impostazione predefinita.
  • Consolidamento: il sistema considera le sezioni con lo stesso nome senza distinzione tra maiuscole e minuscole, anche in più file CODEOWNERS nidificati, come un'unica sezione unificata, seguendo le regole di precedenza standard.

Esclusione del percorso

Per escludere percorsi specifici da una clausola precedente più ampia, imposta zero proprietari per il percorso. Se definisci una regola senza proprietari, il sistema rimuove tutti i proprietari per quel percorso impostato dalle regole precedenti e il percorso non richiede approvazioni del proprietario.

Le corrispondenze di directory funzionano solo se terminano con / o se non contengono caratteri jolly nella parte finale.

Ad esempio, *.py non corrisponderà a una directory nascosta .py/, mentre *.py/ sì.

Risoluzione dei conflitti e precedenza

Se esiste un file .securesourcemanager/CODEOWNERS, tutti gli altri file CODEOWNERS vengono ignorati. Se un percorso corrisponde a due righe diverse nella stessa sezione, verrà applicata solo l'ultima riga. Se le righe si trovano in sezioni diverse, verranno applicate entrambe.

Il sistema utilizza una regola di precedenza basata sulla posizione per i file nidificati:

  • Le regole in un file CODEOWNERS più nidificato (più locale) sostituiscono le regole corrispondenti in un file meno nidificato.
  • Il file della directory principale CODEOWNERS ha sempre la precedenza più bassa.

File CODEOWNERS di esempio

Di seguito è riportato un esempio di file CODEOWNERS che mostra la sintassi CODEOWNERS:

# Un-sectioned rules; 1 approve required from any of owners of last matching line.
# Format: [BRANCH_GLOB] PATH_GLOB [OWNERS...]

# Make repo-admin the owner of all files of the current branch.
*   repo-admin@example.com      # No slash prefix; matches in sub-dirs too.
/**/* repo-admin@example.com      # Slash-prefix equivalent of prior line.

# Match all py files (including sub-dirs). Note repo-admin must be re-added.
*.py  repo-admin@example.com python-owner@example.com

# With repo-admin not included here, repo-admin no longer owns README.
/README.md readme-owner@example.com

/scratchpad.txt             # Can also override a path to have zero owners (path exclusion).

# Branch-specific syntax.
# Note that since un-sectioned rules are independent of sectioned rules,
# the above [Section] rules will still apply to this branch if they
# aren't modified to add e.g. `main ` as a prefix.
dev-* *             # Remove all owners reqs on dev branches.
dev-* /experimental/ exp-owner@example.com   # dev-specific owners.

# Make repo admin own all CODEOWNERS files, regardless of any prior rules.
CODEOWNERS repo-admin@example.com

# Section; 1 approval required *in addition* to owners outside this section.
[Security Team]
/secure-directory/ security-expert@example.com security-reviewer@example.com
/**/*secure\ me* security-expert@example.com security-reviewer@example.com

# Section w/ req approval count of 2 instead of 1.
[Doc Team][2]
/docs doc-expert@example.com doc-reviewer@example.com
*.md doc-expert@example.com doc-reviewer@example.com

Compatibilità con altri gestori del codice sorgente

Secure Source Manager fornisce una sintassi familiare e portatile con altri gestori del codice sorgente. La sintassi CODEOWNERS di Secure Source Manager è compatibile con la sintassi CODEOWNERS di GitHub e parzialmente compatibile con la sintassi CODEOWNERS di GitLab, inclusi i conteggi delle approvazioni sezionali come [Section Name][2].

L'implementazione di Secure Source Manager di CODEOWNERS non supporta la sintassi !path di GitLab per la negazione del percorso. Per informazioni sulla negazione del percorso in Secure Source Manager, consulta Esclusione del percorso. Secure Source Manager non supporta nemmeno i proprietari predefiniti nelle intestazioni delle sezioni, ad esempio [Section Name] @owner1 @owner2.

Gestione della convalida e degli errori

Quando visualizzi un file CODEOWNERS, la UI mostra il relativo stato e avvisi o informazioni a livello di riga (ad esempio, righe che non corrispondono a questo ramo). Puoi passare il mouse sopra i numeri di riga o le righe evidenziate per visualizzare ulteriori dettagli.

Applicazione

Un controllo pre-invio applica il controllo degli errori di sintassi a qualsiasi ramo in cui attivi la regola del ramo dei proprietari del codice. In questo modo, eviti di eseguire il check-in di file CODEOWNERS danneggiati.

Gestione degli errori di sintassi

I controlli pre-invio vengono eseguiti solo sui rami in cui è attivata l'opzione Richiedi revisione del proprietario del codice per le richieste di pull. Se un file CODEOWNERS sintatticamente non valido viene commitato a un ramo e la revisione del proprietario del codice viene abilitata in un secondo momento per quel ramo, il sistema gestisce gli errori in modo controllato:

  • Il sistema ignora le righe che non possono essere analizzate in una definizione di sezione, in una riga di regola o in un formato di commento.
  • Se un conteggio delle approvazioni è negativo, il sistema lo considera pari a 0.
  • Il sistema continua ad analizzare e applicare le righe valide come di consueto.

Passaggi successivi