Skip to content

Commit d34189b

Browse files
Add proper GitHub authentication handling for telemetry
- Add setup_github_authentication() function with interactive prompts - Handle missing GITHUB_TOKEN gracefully with 3 options: 1. Set GITHUB_TOKEN environment variable 2. Authenticate interactively during autotune 3. Skip telemetry and continue without sharing - Set up authentication at start of autotune process (before long benchmark) - Update upload_to_github() to accept pre-authenticated auth object - Improve error messages and user guidance - Update tutorial documentation with authentication instructions - Save results locally as fallback when authentication fails 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 41f3260 commit d34189b

File tree

3 files changed

+148
-13
lines changed

3 files changed

+148
-13
lines changed

docs/src/tutorials/autotune.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,39 @@ By default, autotune results are shared with the LinearSolve.jl community to hel
306306
- Algorithm performance results
307307
- NO personal information or sensitive data
308308

309-
You can disable this with `telemetry=false` if preferred.
309+
### GitHub Authentication for Telemetry
310310

311-
This helps the community understand performance across different hardware configurations and improves the default algorithm selection for future users.
311+
When telemetry is enabled, you'll be prompted to authenticate with GitHub:
312+
313+
```julia
314+
# This will prompt for GitHub authentication
315+
results = autotune_setup(telemetry = true)
316+
```
317+
318+
You have three options:
319+
320+
1. **Environment Variable (Recommended)**: Set `GITHUB_TOKEN` before running Julia:
321+
```bash
322+
export GITHUB_TOKEN=your_personal_access_token
323+
julia
324+
```
325+
326+
2. **Interactive Authentication**: Enter your token when prompted during autotune
327+
328+
3. **Skip Telemetry**: Choose to continue without sharing results
329+
330+
To create a GitHub Personal Access Token:
331+
1. Go to [GitHub Settings > Tokens](https://github.com/settings/tokens)
332+
2. Generate a new token with `public_repo` scope
333+
3. Use it with the autotune process
334+
335+
### Disabling Telemetry
336+
337+
You can disable telemetry completely:
338+
339+
```julia
340+
# No authentication required
341+
results = autotune_setup(telemetry = false)
342+
```
343+
344+
This helps the community understand performance across different hardware configurations and improves the default algorithm selection for future users, but participation is entirely optional.

lib/LinearSolveAutotune/src/LinearSolveAutotune.jl

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ function autotune_setup(;
8989
@info "Configuration: large_matrices=$large_matrices, telemetry=$telemetry, make_plot=$make_plot, set_preferences=$set_preferences"
9090
@info "Element types to benchmark: $(join(eltypes, ", "))"
9191

92+
# Set up GitHub authentication early if telemetry is enabled
93+
github_auth = nothing
94+
if telemetry
95+
@info "🔗 Checking GitHub authentication for telemetry..."
96+
github_auth = setup_github_authentication()
97+
if github_auth === nothing
98+
@info "📊 Continuing with benchmarking (results will be saved locally)"
99+
end
100+
end
101+
92102
# Get system information
93103
system_info = get_system_info()
94104
@info "System detected: $(system_info["os"]) $(system_info["arch"]) with $(system_info["num_cores"]) cores"
@@ -165,9 +175,9 @@ function autotune_setup(;
165175

166176
# Upload telemetry if requested
167177
if telemetry && nrow(successful_results) > 0
168-
@info "Preparing telemetry data for GitHub..."
178+
@info "📤 Preparing telemetry data for sharing..."
169179
markdown_content = format_results_for_github(results_df, system_info, categories)
170-
upload_to_github(markdown_content, plot_files)
180+
upload_to_github(markdown_content, plot_files, github_auth)
171181
end
172182

173183
@info "Autotune setup completed!"

lib/LinearSolveAutotune/src/telemetry.jl

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,86 @@
11
# Telemetry functionality for sharing benchmark results
22

3+
"""
4+
setup_github_authentication()
5+
6+
Set up GitHub authentication for telemetry uploads.
7+
Returns authentication object if successful, nothing if user cancels.
8+
"""
9+
function setup_github_authentication()
10+
# Check if GITHUB_TOKEN environment variable exists
11+
if haskey(ENV, "GITHUB_TOKEN") && !isempty(ENV["GITHUB_TOKEN"])
12+
try
13+
auth = GitHub.authenticate(ENV["GITHUB_TOKEN"])
14+
@info "✅ GitHub authentication successful using GITHUB_TOKEN environment variable"
15+
return auth
16+
catch e
17+
@warn "❌ GITHUB_TOKEN exists but authentication failed: $e"
18+
@info "Please check that your GITHUB_TOKEN is valid and has appropriate permissions"
19+
return nothing
20+
end
21+
end
22+
23+
# No environment variable - ask user to authenticate
24+
println()
25+
println("🔐 GitHub Authentication Required for Telemetry")
26+
println("="^50)
27+
println("To share benchmark results with the LinearSolve.jl community, you need to")
28+
println("authenticate with GitHub. This helps improve algorithm selection for everyone!")
29+
println()
30+
println("Options:")
31+
println("1. Set GITHUB_TOKEN environment variable (recommended for automation)")
32+
println("2. Authenticate interactively now")
33+
println("3. Skip telemetry (disable sharing)")
34+
println()
35+
36+
while true
37+
print("Choose option (1/2/3): ")
38+
choice = readline()
39+
40+
if choice == "1"
41+
println()
42+
println("To set up GITHUB_TOKEN:")
43+
println("1. Go to https://github.com/settings/tokens")
44+
println("2. Generate a Personal Access Token with 'public_repo' scope")
45+
println("3. Set environment variable: export GITHUB_TOKEN=your_token_here")
46+
println("4. Restart Julia and run autotune again")
47+
println()
48+
println("⚠️ Continuing without telemetry for this session...")
49+
return nothing
50+
51+
elseif choice == "2"
52+
println()
53+
print("Enter your GitHub Personal Access Token: ")
54+
token = readline()
55+
56+
if isempty(token)
57+
println("❌ No token provided. Skipping telemetry.")
58+
return nothing
59+
end
60+
61+
try
62+
# Set temporarily for this session
63+
ENV["GITHUB_TOKEN"] = token
64+
auth = GitHub.authenticate(token)
65+
println("✅ Authentication successful! Token set for this session.")
66+
return auth
67+
catch e
68+
println("❌ Authentication failed: $e")
69+
println("Please check that your token is valid and has 'public_repo' scope.")
70+
continue
71+
end
72+
73+
elseif choice == "3"
74+
println("⚠️ Skipping telemetry. Results will not be shared with the community.")
75+
return nothing
76+
77+
else
78+
println("❌ Invalid choice. Please enter 1, 2, or 3.")
79+
continue
80+
end
81+
end
82+
end
83+
384
"""
485
format_results_for_github(df::DataFrame, system_info::Dict, categories::Dict{String, String})
586
@@ -150,18 +231,29 @@ function format_detailed_results_markdown(df::DataFrame)
150231
end
151232

152233
"""
153-
upload_to_github(content::String, plot_files::Union{Nothing, Tuple, Dict};
234+
upload_to_github(content::String, plot_files::Union{Nothing, Tuple, Dict}, auth;
154235
repo="SciML/LinearSolve.jl", issue_number=669)
155236
156237
Upload benchmark results to GitHub issue as a comment.
238+
Requires a pre-authenticated GitHub.jl auth object.
157239
"""
158-
function upload_to_github(content::String, plot_files::Union{Nothing, Tuple, Dict};
240+
function upload_to_github(content::String, plot_files::Union{Nothing, Tuple, Dict}, auth;
159241
repo = "SciML/LinearSolve.jl", issue_number = 669)
160-
@info "Preparing to upload results to GitHub issue #$issue_number in $repo"
242+
243+
if auth === nothing
244+
@info "⚠️ No GitHub authentication available. Saving results locally instead of uploading."
245+
# Save locally as fallback
246+
fallback_file = "autotune_results_$(replace(string(Dates.now()), ":" => "-")).md"
247+
open(fallback_file, "w") do f
248+
write(f, content)
249+
end
250+
@info "📁 Results saved locally to $fallback_file"
251+
return
252+
end
253+
254+
@info "📤 Uploading results to GitHub issue #$issue_number in $repo"
161255

162256
try
163-
# Create GitHub authentication (requires GITHUB_TOKEN environment variable)
164-
auth = GitHub.authenticate(ENV["GITHUB_TOKEN"])
165257

166258
# Get the repository
167259
repo_obj = GitHub.repo(repo)
@@ -188,17 +280,17 @@ function upload_to_github(content::String, plot_files::Union{Nothing, Tuple, Dic
188280
# Post the comment
189281
GitHub.create_comment(repo_obj, issue_number, comment_body, auth = auth)
190282

191-
@info "Successfully posted benchmark results to GitHub issue #$issue_number"
283+
@info "Successfully posted benchmark results to GitHub issue #$issue_number"
192284

193285
catch e
194-
@warn "Failed to upload to GitHub: $e"
195-
@info "Make sure you have set the GITHUB_TOKEN environment variable with appropriate permissions."
286+
@warn "Failed to upload to GitHub: $e"
287+
@info "💡 This could be due to network issues, repository permissions, or API limits."
196288

197289
# Save locally as fallback
198290
fallback_file = "autotune_results_$(replace(string(Dates.now()), ":" => "-")).md"
199291
open(fallback_file, "w") do f
200292
write(f, content)
201293
end
202-
@info "Results saved locally to $fallback_file"
294+
@info "📁 Results saved locally to $fallback_file as backup"
203295
end
204296
end

0 commit comments

Comments
 (0)