Lsp owns transpile and rules #354
Workflow file for this run
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: ty ecosystem-analyzer | |
| permissions: {} | |
| on: | |
| pull_request: | |
| paths: | |
| - "crates/ty*/**" | |
| - "!crates/ty_ide/**" | |
| - "!crates/ty_server/**" | |
| - "!crates/ty_test/**" | |
| - "!crates/ty_completion_eval/**" | |
| - "!crates/ty_wasm/**" | |
| - "crates/ruff_db/**" | |
| - "crates/ruff_python_ast/**" | |
| - "crates/ruff_python_parser/**" | |
| - "crates/ruff_python_stdlib/**" | |
| - ".github/workflows/ty-ecosystem-analyzer.yaml" | |
| - ".github/ty-ecosystem.toml" | |
| - "crates/ty_python_semantic/resources/primer/**" | |
| - "Cargo.lock" | |
| - "!**.md" | |
| - "!**.snap" | |
| # It's tempting to skip all Python files in every directory, | |
| # but changes to Python files in `ty_vendored` can affect the output of ecosystem analysis, | |
| # so we apply a narrow exemption for all files in the corpus directory instead. | |
| - "!crates/ty_python_semantic/resources/corpus/**" | |
| concurrency: | |
| group: ty-ecosystem-analyzer-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| defaults: | |
| run: | |
| shell: bash | |
| env: | |
| CARGO_INCREMENTAL: 0 | |
| CARGO_NET_RETRY: 10 | |
| CARGO_TERM_COLOR: always | |
| RUSTUP_MAX_RETRIES: 10 | |
| RUST_BACKTRACE: 1 | |
| # Line-tables-only debug info: faster builds, backtraces still work. | |
| CARGO_PROFILE_PROFILING_DEBUG: line-tables-only | |
| # TODO: Update the mypy-primer revision in scripts/setup_primer_project.py | |
| # and regenerate its lockfile when updating ecosystem-analyzer. | |
| ECOSYSTEM_ANALYZER_COMMIT: 27b644f296d70fccacb7d7c23c91c5d6ccd8713d | |
| jobs: | |
| build-ty: | |
| name: Build ty (${{ matrix.revision }}) | |
| strategy: | |
| matrix: | |
| revision: [base, pr] | |
| runs-on: ${{ github.repository == 'astral-sh/ruff' && 'depot-ubuntu-22.04-32' || 'ubuntu-latest' }} | |
| # max (6h): the fork's slow `ubuntu-latest` runner overruns the depot-tuned budget | |
| timeout-minutes: 360 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| ref: ${{ github.sha }} | |
| - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 | |
| with: | |
| lookup-only: false | |
| - name: Install Rust toolchain | |
| run: rustup show | |
| - name: "Install mold" | |
| uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1 | |
| - name: Build ty | |
| env: | |
| REVISION: ${{ matrix.revision }} | |
| run: | | |
| if [[ "${REVISION}" == "base" ]]; then | |
| # Faster to do this separately than to use `fetch-depth: 0` with `actions/checkout` | |
| git fetch --no-tags --filter=blob:none --unshallow origin | |
| MERGE_BASE="$(git merge-base "${GITHUB_SHA}" "origin/${GITHUB_BASE_REF}")" | |
| echo "${MERGE_BASE}" > merge-base.txt | |
| echo "Merge base: ${MERGE_BASE}" | |
| echo "PR commit: ${GITHUB_SHA}" | |
| git checkout "${MERGE_BASE}" | |
| fi | |
| echo "Building ${REVISION} revision $(git rev-parse HEAD)" | |
| # basedpython's `ty` package builds a binary named `by`, not `ty` | |
| cargo build --package ty --profile profiling | |
| cp target/profiling/by "ty-${REVISION}" | |
| if [[ "${REVISION}" == "pr" ]]; then | |
| cp crates/ty_python_semantic/resources/primer/flaky.txt projects_flaky.txt | |
| cp .github/ty-ecosystem.toml ty-ecosystem.toml | |
| fi | |
| - name: Upload base ty binary | |
| if: matrix.revision == 'base' | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: ty-build-base | |
| compression-level: 1 | |
| path: | | |
| ty-base | |
| merge-base.txt | |
| - name: Upload PR ty binary, flaky project list, and config | |
| if: matrix.revision == 'pr' | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: ty-build-pr | |
| compression-level: 1 | |
| path: | | |
| ty-pr | |
| projects_flaky.txt | |
| ty-ecosystem.toml | |
| analyze-shards: | |
| needs: [build-ty] | |
| strategy: | |
| matrix: | |
| shard: [0, 1, 2, 3] | |
| runs-on: ${{ github.repository == 'astral-sh/ruff' && 'depot-ubuntu-22.04-32' || 'ubuntu-latest' }} | |
| # max (6h): the fork's slow `ubuntu-latest` runner overruns the depot-tuned budget | |
| timeout-minutes: 360 | |
| env: | |
| EXCLUDE_NEWER: ${{ github.event.pull_request.updated_at }} | |
| # TODO(perf): fluid specializations still time out several large projects (cloud-init, | |
| # core, pandas, prefect, tornado) from a residual superlinear re-solve cost that promotion | |
| # did not fully resolve. Disable fluid for ecosystem analysis until that is fixed. This is | |
| # an env var rather than a config option because the shared config is fed to both the base | |
| # and PR binaries, and the base binary hard-errors on the unknown option; an unknown env | |
| # var is harmlessly ignored. The feature stays enabled by default everywhere else. | |
| TY_DISABLE_FLUID_SPECIALIZATIONS: "1" | |
| steps: | |
| - name: Install the latest version of uv | |
| uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 | |
| with: | |
| version: "0.12.3" | |
| ignore-empty-workdir: true | |
| # The default of `enable-cache: auto` leads to warnings from setup-uv in this job, | |
| # since its cache-invalidation keys (pyproject.toml, uv.lock, etc.) aren't available | |
| # here. But the cache doesn't help us much here anyway, since the uv binary, the | |
| # Python binary, and all pre-built wheels are all excluded from setup-uv's cache. | |
| # The cache would only save us from building two Git dependencies which are both | |
| # small, pure-Python projects. | |
| enable-cache: false | |
| - name: Download ty binaries, flaky project list, and config | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: ty-build-* | |
| merge-multiple: true | |
| - name: Analyze shard ${{ matrix.shard }} | |
| env: | |
| SHARD: ${{ matrix.shard }} | |
| run: | | |
| mkdir -p ~/.config/ty | |
| cp ty-ecosystem.toml ~/.config/ty/ty.toml | |
| chmod +x ty-base ty-pr | |
| MERGE_BASE="$(< merge-base.txt)" | |
| echo "MERGE_BASE: ${MERGE_BASE}" | |
| uvx \ | |
| --from "git+https://github.com/astral-sh/ecosystem-analyzer@${ECOSYSTEM_ANALYZER_COMMIT}" \ | |
| ecosystem-analyzer \ | |
| --flaky-runs 10 \ | |
| diff \ | |
| --projects-flaky projects_flaky.txt \ | |
| --ty-binary-old ty-base \ | |
| --ty-binary-new ty-pr \ | |
| --old "${MERGE_BASE}" \ | |
| --new "${GITHUB_SHA}" \ | |
| --exclude-newer "${EXCLUDE_NEWER}" \ | |
| --shard "${SHARD}" \ | |
| --num-shards 4 \ | |
| --output-old "diagnostics-base-${SHARD}.json" \ | |
| --output-new "diagnostics-PR-${SHARD}.json" | |
| - name: Upload diagnostics | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: diagnostics-shard-${{ matrix.shard }} | |
| path: | | |
| diagnostics-base-${{ matrix.shard }}.json | |
| diagnostics-PR-${{ matrix.shard }}.json | |
| generate-report: | |
| name: Generate diagnostic diff report | |
| needs: [analyze-shards] | |
| runs-on: ubuntu-latest | |
| # max (6h): the fork's slow `ubuntu-latest` runner overruns the depot-tuned budget | |
| timeout-minutes: 360 | |
| steps: | |
| - name: Install the latest version of uv | |
| uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 | |
| with: | |
| version: "0.12.3" | |
| ignore-empty-workdir: true | |
| # The default of `enable-cache: auto` leads to warnings from setup-uv in this job, | |
| # since its cache-invalidation keys (pyproject.toml, uv.lock, etc.) aren't available | |
| # here. But the cache doesn't help us much here anyway, since the uv binary, the | |
| # Python binary, and all pre-built wheels are all excluded from setup-uv's cache. | |
| # The cache would only save us from building two Git dependencies which are both | |
| # small, pure-Python projects. | |
| enable-cache: false | |
| - name: Download shard diagnostics | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: diagnostics-shard-* | |
| merge-multiple: true | |
| - name: Generate reports | |
| id: generate-reports | |
| env: | |
| REF_NAME: ${{ github.ref_name }} | |
| run: | | |
| # Merge shard diagnostics | |
| jq -s '{ outputs: [.[].outputs[]] }' diagnostics-base-*.json > diagnostics-base.json | |
| jq -s '{ outputs: [.[].outputs[]] }' diagnostics-PR-*.json > diagnostics-PR.json | |
| uv tool install "git+https://github.com/astral-sh/ecosystem-analyzer@$ECOSYSTEM_ANALYZER_COMMIT" | |
| mkdir dist | |
| ecosystem-analyzer \ | |
| generate-diff \ | |
| diagnostics-base.json \ | |
| diagnostics-PR.json \ | |
| --old-name "main (merge base)" \ | |
| --new-name "$REF_NAME" \ | |
| --output-html dist/diff.html | |
| set +e | |
| ecosystem-analyzer \ | |
| generate-diff-statistics \ | |
| diagnostics-base.json \ | |
| diagnostics-PR.json \ | |
| --fail-on-new-abnormal-exits \ | |
| --old-name "main (merge base)" \ | |
| --new-name "$REF_NAME" \ | |
| --output diff-statistics.md | |
| DIFF_STATISTICS_EXIT_CODE=$? | |
| set -e | |
| ecosystem-analyzer \ | |
| generate-timing-diff \ | |
| diagnostics-base.json \ | |
| diagnostics-PR.json \ | |
| --old-name "main (merge base)" \ | |
| --new-name "$REF_NAME" \ | |
| --output-html dist/timing.html | |
| cat diff-statistics.md >> comment.md | |
| # Lead the job summary with a clear regression headline when a project newly | |
| # fails, so a timeout/crash isn't buried under the (informational) diagnostic | |
| # -count tables that always change on this fork. | |
| if [ "$DIFF_STATISTICS_EXIT_CODE" != "0" ]; then | |
| { | |
| echo "## ❌ New ecosystem project failures" | |
| echo | |
| echo "One or more projects newly **crash or time out** on this PR — a correctness or" | |
| echo "performance regression, distinct from the informational diagnostic-count changes below." | |
| echo | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| cat diff-statistics.md >> "$GITHUB_STEP_SUMMARY" | |
| echo "diff_statistics_exit_code=$DIFF_STATISTICS_EXIT_CODE" >> "$GITHUB_OUTPUT" | |
| # NOTE: astral-bot deploys both HTML files in this artifact and uses the | |
| # deployed URLs for the report links in its PR comment. | |
| # Make sure to update the bot if you rename the artifact. | |
| - name: "Upload full report" | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: full-report | |
| path: dist/ | |
| # NOTE: astral-sh-bot uses this artifact to post comments on PRs. | |
| # Make sure to update the bot if you rename the artifact. | |
| - name: Upload comment | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: comment.md | |
| path: comment.md | |
| - name: Fail on new abnormal exits | |
| if: steps.generate-reports.outputs.diff_statistics_exit_code != '0' | |
| run: | | |
| # Surface exactly which projects newly failed (and how) as check annotations, | |
| # so the regression is visible inline on the PR without opening the report | |
| # artifact. Rows in `diff-statistics.md` look like: | |
| # | `xarray` | ❌ newly failing | success | timeout | `exit 1` | `timeout` | | |
| new_failures="$(awk -F'|' '/newly failing/ { | |
| proj = $2; gsub(/[` ]/, "", proj) | |
| old = $4; gsub(/^ +| +$/, "", old) | |
| new = $5; gsub(/^ +| +$/, "", new) | |
| print proj "\t" old "\t" new | |
| }' diff-statistics.md)" | |
| if [ -n "$new_failures" ]; then | |
| while IFS=$'\t' read -r proj old new; do | |
| [ -z "$proj" ] && continue | |
| echo "::error title=Ecosystem regression (${proj})::\`${proj}\` newly failing: ${old} -> ${new}" | |
| done <<< "$new_failures" | |
| else | |
| echo "::error title=Ecosystem regression::New abnormal exits detected; see the diagnostic diff report." | |
| fi | |
| exit 1 |