Add prettier formatting and CI validation checks

- Add prettier with consistent formatting config
- Add format and format:check npm scripts
- Add prettier pre-commit hook
- Add validation and formatting checks to CI workflow
- Reformat all TypeScript and JSON files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
David Soria Parra 2025-12-13 10:01:28 +00:00
commit 3c1d641add
No known key found for this signature in database
13 changed files with 94 additions and 40 deletions

View file

@ -33,4 +33,10 @@ jobs:
run: npm ci run: npm ci
- name: Build - name: Build
run: npm run build run: npm run build
- name: Validate config
run: npm run validate
- name: Check formatting
run: npm run format:check

View file

@ -22,3 +22,10 @@ repos:
language: system language: system
pass_filenames: false pass_filenames: false
files: ^src/config/ files: ^src/config/
- id: prettier
name: Prettier formatting
entry: npx prettier --write --ignore-unknown
language: system
types: [text]
files: \.(ts|tsx|js|jsx|json|md)$

5
.prettierignore Normal file
View file

@ -0,0 +1,5 @@
node_modules/
sdks/
*.yaml
*.yml
package-lock.json

7
.prettierrc Normal file
View file

@ -0,0 +1,7 @@
{
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 100,
"tabWidth": 2
}

View file

@ -21,6 +21,7 @@ Infrastructure as Code for managing access to MCP community resources using Pulu
### Manual Deployment ### Manual Deployment
Pre-requisites: Pre-requisites:
- [Pulumi CLI installed](https://www.pulumi.com/docs/iac/download-install/) - [Pulumi CLI installed](https://www.pulumi.com/docs/iac/download-install/)
- [Google Cloud SDK installed](https://cloud.google.com/sdk/docs/install) - [Google Cloud SDK installed](https://cloud.google.com/sdk/docs/install)
- Access to GCP project and GCS bucket - Access to GCP project and GCS bucket
@ -79,6 +80,7 @@ gsutil mb gs://mcp-access-prod-pulumi-state
``` ```
Then: Then:
1. In Google Workspace Admin Console, go to **Account** → **Admin roles** 1. In Google Workspace Admin Console, go to **Account** → **Admin roles**
2. Select **Groups Admin** role (or create a custom role with these privileges): 2. Select **Groups Admin** role (or create a custom role with these privileges):
- Read, create, update, and delete groups - Read, create, update, and delete groups
@ -104,5 +106,6 @@ pulumi config set --secret github:token "ghp_your_github_token_here"
### 3. Configure GitHub Actions Secrets ### 3. Configure GitHub Actions Secrets
Add the CI/CD secrets to GitHub Actions (repository settings → Secrets and variables → Actions): Add the CI/CD secrets to GitHub Actions (repository settings → Secrets and variables → Actions):
- `GCP_PROD_SERVICE_ACCOUNT_KEY`: Content of `sa-key.json` - `GCP_PROD_SERVICE_ACCOUNT_KEY`: Content of `sa-key.json`
- `PULUMI_PROD_PASSPHRASE`: The passphrase you set above - `PULUMI_PROD_PASSPHRASE`: The passphrase you set above

17
package-lock.json generated
View file

@ -15,6 +15,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.18.6", "@types/node": "^22.18.6",
"prettier": "^3.7.2",
"typescript": "^5.9.2" "typescript": "^5.9.2"
} }
}, },
@ -2513,6 +2514,22 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/prettier": {
"version": "3.7.2",
"resolved": "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/prettier/-/prettier-3.7.2.tgz",
"integrity": "sha512-n3HV2J6QhItCXndGa3oMWvWFAgN1ibnS7R9mt6iokScBOC0Ul9/iZORmU2IWUMcyAQaMPjTlY3uT34TqocUxMA==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/proc-log": { "node_modules/proc-log": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",

View file

@ -5,7 +5,9 @@
"main": "src/index.ts", "main": "src/index.ts",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"validate": "npx ts-node scripts/validate-config.ts" "validate": "npx ts-node scripts/validate-config.ts",
"format": "prettier --write .",
"format:check": "prettier --check ."
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -15,6 +17,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.18.6", "@types/node": "^22.18.6",
"prettier": "^3.7.2",
"typescript": "^5.9.2" "typescript": "^5.9.2"
} }
} }

View file

@ -184,4 +184,4 @@ export const GROUPS = defineGroups([
isEmailGroup: true, isEmailGroup: true,
onlyOnPlatforms: ['google'], onlyOnPlatforms: ['google'],
}, },
] as const); ] as const);

View file

@ -16,9 +16,7 @@ export interface RepositoryAccess {
export const REPOSITORY_ACCESS: RepositoryAccess[] = [ export const REPOSITORY_ACCESS: RepositoryAccess[] = [
{ {
repository: 'docs', repository: 'docs',
users: [ users: [{ username: 'jspahrsummers', permission: 'admin' }],
{ username: 'jspahrsummers', permission: 'admin' },
],
teams: [ teams: [
{ team: 'auth-wg', permission: 'push' }, { team: 'auth-wg', permission: 'push' },
{ team: 'core-maintainers', permission: 'maintain' }, { team: 'core-maintainers', permission: 'maintain' },
@ -48,9 +46,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [
}, },
{ {
repository: '.github', repository: '.github',
users: [ users: [{ username: 'jspahrsummers', permission: 'admin' }],
{ username: 'jspahrsummers', permission: 'admin' },
],
teams: [ teams: [
{ team: 'auth-wg', permission: 'triage' }, { team: 'auth-wg', permission: 'triage' },
{ team: 'core-maintainers', permission: 'maintain' }, { team: 'core-maintainers', permission: 'maintain' },
@ -116,9 +112,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [
}, },
{ {
repository: 'modelcontextprotocol', repository: 'modelcontextprotocol',
users: [ users: [{ username: 'jspahrsummers', permission: 'admin' }],
{ username: 'jspahrsummers', permission: 'admin' },
],
teams: [ teams: [
{ team: 'auth-wg', permission: 'push' }, { team: 'auth-wg', permission: 'push' },
{ team: 'core-maintainers', permission: 'maintain' }, { team: 'core-maintainers', permission: 'maintain' },
@ -251,9 +245,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [
{ team: 'python-sdk', permission: 'admin' }, { team: 'python-sdk', permission: 'admin' },
{ team: 'python-sdk-auth', permission: 'admin' }, { team: 'python-sdk-auth', permission: 'admin' },
], ],
users: [ users: [{ username: 'jspahrsummers', permission: 'admin' }],
{ username: 'jspahrsummers', permission: 'admin' },
],
}, },
{ {
repository: 'ruby-sdk', repository: 'ruby-sdk',
@ -280,9 +272,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [
{ team: 'typescript-sdk', permission: 'admin' }, { team: 'typescript-sdk', permission: 'admin' },
{ team: 'typescript-sdk-auth', permission: 'admin' }, { team: 'typescript-sdk-auth', permission: 'admin' },
], ],
users: [ users: [{ username: 'jspahrsummers', permission: 'admin' }],
{ username: 'jspahrsummers', permission: 'admin' },
],
}, },
{ {
repository: 'create-python-server', repository: 'create-python-server',
@ -301,9 +291,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [
{ {
repository: 'registry', repository: 'registry',
teams: [{ team: 'registry-wg', permission: 'admin' }], teams: [{ team: 'registry-wg', permission: 'admin' }],
users: [ users: [{ username: 'rdimitrov', permission: 'admin' }],
{ username: 'rdimitrov', permission: 'admin' },
],
}, },
{ {
repository: 'static', repository: 'static',
@ -322,9 +310,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [
}, },
{ {
repository: 'ext-auth', repository: 'ext-auth',
teams: [ teams: [{ team: 'auth-wg', permission: 'admin' }],
{ team: 'auth-wg', permission: 'admin' },
],
}, },
]; ];

View file

@ -97,7 +97,19 @@ export const MEMBERS: readonly Member[] = [
{ {
github: 'dsp-ant', github: 'dsp-ant',
email: 'david@modelcontextprotocol.io', email: 'david@modelcontextprotocol.io',
memberOf: ['auth-wg', 'core-maintainers', 'docs-maintaners', 'go-sdk', 'ig-financial-services', 'moderators', 'php-sdk', 'python-sdk', 'security-wg', 'transport-wg', 'typescript-sdk'], memberOf: [
'auth-wg',
'core-maintainers',
'docs-maintaners',
'go-sdk',
'ig-financial-services',
'moderators',
'php-sdk',
'python-sdk',
'security-wg',
'transport-wg',
'typescript-sdk',
],
}, },
{ {
github: 'e5l', github: 'e5l',
@ -242,7 +254,14 @@ export const MEMBERS: readonly Member[] = [
}, },
{ {
github: 'pcarleton', github: 'pcarleton',
memberOf: ['core-maintainers', 'python-sdk', 'python-sdk-auth', 'typescript-sdk', 'typescript-sdk-auth', 'auth-wg'], memberOf: [
'core-maintainers',
'python-sdk',
'python-sdk-auth',
'typescript-sdk',
'typescript-sdk-auth',
'auth-wg',
],
}, },
{ {
github: 'pederhp', github: 'pederhp',

View file

@ -10,10 +10,10 @@ export function defineGroups<
const T extends readonly { const T extends readonly {
name: Lowercase<string>; name: Lowercase<string>;
description: string; description: string;
memberOf?: readonly (T[number]['name'])[]; memberOf?: readonly T[number]['name'][];
isEmailGroup?: boolean; isEmailGroup?: boolean;
onlyOnPlatforms?: readonly Platform[]; onlyOnPlatforms?: readonly Platform[];
}[] }[],
>(groups: T) { >(groups: T) {
for (const group of groups) { for (const group of groups) {
if (!isValidGroupName(group.name)) { if (!isValidGroupName(group.name)) {
@ -40,4 +40,4 @@ export interface Member {
github?: string; github?: string;
email?: string; email?: string;
memberOf: readonly GroupKey[]; memberOf: readonly GroupKey[];
} }

View file

@ -29,16 +29,17 @@ GROUPS.forEach((group: Group) => {
// Email groups allow anyone (including externals) to post // Email groups allow anyone (including externals) to post
// Non-email groups are not intended as mailing lists, so use the most restrictive settings // Non-email groups are not intended as mailing lists, so use the most restrictive settings
// whoCanViewGroup is badly named, but actually means 'Permissions to view group messages'. See https://developers.google.com/workspace/admin/groups-settings/v1/reference/groups // whoCanViewGroup is badly named, but actually means 'Permissions to view group messages'. See https://developers.google.com/workspace/admin/groups-settings/v1/reference/groups
...(group.isEmailGroup ? { ...(group.isEmailGroup
whoCanPostMessage: 'ANYONE_CAN_POST', ? {
whoCanContactOwner: 'ALL_OWNERS_CAN_CONTACT', whoCanPostMessage: 'ANYONE_CAN_POST',
whoCanViewGroup: 'ALL_MEMBERS_CAN_VIEW', whoCanContactOwner: 'ALL_OWNERS_CAN_CONTACT',
} : { whoCanViewGroup: 'ALL_MEMBERS_CAN_VIEW',
whoCanPostMessage: 'ALL_OWNERS_CAN_POST', }
whoCanContactOwner: 'ALL_OWNERS_CAN_CONTACT', : {
whoCanViewGroup: 'ALL_OWNERS_CAN_VIEW', whoCanPostMessage: 'ALL_OWNERS_CAN_POST',
}), whoCanContactOwner: 'ALL_OWNERS_CAN_CONTACT',
whoCanViewGroup: 'ALL_OWNERS_CAN_VIEW',
}),
}); });
group.memberOf?.forEach((parentGroupKey) => { group.memberOf?.forEach((parentGroupKey) => {

View file

@ -13,4 +13,4 @@
}, },
"include": ["src/**/*"], "include": ["src/**/*"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }