Skip to content

Add clarifying comments about duplicate parts and calculation method #40

Add clarifying comments about duplicate parts and calculation method

Add clarifying comments about duplicate parts and calculation method #40

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 x11-utils
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
# 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
fi
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:
name: structural-analysis
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
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"
break
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}
### 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
**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
});