Skip to content

Clean up temporary organization scripts #36

Clean up temporary organization scripts

Clean up temporary organization scripts #36

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"