1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import path from 'path';
import { CommandContext } from '../../ui/commands/types.js';
import {
getGitRepoRoot,
getLatestGitHubRelease,
isGitHubRepository,
} from '../../utils/gitUtils.js';
import {
CommandKind,
SlashCommand,
SlashCommandActionReturn,
} from './types.js';
export const setupGithubCommand: SlashCommand = {
name: 'setup-github',
description: 'Set up GitHub Actions',
kind: CommandKind.BUILT_IN,
action: async (
context: CommandContext,
): Promise<SlashCommandActionReturn> => {
if (!isGitHubRepository()) {
throw new Error(
'Unable to determine the GitHub repository. /setup-github must be run from a git repository.',
);
}
// Find the root directory of the repo
let gitRepoRoot: string;
try {
gitRepoRoot = getGitRepoRoot();
} catch (_error) {
console.debug(`Failed to get git repo root:`, _error);
throw new Error(
'Unable to determine the GitHub repository. /setup-github must be run from a git repository.',
);
}
// Get the latest release tag from GitHub
const proxy = context?.services?.config?.getProxy();
const releaseTag = await getLatestGitHubRelease(proxy);
const workflows = [
'gemini-cli/gemini-cli.yml',
'issue-triage/gemini-issue-automated-triage.yml',
'issue-triage/gemini-issue-scheduled-triage.yml',
'pr-review/gemini-pr-review.yml',
];
const commands = [];
// Ensure fast exit
commands.push(`set -eEuo pipefail`);
// Make the directory if it doesn't exist
commands.push(`mkdir -p "${gitRepoRoot}/.github/workflows"`);
for (const workflow of workflows) {
const fileName = path.basename(workflow);
const curlCommand = buildCurlCommand(
`https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/refs/tags/${releaseTag}/examples/workflows/${workflow}`,
[`--output "${gitRepoRoot}/.github/workflows/${fileName}"`],
);
commands.push(curlCommand);
}
commands.push(
`echo "Successfully downloaded ${workflows.length} workflows. Follow the steps in https://github.com/google-github-actions/run-gemini-cli/blob/${releaseTag}/README.md#quick-start (skipping the /setup-github step) to complete setup."`,
`open https://github.com/google-github-actions/run-gemini-cli/blob/${releaseTag}/README.md#quick-start`,
);
const command = `(${commands.join(' && ')})`;
return {
type: 'tool',
toolName: 'run_shell_command',
toolArgs: {
description:
'Setting up GitHub Actions to triage issues and review PRs with Gemini.',
command,
},
};
},
};
// buildCurlCommand is a helper for constructing a consistent curl command.
function buildCurlCommand(u: string, additionalArgs?: string[]): string {
const args = [];
args.push('--fail');
args.push('--location');
args.push('--show-error');
args.push('--silent');
for (const val of additionalArgs || []) {
args.push(val);
}
args.sort();
return `curl ${args.join(' ')} "${u}"`;
}
|