fix(driving): cruise holds its speed on a grade instead of coasting o… #645
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: CI | |
| permissions: | |
| contents: read | |
| actions: write | |
| on: | |
| push: | |
| # feat/career-1.9 is the long-lived 1.9 release line and gets direct | |
| # pushes instead of PRs, so it needs its own hosted CI trigger. | |
| branches: [main, dev, feat/career-1.9] | |
| pull_request: | |
| branches: [main, dev] | |
| workflow_dispatch: | |
| jobs: | |
| test: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [windows-latest, ubuntu-latest] | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 20 | |
| env: | |
| SDL_VIDEODRIVER: dummy | |
| SDL_AUDIODRIVER: dummy | |
| FREIGHT_FATE_NO_SPEECH: "1" | |
| # sys.monitoring coverage core (Python 3.12+): the default tracer makes | |
| # the CPU-bound network sweeps ~5x slower, and that multiplier grows CI | |
| # time with every map expansion. sysmon measured ~1.15x on the same test. | |
| COVERAGE_CORE: sysmon | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install uv | |
| uses: astral-sh/[email protected] | |
| with: | |
| python-version: "3.12" | |
| - name: Install dependencies | |
| run: uv sync --dev | |
| - name: Lint | |
| run: uv run ruff check src tests tools | |
| - name: Run tests | |
| run: uv run pytest tests/ -n auto --durations=15 --cov=src/freight_fate --cov-report=xml | |
| - name: Upload coverage report | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage-${{ matrix.os }} | |
| path: coverage.xml | |
| changelog: | |
| # The changelog gate runs locally as a pre-push hook, which not every | |
| # clone has installed; this enforces it on every PR and also on direct | |
| # pushes to dev and main, which would otherwise slip past ungated. | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Require a changelog entry for user-facing changes | |
| env: | |
| # PRs diff against their target branch; pushes diff against the | |
| # ref the branch pointed at before this push. | |
| BASE: ${{ github.event_name == 'pull_request' && format('origin/{0}', github.base_ref) || github.event.before }} | |
| run: | | |
| if [ "${{ github.event_name }}" = "push" ] && ! git cat-file -e "$BASE" 2>/dev/null; then | |
| # A brand-new branch pushes an all-zeros "before", and a force | |
| # push can point at history this clone no longer has. | |
| echo "Base commit $BASE unavailable (new branch or force push); skipping." | |
| exit 0 | |
| fi | |
| python3 tools/release_notes.py check --base "$BASE" --head HEAD | |
| build: | |
| runs-on: ubuntu-latest | |
| needs: test | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install uv | |
| uses: astral-sh/[email protected] | |
| with: | |
| python-version: "3.12" | |
| - name: Build wheel and sdist | |
| run: uv build | |
| - name: Upload distributions | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: dist | |
| path: dist/ | |
| recover-nightly: | |
| name: Recover failed nightly | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/dev' | |
| needs: [test, changelog] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Retry today's failed snapshot | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| TAG="nightly-$(date -u +%Y%m%d)" | |
| if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then | |
| echo "$TAG already exists; no recovery build needed." | |
| exit 0 | |
| fi | |
| ACTIVE=$(gh run list --repo "$GITHUB_REPOSITORY" \ | |
| --workflow Build --branch dev --limit 20 \ | |
| --json status --jq '[.[] | select(.status == "queued" or .status == "in_progress")] | length') | |
| if [ "$ACTIVE" -gt 0 ]; then | |
| echo "A dev Build is already queued or running; no duplicate recovery needed." | |
| exit 0 | |
| fi | |
| RUN=$(gh run list --repo "$GITHUB_REPOSITORY" \ | |
| --workflow Build --event schedule --limit 1 \ | |
| --json conclusion,createdAt --jq '.[0] // empty | "\(.conclusion) \(.createdAt)"') | |
| CONCLUSION=${RUN%% *} | |
| CREATED=${RUN#* } | |
| if [ "$CONCLUSION" != "failure" ]; then | |
| echo "Latest scheduled Build conclusion is '$CONCLUSION'; not retrying." | |
| exit 0 | |
| fi | |
| # Only recover TODAY's failed snapshot. Before the daily cron has | |
| # fired, the newest scheduled run is yesterday's -- and a stale | |
| # failure there must not make a pre-cron push build today's | |
| # snapshot hours early. | |
| if [ "${CREATED%%T*}" != "$(date -u +%Y-%m-%d)" ]; then | |
| echo "The failed scheduled Build is from ${CREATED%%T*}; today's snapshot has not run yet." | |
| exit 0 | |
| fi | |
| echo "Today's scheduled snapshot failed and $TAG is missing; dispatching recovery." | |
| gh workflow run Build --repo "$GITHUB_REPOSITORY" --ref dev -f dry_run=false |