solunatus 0.4.0

High-precision astronomical calculation library and CLI for sun/moon positions, rise/set times, and lunar phases
Documentation
name: USNO Validation Drift

on:
  schedule:
    - cron: "15 10 * * 1"
  workflow_dispatch:
    inputs:
      max_caution:
        description: "Maximum allowed caution events (7-10 min)"
        required: false
        default: "2"
      max_fail:
        description: "Maximum allowed fail events (>10 min)"
        required: false
        default: "0"
      max_missing:
        description: "Maximum allowed missing events"
        required: false
        default: "0"

permissions:
  contents: read

env:
  CARGO_TERM_COLOR: always

jobs:
  usno_drift_validation:
    name: USNO Drift Validation
    runs-on: ubuntu-latest
    env:
      MAX_CAUTION: ${{ inputs.max_caution || '2' }}
      MAX_FAIL: ${{ inputs.max_fail || '0' }}
      MAX_MISSING: ${{ inputs.max_missing || '0' }}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7
      - name: Build solunatus
        run: cargo build --release --locked --no-default-features --features usno-validation
      - name: Run USNO validation gates
        shell: bash
        run: |
          set -euo pipefail

          check_case() {
            local city="$1"
            local date="$2"
            local slug="$3"
            local output=""
            local attempts=0

            echo ""
            echo "==> Validating city=${city} date=${date}"
            until [[ ${attempts} -ge 3 ]]; do
              attempts=$((attempts + 1))
              if output="$(
                ./target/release/solunatus --city "${city}" --date "${date}" --validate 2>&1
              )"; then
                break
              fi
              echo "Attempt ${attempts}/3 failed for ${city} ${date}; retrying..." >&2
              if [[ ${attempts} -lt 3 ]]; then
                sleep 5
              fi
            done

            if [[ ${attempts} -ge 3 && -z "${output}" ]]; then
              echo "USNO validation command failed with no output for ${city} ${date}" >&2
              return 1
            fi
            echo "${output}"

            pass="$(awk '/^  Pass:/ {print $2}' <<<"${output}" | tail -1)"
            caution="$(awk '/^  Caution:/ {print $2}' <<<"${output}" | tail -1)"
            fail="$(awk '/^  Fail:/ {print $2}' <<<"${output}" | tail -1)"
            missing="$(awk '/^  Missing:/ {print $2}' <<<"${output}" | tail -1)"

            if [[ -z "${pass}" || -z "${caution}" || -z "${fail}" || -z "${missing}" ]]; then
              echo "Could not parse validation summary for ${city} ${date}" >&2
              return 1
            fi

            echo "Thresholds: caution<=${MAX_CAUTION}, fail<=${MAX_FAIL}, missing<=${MAX_MISSING}"
            if (( caution > MAX_CAUTION || fail > MAX_FAIL || missing > MAX_MISSING )); then
              echo "USNO drift threshold breached for ${city} ${date}" >&2
              return 1
            fi

            report_file="$(awk -F': ' '/Validation report written to:/ {print $2}' <<<"${output}" | tail -1)"
            if [[ -n "${report_file}" && -f "${report_file}" ]]; then
              mkdir -p usno-reports
              mv "${report_file}" "usno-reports/${slug}-${date}.html"
            fi
          }

          if ! drift_cases_raw="$(./scripts/usno_drift_cases.sh)"; then
            echo "Failed to load USNO drift validation cases" >&2
            exit 1
          fi
          if [[ -z "${drift_cases_raw}" ]]; then
            echo "USNO drift validation case list is empty" >&2
            exit 1
          fi

          while IFS= read -r drift_case; do
            IFS='|' read -r city date slug <<<"${drift_case}"
            if [[ -z "${city}" || -z "${date}" || -z "${slug}" ]]; then
              echo "Invalid USNO drift validation case: ${drift_case}" >&2
              exit 1
            fi
            check_case "${city}" "${date}" "${slug}"
          done <<<"${drift_cases_raw}"

          echo ""
          echo "USNO drift validation gates passed."

      - name: Publish report summary
        if: always()
        shell: bash
        run: |
          set -euo pipefail

          {
            echo "## USNO Drift Validation Reports"
            if compgen -G "usno-reports/*.html" > /dev/null; then
              echo ""
              echo "Generated reports:"
              for report in usno-reports/*.html; do
                echo "- ${report}"
              done
            else
              echo ""
              echo "No report files were generated."
            fi
          } >> "${GITHUB_STEP_SUMMARY}"