From 310df2deb94e97fda5fe6955c9207f777a80e22e Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 8 Jul 2026 10:03:51 +0900 Subject: [PATCH 1/7] feat: add config for collecting chain errors, regen reference.mdx --- config.schema.json | 5 + proxy.config.json | 1 + src/config/generated/config.ts | 8 + src/config/index.ts | 7 + website/docs/configuration/reference.mdx | 591 +++++++++++++---------- 5 files changed, 364 insertions(+), 248 deletions(-) diff --git a/config.schema.json b/config.schema.json index 5b5d0dfd6..7d42971f5 100644 --- a/config.schema.json +++ b/config.schema.json @@ -297,6 +297,11 @@ "description": "Flag to enable CSRF protections for UI", "type": "boolean" }, + "collectAllChainErrors": { + "description": "When enabled, the push validation chain continues past recoverable check failures (commit messages, author e-mails, secret scanning, etc.) and reports every rejection reason in a single push, instead of stopping at the first failed check. Security and infrastructure failures still stop the chain immediately.", + "type": "boolean", + "default": true + }, "plugins": { "type": "array", "description": "List of plugins to integrate on GitProxy's push or pull actions. Each value is either a file path or a module name.", diff --git a/proxy.config.json b/proxy.config.json index 18da6c6b8..6585c522c 100644 --- a/proxy.config.json +++ b/proxy.config.json @@ -147,6 +147,7 @@ "urlShortener": "", "contactEmail": "", "csrfProtection": true, + "collectAllChainErrors": true, "plugins": [], "apiAuthentication": [ { diff --git a/src/config/generated/config.ts b/src/config/generated/config.ts index 60d2204a8..a6106e4dd 100644 --- a/src/config/generated/config.ts +++ b/src/config/generated/config.ts @@ -36,6 +36,13 @@ export interface GitProxyConfig { * List of repositories that are authorised to be pushed to through the proxy. */ authorisedList?: AuthorisedRepo[]; + /** + * When enabled, the push validation chain continues past recoverable check failures (commit + * messages, author e-mails, secret scanning, etc.) and reports every rejection reason in a + * single push, instead of stopping at the first failed check. Security and infrastructure + * failures still stop the chain immediately. + */ + collectAllChainErrors?: boolean; /** * Block commits based on rules defined over author/committer e-mail addresses, commit * message content and diff content @@ -886,6 +893,7 @@ const typeMap: any = { typ: u(undefined, a(r('AuthenticationElement'))), }, { json: 'authorisedList', js: 'authorisedList', typ: u(undefined, a(r('AuthorisedRepo'))) }, + { json: 'collectAllChainErrors', js: 'collectAllChainErrors', typ: u(undefined, true) }, { json: 'commitConfig', js: 'commitConfig', typ: u(undefined, r('CommitConfig')) }, { json: 'configurationSources', js: 'configurationSources', typ: u(undefined, 'any') }, { json: 'contactEmail', js: 'contactEmail', typ: u(undefined, '') }, diff --git a/src/config/index.ts b/src/config/index.ts index 792062863..93bc668ce 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -41,6 +41,7 @@ const REQUIRED_TOP_LEVEL_CONFIG_KEYS = [ 'attestationConfig', 'authentication', 'authorisedList', + 'collectAllChainErrors', 'commitConfig', 'configurationSources', 'contactEmail', @@ -432,6 +433,12 @@ export const getCSRFProtection = (): boolean | undefined => { return config.csrfProtection; }; +// Whether the push chain continues past recoverable failures and reports all of them at once +export const getCollectAllChainErrors = (): boolean => { + const config = loadFullConfiguration(); + return config.collectAllChainErrors !== false; +}; + // Get loadable push plugins export const getPlugins = () => { const config = loadFullConfiguration(); diff --git a/website/docs/configuration/reference.mdx b/website/docs/configuration/reference.mdx index 3c4167027..ec3b7b6f7 100644 --- a/website/docs/configuration/reference.mdx +++ b/website/docs/configuration/reference.mdx @@ -17,8 +17,7 @@ description: JSON schema reference documentation for GitProxy
- 1. [Optional] Property GitProxy configuration file > proxyUrl - + 1. [Optional] Property GitProxy configuration file > proxyUrl
@@ -27,15 +26,14 @@ description: JSON schema reference documentation for GitProxy | **Type** | `string` | | **Required** | No | -**Description:** Deprecated: Used in early versions of git proxy to configure the remote host that traffic is proxied to. In later versions, the repository URL is used to determine the domain proxied, allowing multiple hosts to be proxied by one instance. +**Description:** Deprecated: Used in early versions of GitProxy to configure the remote host that traffic is proxied to. In later versions, the repository URL is used to determine the domain proxied, allowing multiple hosts to be proxied by one instance.
- 2. [Optional] Property GitProxy configuration file > cookieSecret - + 2. [Optional] Property GitProxy configuration file > cookieSecret
@@ -49,8 +47,7 @@ description: JSON schema reference documentation for GitProxy
- 3. [Optional] Property GitProxy configuration file > sessionMaxAgeHours - + 3. [Optional] Property GitProxy configuration file > sessionMaxAgeHours
@@ -64,8 +61,7 @@ description: JSON schema reference documentation for GitProxy
- 4. [Optional] Property GitProxy configuration file > serverPort - + 4. [Optional] Property GitProxy configuration file > serverPort
@@ -81,8 +77,7 @@ description: JSON schema reference documentation for GitProxy
- 5. [Optional] Property GitProxy configuration file > httpsServerPort - + 5. [Optional] Property GitProxy configuration file > httpsServerPort
@@ -98,8 +93,7 @@ description: JSON schema reference documentation for GitProxy
- 6. [Optional] Property GitProxy configuration file > uiHost - + 6. [Optional] Property GitProxy configuration file > uiHost
@@ -115,8 +109,7 @@ description: JSON schema reference documentation for GitProxy
- 7. [Optional] Property GitProxy configuration file > uiPort - + 7. [Optional] Property GitProxy configuration file > uiPort
@@ -132,8 +125,7 @@ description: JSON schema reference documentation for GitProxy
- 8. [Optional] Property GitProxy configuration file > httpsUiPort - + 8. [Optional] Property GitProxy configuration file > httpsUiPort
@@ -149,8 +141,7 @@ description: JSON schema reference documentation for GitProxy
- 9. [Optional] Property GitProxy configuration file > api - + 9. [Optional] Property GitProxy configuration file > api
@@ -164,8 +155,7 @@ description: JSON schema reference documentation for GitProxy
- 9.1. [Optional] Property GitProxy configuration file > api > ls - + 9.1. [Optional] Property GitProxy configuration file > api > ls
@@ -179,8 +169,7 @@ description: JSON schema reference documentation for GitProxy
- 9.1.1. [Optional] Property GitProxy configuration file > api > ls > userInADGroup - + 9.1.1. [Optional] Property GitProxy configuration file > api > ls > userInADGroup
@@ -205,8 +194,7 @@ description: JSON schema reference documentation for GitProxy
- 9.2. [Optional] Property GitProxy configuration file > api > gitleaks - + 9.2. [Optional] Property GitProxy configuration file > api > gitleaks
@@ -220,8 +208,7 @@ description: JSON schema reference documentation for GitProxy
- 9.2.1. [Optional] Property GitProxy configuration file > api > gitleaks > enabled - + 9.2.1. [Optional] Property GitProxy configuration file > api > gitleaks > enabled
@@ -235,8 +222,7 @@ description: JSON schema reference documentation for GitProxy
- 9.2.2. [Optional] Property GitProxy configuration file > api > gitleaks > ignoreGitleaksAllow - + 9.2.2. [Optional] Property GitProxy configuration file > api > gitleaks > ignoreGitleaksAllow
@@ -250,8 +236,7 @@ description: JSON schema reference documentation for GitProxy
- 9.2.3. [Optional] Property GitProxy configuration file > api > gitleaks > noColor - + 9.2.3. [Optional] Property GitProxy configuration file > api > gitleaks > noColor
@@ -265,8 +250,7 @@ description: JSON schema reference documentation for GitProxy
- 9.2.4. [Optional] Property GitProxy configuration file > api > gitleaks > configPath - + 9.2.4. [Optional] Property GitProxy configuration file > api > gitleaks > configPath
@@ -286,8 +270,7 @@ description: JSON schema reference documentation for GitProxy
- 10. [Optional] Property GitProxy configuration file > commitConfig - + 10. [Optional] Property GitProxy configuration file > commitConfig
@@ -303,8 +286,7 @@ description: JSON schema reference documentation for GitProxy
- 10.1. [Optional] Property GitProxy configuration file > commitConfig > author - + 10.1. [Optional] Property GitProxy configuration file > commitConfig > author
@@ -320,8 +302,7 @@ description: JSON schema reference documentation for GitProxy
- 10.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email - + 10.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email
@@ -337,8 +318,7 @@ description: JSON schema reference documentation for GitProxy
- 10.1.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > local - + 10.1.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > local
@@ -354,8 +334,7 @@ description: JSON schema reference documentation for GitProxy
- 10.1.1.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > local > block - + 10.1.1.1.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > local > block
@@ -376,8 +355,7 @@ description: JSON schema reference documentation for GitProxy
- 10.1.1.2. [Optional] Property GitProxy configuration file > commitConfig > author > email > domain - + 10.1.1.2. [Optional] Property GitProxy configuration file > commitConfig > author > email > domain
@@ -393,8 +371,7 @@ description: JSON schema reference documentation for GitProxy
- 10.1.1.2.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > domain > allow - + 10.1.1.2.1. [Optional] Property GitProxy configuration file > commitConfig > author > email > domain > allow
@@ -421,8 +398,7 @@ description: JSON schema reference documentation for GitProxy
- 10.2. [Optional] Property GitProxy configuration file > commitConfig > message - + 10.2. [Optional] Property GitProxy configuration file > commitConfig > message
@@ -438,8 +414,7 @@ description: JSON schema reference documentation for GitProxy
- 10.2.1. [Optional] Property GitProxy configuration file > commitConfig > message > block - + 10.2.1. [Optional] Property GitProxy configuration file > commitConfig > message > block
@@ -455,8 +430,7 @@ description: JSON schema reference documentation for GitProxy
- 10.2.1.1. [Optional] Property GitProxy configuration file > commitConfig > message > block > literals - + 10.2.1.1. [Optional] Property GitProxy configuration file > commitConfig > message > block > literals
@@ -485,8 +459,7 @@ description: JSON schema reference documentation for GitProxy
- 10.2.1.2. [Optional] Property GitProxy configuration file > commitConfig > message > block > patterns - + 10.2.1.2. [Optional] Property GitProxy configuration file > commitConfig > message > block > patterns
@@ -521,8 +494,7 @@ description: JSON schema reference documentation for GitProxy
- 10.3. [Optional] Property GitProxy configuration file > commitConfig > diff - + 10.3. [Optional] Property GitProxy configuration file > commitConfig > diff
@@ -538,8 +510,7 @@ description: JSON schema reference documentation for GitProxy
- 10.3.1. [Optional] Property GitProxy configuration file > commitConfig > diff > block - + 10.3.1. [Optional] Property GitProxy configuration file > commitConfig > diff > block
@@ -555,8 +526,7 @@ description: JSON schema reference documentation for GitProxy
- 10.3.1.1. [Optional] Property GitProxy configuration file > commitConfig > diff > block > literals - + 10.3.1.1. [Optional] Property GitProxy configuration file > commitConfig > diff > block > literals
@@ -585,8 +555,7 @@ description: JSON schema reference documentation for GitProxy
- 10.3.1.2. [Optional] Property GitProxy configuration file > commitConfig > diff > block > patterns - + 10.3.1.2. [Optional] Property GitProxy configuration file > commitConfig > diff > block > patterns
@@ -616,8 +585,7 @@ description: JSON schema reference documentation for GitProxy
- 10.3.1.3. [Optional] Property GitProxy configuration file > commitConfig > diff > block > providers - + 10.3.1.3. [Optional] Property GitProxy configuration file > commitConfig > diff > block > providers
@@ -633,8 +601,7 @@ description: JSON schema reference documentation for GitProxy
- 10.3.1.3.1. Property GitProxy configuration file > commitConfig > diff > block > providers > additionalProperties - + 10.3.1.3.1. Property GitProxy configuration file > commitConfig > diff > block > providers > additionalProperties
@@ -660,8 +627,7 @@ description: JSON schema reference documentation for GitProxy
- 11. [Optional] Property GitProxy configuration file > attestationConfig - + 11. [Optional] Property GitProxy configuration file > attestationConfig
@@ -677,8 +643,7 @@ description: JSON schema reference documentation for GitProxy
- 11.1. [Optional] Property GitProxy configuration file > attestationConfig > questions - + 11.1. [Optional] Property GitProxy configuration file > attestationConfig > questions
@@ -707,8 +672,7 @@ description: JSON schema reference documentation for GitProxy
- 11.1.1.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > label - + 11.1.1.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > label
@@ -726,8 +690,7 @@ description: JSON schema reference documentation for GitProxy
- 11.1.1.2. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip - + 11.1.1.2. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip
@@ -743,8 +706,7 @@ description: JSON schema reference documentation for GitProxy
- 11.1.1.2.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > text - + 11.1.1.2.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > text
@@ -760,8 +722,7 @@ description: JSON schema reference documentation for GitProxy
- 11.1.1.2.2. [Optional] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links - + 11.1.1.2.2. [Optional] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links
@@ -786,8 +747,7 @@ description: JSON schema reference documentation for GitProxy
- 11.1.1.2.2.1.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links > links items > text - + 11.1.1.2.2.1.1. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links > links items > text
@@ -803,8 +763,7 @@ description: JSON schema reference documentation for GitProxy
- 11.1.1.2.2.1.2. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links > links items > url - + 11.1.1.2.2.1.2. [Required] Property GitProxy configuration file > attestationConfig > questions > Question > tooltip > links > links items > url
@@ -833,8 +792,7 @@ description: JSON schema reference documentation for GitProxy
- 12. [Optional] Property GitProxy configuration file > domains - + 12. [Optional] Property GitProxy configuration file > domains
@@ -844,12 +802,11 @@ description: JSON schema reference documentation for GitProxy | **Required** | No | | **Additional properties** | Any type allowed | -**Description:** Provide custom URLs for the git proxy interfaces in case it cannot determine its own URL +**Description:** Provide custom URLs for the GitProxy interfaces in case it cannot determine its own URL
- 12.1. [Optional] Property GitProxy configuration file > domains > proxy - + 12.1. [Optional] Property GitProxy configuration file > domains > proxy
@@ -868,8 +825,7 @@ description: JSON schema reference documentation for GitProxy
- 12.2. [Optional] Property GitProxy configuration file > domains > service - + 12.2. [Optional] Property GitProxy configuration file > domains > service
@@ -891,8 +847,7 @@ description: JSON schema reference documentation for GitProxy
- 13. [Optional] Property GitProxy configuration file > rateLimit - + 13. [Optional] Property GitProxy configuration file > rateLimit
@@ -906,8 +861,7 @@ description: JSON schema reference documentation for GitProxy
- 13.1. [Required] Property GitProxy configuration file > rateLimit > windowMs - + 13.1. [Required] Property GitProxy configuration file > rateLimit > windowMs
@@ -923,8 +877,7 @@ description: JSON schema reference documentation for GitProxy
- 13.2. [Required] Property GitProxy configuration file > rateLimit > limit - + 13.2. [Required] Property GitProxy configuration file > rateLimit > limit
@@ -940,8 +893,7 @@ description: JSON schema reference documentation for GitProxy
- 13.3. [Optional] Property GitProxy configuration file > rateLimit > statusCode - + 13.3. [Optional] Property GitProxy configuration file > rateLimit > statusCode
@@ -957,8 +909,7 @@ description: JSON schema reference documentation for GitProxy
- 13.4. [Optional] Property GitProxy configuration file > rateLimit > message - + 13.4. [Optional] Property GitProxy configuration file > rateLimit > message
@@ -977,8 +928,7 @@ description: JSON schema reference documentation for GitProxy
- 14. [Optional] Property GitProxy configuration file > privateOrganizations - + 14. [Optional] Property GitProxy configuration file > privateOrganizations
@@ -994,8 +944,7 @@ description: JSON schema reference documentation for GitProxy
- 15. [Optional] Property GitProxy configuration file > urlShortener - + 15. [Optional] Property GitProxy configuration file > urlShortener
@@ -1011,8 +960,7 @@ description: JSON schema reference documentation for GitProxy
- 16. [Optional] Property GitProxy configuration file > contactEmail - + 16. [Optional] Property GitProxy configuration file > contactEmail
@@ -1028,8 +976,7 @@ description: JSON schema reference documentation for GitProxy
- 17. [Optional] Property GitProxy configuration file > csrfProtection - + 17. [Optional] Property GitProxy configuration file > csrfProtection
@@ -1045,8 +992,24 @@ description: JSON schema reference documentation for GitProxy
- 18. [Optional] Property GitProxy configuration file > plugins + 18. [Optional] Property GitProxy configuration file > collectAllChainErrors + +
+ +| | | +| ------------ | --------- | +| **Type** | `boolean` | +| **Required** | No | +| **Default** | `true` | + +**Description:** When enabled, the push validation chain continues past recoverable check failures (commit messages, author e-mails, secret scanning, etc.) and reports every rejection reason in a single push, instead of stopping at the first failed check. Security and infrastructure failures still stop the chain immediately. + +
+
+
+ + 19. [Optional] Property GitProxy configuration file > plugins
@@ -1061,7 +1024,7 @@ description: JSON schema reference documentation for GitProxy | ------------------------------- | ----------- | | [plugins items](#plugins_items) | - | -### 18.1. GitProxy configuration file > plugins > plugins items +### 19.1. GitProxy configuration file > plugins > plugins items | | | | ------------ | -------- | @@ -1073,8 +1036,7 @@ description: JSON schema reference documentation for GitProxy
- 19. [Optional] Property GitProxy configuration file > authorisedList - + 20. [Optional] Property GitProxy configuration file > authorisedList
@@ -1089,7 +1051,7 @@ description: JSON schema reference documentation for GitProxy | --------------------------------------- | ----------- | | [authorisedRepo](#authorisedList_items) | - | -### 19.1. GitProxy configuration file > authorisedList > authorisedRepo +### 20.1. GitProxy configuration file > authorisedList > authorisedRepo | | | | ------------------------- | ---------------------------- | @@ -1100,8 +1062,7 @@ description: JSON schema reference documentation for GitProxy
- 19.1.1. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > project - + 20.1.1. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > project
@@ -1115,8 +1076,7 @@ description: JSON schema reference documentation for GitProxy
- 19.1.2. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > name - + 20.1.2. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > name
@@ -1130,8 +1090,7 @@ description: JSON schema reference documentation for GitProxy
- 19.1.3. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > url - + 20.1.3. [Required] Property GitProxy configuration file > authorisedList > authorisedList items > url
@@ -1148,8 +1107,40 @@ description: JSON schema reference documentation for GitProxy
- 20. [Optional] Property GitProxy configuration file > sink + 21. [Optional] Property GitProxy configuration file > limits + +
+ +| | | +| ------------------------- | ----------- | +| **Type** | `object` | +| **Required** | No | +| **Additional properties** | Not allowed | + +**Description:** Configuration for various limits + +
+ + 21.1. [Optional] Property GitProxy configuration file > limits > maxPackSizeBytes + +
+ +| | | +| ------------ | -------- | +| **Type** | `number` | +| **Required** | No | + +**Description:** Maximum size of a pack file in bytes (default 1GB) +
+
+ +
+
+ +
+ + 22. [Optional] Property GitProxy configuration file > sink
@@ -1164,7 +1155,7 @@ description: JSON schema reference documentation for GitProxy | ------------------------------- | ---------------------------------- | | [database](#sink_items) | Configuration entry for a database | -### 20.1. GitProxy configuration file > sink > database +### 22.1. GitProxy configuration file > sink > database | | | | ------------------------- | ---------------------- | @@ -1184,7 +1175,7 @@ description: JSON schema reference documentation for GitProxy
-#### 20.1.1. Property `GitProxy configuration file > sink > sink items > oneOf > item 0` +#### 22.1.1. Property `GitProxy configuration file > sink > sink items > oneOf > item 0` | | | | ------------------------- | ---------------- | @@ -1196,8 +1187,7 @@ description: JSON schema reference documentation for GitProxy
- 20.1.1.1. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > type - + 22.1.1.1. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > type
@@ -1213,8 +1203,7 @@ Specific value: `"mongo"`
- 20.1.1.2. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > enabled - + 22.1.1.2. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > enabled
@@ -1228,8 +1217,7 @@ Specific value: `"mongo"`
- 20.1.1.3. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > connectionString - + 22.1.1.3. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > connectionString
@@ -1245,8 +1233,7 @@ Specific value: `"mongo"`
- 20.1.1.4. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options - + 22.1.1.4. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options
@@ -1260,8 +1247,7 @@ Specific value: `"mongo"`
- 20.1.1.4.1. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options > authMechanismProperties - + 22.1.1.4.1. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options > authMechanismProperties
@@ -1273,8 +1259,7 @@ Specific value: `"mongo"`
- 20.1.1.4.1.1. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options > authMechanismProperties > AWS_CREDENTIAL_PROVIDER - + 22.1.1.4.1.1. [Optional] Property GitProxy configuration file > sink > sink items > oneOf > item 0 > options > authMechanismProperties > AWS_CREDENTIAL_PROVIDER
@@ -1297,7 +1282,7 @@ Specific value: `"mongo"`
-#### 20.1.2. Property `GitProxy configuration file > sink > sink items > oneOf > item 1` +#### 22.1.2. Property `GitProxy configuration file > sink > sink items > oneOf > item 1` | | | | ------------------------- | ---------------- | @@ -1309,8 +1294,7 @@ Specific value: `"mongo"`
- 20.1.2.1. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 1 > type - + 22.1.2.1. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 1 > type
@@ -1326,8 +1310,7 @@ Specific value: `"fs"`
- 20.1.2.2. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 1 > enabled - + 22.1.2.2. [Required] Property GitProxy configuration file > sink > sink items > oneOf > item 1 > enabled
@@ -1348,8 +1331,7 @@ Specific value: `"fs"`
- 21. [Optional] Property GitProxy configuration file > authentication - + 23. [Optional] Property GitProxy configuration file > authentication
@@ -1364,7 +1346,7 @@ Specific value: `"fs"` | ---------------------------------------------- | ------------------------------------------ | | [authenticationElement](#authentication_items) | Configuration for an authentication source | -### 21.1. GitProxy configuration file > authentication > authenticationElement +### 23.1. GitProxy configuration file > authentication > authenticationElement | | | | ------------------------- | ----------------------------------- | @@ -1386,7 +1368,7 @@ Specific value: `"fs"`
-#### 21.1.1. Property `GitProxy configuration file > authentication > authentication items > oneOf > Local Auth Config` +#### 23.1.1. Property `GitProxy configuration file > authentication > authentication items > oneOf > Local Auth Config` **Title:** Local Auth Config @@ -1400,8 +1382,7 @@ Specific value: `"fs"`
- 21.1.1.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Local Auth Config > type - + 23.1.1.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Local Auth Config > type
@@ -1417,8 +1398,7 @@ Specific value: `"local"`
- 21.1.1.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Local Auth Config > enabled - + 23.1.1.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Local Auth Config > enabled
@@ -1433,7 +1413,7 @@ Specific value: `"local"`
-#### 21.1.2. Property `GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config` +#### 23.1.2. Property `GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config` **Title:** Active Directory Auth Config @@ -1447,8 +1427,7 @@ Specific value: `"local"`
- 21.1.2.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > type - + 23.1.2.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > type
@@ -1464,8 +1443,7 @@ Specific value: `"ActiveDirectory"`
- 21.1.2.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > enabled - + 23.1.2.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > enabled
@@ -1479,8 +1457,7 @@ Specific value: `"ActiveDirectory"`
- 21.1.2.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adminGroup - + 23.1.2.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adminGroup
@@ -1496,8 +1473,7 @@ Specific value: `"ActiveDirectory"`
- 21.1.2.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > userGroup - + 23.1.2.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > userGroup
@@ -1506,15 +1482,14 @@ Specific value: `"ActiveDirectory"` | **Type** | `string` | | **Required** | Yes | -**Description:** Group that indicates that a user should be able to login to the Git Proxy UI and can work as a reviewer +**Description:** Group that indicates that a user should be able to login to the GitProxy UI and can work as a reviewer
- 21.1.2.5. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > domain - + 23.1.2.5. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > domain
@@ -1530,8 +1505,7 @@ Specific value: `"ActiveDirectory"`
- 21.1.2.6. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig - + 23.1.2.6. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig
@@ -1545,8 +1519,7 @@ Specific value: `"ActiveDirectory"`
- 21.1.2.6.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > url - + 23.1.2.6.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > url
@@ -1562,8 +1535,7 @@ Specific value: `"ActiveDirectory"`
- 21.1.2.6.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > baseDN - + 23.1.2.6.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > baseDN
@@ -1579,8 +1551,7 @@ Specific value: `"ActiveDirectory"`
- 21.1.2.6.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > username - + 23.1.2.6.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > username
@@ -1596,8 +1567,7 @@ Specific value: `"ActiveDirectory"`
- 21.1.2.6.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > password - + 23.1.2.6.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > password
@@ -1613,8 +1583,7 @@ Specific value: `"ActiveDirectory"`
- 21.1.2.6.5. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > searchBase - + 23.1.2.6.5. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > Active Directory Auth Config > adConfig > searchBase
@@ -1634,7 +1603,7 @@ Specific value: `"ActiveDirectory"`
-#### 21.1.3. Property `GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config` +#### 23.1.3. Property `GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config` **Title:** Open ID Connect Auth Config @@ -1648,8 +1617,7 @@ Specific value: `"ActiveDirectory"`
- 21.1.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > type - + 23.1.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > type
@@ -1665,8 +1633,7 @@ Specific value: `"openidconnect"`
- 21.1.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > enabled - + 23.1.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > enabled
@@ -1680,8 +1647,7 @@ Specific value: `"openidconnect"`
- 21.1.3.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig - + 23.1.3.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig
@@ -1695,8 +1661,7 @@ Specific value: `"openidconnect"`
- 21.1.3.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > issuer - + 23.1.3.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > issuer
@@ -1710,8 +1675,7 @@ Specific value: `"openidconnect"`
- 21.1.3.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > clientID - + 23.1.3.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > clientID
@@ -1725,8 +1689,7 @@ Specific value: `"openidconnect"`
- 21.1.3.3.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > clientSecret - + 23.1.3.3.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > clientSecret
@@ -1740,8 +1703,7 @@ Specific value: `"openidconnect"`
- 21.1.3.3.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > callbackURL - + 23.1.3.3.4. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > callbackURL
@@ -1755,8 +1717,7 @@ Specific value: `"openidconnect"`
- 21.1.3.3.5. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > scope - + 23.1.3.3.5. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > Open ID Connect Auth Config > oidcConfig > scope
@@ -1774,7 +1735,7 @@ Specific value: `"openidconnect"`
-#### 21.1.4. Property `GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config` +#### 23.1.4. Property `GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config` **Title:** JWT Auth Config @@ -1788,8 +1749,7 @@ Specific value: `"openidconnect"`
- 21.1.4.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > type - + 23.1.4.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > type
@@ -1805,8 +1765,7 @@ Specific value: `"jwt"`
- 21.1.4.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > enabled - + 23.1.4.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > enabled
@@ -1820,8 +1779,7 @@ Specific value: `"jwt"`
- 21.1.4.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig - + 23.1.4.3. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig
@@ -1835,8 +1793,7 @@ Specific value: `"jwt"`
- 21.1.4.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > clientID - + 23.1.4.3.1. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > clientID
@@ -1850,8 +1807,7 @@ Specific value: `"jwt"`
- 21.1.4.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > authorityURL - + 23.1.4.3.2. [Required] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > authorityURL
@@ -1865,8 +1821,7 @@ Specific value: `"jwt"`
- 21.1.4.3.3. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > expectedAudience - + 23.1.4.3.3. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > expectedAudience
@@ -1880,8 +1835,7 @@ Specific value: `"jwt"`
- 21.1.4.3.4. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > roleMapping - + 23.1.4.3.4. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > roleMapping
@@ -1893,8 +1847,7 @@ Specific value: `"jwt"`
- 21.1.4.3.4.1. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > roleMapping > admin - + 23.1.4.3.4.1. [Optional] Property GitProxy configuration file > authentication > authentication items > oneOf > JWT Auth Config > jwtConfig > roleMapping > admin
@@ -1922,8 +1875,7 @@ Specific value: `"jwt"`
- 22. [Optional] Property GitProxy configuration file > tempPassword - + 24. [Optional] Property GitProxy configuration file > tempPassword
@@ -1937,8 +1889,7 @@ Specific value: `"jwt"`
- 22.1. [Optional] Property GitProxy configuration file > tempPassword > sendEmail - + 24.1. [Optional] Property GitProxy configuration file > tempPassword > sendEmail
@@ -1952,8 +1903,7 @@ Specific value: `"jwt"`
- 22.2. [Optional] Property GitProxy configuration file > tempPassword > emailConfig - + 24.2. [Optional] Property GitProxy configuration file > tempPassword > emailConfig
@@ -1973,8 +1923,7 @@ Specific value: `"jwt"`
- 23. [Optional] Property GitProxy configuration file > apiAuthentication - + 25. [Optional] Property GitProxy configuration file > apiAuthentication
@@ -1989,7 +1938,7 @@ Specific value: `"jwt"` | ------------------------------------------------- | ------------------------------------------ | | [authenticationElement](#apiAuthentication_items) | Configuration for an authentication source | -### 23.1. GitProxy configuration file > apiAuthentication > authenticationElement +### 25.1. GitProxy configuration file > apiAuthentication > authenticationElement | | | | ------------------------- | --------------------------------------------- | @@ -2005,8 +1954,7 @@ Specific value: `"jwt"`
- 24. [Optional] Property GitProxy configuration file > tls - + 26. [Optional] Property GitProxy configuration file > tls
@@ -2020,8 +1968,7 @@ Specific value: `"jwt"`
- 24.1. [Required] Property GitProxy configuration file > tls > enabled - + 26.1. [Required] Property GitProxy configuration file > tls > enabled
@@ -2035,8 +1982,7 @@ Specific value: `"jwt"`
- 24.2. [Required] Property GitProxy configuration file > tls > key - + 26.2. [Required] Property GitProxy configuration file > tls > key
@@ -2050,8 +1996,7 @@ Specific value: `"jwt"`
- 24.3. [Required] Property GitProxy configuration file > tls > cert - + 26.3. [Required] Property GitProxy configuration file > tls > cert
@@ -2068,8 +2013,7 @@ Specific value: `"jwt"`
- 25. [Optional] Property GitProxy configuration file > sslKeyPemPath - + 27. [Optional] Property GitProxy configuration file > sslKeyPemPath
@@ -2085,8 +2029,7 @@ Specific value: `"jwt"`
- 26. [Optional] Property GitProxy configuration file > sslCertPemPath - + 28. [Optional] Property GitProxy configuration file > sslCertPemPath
@@ -2102,8 +2045,7 @@ Specific value: `"jwt"`
- 27. [Optional] Property GitProxy configuration file > configurationSources - + 29. [Optional] Property GitProxy configuration file > configurationSources
@@ -2118,8 +2060,7 @@ Specific value: `"jwt"`
- 28. [Optional] Property GitProxy configuration file > uiRouteAuth - + 30. [Optional] Property GitProxy configuration file > uiRouteAuth
@@ -2133,8 +2074,7 @@ Specific value: `"jwt"`
- 28.1. [Optional] Property GitProxy configuration file > uiRouteAuth > enabled - + 30.1. [Optional] Property GitProxy configuration file > uiRouteAuth > enabled
@@ -2148,8 +2088,7 @@ Specific value: `"jwt"`
- 28.2. [Optional] Property GitProxy configuration file > uiRouteAuth > rules - + 30.2. [Optional] Property GitProxy configuration file > uiRouteAuth > rules
@@ -2162,7 +2101,7 @@ Specific value: `"jwt"` | ----------------------------------------- | ----------- | | [routeAuthRule](#uiRouteAuth_rules_items) | - | -#### 28.2.1. GitProxy configuration file > uiRouteAuth > rules > routeAuthRule +#### 30.2.1. GitProxy configuration file > uiRouteAuth > rules > routeAuthRule | | | | ------------------------- | --------------------------- | @@ -2173,8 +2112,7 @@ Specific value: `"jwt"`
- 28.2.1.1. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > pattern - + 30.2.1.1. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > pattern
@@ -2188,8 +2126,21 @@ Specific value: `"jwt"`
- 28.2.1.2. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > adminOnly + 30.2.1.2. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > adminOnly + +
+| | | +| ------------ | --------- | +| **Type** | `boolean` | +| **Required** | No | + +
+
+ +
+ + 30.2.1.3. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > loginRequired
@@ -2201,10 +2152,78 @@ Specific value: `"jwt"`
+
+
+ +
+
+ +
+ + 31. [Optional] Property GitProxy configuration file > ssh + +
+ +| | | +| ------------------------- | ----------- | +| **Type** | `object` | +| **Required** | No | +| **Additional properties** | Not allowed | + +**Description:** SSH proxy server configuration. The proxy uses SSH agent forwarding to authenticate with remote Git servers (GitHub, GitLab, etc.) using the client's SSH keys. The proxy's own host key is auto-generated and only used to identify the proxy to connecting clients. + +
+ + 31.1. [Required] Property GitProxy configuration file > ssh > enabled + +
+ +| | | +| ------------ | --------- | +| **Type** | `boolean` | +| **Required** | Yes | + +**Description:** Enable SSH proxy server. When enabled, clients can connect via SSH and the proxy will forward their SSH agent to authenticate with remote Git servers. + +
+
+ +
+ + 31.2. [Optional] Property GitProxy configuration file > ssh > port + +
+ +| | | +| ------------ | -------- | +| **Type** | `number` | +| **Required** | No | +| **Default** | `2222` | + +**Description:** Port for SSH proxy server to listen on. Clients connect to this port instead of directly to GitHub/GitLab. + +
+
+
- 28.2.1.3. [Optional] Property GitProxy configuration file > uiRouteAuth > rules > rules items > loginRequired + 31.3. [Optional] Property GitProxy configuration file > ssh > agentForwardingErrorMessage + +
+ +| | | +| ------------ | -------- | +| **Type** | `string` | +| **Required** | No | +**Description:** Custom error message shown when SSH agent forwarding is not enabled or no keys are loaded in the client's SSH agent. If not specified, a default message with git config commands will be shown. This allows organizations to customize instructions based on their security policies. + +
+
+ +
+ + 31.4. [Optional] Property GitProxy configuration file > ssh > debug
@@ -2212,10 +2231,56 @@ Specific value: `"jwt"` | ------------ | --------- | | **Type** | `boolean` | | **Required** | No | +| **Default** | `false` | + +**Description:** Enable verbose SSH protocol debug logging (both for the local SSH server and for outbound connections to remote Git servers). Emits one log line per SSH packet, so leave disabled in production. + +
+
+ +
+ + 31.5. [Optional] Property GitProxy configuration file > ssh > hostKey + +
+ +| | | +| ------------------------- | ----------- | +| **Type** | `object` | +| **Required** | No | +| **Additional properties** | Not allowed | + +**Description:** Custom SSH host key paths. If not specified, a host key is auto-generated at .ssh/proxy_host_key. + +
+ + 31.5.1. [Required] Property GitProxy configuration file > ssh > hostKey > privateKeyPath + +
+ +| | | +| ------------ | -------- | +| **Type** | `string` | +| **Required** | Yes | + +**Description:** Path to the private key file (e.g. /etc/git-proxy/host_key)
+
+ + 31.5.2. [Required] Property GitProxy configuration file > ssh > hostKey > publicKeyPath + +
+ +| | | +| ------------ | -------- | +| **Type** | `string` | +| **Required** | Yes | + +**Description:** Path to the public key file (e.g. /etc/git-proxy/host_key.pub) +
@@ -2224,8 +2289,41 @@ Specific value: `"jwt"`
- 29. [Optional] Property GitProxy configuration file > upstreamProxy + 31.6. [Optional] Property GitProxy configuration file > ssh > knownHosts + +
+ +| | | +| ------------------------- | ------------------------------------------------------------------------------------------- | +| **Type** | `object` | +| **Required** | No | +| **Additional properties** | [Each additional property must conform to the schema](#ssh_knownHosts_additionalProperties) | + +**Description:** SSH host key fingerprints for verifying remote Git servers, merged with built-in defaults for github.com and gitlab.com. + +
+ + 31.6.1. Property GitProxy configuration file > ssh > knownHosts > additionalProperties + +
+ +| | | +| ------------ | -------- | +| **Type** | `string` | +| **Required** | No | + +
+
+ +
+
+
+
+ +
+ + 32. [Optional] Property GitProxy configuration file > upstreamProxy
@@ -2239,8 +2337,7 @@ Specific value: `"jwt"`
- 29.1. [Optional] Property GitProxy configuration file > upstreamProxy > enabled - + 32.1. [Optional] Property GitProxy configuration file > upstreamProxy > enabled
@@ -2256,8 +2353,7 @@ Specific value: `"jwt"`
- 29.2. [Optional] Property GitProxy configuration file > upstreamProxy > url - + 32.2. [Optional] Property GitProxy configuration file > upstreamProxy > url
@@ -2274,8 +2370,7 @@ Specific value: `"jwt"`
- 29.3. [Optional] Property GitProxy configuration file > upstreamProxy > noProxy - + 32.3. [Optional] Property GitProxy configuration file > upstreamProxy > noProxy
@@ -2290,7 +2385,7 @@ Specific value: `"jwt"` | --------------------------------------------- | ----------- | | [noProxy items](#upstreamProxy_noProxy_items) | - | -#### 29.3.1. GitProxy configuration file > upstreamProxy > noProxy > noProxy items +#### 32.3.1. GitProxy configuration file > upstreamProxy > noProxy > noProxy items | | | | ------------ | -------- | @@ -2304,4 +2399,4 @@ Specific value: `"jwt"`
---------------------------------------------------------------------------------------------------------------------------- -Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-06-02 at 22:41:17 +0900 +Generated using [json-schema-for-humans](https://github.com/coveooss/json-schema-for-humans) on 2026-07-08 at 00:58:14 +0000 From ca2772d9f6b43cdb1e3b06e379705232e9ad9472 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 8 Jul 2026 20:19:56 +0900 Subject: [PATCH 2/7] feat: modify chain to collect failed steps and report --- src/proxy/chain.ts | 68 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/src/proxy/chain.ts b/src/proxy/chain.ts index ba58b3f4c..7d44a7127 100644 --- a/src/proxy/chain.ts +++ b/src/proxy/chain.ts @@ -22,6 +22,7 @@ import * as proc from './processors'; import { Processor } from './processors/types'; import { attemptAutoApproval, attemptAutoRejection } from './actions/autoActions'; import { handleErrorAndLog } from '../utils/errors'; +import { getCollectAllChainErrors } from '../config'; const branchPushChain: Processor['exec'][] = [ proc.push.checkEmptyBranch, @@ -54,8 +55,30 @@ const tagPushChain: Processor['exec'][] = [ const pullActionChain: Processor['exec'][] = [proc.push.checkRepoInAuthorisedList]; const defaultActionChain: Processor['exec'][] = [proc.push.checkRepoInAuthorisedList]; +const collectibleSteps = new Set([ + proc.push.checkMessages, + proc.push.checkAuthorEmails, + proc.push.checkHiddenCommits, + proc.push.preReceive, + proc.push.gitleaks, + proc.push.scanDiff, +]); let pluginsInserted = false; +const composeErrorMessage = (action: Action): string | undefined => { + const messages = (action.steps ?? []) + .filter((step) => step.error && step.errorMessage) + .map((step) => (step.errorMessage as string).trim()); + + if (messages.length < 2) { + return undefined; + } + + return ( + `The following ${messages.length} checks failed:\n\n` + + messages.map((message, i) => `${i + 1}. ${message}`).join('\n\n') + ); +}; export const executeChain = async (req: Request, _res: Response): Promise => { let action: Action = {} as Action; @@ -71,17 +94,55 @@ export const executeChain = async (req: Request, _res: Response): Promise step.error); + if (failedNow) { + // recoverable failures are recorded and the chain keeps running, + // so a single push reports every rejection reason at once + if (!(collectAll && collectibleSteps.has(fn))) { + break; + } + collectedErrors = true; + } else if (!collectedErrors) { + // error that predates the chain (e.g. produced while parsing the push) + break; + } + } + + if (fn === proc.push.pullRemote) { //if the pull was successful then record the fact we need to clean it up again // pullRemote should cleanup unsuccessful clones itself checkoutCleanUpRequired = true; } } + + if (collectedErrors) { + const combinedMessage = composeErrorMessage(action); + if (combinedMessage) { + action.errorMessage = combinedMessage; + } + } } catch (error: unknown) { const msg = handleErrorAndLog(error, 'An unexpected error occurred when executing the chain'); action.error = true; @@ -94,7 +155,8 @@ export const executeChain = async (req: Request, _res: Response): Promise Date: Wed, 8 Jul 2026 20:52:44 +0900 Subject: [PATCH 3/7] test: add new chain tests --- src/proxy/chain.ts | 19 +++++++++ test/chain.test.ts | 103 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/src/proxy/chain.ts b/src/proxy/chain.ts index 7d44a7127..cdbae51bc 100644 --- a/src/proxy/chain.ts +++ b/src/proxy/chain.ts @@ -55,6 +55,17 @@ const tagPushChain: Processor['exec'][] = [ const pullActionChain: Processor['exec'][] = [proc.push.checkRepoInAuthorisedList]; const defaultActionChain: Processor['exec'][] = [proc.push.checkRepoInAuthorisedList]; + +/** + * Steps whose failures are recoverable by the user (bad commit message, bad + * author e-mail, detected secret, etc). When collectAllChainErrors is enabled, + * a failure in one of these steps is recorded but the chain keeps running so + * that a single push reports every rejection reason at once. + * + * Steps not listed here stop the chain immediately when they fail + * such as repository authorisation, user push permission, or later steps + * depending on their output (pullRemote, writePack, getDiff) + */ const collectibleSteps = new Set([ proc.push.checkMessages, proc.push.checkAuthorEmails, @@ -65,6 +76,14 @@ const collectibleSteps = new Set([ ]); let pluginsInserted = false; + +/** + * Compose a single error message from all failed steps, so that the git + * client displays every rejection reason for the push. + * @param {Action} action The action whose failed steps are reported. + * @return {string | undefined} The combined message, or undefined when there + * are fewer than two failed steps (the single step message is kept as-is). + */ const composeErrorMessage = (action: Action): string | undefined => { const messages = (action.steps ?? []) .filter((step) => step.error && step.errorMessage) diff --git a/test/chain.test.ts b/test/chain.test.ts index 215da7632..30842dd1d 100644 --- a/test/chain.test.ts +++ b/test/chain.test.ts @@ -454,6 +454,109 @@ describe('proxy chain', function () { expect(consoleErrorSpy).toHaveBeenCalledWith('Error during auto-rejection: Database error'); }); + describe('error collection', () => { + // simulates a real processor failing + const failStep = (message: string) => async (req: any, action: any) => { + action.steps = [...(action.steps ?? []), { error: true, errorMessage: message }]; + action.error = true; + action.continue = () => false; + return action; + }; + + const setupPushAction = () => { + const action = { + type: 'push', + steps: [], + continue: () => true, + allowPush: false, + }; + mockPreProcessors.parseAction.mockResolvedValue(action); + mockPreProcessors.parsePush.mockResolvedValue(action); + return action; + }; + + it('should continue past recoverable failures and run the remaining checks', async () => { + setupPushAction(); + mockPushProcessors.checkMessages.mockImplementation(failStep('bad commit message')); + + const result = await chain.executeChain({}); + + // all later steps still ran + expect(mockPushProcessors.checkAuthorEmails).toHaveBeenCalled(); + expect(mockPushProcessors.checkUserPushPermission).toHaveBeenCalled(); + expect(mockPushProcessors.pullRemote).toHaveBeenCalled(); + expect(mockPushProcessors.writePack).toHaveBeenCalled(); + expect(mockPushProcessors.getDiff).toHaveBeenCalled(); + expect(mockPushProcessors.gitleaks).toHaveBeenCalled(); + expect(mockPushProcessors.scanDiff).toHaveBeenCalled(); + + // but a failing push is never queued for approval + expect(mockPushProcessors.blockForAuth).not.toHaveBeenCalled(); + expect(result.error).toBe(true); + }); + + it('should report every collected failure in a single combined message', async () => { + setupPushAction(); + mockPushProcessors.checkMessages.mockImplementation(failStep('bad commit message')); + mockPushProcessors.scanDiff.mockImplementation(failStep('secret detected in diff')); + + const result = await chain.executeChain({}); + + expect(result.errorMessage).toContain('rejected by 2 checks'); + expect(result.errorMessage).toContain('bad commit message'); + expect(result.errorMessage).toContain('secret detected in diff'); + }); + + it('should keep the original message when only one collectible step fails', async () => { + setupPushAction(); + mockPushProcessors.checkAuthorEmails.mockImplementation(failStep('illegal author email')); + + const result = await chain.executeChain({}); + + expect(result.errorMessage).toBeUndefined(); // addStep is mocked so chain must not overwrite + expect(result.steps).toHaveLength(1); + expect(result.steps[0].errorMessage).toBe('illegal author email'); + }); + + it('should still stop immediately when a fatal step fails', async () => { + setupPushAction(); + mockPushProcessors.checkUserPushPermission.mockImplementation(failStep('no push permission')); + + await chain.executeChain({}); + + expect(mockPushProcessors.pullRemote).not.toHaveBeenCalled(); + expect(mockPushProcessors.scanDiff).not.toHaveBeenCalled(); + expect(mockPushProcessors.blockForAuth).not.toHaveBeenCalled(); + }); + + it('should stop at the first failure when collectAllChainErrors is disabled', async () => { + const config = await import('../src/config'); + vi.spyOn(config, 'getCollectAllChainErrors').mockReturnValue(false); + + setupPushAction(); + mockPushProcessors.checkMessages.mockImplementation(failStep('bad commit message')); + + await chain.executeChain({}); + + expect(mockPushProcessors.checkAuthorEmails).not.toHaveBeenCalled(); + expect(mockPushProcessors.blockForAuth).not.toHaveBeenCalled(); + }); + + it('should not auto-approve a push that collected failures', async () => { + setupPushAction(); + mockPushProcessors.checkMessages.mockImplementation(failStep('bad commit message')); + mockPushProcessors.preReceive.mockImplementation(async (req: any, action: any) => { + action.autoApproved = true; + return action; + }); + const dbSpy = vi.spyOn(db, 'authorise'); + + await chain.executeChain({}); + + expect(dbSpy).not.toHaveBeenCalled(); + }); + }); + it('returns pullActionChain for pull actions', async () => { const action = new Action( '1', From 76cde9454da8f155ec224bedfffc9eb1f42d0849 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 8 Jul 2026 21:08:30 +0900 Subject: [PATCH 4/7] test: fix chain test error message --- test/chain.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/chain.test.ts b/test/chain.test.ts index 30842dd1d..37b3d8ca2 100644 --- a/test/chain.test.ts +++ b/test/chain.test.ts @@ -502,7 +502,7 @@ describe('proxy chain', function () { const result = await chain.executeChain({}); - expect(result.errorMessage).toContain('rejected by 2 checks'); + expect(result.errorMessage).toContain('The following 2 checks failed:'); expect(result.errorMessage).toContain('bad commit message'); expect(result.errorMessage).toContain('secret detected in diff'); }); From 2b94ef1072aca48b429ca6728a0c216b60748e39 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 15 Jul 2026 11:33:26 +0900 Subject: [PATCH 5/7] fix: remove collectAllChainErrors config option (make it default behavior) --- config.schema.json | 5 ----- proxy.config.json | 1 - src/config/generated/config.ts | 8 -------- src/config/index.ts | 7 ------- src/proxy/chain.ts | 10 +++------- test/chain.test.ts | 13 ------------- website/docs/configuration/reference.mdx | 17 ----------------- 7 files changed, 3 insertions(+), 58 deletions(-) diff --git a/config.schema.json b/config.schema.json index 7d42971f5..5b5d0dfd6 100644 --- a/config.schema.json +++ b/config.schema.json @@ -297,11 +297,6 @@ "description": "Flag to enable CSRF protections for UI", "type": "boolean" }, - "collectAllChainErrors": { - "description": "When enabled, the push validation chain continues past recoverable check failures (commit messages, author e-mails, secret scanning, etc.) and reports every rejection reason in a single push, instead of stopping at the first failed check. Security and infrastructure failures still stop the chain immediately.", - "type": "boolean", - "default": true - }, "plugins": { "type": "array", "description": "List of plugins to integrate on GitProxy's push or pull actions. Each value is either a file path or a module name.", diff --git a/proxy.config.json b/proxy.config.json index 6585c522c..18da6c6b8 100644 --- a/proxy.config.json +++ b/proxy.config.json @@ -147,7 +147,6 @@ "urlShortener": "", "contactEmail": "", "csrfProtection": true, - "collectAllChainErrors": true, "plugins": [], "apiAuthentication": [ { diff --git a/src/config/generated/config.ts b/src/config/generated/config.ts index a6106e4dd..60d2204a8 100644 --- a/src/config/generated/config.ts +++ b/src/config/generated/config.ts @@ -36,13 +36,6 @@ export interface GitProxyConfig { * List of repositories that are authorised to be pushed to through the proxy. */ authorisedList?: AuthorisedRepo[]; - /** - * When enabled, the push validation chain continues past recoverable check failures (commit - * messages, author e-mails, secret scanning, etc.) and reports every rejection reason in a - * single push, instead of stopping at the first failed check. Security and infrastructure - * failures still stop the chain immediately. - */ - collectAllChainErrors?: boolean; /** * Block commits based on rules defined over author/committer e-mail addresses, commit * message content and diff content @@ -893,7 +886,6 @@ const typeMap: any = { typ: u(undefined, a(r('AuthenticationElement'))), }, { json: 'authorisedList', js: 'authorisedList', typ: u(undefined, a(r('AuthorisedRepo'))) }, - { json: 'collectAllChainErrors', js: 'collectAllChainErrors', typ: u(undefined, true) }, { json: 'commitConfig', js: 'commitConfig', typ: u(undefined, r('CommitConfig')) }, { json: 'configurationSources', js: 'configurationSources', typ: u(undefined, 'any') }, { json: 'contactEmail', js: 'contactEmail', typ: u(undefined, '') }, diff --git a/src/config/index.ts b/src/config/index.ts index 93bc668ce..792062863 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -41,7 +41,6 @@ const REQUIRED_TOP_LEVEL_CONFIG_KEYS = [ 'attestationConfig', 'authentication', 'authorisedList', - 'collectAllChainErrors', 'commitConfig', 'configurationSources', 'contactEmail', @@ -433,12 +432,6 @@ export const getCSRFProtection = (): boolean | undefined => { return config.csrfProtection; }; -// Whether the push chain continues past recoverable failures and reports all of them at once -export const getCollectAllChainErrors = (): boolean => { - const config = loadFullConfiguration(); - return config.collectAllChainErrors !== false; -}; - // Get loadable push plugins export const getPlugins = () => { const config = loadFullConfiguration(); diff --git a/src/proxy/chain.ts b/src/proxy/chain.ts index cdbae51bc..ac8b48f0e 100644 --- a/src/proxy/chain.ts +++ b/src/proxy/chain.ts @@ -22,7 +22,6 @@ import * as proc from './processors'; import { Processor } from './processors/types'; import { attemptAutoApproval, attemptAutoRejection } from './actions/autoActions'; import { handleErrorAndLog } from '../utils/errors'; -import { getCollectAllChainErrors } from '../config'; const branchPushChain: Processor['exec'][] = [ proc.push.checkEmptyBranch, @@ -58,9 +57,8 @@ const defaultActionChain: Processor['exec'][] = [proc.push.checkRepoInAuthorised /** * Steps whose failures are recoverable by the user (bad commit message, bad - * author e-mail, detected secret, etc). When collectAllChainErrors is enabled, - * a failure in one of these steps is recorded but the chain keeps running so - * that a single push reports every rejection reason at once. + * author e-mail, detected secret, etc). Failures in these steps are recorded + * but the chain keeps running so rejection reasons are reported at once. * * Steps not listed here stop the chain immediately when they fail * such as repository authorisation, user push permission, or later steps @@ -69,7 +67,6 @@ const defaultActionChain: Processor['exec'][] = [proc.push.checkRepoInAuthorised const collectibleSteps = new Set([ proc.push.checkMessages, proc.push.checkAuthorEmails, - proc.push.checkHiddenCommits, proc.push.preReceive, proc.push.gitleaks, proc.push.scanDiff, @@ -113,7 +110,6 @@ export const executeChain = async (req: Request, _res: Response): Promise { - const config = await import('../src/config'); - vi.spyOn(config, 'getCollectAllChainErrors').mockReturnValue(false); - - setupPushAction(); - mockPushProcessors.checkMessages.mockImplementation(failStep('bad commit message')); - - await chain.executeChain({}); - - expect(mockPushProcessors.checkAuthorEmails).not.toHaveBeenCalled(); - expect(mockPushProcessors.blockForAuth).not.toHaveBeenCalled(); - }); - it('should not auto-approve a push that collected failures', async () => { setupPushAction(); mockPushProcessors.checkMessages.mockImplementation(failStep('bad commit message')); diff --git a/website/docs/configuration/reference.mdx b/website/docs/configuration/reference.mdx index ec3b7b6f7..9a56cf0e2 100644 --- a/website/docs/configuration/reference.mdx +++ b/website/docs/configuration/reference.mdx @@ -990,23 +990,6 @@ description: JSON schema reference documentation for GitProxy
-
- - 18. [Optional] Property GitProxy configuration file > collectAllChainErrors - -
- -| | | -| ------------ | --------- | -| **Type** | `boolean` | -| **Required** | No | -| **Default** | `true` | - -**Description:** When enabled, the push validation chain continues past recoverable check failures (commit messages, author e-mails, secret scanning, etc.) and reports every rejection reason in a single push, instead of stopping at the first failed check. Security and infrastructure failures still stop the chain immediately. - -
-
-
19. [Optional] Property GitProxy configuration file > plugins From 97d6e78783832698232c0193c03bec356e6d8a4e Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 15 Jul 2026 13:41:30 +0900 Subject: [PATCH 6/7] feat: add ProcessorExec type, add isCollectible flag for processors --- src/proxy/chain.ts | 41 ++++++------------- .../push-action/checkAuthorEmails.ts | 1 + .../processors/push-action/checkMessages.ts | 1 + src/proxy/processors/push-action/gitleaks.ts | 1 + .../processors/push-action/preReceive.ts | 1 + src/proxy/processors/push-action/scanDiff.ts | 1 + src/proxy/processors/types.ts | 14 ++++++- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/proxy/chain.ts b/src/proxy/chain.ts index dbd339519..cdd102d58 100644 --- a/src/proxy/chain.ts +++ b/src/proxy/chain.ts @@ -19,12 +19,12 @@ import { Request, Response } from 'express'; import { PluginLoader } from '../plugin'; import { Action, RequestType, PushType } from './actions'; import * as proc from './processors'; -import { Processor } from './processors/types'; +import { ProcessorExec } from './processors/types'; import { attemptAutoApproval, attemptAutoRejection } from './actions/autoActions'; import { handleErrorAndLog } from '../utils/errors'; import { createProgressWriter } from './sideband'; -const branchPushChain: Processor['exec'][] = [ +const branchPushChain: ProcessorExec[] = [ proc.push.checkEmptyBranch, proc.push.checkRepoInAuthorisedList, proc.push.checkMessages, @@ -41,7 +41,7 @@ const branchPushChain: Processor['exec'][] = [ proc.push.blockForAuth, ]; -const tagPushChain: Processor['exec'][] = [ +const tagPushChain: ProcessorExec[] = [ proc.push.checkRepoInAuthorisedList, proc.push.checkUserPushPermission, proc.push.checkIfWaitingAuth, @@ -52,26 +52,9 @@ const tagPushChain: Processor['exec'][] = [ proc.push.blockForAuth, ]; -const pullActionChain: Processor['exec'][] = [proc.push.checkRepoInAuthorisedList]; +const pullActionChain: ProcessorExec[] = [proc.push.checkRepoInAuthorisedList]; -const defaultActionChain: Processor['exec'][] = [proc.push.checkRepoInAuthorisedList]; - -/** - * Steps whose failures are recoverable by the user (bad commit message, bad - * author e-mail, detected secret, etc). Failures in these steps are recorded - * but the chain keeps running so rejection reasons are reported at once. - * - * Steps not listed here stop the chain immediately when they fail - * such as repository authorisation, user push permission, or later steps - * depending on their output (pullRemote, writePack, getDiff) - */ -const collectibleSteps = new Set([ - proc.push.checkMessages, - proc.push.checkAuthorEmails, - proc.push.preReceive, - proc.push.gitleaks, - proc.push.scanDiff, -]); +const defaultActionChain: ProcessorExec[] = [proc.push.checkRepoInAuthorisedList]; let pluginsInserted = false; @@ -116,11 +99,11 @@ const stepProgressLabels: Record = { /** * Obtain the message to display before a chain step. - * @param {Processor['exec']} fn The chain step about to be executed. + * @param {ProcessorExec} fn The chain step about to be executed. * @return {string} The message to display. */ -const getProgressMessage = (fn: Processor['exec']): string => { - const displayName = (fn as { displayName?: string }).displayName; +const getProgressMessage = (fn: ProcessorExec): string => { + const { displayName } = fn; if (displayName && stepProgressLabels[displayName]) { return stepProgressLabels[displayName]; } @@ -170,9 +153,9 @@ export const executeChain = async (req: Request, res: Response): Promise const failedNow = (action.steps ?? []).slice(stepsBefore).some((step) => step.error); if (failedNow) { - // recoverable failures are recorded and the chain keeps running, - // so a single push reports every rejection reason at once - if (!collectibleSteps.has(fn)) { + // collectible steps have their failures can report all their + // rejection reasons at once, non-collectible steps fail immediately + if (!fn.isCollectible) { break; } collectedErrors = true; @@ -224,7 +207,7 @@ export const executeChain = async (req: Request, res: Response): Promise */ let chainPluginLoader: PluginLoader; -export const getChain = async (action: Action): Promise => { +export const getChain = async (action: Action): Promise => { if (chainPluginLoader === undefined) { console.error( 'Plugin loader was not initialized! This is an application error. Please report it to the GitProxy maintainers. Skipping plugins...', diff --git a/src/proxy/processors/push-action/checkAuthorEmails.ts b/src/proxy/processors/push-action/checkAuthorEmails.ts index 150e8bed7..a0535fa4e 100644 --- a/src/proxy/processors/push-action/checkAuthorEmails.ts +++ b/src/proxy/processors/push-action/checkAuthorEmails.ts @@ -73,5 +73,6 @@ const exec = async (_req: Request, action: Action): Promise => { }; exec.displayName = 'checkAuthorEmails.exec'; +exec.isCollectible = true; export { exec }; diff --git a/src/proxy/processors/push-action/checkMessages.ts b/src/proxy/processors/push-action/checkMessages.ts index e1b111582..05ed2a2ea 100644 --- a/src/proxy/processors/push-action/checkMessages.ts +++ b/src/proxy/processors/push-action/checkMessages.ts @@ -92,5 +92,6 @@ const exec = async (_req: Request, action: Action): Promise => { }; exec.displayName = 'checkMessages.exec'; +exec.isCollectible = true; export { exec }; diff --git a/src/proxy/processors/push-action/gitleaks.ts b/src/proxy/processors/push-action/gitleaks.ts index 44b227ac8..abbc582b6 100644 --- a/src/proxy/processors/push-action/gitleaks.ts +++ b/src/proxy/processors/push-action/gitleaks.ts @@ -197,5 +197,6 @@ const exec = async (_req: Request, action: Action): Promise => { }; exec.displayName = 'gitleaks.exec'; +exec.isCollectible = true; export { exec }; diff --git a/src/proxy/processors/push-action/preReceive.ts b/src/proxy/processors/push-action/preReceive.ts index 84a7eca3d..8f6360269 100644 --- a/src/proxy/processors/push-action/preReceive.ts +++ b/src/proxy/processors/push-action/preReceive.ts @@ -98,5 +98,6 @@ const exec = async ( }; exec.displayName = 'executeExternalPreReceiveHook.exec'; +exec.isCollectible = true; export { exec }; diff --git a/src/proxy/processors/push-action/scanDiff.ts b/src/proxy/processors/push-action/scanDiff.ts index e6fceb0e9..a9cfa5d78 100644 --- a/src/proxy/processors/push-action/scanDiff.ts +++ b/src/proxy/processors/push-action/scanDiff.ts @@ -205,5 +205,6 @@ const exec = async (_req: Request, action: Action): Promise => { }; exec.displayName = 'scanDiff.exec'; +exec.isCollectible = true; export { exec }; diff --git a/src/proxy/processors/types.ts b/src/proxy/processors/types.ts index ba40c8138..550255761 100644 --- a/src/proxy/processors/types.ts +++ b/src/proxy/processors/types.ts @@ -19,8 +19,20 @@ import { Request } from 'express'; import { Question } from '../../config/generated/config'; import { Action } from '../actions'; +export interface ProcessorExec { + (req: Request, action: Action): Promise; + /** Used for progress and step reporting (e.g. 'checkMessages.exec'). */ + readonly displayName?: string; + /** + * Failures in collectible steps are recoverable by the user. Failures are + * recorded and all rejection reasons are reported at the end of the chain. + * When false or unset, a failure stops the chain immediately. + */ + readonly isCollectible?: boolean; +} + export interface Processor { - exec(req: Request, action: Action): Promise; + exec: ProcessorExec; metadata: ProcessorMetadata; } From 3e2cdbce8242a610f0f64d07117cbaf641cafad5 Mon Sep 17 00:00:00 2001 From: Juan Escalada Date: Wed, 15 Jul 2026 13:49:06 +0900 Subject: [PATCH 7/7] test: fix chain tests --- test/chain.test.ts | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/test/chain.test.ts b/test/chain.test.ts index 609a83bc9..f77b18c30 100644 --- a/test/chain.test.ts +++ b/test/chain.test.ts @@ -27,23 +27,26 @@ const mockLoader = { ], }; +const collectibleFn = () => Object.assign(vi.fn(), { isCollectible: true }); +const nonCollectibleFn = () => Object.assign(vi.fn(), { isCollectible: false }); + const initMockPushProcessors = () => { return { - checkEmptyBranch: vi.fn(), - checkRepoInAuthorisedList: vi.fn(), - checkMessages: vi.fn(), - checkAuthorEmails: vi.fn(), - checkUserPushPermission: vi.fn(), - checkIfWaitingAuth: vi.fn(), - checkHiddenCommits: vi.fn(), - pullRemote: vi.fn(), - writePack: vi.fn(), - preReceive: vi.fn(), - getDiff: vi.fn(), - gitleaks: vi.fn(), - clearBareClone: vi.fn(), - scanDiff: vi.fn(), - blockForAuth: vi.fn(), + checkEmptyBranch: nonCollectibleFn(), + checkRepoInAuthorisedList: nonCollectibleFn(), + checkMessages: collectibleFn(), + checkAuthorEmails: collectibleFn(), + checkUserPushPermission: nonCollectibleFn(), + checkIfWaitingAuth: nonCollectibleFn(), + checkHiddenCommits: nonCollectibleFn(), + pullRemote: nonCollectibleFn(), + writePack: nonCollectibleFn(), + preReceive: collectibleFn(), + getDiff: nonCollectibleFn(), + gitleaks: collectibleFn(), + clearBareClone: nonCollectibleFn(), + scanDiff: collectibleFn(), + blockForAuth: nonCollectibleFn(), }; };