Skip to content

Commit 63a86b8

Browse files
committed
feat: add review:serve task using gh CLI for easy PR preview
1 parent 4d69901 commit 63a86b8

2 files changed

Lines changed: 79 additions & 2 deletions

File tree

β€Ž.github/workflows/main.ymlβ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ jobs:
9393
- **Site Build**: Available in workflow artifacts as \`site-${{ github.sha }}\`
9494
- **Gem Package**: Available in workflow artifacts as \`gem-${{ github.sha }}\`
9595
96-
To preview the site locally:
96+
To preview the site locally (requires [GitHub CLI](https://cli.github.com/)):
9797
\`\`\`bash
98-
SHA=${{ github.sha }} GITHUB_TOKEN=<your-token> bundle exec rake review:serve
98+
SHA=${{ github.sha }} bundle exec rake review:serve
9999
\`\`\`
100100
101101
This will automatically fetch, extract, and serve the review site at http://localhost:4001

β€ŽRakefileβ€Ž

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,83 @@ task serve: [:build_site] do
274274
system(serve_cmd) or raise 'Jekyll serve failed'
275275
end
276276

277+
namespace :review do
278+
desc 'Fetch and serve a PR review build from GitHub Actions artifact'
279+
task :serve do
280+
require 'fileutils'
281+
require 'tmpdir'
282+
require 'json'
283+
284+
sha = ENV['SHA'] || abort('❌ SHA environment variable required (e.g., SHA=abc123 rake review:serve)')
285+
port = ENV['PORT'] || '4001'
286+
repo = 'DocOps/lab'
287+
288+
puts "πŸ” Fetching artifact for commit #{sha[0..7]}..."
289+
290+
# Check if gh CLI is available
291+
unless system('which gh > /dev/null 2>&1')
292+
abort('❌ GitHub CLI (gh) not found. Install using your system\'s package manager (or see https://cli.github.com/)')
293+
end
294+
295+
# Create temp directory for review
296+
review_dir = File.join(Dir.tmpdir, 'docops-lab-review', sha)
297+
FileUtils.mkdir_p review_dir
298+
299+
# Find workflow run for this SHA
300+
puts 'πŸ”Ž Finding workflow run...'
301+
run_json = `gh run list --repo #{repo} --json databaseId,status,conclusion,name,headSha --limit 20`
302+
runs = JSON.parse(run_json)
303+
304+
# Filter for runs matching this SHA and the main workflow
305+
matching_runs = runs.select { |r| r['headSha'].start_with?(sha) && r['name'] == 'Main CI/CD Pipeline' }
306+
307+
abort("❌ No workflow runs found for commit #{sha[0..7]}") if matching_runs.empty?
308+
309+
run = matching_runs.find { |r| r['status'] == 'completed' && r['conclusion'] == 'success' }
310+
311+
if run.nil?
312+
in_progress = matching_runs.find { |r| r['status'] == 'in_progress' }
313+
if in_progress
314+
abort('⏳ Workflow is still running for this commit. Wait for it to complete.')
315+
else
316+
abort("❌ No successful workflow run found for commit #{sha[0..7]}")
317+
end
318+
end
319+
320+
run_id = run['databaseId']
321+
puts "βœ“ Found workflow run ##{run_id}"
322+
323+
# Get artifacts for this run to find the actual site artifact name
324+
puts 'πŸ”Ž Finding site artifact...'
325+
artifacts_json = `gh api repos/#{repo}/actions/runs/#{run_id}/artifacts`
326+
artifacts = JSON.parse(artifacts_json)['artifacts']
327+
site_artifact = artifacts.find { |a| a['name'].start_with?('site-') }
328+
329+
abort('❌ No site artifact found for this run') unless site_artifact
330+
artifact_name = site_artifact['name']
331+
332+
# Check if site is already cached
333+
if File.exist?(File.join(review_dir, 'index.html'))
334+
puts "βœ“ Using cached site from #{review_dir}"
335+
else
336+
puts "πŸ“¦ Downloading #{artifact_name}..."
337+
Dir.chdir(review_dir) do
338+
result = system("gh run download #{run_id} --repo #{repo} --name #{artifact_name}")
339+
abort('❌ Failed to download artifact') unless result
340+
end
341+
end
342+
343+
puts "βœ… Review site ready at #{review_dir}"
344+
puts "πŸš€ Starting server on http://localhost:#{port}..."
345+
puts ' (Press Ctrl+C to stop)'
346+
puts ''
347+
348+
# Serve with Jekyll, specifying the source directory
349+
serve_cmd = "bundle exec jekyll serve --watch --port #{port} --skip-initial-build --source #{review_dir}"
350+
system(serve_cmd) or abort('❌ Server failed')
351+
end
352+
end
353+
277354
desc 'Clean build artifacts'
278355
task :clean do
279356
puts '🧹 Cleaning build artifacts...'

0 commit comments

Comments
Β (0)