Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8847239637 |
+39
-4
@@ -897,22 +897,57 @@ server.tool(
|
||||
|
||||
server.tool(
|
||||
'gitea_bulk_file_push',
|
||||
'Push the same file content to multiple repos (uses Contents API)',
|
||||
'Push the same file content to multiple repos (uses Contents API). Provide repos list OR platform to auto-discover repos by metadata platform.',
|
||||
{
|
||||
owner: z.string().describe('Organization name'),
|
||||
repos: z.array(z.string()).describe('List of repository names'),
|
||||
repos: z.array(z.string()).optional().describe('List of repository names (omit to use platform filter)'),
|
||||
platform: z.string().optional().describe('Auto-discover repos by metadata platform (e.g. joomla, go, mcp). Ignored if repos is provided.'),
|
||||
path: z.string().describe('File path in each repo (e.g. .mokogitea/workflows/pre-release.yml)'),
|
||||
content_base64: z.string().describe('Base64-encoded file content'),
|
||||
message: z.string().describe('Commit message'),
|
||||
branch: z.string().optional().describe('Target branch (default: main)'),
|
||||
...ConnectionParam,
|
||||
},
|
||||
async ({ owner, repos, path, content_base64, message, branch, connection }) => {
|
||||
async ({ owner, repos, platform, path, content_base64, message, branch, connection }) => {
|
||||
const client = clientFor(connection);
|
||||
const targetBranch = branch ?? 'main';
|
||||
const results: Array<{ repo: string; status: string }> = [];
|
||||
|
||||
for (const repo of repos) {
|
||||
// Resolve repo list: explicit repos or auto-discover by platform
|
||||
let targetRepos: string[];
|
||||
if (repos && repos.length > 0) {
|
||||
targetRepos = repos;
|
||||
} else if (platform) {
|
||||
// List all org repos, then filter by metadata platform
|
||||
const allRepos: string[] = [];
|
||||
let page = 1;
|
||||
while (true) {
|
||||
const res = await client.get(`/orgs/${owner}/repos`, { page: String(page), limit: '50' });
|
||||
const data = res.data as Array<{ name: string }>;
|
||||
if (!data || data.length === 0) break;
|
||||
allRepos.push(...data.map(r => r.name));
|
||||
if (data.length < 50) break;
|
||||
page++;
|
||||
}
|
||||
// Check metadata for each repo
|
||||
const matched: string[] = [];
|
||||
for (const repo of allRepos) {
|
||||
try {
|
||||
const meta = await client.get(`/repos/${owner}/${repo}/metadata`);
|
||||
const p = (meta.data as { platform?: string })?.platform;
|
||||
if (p === platform) matched.push(repo);
|
||||
} catch { /* skip repos without metadata */ }
|
||||
}
|
||||
targetRepos = matched;
|
||||
if (targetRepos.length === 0) {
|
||||
return { content: [{ type: 'text' as const, text: `No repos found with platform "${platform}" in ${owner}` }] };
|
||||
}
|
||||
results.push({ repo: '(discovery)', status: `found ${targetRepos.length} repos: ${targetRepos.join(', ')}` });
|
||||
} else {
|
||||
return { content: [{ type: 'text' as const, text: 'Error: provide either repos list or platform filter' }] };
|
||||
}
|
||||
|
||||
for (const repo of targetRepos) {
|
||||
try {
|
||||
// Get current file SHA
|
||||
const existing = await client.get(`/repos/${owner}/${repo}/contents/${path}?ref=${targetBranch}`);
|
||||
|
||||
Reference in New Issue
Block a user