1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ # SPDX-License-Identifier: Apache-2.0
16
+
17
+ name : Build CLI Binaries
18
+
19
+ on :
20
+ workflow_dispatch :
21
+
22
+ jobs :
23
+ build :
24
+ strategy :
25
+ matrix :
26
+ include :
27
+ - os : ubuntu-latest
28
+ target : linux-x64
29
+ - os : ubuntu-24.04-arm
30
+ target : linux-arm64
31
+ - os : macos-13 # x64/Intel
32
+ target : darwin-x64
33
+ - os : macos-latest # ARM64/M1
34
+ target : darwin-arm64
35
+ - os : windows-latest
36
+ target : win32-x64
37
+ # Note: Windows ARM64 currently runs x64 binaries through emulation
38
+ # Native ARM64 support is not yet available in Bun
39
+ # See: https://github.com/oven-sh/bun/pull/11430
40
+ # - os: windows-11-arm
41
+ # target: win32-arm64
42
+
43
+ runs-on : ${{ matrix.os }}
44
+
45
+ steps :
46
+ - name : Checkout code
47
+ uses : actions/checkout@v4
48
+
49
+ - name : Setup Bun
50
+ uses : oven-sh/setup-bun@v2
51
+ with :
52
+ bun-version : latest
53
+
54
+ - name : Setup pnpm
55
+ uses : pnpm/action-setup@v3
56
+ with :
57
+ version : 10.11.0
58
+
59
+ - name : Setup Node.js
60
+ uses : actions/setup-node@v4
61
+ with :
62
+ node-version : ' 20'
63
+ cache : ' pnpm'
64
+
65
+ - name : Install root dependencies
66
+ run : pnpm i
67
+
68
+ - name : Install genkit-tools dependencies
69
+ run : pnpm pnpm-install-genkit-tools
70
+
71
+ - name : Build genkit-tools
72
+ run : pnpm build:genkit-tools
73
+
74
+ - name : Set binary extension
75
+ id : binary
76
+ shell : bash
77
+ run : |
78
+ if [[ "${{ matrix.target }}" == win32-* ]]; then
79
+ echo "ext=.exe" >> $GITHUB_OUTPUT
80
+ else
81
+ echo "ext=" >> $GITHUB_OUTPUT
82
+ fi
83
+
84
+ - name : Compile CLI binary
85
+ shell : bash
86
+ run : |
87
+ cd genkit-tools/cli
88
+ pnpm compile:bun
89
+
90
+ # Handle the binary name based on OS
91
+ if [[ "${{ matrix.os }}" == windows-* ]]; then
92
+ # On Windows, Bun outputs genkit.exe
93
+ mv dist/bin/genkit.exe "dist/bin/genkit-${{ matrix.target }}.exe"
94
+ else
95
+ # On Unix-like systems, no extension
96
+ mv dist/bin/genkit "dist/bin/genkit-${{ matrix.target }}"
97
+ fi
98
+
99
+ - name : Upload binary artifact
100
+ uses : actions/upload-artifact@v4
101
+ with :
102
+ name : genkit-${{ matrix.target }}
103
+ path : genkit-tools/cli/dist/bin/genkit-${{ matrix.target }}${{ steps.binary.outputs.ext }}
104
+ retention-days : 1 # TODO: Consider increasing to 7 days for better debugging capability
105
+
106
+ test :
107
+ needs : build
108
+ strategy :
109
+ matrix :
110
+ include :
111
+ - os : ubuntu-latest
112
+ target : linux-x64
113
+ - os : ubuntu-24.04-arm
114
+ target : linux-arm64
115
+ - os : macos-13
116
+ target : darwin-x64
117
+ - os : macos-latest
118
+ target : darwin-arm64
119
+ - os : windows-latest
120
+ target : win32-x64
121
+
122
+ runs-on : ${{ matrix.os }}
123
+
124
+ steps :
125
+ - name : Set binary extension
126
+ id : binary
127
+ shell : bash
128
+ run : |
129
+ if [[ "${{ matrix.target }}" == win32-* ]]; then
130
+ echo "ext=.exe" >> $GITHUB_OUTPUT
131
+ else
132
+ echo "ext=" >> $GITHUB_OUTPUT
133
+ fi
134
+
135
+ - name : Download binary artifact
136
+ uses : actions/download-artifact@v4
137
+ with :
138
+ name : genkit-${{ matrix.target }}
139
+ path : ./
140
+
141
+ - name : Make binary executable (Unix)
142
+ if : runner.os != 'Windows'
143
+ run : chmod +x genkit-${{ matrix.target }}
144
+
145
+ - name : Test --help command
146
+ shell : bash
147
+ run : |
148
+ echo "Testing genkit --help"
149
+ ./genkit-${{ matrix.target }}${{ steps.binary.outputs.ext }} --help
150
+
151
+ - name : Test --version command
152
+ shell : bash
153
+ run : |
154
+ echo "Testing genkit --version"
155
+ ./genkit-${{ matrix.target }}${{ steps.binary.outputs.ext }} --version
156
+
157
+ - name : Verify UI commands exist
158
+ shell : bash
159
+ run : |
160
+ echo "Verifying UI commands are available"
161
+ ./genkit-${{ matrix.target }}${{ steps.binary.outputs.ext }} ui:start --help
162
+ ./genkit-${{ matrix.target }}${{ steps.binary.outputs.ext }} ui:stop --help
163
+
164
+ - name : Test UI start functionality (Unix only)
165
+ if : runner.os != 'Windows'
166
+ shell : bash
167
+ run : |
168
+ echo "Testing genkit ui:start"
169
+
170
+ # Start UI in background, piping any prompts to accept them
171
+ (echo "" | ./genkit-${{ matrix.target }} ui:start 2>&1 | tee ui_output.log) &
172
+ UI_PID=$!
173
+
174
+ # Give it time to start
175
+ sleep 5
176
+
177
+ # Check if it started successfully by looking for the expected output
178
+ if grep -q "Genkit Developer UI started at:" ui_output.log 2>/dev/null; then
179
+ echo "✓ UI started successfully"
180
+ cat ui_output.log
181
+
182
+ # Try to stop it gracefully
183
+ echo "Testing genkit ui:stop"
184
+ ./genkit-${{ matrix.target }} ui:stop || true
185
+
186
+ # Give it time to stop
187
+ sleep 2
188
+ else
189
+ echo "UI output:"
190
+ cat ui_output.log 2>/dev/null || echo "No output captured"
191
+
192
+ # Check if process is still running
193
+ if ps -p $UI_PID > /dev/null 2>&1; then
194
+ echo "Process is running but didn't produce expected output"
195
+ kill $UI_PID 2>/dev/null || true
196
+ else
197
+ echo "Process exited (might be due to cookie prompt or missing project)"
198
+ fi
199
+ fi
200
+
201
+ # Clean up any remaining processes
202
+ pkill -f "genkit.*ui:start" 2>/dev/null || true
203
+
204
+ - name : Test UI start functionality (Windows only)
205
+ if : runner.os == 'Windows'
206
+ shell : pwsh
207
+ run : |
208
+ Write-Host "Testing genkit ui:start"
209
+
210
+ # Create empty input file first for redirecting stdin
211
+ "" | Out-File -FilePath ".\empty.txt"
212
+
213
+ # Start UI in background, redirecting input to handle prompts
214
+ $process = Start-Process -FilePath ".\genkit-${{ matrix.target }}.exe" `
215
+ -ArgumentList "ui:start" `
216
+ -RedirectStandardInput ".\empty.txt" `
217
+ -RedirectStandardOutput ".\ui_output.log" `
218
+ -RedirectStandardError ".\ui_error.log" `
219
+ -PassThru `
220
+ -NoNewWindow
221
+
222
+ # Give it time to start
223
+ Start-Sleep -Seconds 5
224
+
225
+ # Read the output
226
+ $output = Get-Content ".\ui_output.log" -ErrorAction SilentlyContinue
227
+ $errorOutput = Get-Content ".\ui_error.log" -ErrorAction SilentlyContinue
228
+
229
+ if ($output -match "Genkit Developer UI started at:") {
230
+ Write-Host "✓ UI started successfully"
231
+ Write-Host "Output:"
232
+ $output | Write-Host
233
+
234
+ # Try to stop it gracefully
235
+ Write-Host "Testing genkit ui:stop"
236
+ & ".\genkit-${{ matrix.target }}.exe" ui:stop
237
+
238
+ Start-Sleep -Seconds 2
239
+ } else {
240
+ Write-Host "UI did not start as expected"
241
+ Write-Host "Output:"
242
+ $output | Write-Host
243
+ Write-Host "Error:"
244
+ $errorOutput | Write-Host
245
+
246
+ # Check if process is still running
247
+ if (-not $process.HasExited) {
248
+ Write-Host "Process is still running, terminating..."
249
+ Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue
250
+ } else {
251
+ Write-Host "Process exited (might be due to cookie prompt or missing project)"
252
+ }
253
+ }
254
+
255
+ # Clean up any remaining genkit processes
256
+ Get-Process | Where-Object { $_.ProcessName -match "genkit" } | Stop-Process -Force -ErrorAction SilentlyContinue
0 commit comments