Skip to content

fix(op): contain raw-file output paths inside the package directory (… #2977

fix(op): contain raw-file output paths inside the package directory (…

fix(op): contain raw-file output paths inside the package directory (… #2977

Workflow file for this run

name: CI
# ALWAYS-TRIGGERED, path-scoped INSIDE the workflow: the `changes` job gates
# the expensive jobs on non-docs changes, and the `if: always()` aggregator
# (ci-success) reports success even when they were path-skipped. This replaces
# the old paths-ignore + ci-docs-skip.yml inverse-path pair: a required
# context that a trigger-level path filter skips stays "Expected" forever and
# wedges the PR, while a skipped in-workflow job reports `skipped`, which the
# aggregator treats as pass. Do NOT add trigger-level `paths:` here.
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
# Cancel an in-progress run when a newer commit is pushed to the same ref.
# main is excluded so a push to main never gets cancelled mid-flight.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
permissions:
contents: read
# dorny/paths-filter reads the PR file list on pull_request events.
pull-requests: read
jobs:
changes:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Detect non-docs changes
id: filter
# v3.0.2, SHA-pinned. Runs ONLY on pull_request, where dorny
# reads the PR file list via the API (a push would need a local
# diff our shallow, credential-free checkout cannot provide) —
# and pushes to main / dispatches run everything regardless.
# `code` = anything that is not documentation; the negations
# mirror the old paths-ignore list.
if: github.event_name == 'pull_request'
uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706
with:
filters: |
code:
- "**"
- ".github/**"
- "!*.md"
- "!**/*.md"
- "!docs/**"
- "!LICENSE"
fmt:
needs: [changes]
if: github.event_name != 'pull_request' || needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Run rustfmt
run: cargo fmt --all -- --check
clippy:
needs: [changes]
if: github.event_name != 'pull_request' || needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- uses: ./.github/actions/setup-rust
with:
# check artifacts, not build artifacts — own cache class
shared-key: clippy
- name: Run Clippy
run: cargo clippy --workspace --all-targets --locked -- -D warnings
# NOTE: the workspace test job was removed once ci-linux-native.yml's
# required `tests` job (the same `core-tests` composite) covered it — the two
# ran the identical suite. The mTLS reverse-proxy step it also carried
# (`--features networking-proxy`) was mothballed from per-PR CI by owner
# decision; that coverage now runs in release.yml. See the note in the
# ci-linux-native `tests` job.
dogfood:
needs: [changes]
if: github.event_name != 'pull_request' || needs.changes.outputs.code == 'true'
# `actions: read` is for the cache-save verification step below; the
# job-level block replaces the workflow-level grant, so `contents` has
# to be restated for actions/checkout.
permissions:
contents: read
actions: read
runs-on: ubuntu-latest
# 30, not 20: a cold build (no usable cache entry) is ~13 min of cargo
# on top of ~1 min of disk reclaim and up to ~4 min of cache restore,
# which left a slow runner no margin. Run #30482500938 was cancelled
# mid-`Compiling mip` at exactly 20:00 and took `ci-success` red with
# it -- the aggregator counts `cancelled` as failure.
timeout-minutes: 30
steps:
- name: Free Disk Space
uses: endersonmenezes/free-disk-space@7901478139cff6e9d44df5972fd8ab8fcade4db1 # v3
with:
remove_android: true
remove_dotnet: true
remove_haskell: true
# The tool cache (~8 GB) and the cloud CLIs go too, to keep
# the save step below off the ENOSPC wall. Nothing in this job
# reads either: the two JS actions run on the runner's bundled
# node, `run-task` is a shell composite, and the build itself
# fetches over plain HTTPS. `remove_packages` takes a
# space-separated list, NOT a boolean -- the action's `main.sh`
# validates for an embedded space and `exit 0`s on `true`,
# which would silently skip every reclaim above as well.
remove_tool_cache: true
remove_packages: azure-cli google-cloud-cli
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Cache Cargo state
# Restore-only; the save half (main only) runs at the end of the
# job, matching the KVM lane's cache policy.
id: cargo-cache
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ~/.local/state/minimal/state
key: dogfood-minimal-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: dogfood-minimal-cargo-
- name: Smoketest building Minimal
# R2 read-path canary (build-servers#145): point the package-cache
# READER at the Cloudflare R2 mirror to prove GCS egress collapses
# with cache hit-rate parity. Only this step reads the package
# cache; `run-task` fetches the CLI itself from the separate GCS
# shim bucket, which is unaffected. The mutable `index.shisha` is
# bypassed to GCS at the edge (infra#277), so it stays fresh.
# Trailing slash is required (`Url::join`). Rollback = delete
# this `env` block.
uses: gominimal/run-task@a5ed123f612b9774e3d6eaa7af45370e33aa1116 # v1
env:
MINIMAL_REMOTE_CACHE_URL: https://cache.minimal.farm/
with:
channel: unstable
task: build-smoke
- name: Save Cargo state cache (main only)
# PR branches restore but never write: caches written by every
# branch LRU-evict the main entries all PRs restore from.
if: github.ref == 'refs/heads/main' && steps.cargo-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ~/.local/state/minimal/state
key: ${{ steps.cargo-cache.outputs.cache-primary-key }}
- name: Verify the cache actually saved (main only)
# A save that runs out of disk is downgraded to `##[warning]Failed
# to save` and leaves the job green, so the entry can freeze for
# days while every run silently pays a cold build. Turn that into
# a red main. Rationale and the incident in the script header.
if: github.ref == 'refs/heads/main' && steps.cargo-cache.outputs.cache-hit != 'true'
env:
GH_TOKEN: ${{ github.token }}
CACHE_KEY: ${{ steps.cargo-cache.outputs.cache-primary-key }}
run: scripts/ci-verify-cache-saved.sh "$CACHE_KEY"
cargo-deny:
needs: [changes]
if: github.event_name != 'pull_request' || needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2
minimal-check:
needs: [changes]
if: github.event_name != 'pull_request' || needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- uses: gominimal/check@1a5fa19a2a93d25417d191d9b3e75de39c3eaf25 # v1
with:
channel: unstable
# Single required status check for branch protection. Green when every
# gating job succeeded OR was path-skipped (docs-only changes); red only
# on failure/cancellation.
ci-success:
if: always()
needs: [changes, fmt, clippy, dogfood, cargo-deny, minimal-check]
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Verify all gating jobs succeeded or were skipped
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1
- run: echo "All CI gates passed"