From 0e4fe01eafc3aa31a27779f5e5f89d11d54e0745 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 06:47:16 +0000 Subject: [PATCH 01/10] Initial plan From 6aceeeba056ccfe560fb7dafc732ba4369b788fa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 06:50:58 +0000 Subject: [PATCH 02/10] Fix Xvfb startup error by explicitly starting Xvfb on display :99 Co-authored-by: dorkmo <1923070+dorkmo@users.noreply.github.com> --- .github/workflows/openscad-render.yml | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/.github/workflows/openscad-render.yml b/.github/workflows/openscad-render.yml index c3dbefb..bdc2194 100644 --- a/.github/workflows/openscad-render.yml +++ b/.github/workflows/openscad-render.yml @@ -25,13 +25,19 @@ jobs: sudo apt-get install -y openscad xvfb openscad --version + - name: Start Xvfb + run: | + Xvfb :99 -screen 0 1024x768x16 & + sleep 2 + echo "DISPLAY=:99" >> $GITHUB_ENV + - name: Validate OpenSCAD syntax run: | echo "Validating OpenSCAD files..." cd LifeTrac-v25/mechanical_design # Check main design file - xvfb-run openscad -o /dev/null --export-format echo openscad/lifetrac_v25.scad + openscad -o /dev/null --export-format echo openscad/lifetrac_v25.scad if [ $? -eq 0 ]; then echo "✓ Main design file is valid" else @@ -42,7 +48,7 @@ jobs: # Check module files for module in modules/*.scad; do echo "Checking $module..." - xvfb-run openscad -o /dev/null --export-format echo "$module" + openscad -o /dev/null --export-format echo "$module" if [ $? -eq 0 ]; then echo "✓ $module is valid" else @@ -62,7 +68,7 @@ jobs: # Generate assembly.png (1024x768 matching CEB-Press example) echo "Generating assembly.png..." - xvfb-run openscad -o assembly.png \ + openscad -o assembly.png \ --camera=3000,3000,2000,0,0,500 \ --imgsize=1024,768 \ --projection=p \ @@ -71,7 +77,7 @@ jobs: # Generate cnclayout.svg (2D projection for CNC cutting) echo "Generating cnclayout.svg..." - xvfb-run openscad -o cnclayout.svg \ + openscad -o cnclayout.svg \ --projection=o \ --viewall \ cnclayout.scad @@ -85,7 +91,7 @@ jobs: # Main assembly view echo "Rendering main assembly..." - xvfb-run openscad -o output/renders/lifetrac_v25_main.png \ + openscad -o output/renders/lifetrac_v25_main.png \ --camera=3000,3000,2000,0,0,500 \ --imgsize=1920,1080 \ --projection=p \ @@ -94,7 +100,7 @@ jobs: # Front view echo "Rendering front view..." - xvfb-run openscad -o output/renders/lifetrac_v25_front.png \ + openscad -o output/renders/lifetrac_v25_front.png \ --camera=0,3000,1000,0,0,500 \ --imgsize=1920,1080 \ --projection=p \ @@ -103,7 +109,7 @@ jobs: # Side view echo "Rendering side view..." - xvfb-run openscad -o output/renders/lifetrac_v25_side.png \ + openscad -o output/renders/lifetrac_v25_side.png \ --camera=3000,0,1000,0,0,500 \ --imgsize=1920,1080 \ --projection=p \ @@ -112,7 +118,7 @@ jobs: # Top view echo "Rendering top view..." - xvfb-run openscad -o output/renders/lifetrac_v25_top.png \ + openscad -o output/renders/lifetrac_v25_top.png \ --camera=0,0,3000,0,0,500 \ --imgsize=1920,1080 \ --projection=o \ @@ -129,7 +135,7 @@ jobs: for module in modules/*.scad; do filename=$(basename "$module" .scad) echo "Rendering $filename examples..." - xvfb-run openscad -o "output/renders/${filename}_examples.png" \ + openscad -o "output/renders/${filename}_examples.png" \ --camera=500,500,500,0,0,0 \ --imgsize=1600,900 \ --projection=p \ @@ -148,7 +154,7 @@ jobs: for i in {0..35}; do t=$(awk "BEGIN {print $i/36}") printf "Frame %d (t=%.4f)\n" $i $t - xvfb-run openscad -o "output/animations/frames/frame_$(printf %03d $i).png" \ + openscad -o "output/animations/frames/frame_$(printf %03d $i).png" \ --camera=3000,3000,2000,0,0,500 \ --imgsize=1280,720 \ --projection=p \ From 3f820e78a68367e592910db60bf21aa7a9d5ca4a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 06:52:14 +0000 Subject: [PATCH 03/10] Improve Xvfb startup reliability and add cleanup step Co-authored-by: dorkmo <1923070+dorkmo@users.noreply.github.com> --- .github/workflows/openscad-render.yml | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/.github/workflows/openscad-render.yml b/.github/workflows/openscad-render.yml index bdc2194..8f345be 100644 --- a/.github/workflows/openscad-render.yml +++ b/.github/workflows/openscad-render.yml @@ -28,7 +28,22 @@ jobs: - name: Start Xvfb run: | Xvfb :99 -screen 0 1024x768x16 & - sleep 2 + XVFB_PID=$! + echo "XVFB_PID=$XVFB_PID" >> $GITHUB_ENV + + # Wait for Xvfb to be ready (max 10 seconds) + for i in {1..10}; do + if xdpyinfo -display :99 >/dev/null 2>&1; then + echo "Xvfb is ready on display :99" + break + fi + if [ $i -eq 10 ]; then + echo "Timeout waiting for Xvfb to start" + exit 1 + fi + sleep 1 + done + echo "DISPLAY=:99" >> $GITHUB_ENV - name: Validate OpenSCAD syntax @@ -262,6 +277,14 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Cleanup Xvfb + if: always() + run: | + if [ -n "$XVFB_PID" ]; then + echo "Stopping Xvfb process (PID: $XVFB_PID)" + kill $XVFB_PID || true + fi + - name: Comment on PR with results if: github.event_name == 'pull_request' uses: actions/github-script@v7 From 3b2868e2d79f43400c00ab7a21e3b14820e85f71 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 06:53:11 +0000 Subject: [PATCH 04/10] Improve Xvfb cleanup with graceful and forced shutdown Co-authored-by: dorkmo <1923070+dorkmo@users.noreply.github.com> --- .github/workflows/openscad-render.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/openscad-render.yml b/.github/workflows/openscad-render.yml index 8f345be..29f748e 100644 --- a/.github/workflows/openscad-render.yml +++ b/.github/workflows/openscad-render.yml @@ -282,7 +282,19 @@ jobs: run: | if [ -n "$XVFB_PID" ]; then echo "Stopping Xvfb process (PID: $XVFB_PID)" - kill $XVFB_PID || true + # Try graceful shutdown first + kill -TERM $XVFB_PID 2>/dev/null || true + # Wait up to 5 seconds for process to terminate + for i in {1..5}; do + if ! kill -0 $XVFB_PID 2>/dev/null; then + echo "Xvfb stopped gracefully" + exit 0 + fi + sleep 1 + done + # Force kill if still running + kill -KILL $XVFB_PID 2>/dev/null || true + echo "Xvfb force stopped" fi - name: Comment on PR with results From c7ff56bf60db9451d53268ef4e7ccb783f1cee06 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 06:59:41 +0000 Subject: [PATCH 05/10] Split structural analysis into separate workflow from rendering Co-authored-by: dorkmo <1923070+dorkmo@users.noreply.github.com> --- .github/workflows/openscad-render.yml | 42 +---- .../openscad-structural-analysis.yml | 177 ++++++++++++++++++ 2 files changed, 184 insertions(+), 35 deletions(-) create mode 100644 .github/workflows/openscad-structural-analysis.yml diff --git a/.github/workflows/openscad-render.yml b/.github/workflows/openscad-render.yml index 29f748e..fba28a6 100644 --- a/.github/workflows/openscad-render.yml +++ b/.github/workflows/openscad-render.yml @@ -11,9 +11,9 @@ on: workflow_dispatch: jobs: - validate-and-render: + render: runs-on: ubuntu-latest - name: Validate OpenSCAD and Generate Outputs + name: Generate Renders and Outputs steps: - name: Checkout repository @@ -46,32 +46,7 @@ jobs: echo "DISPLAY=:99" >> $GITHUB_ENV - - name: Validate OpenSCAD syntax - run: | - echo "Validating OpenSCAD files..." - cd LifeTrac-v25/mechanical_design - - # Check main design file - openscad -o /dev/null --export-format echo openscad/lifetrac_v25.scad - if [ $? -eq 0 ]; then - echo "✓ Main design file is valid" - else - echo "✗ Main design file has errors" - exit 1 - fi - - # Check module files - for module in modules/*.scad; do - echo "Checking $module..." - openscad -o /dev/null --export-format echo "$module" - if [ $? -eq 0 ]; then - echo "✓ $module is valid" - else - echo "✗ $module has errors" - exit 1 - fi - done - + - name: Create output directories run: | cd LifeTrac-v25/mechanical_design @@ -222,18 +197,13 @@ jobs: - assembly.png (3D render of complete assembly) - cnclayout.svg (2D layout for CNC cutting) - ## Validation Results - - ✓ All OpenSCAD files validated successfully - ✓ Main design file compiled without errors - ✓ All module files syntax-checked - ## Next Steps 1. Review rendered images in the artifacts 2. Use cnclayout.svg for CNC plasma cutting 3. Use animation frames to create videos 4. Export DXF files for individual parts using export_all_cnc_parts.sh + 5. Check the Structural Analysis workflow for design validation results --- Generated by GitHub Actions @@ -305,7 +275,7 @@ jobs: const fs = require('fs'); const comment = `## OpenSCAD Render Results 🎨 - ✅ All OpenSCAD files validated successfully! + ✅ Rendering completed successfully! ### Generated Outputs - 📸 Preview renders (main, front, side, top views) @@ -321,6 +291,8 @@ jobs: ### CNC Files - \`assembly.png\` and \`cnclayout.svg\` committed to repository + _Note: Check the **OpenSCAD Structural Analysis** workflow for design validation and structural analysis results._ + **Workflow Run:** [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) `; diff --git a/.github/workflows/openscad-structural-analysis.yml b/.github/workflows/openscad-structural-analysis.yml new file mode 100644 index 0000000..f95b38b --- /dev/null +++ b/.github/workflows/openscad-structural-analysis.yml @@ -0,0 +1,177 @@ +name: OpenSCAD Structural Analysis + +on: + push: + paths: + - 'LifeTrac-v25/mechanical_design/**/*.scad' + - '.github/workflows/openscad-structural-analysis.yml' + pull_request: + paths: + - 'LifeTrac-v25/mechanical_design/**/*.scad' + workflow_dispatch: + +jobs: + structural-analysis: + runs-on: ubuntu-latest + name: Validate Structural Design + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install OpenSCAD + run: | + sudo apt-get update + sudo apt-get install -y openscad xvfb + openscad --version + + - name: Start Xvfb + run: | + Xvfb :99 -screen 0 1024x768x16 & + XVFB_PID=$! + echo "XVFB_PID=$XVFB_PID" >> $GITHUB_ENV + + # Wait for Xvfb to be ready (max 10 seconds) + for i in {1..10}; do + if xdpyinfo -display :99 >/dev/null 2>&1; then + echo "Xvfb is ready on display :99" + break + fi + if [ $i -eq 10 ]; then + echo "Timeout waiting for Xvfb to start" + exit 1 + fi + sleep 1 + done + + echo "DISPLAY=:99" >> $GITHUB_ENV + + - name: Validate OpenSCAD syntax + run: | + echo "Validating OpenSCAD files..." + cd LifeTrac-v25/mechanical_design + + # Check main design file + openscad -o /dev/null --export-format echo openscad/lifetrac_v25.scad + if [ $? -eq 0 ]; then + echo "✓ Main design file is valid" + else + echo "✗ Main design file has errors" + exit 1 + fi + + # Check module files + for module in modules/*.scad; do + echo "Checking $module..." + openscad -o /dev/null --export-format echo "$module" + if [ $? -eq 0 ]; then + echo "✓ $module is valid" + else + echo "✗ $module has errors" + exit 1 + fi + done + + - name: Run structural analysis + run: | + echo "Running structural analysis on main design..." + cd LifeTrac-v25/mechanical_design + + # Run OpenSCAD with echo output to capture structural analysis + openscad -o /dev/null --export-format echo openscad/lifetrac_v25.scad 2>&1 | tee structural_analysis.log + + echo "Structural analysis complete. Check logs for results." + + - name: Generate structural analysis report + run: | + cd LifeTrac-v25/mechanical_design + + # Extract key metrics from the log + echo "# Structural Analysis Report" > structural_report.md + echo "" >> structural_report.md + echo "**Generated:** $(date)" >> structural_report.md + echo "**Commit:** ${{ github.sha }}" >> structural_report.md + echo "**Branch:** ${{ github.ref_name }}" >> structural_report.md + echo "" >> structural_report.md + + # Extract structural summary if present + if grep -q "COMPLETE STRUCTURAL ANALYSIS SUMMARY" structural_analysis.log; then + echo "## Structural Analysis Results" >> structural_report.md + echo "" >> structural_report.md + echo "\`\`\`" >> structural_report.md + sed -n '/COMPLETE STRUCTURAL ANALYSIS SUMMARY/,/========================================/p' structural_analysis.log | tail -n +2 >> structural_report.md + echo "\`\`\`" >> structural_report.md + else + echo "No structural analysis summary found in output." >> structural_report.md + fi + + cat structural_report.md + + - name: Upload structural analysis artifacts + uses: actions/upload-artifact@v4 + with: + name: structural-analysis + path: | + LifeTrac-v25/mechanical_design/structural_analysis.log + LifeTrac-v25/mechanical_design/structural_report.md + retention-days: 90 + + - name: Cleanup Xvfb + if: always() + run: | + if [ -n "$XVFB_PID" ]; then + echo "Stopping Xvfb process (PID: $XVFB_PID)" + # Try graceful shutdown first + kill -TERM $XVFB_PID 2>/dev/null || true + # Wait up to 5 seconds for process to terminate + for i in {1..5}; do + if ! kill -0 $XVFB_PID 2>/dev/null; then + echo "Xvfb stopped gracefully" + exit 0 + fi + sleep 1 + done + # Force kill if still running + kill -KILL $XVFB_PID 2>/dev/null || true + echo "Xvfb force stopped" + fi + + - name: Comment on PR with structural analysis + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + + // Read the structural report + let reportContent = 'Structural analysis completed. Check artifacts for detailed results.'; + try { + const report = fs.readFileSync('LifeTrac-v25/mechanical_design/structural_report.md', 'utf8'); + // Extract just the results section + const match = report.match(/## Structural Analysis Results[\s\S]*$/); + if (match) { + reportContent = match[0]; + } + } catch (err) { + console.log('Could not read structural report:', err); + } + + const comment = `## OpenSCAD Structural Analysis Results 🔧 + + ✅ Structural analysis completed! + + ${reportContent} + + ### Artifacts + Download the detailed analysis from the workflow artifacts: + - \`structural-analysis\` - Complete logs and report + + **Workflow Run:** [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) + `; + + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: comment + }); From 0d9a3757d02d2d84a5d5f62b157bd12406ddb426 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 07:01:33 +0000 Subject: [PATCH 06/10] Address code review feedback: add x11-utils and fix cleanup logic Co-authored-by: dorkmo <1923070+dorkmo@users.noreply.github.com> --- .github/workflows/openscad-render.yml | 4 ++-- .github/workflows/openscad-structural-analysis.yml | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/openscad-render.yml b/.github/workflows/openscad-render.yml index fba28a6..d67d96e 100644 --- a/.github/workflows/openscad-render.yml +++ b/.github/workflows/openscad-render.yml @@ -22,7 +22,7 @@ jobs: - name: Install OpenSCAD run: | sudo apt-get update - sudo apt-get install -y openscad xvfb + sudo apt-get install -y openscad xvfb x11-utils openscad --version - name: Start Xvfb @@ -258,7 +258,7 @@ jobs: for i in {1..5}; do if ! kill -0 $XVFB_PID 2>/dev/null; then echo "Xvfb stopped gracefully" - exit 0 + break fi sleep 1 done diff --git a/.github/workflows/openscad-structural-analysis.yml b/.github/workflows/openscad-structural-analysis.yml index f95b38b..e86f8e1 100644 --- a/.github/workflows/openscad-structural-analysis.yml +++ b/.github/workflows/openscad-structural-analysis.yml @@ -22,7 +22,7 @@ jobs: - name: Install OpenSCAD run: | sudo apt-get update - sudo apt-get install -y openscad xvfb + sudo apt-get install -y openscad xvfb x11-utils openscad --version - name: Start Xvfb @@ -99,7 +99,9 @@ jobs: echo "## Structural Analysis Results" >> structural_report.md echo "" >> structural_report.md echo "\`\`\`" >> structural_report.md - sed -n '/COMPLETE STRUCTURAL ANALYSIS SUMMARY/,/========================================/p' structural_analysis.log | tail -n +2 >> structural_report.md + # Extract from summary start to next delimiter or end of relevant section + sed -n '/COMPLETE STRUCTURAL ANALYSIS SUMMARY/,/========================================/{p;/========================================/q}' structural_analysis.log | tail -n +2 >> structural_report.md || \ + sed -n '/COMPLETE STRUCTURAL ANALYSIS SUMMARY/,$p' structural_analysis.log | tail -n +2 | head -n 20 >> structural_report.md echo "\`\`\`" >> structural_report.md else echo "No structural analysis summary found in output." >> structural_report.md @@ -127,7 +129,7 @@ jobs: for i in {1..5}; do if ! kill -0 $XVFB_PID 2>/dev/null; then echo "Xvfb stopped gracefully" - exit 0 + break fi sleep 1 done From b080cd4d145e512bea54f42b250a8fb300ead347 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 7 Dec 2025 07:08:13 +0000 Subject: [PATCH 07/10] Update assembly.png and cnclayout.svg [skip ci] --- LifeTrac-v25/mechanical_design/assembly.png | Bin 31234 -> 34641 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/LifeTrac-v25/mechanical_design/assembly.png b/LifeTrac-v25/mechanical_design/assembly.png index 6da02c9d72b051fa788e43e385e9cc1f50ed4a0c..1d837a45ee13669bfe4bf43170a3b5ef2904cf2d 100644 GIT binary patch literal 34641 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 literal 31234 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

WryQCnsuV^zAMd6 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 e<3-HhQI Date: Sun, 7 Dec 2025 07:14:29 +0000 Subject: [PATCH 08/10] Add persistent structural analysis log file with failure descriptions Co-authored-by: dorkmo <1923070+dorkmo@users.noreply.github.com> --- .../openscad-structural-analysis.yml | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/.github/workflows/openscad-structural-analysis.yml b/.github/workflows/openscad-structural-analysis.yml index e86f8e1..603a25c 100644 --- a/.github/workflows/openscad-structural-analysis.yml +++ b/.github/workflows/openscad-structural-analysis.yml @@ -109,6 +109,122 @@ jobs: cat structural_report.md + - name: Create persistent structural analysis log + run: | + cd LifeTrac-v25/mechanical_design + + # Create or update the persistent log file + echo "# Structural Analysis Test Log" > STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + echo "This file tracks the history of structural analysis test results." >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + echo "---" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + echo "## Latest Analysis" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + echo "**Date:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> STRUCTURAL_ANALYSIS_LOG.md + echo "**Commit:** ${{ github.sha }}" >> STRUCTURAL_ANALYSIS_LOG.md + echo "**Branch:** ${{ github.ref_name }}" >> STRUCTURAL_ANALYSIS_LOG.md + echo "**Workflow Run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + + # Extract and format the structural analysis results + if grep -q "COMPLETE STRUCTURAL ANALYSIS SUMMARY" structural_analysis.log; then + echo "### Results Summary" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + echo "\`\`\`" >> STRUCTURAL_ANALYSIS_LOG.md + sed -n '/COMPLETE STRUCTURAL ANALYSIS SUMMARY/,/========================================/{p;/========================================/q}' structural_analysis.log | tail -n +2 >> STRUCTURAL_ANALYSIS_LOG.md || \ + sed -n '/COMPLETE STRUCTURAL ANALYSIS SUMMARY/,$p' structural_analysis.log | tail -n +2 | head -n 20 >> STRUCTURAL_ANALYSIS_LOG.md + echo "\`\`\`" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + + # Extract detailed failure information if any tests failed + if grep -q "FAIL" structural_analysis.log; then + echo "### ⚠️ Failed Components" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + + # Extract rated capacity + CAPACITY=$(grep "RATED LIFT CAPACITY:" structural_analysis.log | head -1 | sed 's/ECHO: "RATED LIFT CAPACITY:", //') + echo "**Current Rated Capacity:** $CAPACITY" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + + # List each failed component with details + echo "#### Detailed Failure Analysis" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + + # Arm Bending + if grep -q "Arm Bending.*FAIL" structural_analysis.log; then + echo "**1. Arm Bending Stress**" >> STRUCTURAL_ANALYSIS_LOG.md + grep -A 5 "=== ARM BENDING STRESS ANALYSIS ===" structural_analysis.log | grep "ECHO:" | sed 's/ECHO: /- /' >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + fi + + # Arm Deflection + if grep -q "Arm Deflection.*FAIL" structural_analysis.log; then + echo "**2. Arm Deflection**" >> STRUCTURAL_ANALYSIS_LOG.md + grep -A 5 "=== ARM DEFLECTION ANALYSIS ===" structural_analysis.log | grep "ECHO:" | sed 's/ECHO: /- /' >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + fi + + # Cross Beam + if grep -q "Cross Beam.*FAIL" structural_analysis.log; then + echo "**3. Cross Beam Bending**" >> STRUCTURAL_ANALYSIS_LOG.md + grep -A 5 "=== CROSS BEAM STRESS ANALYSIS ===" structural_analysis.log | grep "ECHO:" | sed 's/ECHO: /- /' >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + fi + + # Pivot Ring Welds + if grep -q "Pivot Ring.*FAIL" structural_analysis.log; then + echo "**4. Pivot Ring Welds**" >> STRUCTURAL_ANALYSIS_LOG.md + grep -A 5 "=== PIVOT RING WELD ANALYSIS ===" structural_analysis.log | grep "ECHO:" | sed 's/ECHO: /- /' >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + fi + + echo "### Recommended Actions" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + echo "See [STRUCTURAL_ANALYSIS.md](STRUCTURAL_ANALYSIS.md) for design modification recommendations." >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + else + echo "### ✅ All Tests Passed" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + echo "All structural analysis checks passed successfully." >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + fi + else + echo "### Error" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + echo "No structural analysis summary found in output. Check the workflow logs for errors." >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + fi + + echo "---" >> STRUCTURAL_ANALYSIS_LOG.md + echo "" >> STRUCTURAL_ANALYSIS_LOG.md + echo "_This file is automatically updated by the OpenSCAD Structural Analysis workflow._" >> STRUCTURAL_ANALYSIS_LOG.md + + cat STRUCTURAL_ANALYSIS_LOG.md + + - name: Commit structural analysis log + run: | + cd LifeTrac-v25/mechanical_design + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + + # Add the log file + git add STRUCTURAL_ANALYSIS_LOG.md + + # Check if there are changes + if ! git diff --staged --quiet; then + git commit -m "Update structural analysis log [skip ci]" + git push --force-with-lease origin HEAD || { + echo "INFO: git push failed. This is expected on PRs from forks." + echo "The log file is available as a workflow artifact." + } + else + echo "No changes to structural analysis log" + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Upload structural analysis artifacts uses: actions/upload-artifact@v4 with: @@ -116,6 +232,7 @@ jobs: path: | LifeTrac-v25/mechanical_design/structural_analysis.log LifeTrac-v25/mechanical_design/structural_report.md + LifeTrac-v25/mechanical_design/STRUCTURAL_ANALYSIS_LOG.md retention-days: 90 - name: Cleanup Xvfb @@ -164,6 +281,10 @@ jobs: ${reportContent} + ### Persistent Log + A detailed log with failure descriptions has been committed to: + - \`LifeTrac-v25/mechanical_design/STRUCTURAL_ANALYSIS_LOG.md\` + ### Artifacts Download the detailed analysis from the workflow artifacts: - \`structural-analysis\` - Complete logs and report From af6e450293afe69dd38725075cdacfaa580bdeb2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 7 Dec 2025 07:16:34 +0000 Subject: [PATCH 09/10] Update structural analysis log [skip ci] --- .../STRUCTURAL_ANALYSIS_LOG.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 LifeTrac-v25/mechanical_design/STRUCTURAL_ANALYSIS_LOG.md diff --git a/LifeTrac-v25/mechanical_design/STRUCTURAL_ANALYSIS_LOG.md b/LifeTrac-v25/mechanical_design/STRUCTURAL_ANALYSIS_LOG.md new file mode 100644 index 0000000..75fd358 --- /dev/null +++ b/LifeTrac-v25/mechanical_design/STRUCTURAL_ANALYSIS_LOG.md @@ -0,0 +1,20 @@ +# Structural Analysis Test Log + +This file tracks the history of structural analysis test results. + +--- + +## Latest Analysis + +**Date:** 2025-12-07 07:16:34 UTC +**Commit:** 379a04d9ad945b5817b3ea2a91384fda2ece5e4c +**Branch:** copilot/update-xvfb-installation +**Workflow Run:** https://github.com/OpenSourceEcology/LifeTrac/actions/runs/20000741019 + +### Error + +No structural analysis summary found in output. Check the workflow logs for errors. + +--- + +_This file is automatically updated by the OpenSCAD Structural Analysis workflow._ From eda6ae4ac26068713c9f6264a5d9b13a41bf77fd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 07:28:26 +0000 Subject: [PATCH 10/10] Add animated GIF generation and commit to repository Co-authored-by: dorkmo <1923070+dorkmo@users.noreply.github.com> --- .github/workflows/openscad-render.yml | 47 +++++++++++++++------------ 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/.github/workflows/openscad-render.yml b/.github/workflows/openscad-render.yml index d67d96e..a65d982 100644 --- a/.github/workflows/openscad-render.yml +++ b/.github/workflows/openscad-render.yml @@ -155,19 +155,19 @@ jobs: echo "Animation frames generated" - - name: Create animation GIF (if imagemagick available) - continue-on-error: true + - name: Create animation GIF run: | sudo apt-get install -y imagemagick cd LifeTrac-v25/mechanical_design/output/animations - if command -v convert &> /dev/null; then - echo "Creating animation GIF..." - convert -delay 10 -loop 0 frames/frame_*.png lifetrac_v25_animation.gif - echo "Animation GIF created" - else - echo "ImageMagick not available, skipping GIF creation" - fi + echo "Creating animation GIF of arm movement..." + convert -delay 10 -loop 0 frames/frame_*.png lifetrac_v25_animation.gif + + # Copy to parent directory for easy access + cp lifetrac_v25_animation.gif ../../lifetrac_v25_animation.gif + + echo "✓ Animation GIF created successfully" + ls -lh ../../lifetrac_v25_animation.gif - name: Generate summary report run: | @@ -190,8 +190,8 @@ jobs: - Module examples (5 modules) ### Animations - - 36 animation frames - - Animation GIF (if ImageMagick available) + - 36 animation frames (1280x720 PNG) + - Animated GIF showing arm movement (lifetrac_v25_animation.gif) ### CNC Files - assembly.png (3D render of complete assembly) @@ -200,10 +200,11 @@ jobs: ## Next Steps 1. Review rendered images in the artifacts - 2. Use cnclayout.svg for CNC plasma cutting - 3. Use animation frames to create videos - 4. Export DXF files for individual parts using export_all_cnc_parts.sh - 5. Check the Structural Analysis workflow for design validation results + 2. View lifetrac_v25_animation.gif to see arm movement + 3. Use cnclayout.svg for CNC plasma cutting + 4. Use animation frames to create videos + 5. Export DXF files for individual parts using export_all_cnc_parts.sh + 6. Check the Structural Analysis workflow for design validation results --- Generated by GitHub Actions @@ -225,24 +226,24 @@ jobs: path: LifeTrac-v25/mechanical_design/output/animations/ retention-days: 90 - - name: Commit and push assembly.png and cnclayout.svg + - name: Commit and push rendered outputs run: | cd LifeTrac-v25/mechanical_design git config --global user.name 'github-actions[bot]' git config --global user.email 'github-actions[bot]@users.noreply.github.com' # Add the generated files - git add assembly.png cnclayout.svg + git add assembly.png cnclayout.svg lifetrac_v25_animation.gif # Check if there are changes if ! git diff --staged --quiet; then - git commit -m "Update assembly.png and cnclayout.svg [skip ci]" + git commit -m "Update rendered outputs (assembly, layout, animation) [skip ci]" git push --force-with-lease origin HEAD || { echo "INFO: git push failed. This is expected on PRs from forks." echo "The files are available as workflow artifacts." } else - echo "No changes to assembly.png or cnclayout.svg" + echo "No changes to rendered output files" fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -280,6 +281,7 @@ jobs: ### Generated Outputs - 📸 Preview renders (main, front, side, top views) - 🎬 Animation frames (36 frames) + - 🎞️ Animated GIF of arm movement (lifetrac_v25_animation.gif) - 🔧 Module examples - 🖼️ Assembly image and CNC layout (assembly.png, cnclayout.svg) @@ -288,8 +290,11 @@ jobs: - \`openscad-renders\` - Preview images - \`openscad-animations\` - Animation frames and GIF - ### CNC Files - - \`assembly.png\` and \`cnclayout.svg\` committed to repository + ### Committed Files + The following files have been committed to the repository: + - \`assembly.png\` - 3D assembly render + - \`cnclayout.svg\` - 2D CNC cutting layout + - \`lifetrac_v25_animation.gif\` - Animation showing arm movement _Note: Check the **OpenSCAD Structural Analysis** workflow for design validation and structural analysis results._