Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copy this file to .env and fill in values to enable optional features at build time.
# .env is gitignored and will never be committed.

# CurseForge API key — required only to build with CurseForge modpack support.
# Obtain one at https://console.curseforge.com/
# If absent, CurseForge modpack import is disabled at runtime (all other features work normally).
# CURSEFORGE_API_KEY=your_key_here
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ __pycache__/
# Tauri artifacts
artifacts/

# Local secrets (do not commit)
.env
.env.local

# AUR Release
release/

Expand Down
1 change: 1 addition & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ ctor = "0.6.3"
inventory = "0.3.21"

[build-dependencies]
dotenvy = { version = "0.15", default-features = false }
tauri-build = { version = "2.0", features = [] }

[target.'cfg(all(windows, target_env = "gnu"))'.build-dependencies]
Expand Down
7 changes: 7 additions & 0 deletions src-tauri/build.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
fn main() {
// Load .env file if present so optional build-time vars (e.g. CURSEFORGE_API_KEY)
// are available to option_env!() without requiring CI to have a real .env file.
if let Ok(path) = dotenvy::dotenv() {
println!("cargo:rerun-if-changed={}", path.display());
}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dotenvy::dotenv() in a build script only affects the build-script process; it does not automatically make CURSEFORGE_API_KEY visible to the crate compilation where option_env!() is evaluated. As written, values from .env likely won’t be embedded, contradicting the comment and PR description. If you want .env to inject the key at compile time, emit cargo:rustc-env=CURSEFORGE_API_KEY=... when the var is present (and keep the rerun-if-* lines).

Suggested change
}
}
// If CURSEFORGE_API_KEY is set (from .env or the environment), forward it to rustc
if let Ok(value) = std::env::var("CURSEFORGE_API_KEY") {
println!("cargo:rustc-env=CURSEFORGE_API_KEY={}", value);
}

Copilot uses AI. Check for mistakes.
println!("cargo:rerun-if-env-changed=CURSEFORGE_API_KEY");

// For MinGW targets, use embed-resource to generate proper COFF format
#[cfg(all(windows, target_env = "gnu"))]
{
Expand Down
11 changes: 5 additions & 6 deletions src-tauri/src/core/modpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ fn parse_multimc(archive: &mut Archive) -> Result<ParsedModpack, String> {

// ── CurseForge API resolution ─────────────────────────────────────────────

const CURSEFORGE_API_KEY: Option<&str> = option_env!("CURSEFORGE_API_KEY");

async fn resolve_curseforge_files(files: &[ModpackFile]) -> Result<Vec<ModpackFile>, String> {
let file_ids: Vec<u64> = files
.iter()
Expand Down Expand Up @@ -366,12 +368,9 @@ async fn cf_post(
endpoint: &str,
body: &serde_json::Value,
) -> Result<serde_json::Value, String> {
let api_key = std::env::var("CURSEFORGE_API_KEY")
.map_err(|_| "CURSEFORGE_API_KEY is not set".to_string())?;
if api_key.trim().is_empty() {
return Err("CURSEFORGE_API_KEY is empty".to_string());
}

let api_key = CURSEFORGE_API_KEY
.ok_or("CurseForge modpack support requires CURSEFORGE_API_KEY set at build time")?;

let resp = client
.post(format!("https://api.curseforge.com{endpoint}"))
.header("x-api-key", api_key)
Expand Down