diff --git a/.github/workflows/cleanup-target.yml b/.github/workflows/cleanup-target.yml new file mode 100644 index 00000000..21034dc9 --- /dev/null +++ b/.github/workflows/cleanup-target.yml @@ -0,0 +1,37 @@ +name: Cleanup Target Directory + +on: + schedule: + - cron: '0 0 * * 0' # Weekly cleanup on Sundays at midnight UTC + workflow_dispatch: + +jobs: + cleanup: + name: Clean old build artifacts + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Clean release artifacts + run: | + cargo clean --release + cargo clean --doc + + - name: Display disk usage + run: | + echo "Target directory size after cleanup:" + du -sh target/ + + - name: Summary + run: | + echo "### Cleanup completed" >> $GITHUB_STEP_SUMMARY + echo "- Cleaned release artifacts" >> $GITHUB_STEP_SUMMARY + echo "- Cleaned documentation artifacts" >> $GITHUB_STEP_SUMMARY diff --git a/Cargo.toml b/Cargo.toml index aac142b1..e14e659e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,3 +42,18 @@ lto = true codegen-units = 1 opt-level = 3 panic = "abort" + +# CI-optimized profiles for faster builds with less disk usage +[profile.ci] +inherits = "dev" +incremental = false +codegen-units = 16 +split-debuginfo = "off" +debug = false +strip = true + +[profile.ci-release] +inherits = "release" +lto = "thin" +codegen-units = 8 +strip = "symbols" diff --git a/crates/terraphim_automata/src/lib.rs b/crates/terraphim_automata/src/lib.rs index 86f03e91..07eec9e9 100644 --- a/crates/terraphim_automata/src/lib.rs +++ b/crates/terraphim_automata/src/lib.rs @@ -347,8 +347,20 @@ pub async fn load_thesaurus(automata_path: &AutomataPath) -> Result { } let contents = match automata_path { - AutomataPath::Local(path) => fs::read_to_string(path)?, - AutomataPath::Remote(url) => read_url(url.clone()).await?, + AutomataPath::Local(path) => { + // Check if file exists before attempting to read + if !std::path::Path::new(path).exists() { + return Err(TerraphimAutomataError::InvalidThesaurus( + format!("Thesaurus file not found: {}", path.display()) + )); + } + fs::read_to_string(path)? + } + AutomataPath::Remote(_) => { + return Err(TerraphimAutomataError::InvalidThesaurus( + "Remote loading is not supported. Enable the 'remote-loading' feature.".to_string(), + )); + } }; let thesaurus = serde_json::from_str(&contents)?; diff --git a/crates/terraphim_service/src/lib.rs b/crates/terraphim_service/src/lib.rs index 87235fc2..24ca67e0 100644 --- a/crates/terraphim_service/src/lib.rs +++ b/crates/terraphim_service/src/lib.rs @@ -259,11 +259,25 @@ impl TerraphimService { Ok(thesaurus) } Err(e) => { - log::error!( - "Failed to build thesaurus from local KG for role {}: {:?}", - role_name, - e - ); + // Check if error is "file not found" (expected for optional files) + // and downgrade log level from ERROR to DEBUG + let is_file_not_found = + e.to_string().contains("file not found") + || e.to_string().contains("not found:"); + + if is_file_not_found { + log::debug!( + "Failed to build thesaurus from local KG (optional file not found) for role {}: {:?}", + role_name, + e + ); + } else { + log::error!( + "Failed to build thesaurus from local KG for role {}: {:?}", + role_name, + e + ); + } Err(ServiceError::Config( "Failed to load or build thesaurus".into(), )) @@ -345,14 +359,19 @@ impl TerraphimService { Ok(thesaurus) } Err(e) => { - log::error!( - "Failed to build thesaurus from local KG for role {}: {:?}", - role_name, - e - ); - Err(ServiceError::Config( - "Failed to build thesaurus from local KG".into(), - )) + // Check if error is "file not found" (expected for optional files) + // and downgrade log level from ERROR to DEBUG + let is_file_not_found = e.to_string().contains("file not found"); + + if is_file_not_found { + log::debug!("Failed to build thesaurus from local KG (optional file not found) for role {}: {:?}", role_name, e); + } else { + log::error!( + "Failed to build thesaurus from local KG for role {}: {:?}", + role_name, + e + ); + } } } } else { @@ -417,7 +436,19 @@ impl TerraphimService { rolegraphs.insert(role_name.clone(), rolegraph_value); } Err(e) => { - log::error!("Failed to update role and thesaurus: {:?}", e) + // Check if error is "file not found" (expected for optional files) + // and downgrade log level from ERROR to DEBUG + let is_file_not_found = + e.to().to_string().contains("file not found"); + + if is_file_not_found { + log::debug!("Failed to update role and thesaurus (optional file not found): {:?}", e); + } else { + log::error!( + "Failed to update role and thesaurus: {:?}", + e + ); + } } } @@ -459,7 +490,16 @@ impl TerraphimService { Ok(thesaurus) } Err(e) => { - log::error!("Failed to load thesaurus: {:?}", e); + // Check if error is "file not found" (expected for optional files) + // and downgrade log level from ERROR to DEBUG + let is_file_not_found = e.to_string().contains("file not found") + || e.to_string().contains("not found:"); + + if is_file_not_found { + log::debug!("Thesaurus file not found (optional): {:?}", e); + } else { + log::error!("Failed to load thesaurus: {:?}", e); + } // Try to build thesaurus from KG and update the config_state directly let mut rolegraphs = self.config_state.roles.clone(); let result = load_thesaurus_from_automata_path( diff --git a/scripts/cleanup-build.sh b/scripts/cleanup-build.sh new file mode 100644 index 00000000..04cd956b --- /dev/null +++ b/scripts/cleanup-build.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# Cleanup build artifacts to prevent target directory bloat +# Usage: ./scripts/cleanup-build.sh [options] +# Options: +# --aggressive Remove more artifacts (docs, unused deps) +# --dry-run Show what would be deleted without actually deleting + +set -euo pipefail + +AGGRESSIVE=false +DRY_RUN=false + +while [[ $# -gt 0 ]]; do + case $1 in + --aggressive) + AGGRESSIVE=true + shift + ;; + --dry-run) + DRY_RUN=true + shift + ;; + *) + echo "Unknown option: $1" + echo "Usage: $0 [--aggressive] [--dry-run]" + exit 1 + ;; + esac +done + +cd "$(git rev-parse --show-toplevel)" || exit 1 + +echo "=== Terraphim Build Cleanup ===" +echo "Mode: $([ "$DRY_RUN" = true ] && echo 'DRY RUN (no changes)' || echo 'ACTIVE')" +echo "Aggressive: $AGGRESSIVE" +echo "" + +# Calculate current size +echo "Current target directory size:" +du -sh target/ 2>/dev/null || echo "No target directory found" +echo "" + +# Cleanup commands +cleanup_commands=( + "Remove old release builds older than 7 days: find target/release -name '*.rlib' -mtime +7 -delete" + "Remove debug rlibs older than 3 days: find target/debug -name '*.rlib' -mtime +3 -delete" + "Remove doc directory: rm -rf target/doc" + "Remove incremental compilation: rm -rf target/*/incremental" +) + +if [ "$AGGRESSIVE" = true ]; then + cleanup_commands+=( + "Remove all debug builds: cargo clean --debug" + "Remove example builds: find target -name 'examples' -type d -exec rm -rf {} +" + "Remove benchmark builds: find target -name 'benches' -type d -exec rm -rf {} +" + ) +fi + +# Execute cleanup +for cmd in "${cleanup_commands[@]}"; do + echo "Executing: $cmd" + if [ "$DRY_RUN" = false ]; then + eval "$cmd" 2>/dev/null || true + fi +done + +echo "" + +# Show sizes of large directories +echo "=== Large directories in target ===" + +find target -maxdepth 2 -type d -exec du -sh {} \; 2>/dev/null | sort -rh | head -20 || true + +echo "" + +# Final size after cleanup +echo "Target directory size after cleanup:" +du -sh target/ 2>/dev/null || echo "No target directory found" + +echo "" +if [ "$DRY_RUN" = false ]; then + echo "Cleanup completed!" + echo "Run with --dry-run to preview changes" +else + echo "Dry run completed. Run without --dry-run to execute cleanup." +fi