From 3c1d641add7c6e103e391baba07e8c41bd5f43f4 Mon Sep 17 00:00:00 2001 From: David Soria Parra Date: Sat, 13 Dec 2025 10:01:28 +0000 Subject: [PATCH] Add prettier formatting and CI validation checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- .github/workflows/ci.yml | 8 +++++++- .pre-commit-config.yaml | 7 +++++++ .prettierignore | 5 +++++ .prettierrc | 7 +++++++ README.md | 3 +++ package-lock.json | 17 +++++++++++++++++ package.json | 5 ++++- src/config/groups.ts | 2 +- src/config/repoAccess.ts | 28 +++++++--------------------- src/config/users.ts | 23 +++++++++++++++++++++-- src/config/utils.ts | 6 +++--- src/google.ts | 21 +++++++++++---------- tsconfig.json | 2 +- 13 files changed, 94 insertions(+), 40 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1ff399..bcbd3db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,4 +33,10 @@ jobs: run: npm ci - name: Build - run: npm run build \ No newline at end of file + run: npm run build + + - name: Validate config + run: npm run validate + + - name: Check formatting + run: npm run format:check \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 770ad7e..7962d99 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,3 +22,10 @@ repos: language: system pass_filenames: false 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)$ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..8e8e1fe --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +node_modules/ +sdks/ +*.yaml +*.yml +package-lock.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..a95cb05 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "es5", + "printWidth": 100, + "tabWidth": 2 +} diff --git a/README.md b/README.md index 57a50af..e07859b 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Infrastructure as Code for managing access to MCP community resources using Pulu ### Manual Deployment Pre-requisites: + - [Pulumi CLI installed](https://www.pulumi.com/docs/iac/download-install/) - [Google Cloud SDK installed](https://cloud.google.com/sdk/docs/install) - Access to GCP project and GCS bucket @@ -79,6 +80,7 @@ gsutil mb gs://mcp-access-prod-pulumi-state ``` Then: + 1. In Google Workspace Admin Console, go to **Account** → **Admin roles** 2. Select **Groups Admin** role (or create a custom role with these privileges): - 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 Add the CI/CD secrets to GitHub Actions (repository settings → Secrets and variables → Actions): + - `GCP_PROD_SERVICE_ACCOUNT_KEY`: Content of `sa-key.json` - `PULUMI_PROD_PASSPHRASE`: The passphrase you set above diff --git a/package-lock.json b/package-lock.json index c914992..84cac9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ }, "devDependencies": { "@types/node": "^22.18.6", + "prettier": "^3.7.2", "typescript": "^5.9.2" } }, @@ -2513,6 +2514,22 @@ "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": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", diff --git a/package.json b/package.json index 42d2018..59c9dd7 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "main": "src/index.ts", "scripts": { "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", "dependencies": { @@ -15,6 +17,7 @@ }, "devDependencies": { "@types/node": "^22.18.6", + "prettier": "^3.7.2", "typescript": "^5.9.2" } } diff --git a/src/config/groups.ts b/src/config/groups.ts index 73291b4..72c1552 100644 --- a/src/config/groups.ts +++ b/src/config/groups.ts @@ -184,4 +184,4 @@ export const GROUPS = defineGroups([ isEmailGroup: true, onlyOnPlatforms: ['google'], }, -] as const); \ No newline at end of file +] as const); diff --git a/src/config/repoAccess.ts b/src/config/repoAccess.ts index e05b59f..937a0f3 100644 --- a/src/config/repoAccess.ts +++ b/src/config/repoAccess.ts @@ -16,9 +16,7 @@ export interface RepositoryAccess { export const REPOSITORY_ACCESS: RepositoryAccess[] = [ { repository: 'docs', - users: [ - { username: 'jspahrsummers', permission: 'admin' }, - ], + users: [{ username: 'jspahrsummers', permission: 'admin' }], teams: [ { team: 'auth-wg', permission: 'push' }, { team: 'core-maintainers', permission: 'maintain' }, @@ -48,9 +46,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [ }, { repository: '.github', - users: [ - { username: 'jspahrsummers', permission: 'admin' }, - ], + users: [{ username: 'jspahrsummers', permission: 'admin' }], teams: [ { team: 'auth-wg', permission: 'triage' }, { team: 'core-maintainers', permission: 'maintain' }, @@ -116,9 +112,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [ }, { repository: 'modelcontextprotocol', - users: [ - { username: 'jspahrsummers', permission: 'admin' }, - ], + users: [{ username: 'jspahrsummers', permission: 'admin' }], teams: [ { team: 'auth-wg', permission: 'push' }, { team: 'core-maintainers', permission: 'maintain' }, @@ -251,9 +245,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [ { team: 'python-sdk', permission: 'admin' }, { team: 'python-sdk-auth', permission: 'admin' }, ], - users: [ - { username: 'jspahrsummers', permission: 'admin' }, - ], + users: [{ username: 'jspahrsummers', permission: 'admin' }], }, { repository: 'ruby-sdk', @@ -280,9 +272,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [ { team: 'typescript-sdk', permission: 'admin' }, { team: 'typescript-sdk-auth', permission: 'admin' }, ], - users: [ - { username: 'jspahrsummers', permission: 'admin' }, - ], + users: [{ username: 'jspahrsummers', permission: 'admin' }], }, { repository: 'create-python-server', @@ -301,9 +291,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [ { repository: 'registry', teams: [{ team: 'registry-wg', permission: 'admin' }], - users: [ - { username: 'rdimitrov', permission: 'admin' }, - ], + users: [{ username: 'rdimitrov', permission: 'admin' }], }, { repository: 'static', @@ -322,9 +310,7 @@ export const REPOSITORY_ACCESS: RepositoryAccess[] = [ }, { repository: 'ext-auth', - teams: [ - { team: 'auth-wg', permission: 'admin' }, - ], + teams: [{ team: 'auth-wg', permission: 'admin' }], }, ]; diff --git a/src/config/users.ts b/src/config/users.ts index b0e6ae9..da7a07c 100644 --- a/src/config/users.ts +++ b/src/config/users.ts @@ -97,7 +97,19 @@ export const MEMBERS: readonly Member[] = [ { github: 'dsp-ant', 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', @@ -242,7 +254,14 @@ export const MEMBERS: readonly Member[] = [ }, { 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', diff --git a/src/config/utils.ts b/src/config/utils.ts index 241b86f..fd0112a 100644 --- a/src/config/utils.ts +++ b/src/config/utils.ts @@ -10,10 +10,10 @@ export function defineGroups< const T extends readonly { name: Lowercase; description: string; - memberOf?: readonly (T[number]['name'])[]; + memberOf?: readonly T[number]['name'][]; isEmailGroup?: boolean; onlyOnPlatforms?: readonly Platform[]; - }[] + }[], >(groups: T) { for (const group of groups) { if (!isValidGroupName(group.name)) { @@ -40,4 +40,4 @@ export interface Member { github?: string; email?: string; memberOf: readonly GroupKey[]; -} \ No newline at end of file +} diff --git a/src/google.ts b/src/google.ts index 503ded0..96c7d7c 100644 --- a/src/google.ts +++ b/src/google.ts @@ -29,16 +29,17 @@ GROUPS.forEach((group: Group) => { // Email groups allow anyone (including externals) to post // 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 - ...(group.isEmailGroup ? { - whoCanPostMessage: 'ANYONE_CAN_POST', - 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', - }), - + ...(group.isEmailGroup + ? { + whoCanPostMessage: 'ANYONE_CAN_POST', + 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', + }), }); group.memberOf?.forEach((parentGroupKey) => { diff --git a/tsconfig.json b/tsconfig.json index 4b8e53f..09e8d66 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,4 +13,4 @@ }, "include": ["src/**/*"], "exclude": ["node_modules"] -} \ No newline at end of file +}