Clean up temporary organization scripts #36
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish Traceability Badge | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: [ main, master ] | |
| paths: | |
| - 'docs/roadmap.ndjson' | |
| - 'tests/**' | |
| - 'traceability_check.py' | |
| - '.github/workflows/traceability.yml' | |
| - '.github/workflows/traceability-badge.yml' | |
| workflow_run: | |
| workflows: [ "Traceability Coverage" ] | |
| types: [ completed ] | |
| permissions: | |
| actions: read | |
| contents: write | |
| pages: write | |
| id-token: write | |
| concurrency: | |
| group: 'pages-traceability-badge' | |
| cancel-in-progress: true | |
| jobs: | |
| validate: | |
| uses: ./.github/workflows/mission-validate.yml | |
| badge: | |
| needs: validate | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Compute traceability coverage JSON | |
| run: | | |
| sudo apt-get update -y | |
| sudo apt-get install -y jq unzip | |
| python -m pip install -U pip | |
| # Run checker; do not fail build if roadmap/tests are absent | |
| python traceability_check.py --json-out traceability_coverage.json || true | |
| echo "Traceability JSON (if any):" | |
| test -f traceability_coverage.json && cat traceability_coverage.json || echo '{}' > traceability_coverage.json | |
| - name: Log environment and disk | |
| run: | | |
| echo "Traceability build timestamp: 2025-08-14 19:13 PDT" | |
| uname -a | |
| python --version | |
| df -h | |
| - name: Generate Shields.io badge JSON | |
| run: | | |
| python - << 'PY' | |
| import json, os | |
| # Default badge | |
| badge = { | |
| "schemaVersion": 1, | |
| "label": "Traceability", | |
| "message": "n/a", | |
| "color": "lightgrey" | |
| } | |
| try: | |
| with open('traceability_coverage.json', 'r') as f: | |
| data = json.load(f) | |
| pct = float(data.get('coverage_percent', 0.0)) | |
| badge['message'] = f"{pct:.1f}%" | |
| # Simple color scale | |
| if pct >= 90: | |
| badge['color'] = 'brightgreen' | |
| elif pct >= 75: | |
| badge['color'] = 'green' | |
| elif pct >= 60: | |
| badge['color'] = 'yellowgreen' | |
| elif pct >= 40: | |
| badge['color'] = 'orange' | |
| else: | |
| badge['color'] = 'red' | |
| except Exception as e: | |
| # Keep defaults on error | |
| badge['message'] = 'n/a' | |
| badge['color'] = 'lightgrey' | |
| os.makedirs('public', exist_ok=True) | |
| with open('public/traceability_badge.json', 'w') as f: | |
| json.dump(badge, f) | |
| print('Badge JSON:') | |
| print(json.dumps(badge, indent=2)) | |
| PY | |
| - name: Ensure .nojekyll | |
| run: | | |
| echo "Ensuring .nojekyll: 2025-08-14 19:53 PDT" | |
| mkdir -p public | |
| touch public/.nojekyll | |
| - name: Log workflow dependencies | |
| run: | | |
| echo "Checking dependencies: 2025-08-14 20:10 PDT" | |
| gh run list --repo ${{ github.repository }} --workflow mission-validate.yml --limit 1 || echo "gh not available" | |
| - name: Wait for mission-validate | |
| run: | | |
| echo "Waiting for mission-validate: 2025-08-14 20:38 PDT" | |
| sleep 60 | |
| - name: Fetch latest 40 Eridani artifacts | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| echo "Fetching 40 Eridani artifacts: 2025-08-14 20:38 PDT" | |
| for attempt in 1 2 3 4 5 6; do | |
| curl -s -H "Authorization: Bearer ${GITHUB_TOKEN}" -H "Accept: application/vnd.github+json" \ | |
| https://api.github.com/repos/${{ github.repository }}/actions/artifacts > artifacts.json && break | |
| echo "List retry $attempt failed; waiting 20s" | |
| sleep 20 | |
| done | |
| ARTIFACT_ID=$(jq -r '.artifacts | map(select(.name == "40eridani-artifacts" and .expired == false)) | sort_by(.created_at) | last | .id' artifacts.json) | |
| if [ -z "$ARTIFACT_ID" ] || [ "$ARTIFACT_ID" = "null" ]; then | |
| echo "Error: No valid 40eridani-artifacts. Available:" | |
| jq -r '.artifacts[] | .name + " (created: " + .created_at + ", expired: " + (.expired | tostring) + ")"' artifacts.json | |
| exit 1 | |
| fi | |
| for attempt in 1 2 3 4 5 6; do | |
| curl -L -sSf -H "Authorization: Bearer ${GITHUB_TOKEN}" -H "Accept: application/vnd.github+json" \ | |
| https://api.github.com/repos/${{ github.repository }}/actions/artifacts/${ARTIFACT_ID}/zip -o 40eridani-artifacts.zip && break | |
| echo "Download retry $attempt failed; waiting 20s" | |
| sleep 20 | |
| done | |
| mkdir -p artifacts | |
| unzip -o 40eridani-artifacts.zip -d artifacts || { echo "Unzip failed"; ls -R artifacts || true; exit 1; } | |
| echo "Artifact contents: $(ls -R artifacts)" | |
| mkdir -p public | |
| cp artifacts/40eridani_*.png public/ || { echo "No PNGs found"; ls -R artifacts; exit 1; } | |
| # Also copy tiny UQ PNG explicitly | |
| if [ -f artifacts/40eridani_uq_tiny.png ]; then cp -v artifacts/40eridani_uq_tiny.png public/; fi | |
| echo "Copied PNGs: $(ls public/40eridani_*.png)" | |
| - name: Verify Pages artifacts | |
| run: | | |
| echo "Verifying Pages artifacts: 2025-08-14 20:38 PDT" | |
| ls public/40eridani_*.png || { echo "Missing 40eridani plots in public/"; exit 1; } | |
| echo "Found plots: $(ls public/40eridani_*.png)" | |
| du -sh public || true | |
| - name: Publish UQ dashboard assets | |
| run: | | |
| python -m pip install -U pip | |
| python bin/publish_uq_dashboard.py --artifacts artifacts --public public | |
| - name: Create index.html | |
| run: | | |
| echo "Creating index.html: 2025-08-14 21:41 PDT" | |
| cat > public/index.html << 'EOF' | |
| <!DOCTYPE html> | |
| <html> | |
| <head><title>Warp Bubble Plots</title></head> | |
| <body> | |
| <h1>40 Eridani A Simulation Plots</h1> | |
| <p>Note: Plots may be unavailable during CI updates. Check after 2025-08-14 22:32 PDT or download from <a href="https://zenodo.org/record/<your-doi>">Zenodo</a>.</p> | |
| <ul> | |
| <li><a href="40eridani_energy.png">Standard Energy Distribution</a></li> | |
| <li><a href="40eridani_feasibility.png">Standard Feasibility</a></li> | |
| <li><a href="40eridani_energy_extended.png">Extended Energy Distribution</a></li> | |
| <li><a href="40eridani_feasibility_extended.png">Extended Feasibility</a></li> | |
| <li><a href="40eridani_energy_varied.png">Varied Profile Energy</a></li> | |
| <li><a href="40eridani_feasibility_varied.png">Varied Profile Feasibility</a></li> | |
| <li><a href="40eridani_uq_tiny.png">Tiny UQ PNG (deterministic)</a></li> | |
| <li><a href="traceability_badge.json">Traceability Badge JSON</a></li> | |
| </ul> | |
| <h2>Compact UQ Dashboard</h2> | |
| <p>Key artifacts from the latest CI run:</p> | |
| <ul> | |
| <li><a href="feasibility_gates_report.json">Feasibility Gates Report</a></li> | |
| <li><a href="perf_summary.png">Perf Summary</a></li> | |
| <li><a href="perf_smoke.png">Perf Smoke (notebook)</a></li> | |
| </ul> | |
| </body> | |
| </html> | |
| EOF | |
| - name: Validate Pages PNGs | |
| run: | | |
| echo "Validating Pages PNGs: 2025-08-14 21:41 PDT" | |
| sudo apt-get update && sudo apt-get install -y imagemagick | |
| for file in public/40eridani_*.png; do | |
| file "$file" | grep -q "PNG image data" || { echo "$file not valid"; exit 1; } | |
| identify "$file" || { echo "$file corrupt"; exit 1; } | |
| done | |
| - name: Validate index.html links | |
| run: | | |
| echo "Validating index.html: 2025-08-14 20:38 PDT" | |
| grep -q "40eridani_energy.png" public/index.html || { echo "Missing energy.png link"; exit 1; } | |
| grep -q "traceability_badge.json" public/index.html || { echo "Missing badge JSON link"; exit 1; } | |
| grep -q "40eridani_uq_tiny.png" public/index.html || { echo "Missing tiny UQ PNG link"; exit 1; } | |
| - name: Wait for Pages refresh | |
| run: | | |
| echo "Waiting for Pages refresh: 2025-08-14 21:41 PDT" | |
| sleep 900 | |
| - name: Upload artifact for GitHub Pages | |
| uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: ./public | |
| deploy: | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| runs-on: ubuntu-latest | |
| needs: badge | |
| steps: | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v4 | |
| - name: Log Pages deployment | |
| run: | | |
| echo "Deployed to Pages: 2025-08-14 21:41 PDT" | |
| for url in 40eridani_energy.png 40eridani_feasibility.png 40eridani_uq_tiny.png index.html; do | |
| status=$(curl -s -I https://arcticoder.github.io/warp-bubble-optimizer/$url | head -n 1) | |
| echo "$url: $status" | |
| echo "$status" | grep -q "200 OK" || { echo "Error: $url failed"; exit 1; } | |
| done | |
| - name: Clear Pages cache | |
| run: | | |
| echo "Clearing Pages cache: 2025-08-14 20:38 PDT" | |
| curl -X POST -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ | |
| https://api.github.com/repos/${{ github.repository }}/pages/builds || true | |
| - name: Check Pages branch | |
| run: | | |
| echo "Checking Pages branch: 2025-08-14 20:38 PDT" | |
| curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ | |
| https://api.github.com/repos/${{ github.repository }}/pages | jq -r .source.branch || true | |
| - name: Notify Pages success | |
| run: | | |
| echo "Pages deployed successfully: 2025-08-14 20:38 PDT" | |
| echo "Check: https://arcticoder.github.io/warp-bubble-optimizer/index.html" |