Skip to content

ci(docs): automate GitHub wiki sync (add missing pages + cover counts) - #3900

Merged
diegosouzapw merged 1 commit into
release/v3.8.26from
chore/wiki-sync-automation
Jun 15, 2026
Merged

diegosouzapw merged 1 commit into
release/v3.8.26from
chore/wiki-sync-automation

Conversation

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Automatiza o sync da Wiki do GitHub com a documentação — A (sync agora) + B (CI por release).

Contexto

A wiki não tem gerador nativo e derivava a cada release (estava em 212+ providers / 14 strategies / 37 MCP tools enquanto o código ia a 226 / 15 / 87, e docs novos como SUPPLY_CHAIN nunca apareciam). Uma automação parcial foi construída na branch docs/sync-v3.8.24 mas nunca mergeou — só o push manual de 2026-06-13 aconteceu.

A — sync executado agora

Rodei sync-wiki.mjs e já dei push de 25 páginas faltantes na wiki (9517ae7..5331dc8): Supply-Chain, Playground-Studio, Traffic-Inspector, AgentBridge, Embedded-Services, Quota-Share, ACP, Agent-Skills, Quick-Start, Providers-Guide, Free-Tiers-Guide, Auto-Combo-Guide, Quality-Gates, Monitoring-Sections, Plugin-SDK, CLI-Token, Codex-CLI-Configuration, Search-Tools-Studio, Tiers, Zed-Docker, Extending-Compression, Discovery-Tool-Design, Unlimited-LLM-Access, Agentrouter, V3.8.0. Cover counts do Home já estavam in-sync (226/15/87/42).

B — CI automático

  • scripts/docs/sync-wiki.mjs — adiciona docs/ ausentes da wiki (curado; relatórios/planos internos excluídos via NEW_PAGE_EXCLUDE) + sincroniza as 4 contagens do Home.md. Casa os nomes hand-curated (não-determinísticos, ex. API-Reference vs Fly-io-Deployment-Guide) por chave fuzzy normalizada e escreve o nome existente → nunca cria página duplicada.
  • .github/workflows/wiki-sync.yml — roda em todo push na main que toca docs/** (ou uma fonte de contagem) + workflow_dispatch; push via GITHUB_TOKEN (contents: write).
  • tests/unit/sync-wiki.test.ts — 8 testes das funções puras.

⚠️ Decisão de segurança: sobrescrita de páginas existentes é OPT-IN (--update-existing, default OFF)

Vários docs-fonte ainda têm contagens defasadas (ex.: ARCHITECTURE.md diz "177 providers / 37 MCP tools" enquanto a wiki foi corrigida à mão para 226/87). Sobrescrever a partir de uma fonte mais velha regrediria a wiki. Por isso o sync (e o CI) por padrão só adiciona páginas novas + contagens — nunca regride. A paridade total de conteúdo depende de regenerar os counts nos docs-fonte primeiro (escopo do docs/ops/DOCUMENTATION_AUDIT_REPORT.md).

Validação

✅ node --test tests/unit/sync-wiki.test.ts (8/8) · ✅ check:test-discovery (1813 testes, teste novo coletado) · ✅ check:docs-sync PASS · ✅ eslint limpo · ✅ workflow usa env-vars (sem injeção) · ✅ push da wiki ao vivo confirmado (só adições, 0 deleções).

The wiki has no native generator and drifts each release — it lacked SUPPLY_CHAIN
plus 24 other docs pages, and the cover counts went stale (212+/14/37 vs 226/15/87).

Adds:
  - scripts/docs/sync-wiki.mjs — adds docs/ pages missing from the wiki (curated;
    internal reports/plans/index excluded) and syncs the four Home.md cover counts.
    Matches the hand-curated, non-deterministic wiki page names by a normalized fuzzy
    key and writes the EXISTING name, so it never creates duplicate pages. Overwriting
    existing-page content is opt-in (--update-existing) and intentionally OFF by
    default: several docs sources still carry stale counts (e.g. ARCHITECTURE.md says
    "177 providers / 37 MCP tools" while the wiki cover is 226/87), so a blind overwrite
    would REGRESS the wiki. Full parity is gated on regenerating those sources — see
    docs/ops/DOCUMENTATION_AUDIT_REPORT.md.
  - .github/workflows/wiki-sync.yml — runs the sync on every push to main that touches
    docs/ (or a count source) + workflow_dispatch, pushing via GITHUB_TOKEN.
  - tests/unit/sync-wiki.test.ts — pure-function coverage (8 tests).

The first run already pushed the 25 missing pages to the wiki.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new script scripts/docs/sync-wiki.mjs and its corresponding unit tests in tests/unit/sync-wiki.test.ts to automate the synchronization of GitHub wiki content and cover-page counts. The code review identified several issues and improvement opportunities: the regex for extracting the MCP tool count will fail because the target constant is computed dynamically rather than defined as a literal; the locales count is retrieved but never actually replaced in Home.md; the routing strategy extraction assumes double quotes and could fail with single quotes; the provider count replacement regex is too generic and may cause unintended text replacements; and there is a lack of unit test coverage for the mcpTools substitution logic.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +108 to +112
function mcpToolCount() {
// Prefer a literal; the constant is computed at runtime so best-effort only.
const m = read("open-sse/mcp-server/server.ts").match(/TOTAL_MCP_TOOL_COUNT\s*=\s*(\d+)\b/);
return m ? Number(m[1]) : null;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

O regex /TOTAL_MCP_TOOL_COUNT\s*=\s*(\d+)\b/ nunca irá encontrar uma correspondência no arquivo open-sse/mcp-server/server.ts. No arquivo de origem, TOTAL_MCP_TOOL_COUNT não é definido como um literal numérico (ex: 87), mas sim calculado dinamicamente em tempo de execução somando o comprimento de vários arrays e chaves de objetos:

const TOTAL_MCP_TOOL_COUNT =
  MCP_TOOLS.length +
  Object.keys(memoryTools).length + ...

Como resultado, mcpToolCount() sempre retornará null, e a contagem de ferramentas MCP no Home.md nunca será atualizada automaticamente por este script.

Sugestão:
Para resolver isso de forma robusta, você pode:

  1. Adicionar um comentário especial no arquivo server.ts (ex: // TOTAL_MCP_TOOL_COUNT = 87) que possa ser capturado pelo regex (embora exija atualização manual ou via hook).
  2. Ou, dado que o ambiente de CI já possui suporte para executar TypeScript (visto que roda tests/unit/sync-wiki.test.ts), você pode criar um pequeno script auxiliar que importe dinamicamente o server.ts (ou as ferramentas diretamente), calcule o valor real e o salve em um arquivo temporário ou o passe como argumento/variável de ambiente para o sync-wiki.mjs.

Comment on lines +135 to +138
if (counts.mcpTools) {
out = out.replace(/(\|\s*\*\*MCP Server\*\*\s*\|\s*)\d+( tools)/g, `$1${counts.mcpTools}$2`);
}
return out;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Embora a descrição do PR mencione a sincronização de 4 contagens no Home.md (226/15/87/42, onde 42 representa as locales/idiomas), a função syncHomeCounts não possui nenhuma lógica para substituir a contagem de locales no texto do Home.md. O valor de counts.locales é obtido em readCounts(), mas é completamente ignorado em syncHomeCounts.

Sugestão:
Adicione a lógica de substituição para counts.locales em syncHomeCounts (por exemplo, procurando por padrões como **42 Languages** ou similar, dependendo de como está estruturado no seu Home.md).

  if (counts.mcpTools) {
    out = out.replace(/(\|\s*\*\*MCP Server\*\*\s*\|\s*)\d+( tools)/g, "$1" + counts.mcpTools + "$2");
  }
  if (counts.locales) {
    out = out.replace(/\*\*\d+ Languages\*\*/g, "**" + counts.locales + " Languages**");
  }
  return out;

Comment on lines +94 to +99
function strategyCount() {
const m = read("src/shared/constants/routingStrategies.ts").match(
/ROUTING_STRATEGY_VALUES\s*=\s*\[([^\]]*)\]/
);
return m ? (m[1].match(/"[^"]+"/g) || []).length : null;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

O método atual assume estritamente que as strings no array ROUTING_STRATEGY_VALUES estão delimitadas por aspas duplas ("). Se um desenvolvedor ou um formatador automático (como o Prettier) alterar as aspas para aspas simples ('), o método match(/"[^"]+"/g) retornará null, fazendo com que a contagem de estratégias falhe silenciosamente (retornando 0).

Podemos tornar essa busca muito mais robusta permitindo aspas simples ou duplas.

Suggested change
function strategyCount() {
const m = read("src/shared/constants/routingStrategies.ts").match(
/ROUTING_STRATEGY_VALUES\s*=\s*\[([^\]]*)\]/
);
return m ? (m[1].match(/"[^"]+"/g) || []).length : null;
}
function strategyCount() {
const m = read("src/shared/constants/routingStrategies.ts").match(
/ROUTING_STRATEGY_VALUES\s*=\s*\[([^\]]*)\]/
);
return m ? (m[1].match(/(?:"[^"]*"|'[^']*')/g) || []).length : null;
}

Comment on lines +125 to +131
if (counts.providers) {
out = out
.replace(/Connect every AI tool to \d+ providers/g, `Connect every AI tool to ${counts.providers} providers`)
.replace(/\*\*\d+ AI Providers\*\*/g, `**${counts.providers} AI Providers**`)
.replace(/All \d+ supported providers/g, `All ${counts.providers} supported providers`)
.replace(/\b\d+ providers\b/g, `${counts.providers} providers`);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

A substituição global utilizando o regex /\b\d+ providers\b/g na linha 130 é extremamente genérica. Ela irá corresponder e substituir qualquer ocorrência de um número seguido de "providers" no arquivo Home.md (por exemplo, frases como "we support 5 providers in this category" seriam incorretamente alteradas para "226 providers").

Como as três substituições anteriores (linhas 127-129) já cobrem os padrões específicos e estruturados do Home.md, recomendo remover essa substituição genérica ou torná-la muito mais específica para evitar efeitos colaterais indesejados em outras partes do texto.

  if (counts.providers) {
    out = out
      .replace(/Connect every AI tool to \d+ providers/g, "Connect every AI tool to " + counts.providers + " providers")
      .replace(/\*\*\d+ AI Providers\*\*/g, "**" + counts.providers + " AI Providers**")
      .replace(/All \d+ supported providers/g, "All " + counts.providers + " supported providers");
  }

Comment on lines +45 to +52
test("syncHomeCounts: rewrites the cover-page provider/strategy counts", () => {
const home = "Connect every AI tool to 177 providers.\n**177 AI Providers** · **14 Routing Strategies**\n";
const out = syncHomeCounts(home, { providers: 226, strategies: 15, mcpTools: null, locales: 42 });
assert.ok(out.includes("226 providers"));
assert.ok(out.includes("**226 AI Providers**"));
assert.ok(out.includes("**15 Routing Strategies**"));
assert.ok(!out.includes("177"));
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Atualmente, não há nenhum caso de teste que valide a substituição bem-sucedida de mcpTools na função syncHomeCounts. O teste existente passa mcpTools: null e apenas valida providers e strategies.

Recomendo expandir o teste ou adicionar um novo caso de teste para garantir que a substituição da tabela do MCP Server (| **MCP Server** | 87 tools |) funcione conforme o esperado quando mcpTools for fornecido.

test("syncHomeCounts: rewrites the cover-page provider/strategy/mcp counts", () => {
  const home = "Connect every AI tool to 177 providers.\n**177 AI Providers** · **14 Routing Strategies**\n| **MCP Server** | 37 tools |\n";
  const out = syncHomeCounts(home, { providers: 226, strategies: 15, mcpTools: 87, locales: 42 });
  assert.ok(out.includes("226 providers"));
  assert.ok(out.includes("**226 AI Providers**"));
  assert.ok(out.includes("**15 Routing Strategies**"));
  assert.ok(out.includes("| **MCP Server** | 87 tools |"));
  assert.ok(!out.includes("177"));
  assert.ok(!out.includes("37"));
});

@diegosouzapw
diegosouzapw merged commit 3424155 into release/v3.8.26 Jun 15, 2026
2 checks passed
diegosouzapw added a commit that referenced this pull request Jun 15, 2026
…#3804)

Integrated into release/v3.8.26 — reconciled: kept #3900's superset wiki-sync, dropped the superseded sync-wiki-home; counts taken from the newer canonical release docs; net-new value = vale/markdownlint docs-lint infra + 7 new docs (Notion/Obsidian/Plugin-Marketplace/Cost-Tracking/Free-Provider-Rankings/Feature-Flags/Egress-Policy) + check-docs-counts-sync guard.
@diegosouzapw diegosouzapw mentioned this pull request Jun 16, 2026
@diegosouzapw
diegosouzapw deleted the chore/wiki-sync-automation branch June 17, 2026 00:54
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
cheaper-inference#3900)

The wiki has no native generator and drifts each release — it lacked SUPPLY_CHAIN
plus 24 other docs pages, and the cover counts went stale (212+/14/37 vs 226/15/87).

Adds:
  - scripts/docs/sync-wiki.mjs — adds docs/ pages missing from the wiki (curated;
    internal reports/plans/index excluded) and syncs the four Home.md cover counts.
    Matches the hand-curated, non-deterministic wiki page names by a normalized fuzzy
    key and writes the EXISTING name, so it never creates duplicate pages. Overwriting
    existing-page content is opt-in (--update-existing) and intentionally OFF by
    default: several docs sources still carry stale counts (e.g. ARCHITECTURE.md says
    "177 providers / 37 MCP tools" while the wiki cover is 226/87), so a blind overwrite
    would REGRESS the wiki. Full parity is gated on regenerating those sources — see
    docs/ops/DOCUMENTATION_AUDIT_REPORT.md.
  - .github/workflows/wiki-sync.yml — runs the sync on every push to main that touches
    docs/ (or a count source) + workflow_dispatch, pushing via GITHUB_TOKEN.
  - tests/unit/sync-wiki.test.ts — pure-function coverage (8 tests).

The first run already pushed the 25 missing pages to the wiki.
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…cheaper-inference#3804)

Integrated into release/v3.8.26 — reconciled: kept cheaper-inference#3900's superset wiki-sync, dropped the superseded sync-wiki-home; counts taken from the newer canonical release docs; net-new value = vale/markdownlint docs-lint infra + 7 new docs (Notion/Obsidian/Plugin-Marketplace/Cost-Tracking/Free-Provider-Rankings/Feature-Flags/Egress-Policy) + check-docs-counts-sync guard.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant