about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/.github
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/.github')
-rw-r--r--src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/bug_report.md33
-rw-r--r--src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/critical_nightly_regression.md16
-rw-r--r--src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/feature_request.md8
-rw-r--r--src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/question.md8
-rw-r--r--src/tools/rust-analyzer/.github/actions/github-release/Dockerfile8
-rw-r--r--src/tools/rust-analyzer/.github/actions/github-release/README.md21
-rw-r--r--src/tools/rust-analyzer/.github/actions/github-release/action.yml15
-rw-r--r--src/tools/rust-analyzer/.github/actions/github-release/main.js144
-rw-r--r--src/tools/rust-analyzer/.github/actions/github-release/package.json10
-rw-r--r--src/tools/rust-analyzer/.github/rust.json33
-rw-r--r--src/tools/rust-analyzer/.github/workflows/autopublish.yaml60
-rw-r--r--src/tools/rust-analyzer/.github/workflows/ci.yaml256
-rw-r--r--src/tools/rust-analyzer/.github/workflows/fuzz.yml43
-rw-r--r--src/tools/rust-analyzer/.github/workflows/metrics.yaml153
-rw-r--r--src/tools/rust-analyzer/.github/workflows/publish-libs.yaml36
-rw-r--r--src/tools/rust-analyzer/.github/workflows/release.yaml280
-rw-r--r--src/tools/rust-analyzer/.github/workflows/rustdoc.yaml34
17 files changed, 1158 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/bug_report.md b/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000000..97c1b64494d
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,33 @@
+---
+name: Bug report
+about: Create a bug report for rust-analyzer.
+title: ''
+labels: 'C-bug'
+assignees: ''
+
+---
+
+<!--
+Troubleshooting guide: https://rust-analyzer.github.io/manual.html#troubleshooting
+Forum for questions: https://users.rust-lang.org/c/ide/14
+
+Before submitting, please make sure that you're not running into one of these known issues:
+
+ 1. on-the-fly diagnostics are mostly unimplemented (`cargo check` diagnostics will be shown when saving a file): #3107
+
+Otherwise please try to provide information which will help us to fix the issue faster. Minimal reproducible examples with few dependencies are especially lovely <3.
+-->
+
+**rust-analyzer version**: (eg. output of "rust-analyzer: Show RA Version" command, accessible in VSCode via <kbd>Ctrl/⌘</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>)
+
+**rustc version**: (eg. output of `rustc -V`)
+
+**relevant settings**: (eg. client settings, or environment variables like `CARGO`, `RUSTC`, `RUSTUP_HOME` or `CARGO_HOME`)
+
+**repository link (if public, optional)**: (eg. [rust-analyzer](https://github.com/rust-lang/rust-analyzer))
+
+**code snippet to reproduce**: 
+```rust
+// add your code here
+
+```
diff --git a/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/critical_nightly_regression.md b/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/critical_nightly_regression.md
new file mode 100644
index 00000000000..ad220ff65ca
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/critical_nightly_regression.md
@@ -0,0 +1,16 @@
+---
+name: Critical Nightly Regression
+about: You are using nightly rust-analyzer and the latest version is unusable.
+title: ''
+labels: 'Broken Window'
+assignees: ''
+
+---
+
+<!--
+Troubleshooting guide: https://rust-analyzer.github.io/manual.html#troubleshooting
+
+Please try to provide information which will help us to fix the issue faster. Minimal reproducible examples with few dependencies are especially lovely <3.
+-->
+
+This is a serious regression in nightly and it's important to fix it before the next release.
diff --git a/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/feature_request.md b/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 00000000000..5207957c459
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,8 @@
+---
+name: Feature Request
+about: Create a feature request for rust-analyzer.
+title: ''
+labels: 'C-feature'
+assignees: ''
+
+---
diff --git a/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/question.md b/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 00000000000..a90ade882bd
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,8 @@
+---
+name: Support Question
+about: A question regarding functionality of rust-analyzer.
+title: ''
+labels: 'C-support'
+assignees: ''
+
+---
diff --git a/src/tools/rust-analyzer/.github/actions/github-release/Dockerfile b/src/tools/rust-analyzer/.github/actions/github-release/Dockerfile
new file mode 100644
index 00000000000..5849eac7d24
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/actions/github-release/Dockerfile
@@ -0,0 +1,8 @@
+FROM node:slim
+
+COPY . /action
+WORKDIR /action
+
+RUN npm install --production
+
+ENTRYPOINT ["node", "/action/main.js"]
diff --git a/src/tools/rust-analyzer/.github/actions/github-release/README.md b/src/tools/rust-analyzer/.github/actions/github-release/README.md
new file mode 100644
index 00000000000..c8ff3ec6e52
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/actions/github-release/README.md
@@ -0,0 +1,21 @@
+# github-release
+
+Copy-pasted from
+https://github.com/bytecodealliance/wasmtime/tree/8acfdbdd8aa550d1b84e0ce1e6222a6605d14e38/.github/actions/github-release
+
+An action used to publish GitHub releases for `wasmtime`.
+
+As of the time of this writing there's a few actions floating around which
+perform github releases but they all tend to have their set of drawbacks.
+Additionally nothing handles deleting releases which we need for our rolling
+`dev` release.
+
+To handle all this, this action rolls its own implementation using the
+actions/toolkit repository and packages published there. These run in a Docker
+container and take various inputs to orchestrate the release from the build.
+
+More comments can be found in `main.js`.
+
+Testing this is really hard. If you want to try though run `npm install` and
+then `node main.js`. You'll have to configure a bunch of env vars though to get
+anything reasonably working.
diff --git a/src/tools/rust-analyzer/.github/actions/github-release/action.yml b/src/tools/rust-analyzer/.github/actions/github-release/action.yml
new file mode 100644
index 00000000000..51a074adfaa
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/actions/github-release/action.yml
@@ -0,0 +1,15 @@
+name: 'wasmtime github releases'
+description: 'wasmtime github releases'
+inputs:
+  token:
+    description: ''
+    required: true
+  name:
+    description: ''
+    required: true
+  files:
+    description: ''
+    required: true
+runs:
+  using: 'docker'
+  image: 'Dockerfile'
diff --git a/src/tools/rust-analyzer/.github/actions/github-release/main.js b/src/tools/rust-analyzer/.github/actions/github-release/main.js
new file mode 100644
index 00000000000..e8dba398733
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/actions/github-release/main.js
@@ -0,0 +1,144 @@
+const core = require('@actions/core');
+const path = require("path");
+const fs = require("fs");
+const github = require('@actions/github');
+const glob = require('glob');
+
+function sleep(milliseconds) {
+  return new Promise(resolve => setTimeout(resolve, milliseconds));
+}
+
+async function runOnce() {
+  // Load all our inputs and env vars. Note that `getInput` reads from `INPUT_*`
+  const files = core.getInput('files');
+  const name = core.getInput('name');
+  const token = core.getInput('token');
+  const slug = process.env.GITHUB_REPOSITORY;
+  const owner = slug.split('/')[0];
+  const repo = slug.split('/')[1];
+  const sha = process.env.HEAD_SHA;
+
+  core.info(`files: ${files}`);
+  core.info(`name: ${name}`);
+
+  const options = {
+    request: {
+      timeout: 30000,
+    }
+  };
+  const octokit = github.getOctokit(token, options);
+
+  // Delete the previous release since we can't overwrite one. This may happen
+  // due to retrying an upload or it may happen because we're doing the dev
+  // release.
+  const releases = await octokit.paginate("GET /repos/:owner/:repo/releases", { owner, repo });
+  for (const release of releases) {
+    if (release.tag_name !== name) {
+      continue;
+    }
+    const release_id = release.id;
+    core.info(`deleting release ${release_id}`);
+    await octokit.rest.repos.deleteRelease({ owner, repo, release_id });
+  }
+
+  // We also need to update the `dev` tag while we're at it on the `dev` branch.
+  if (name == 'nightly') {
+    try {
+      core.info(`updating nightly tag`);
+      await octokit.rest.git.updateRef({
+        owner,
+        repo,
+        ref: 'tags/nightly',
+        sha,
+        force: true,
+      });
+    } catch (e) {
+      core.error(e);
+      core.info(`creating nightly tag`);
+      await octokit.rest.git.createTag({
+        owner,
+        repo,
+        tag: 'nightly',
+        message: 'nightly release',
+        object: sha,
+        type: 'commit',
+      });
+    }
+  }
+
+  // Creates an official GitHub release for this `tag`, and if this is `dev`
+  // then we know that from the previous block this should be a fresh release.
+  core.info(`creating a release`);
+  const release = await octokit.rest.repos.createRelease({
+    owner,
+    repo,
+    name,
+    tag_name: name,
+    target_commitish: sha,
+    prerelease: name === 'nightly',
+  });
+  const release_id = release.data.id;
+
+  // Upload all the relevant assets for this release as just general blobs.
+  for (const file of glob.sync(files)) {
+    const size = fs.statSync(file).size;
+    const name = path.basename(file);
+
+    await runWithRetry(async function () {
+      // We can't overwrite assets, so remove existing ones from a previous try.
+      let assets = await octokit.rest.repos.listReleaseAssets({
+        owner,
+        repo,
+        release_id
+      });
+      for (const asset of assets.data) {
+        if (asset.name === name) {
+          core.info(`delete asset ${name}`);
+          const asset_id = asset.id;
+          await octokit.rest.repos.deleteReleaseAsset({ owner, repo, asset_id });
+        }
+      }
+
+      core.info(`upload ${file}`);
+      const headers = { 'content-length': size, 'content-type': 'application/octet-stream' };
+      const data = fs.createReadStream(file);
+      await octokit.rest.repos.uploadReleaseAsset({
+        data,
+        headers,
+        name,
+        url: release.data.upload_url,
+      });
+    });
+  }
+}
+
+async function runWithRetry(f) {
+  const retries = 10;
+  const maxDelay = 4000;
+  let delay = 1000;
+
+  for (let i = 0; i < retries; i++) {
+    try {
+      await f();
+      break;
+    } catch (e) {
+      if (i === retries - 1)
+        throw e;
+
+      core.error(e);
+      const currentDelay = Math.round(Math.random() * delay);
+      core.info(`sleeping ${currentDelay} ms`);
+      await sleep(currentDelay);
+      delay = Math.min(delay * 2, maxDelay);
+    }
+  }
+}
+
+async function run() {
+  await runWithRetry(runOnce);
+}
+
+run().catch(err => {
+  core.error(err);
+  core.setFailed(err.message);
+});
diff --git a/src/tools/rust-analyzer/.github/actions/github-release/package.json b/src/tools/rust-analyzer/.github/actions/github-release/package.json
new file mode 100644
index 00000000000..af4bf074d2d
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/actions/github-release/package.json
@@ -0,0 +1,10 @@
+{
+  "name": "wasmtime-github-release",
+  "version": "0.0.0",
+  "main": "main.js",
+  "dependencies": {
+    "@actions/core": "^1.6",
+    "@actions/github": "^5.0",
+    "glob": "^7.1.5"
+  }
+}
diff --git a/src/tools/rust-analyzer/.github/rust.json b/src/tools/rust-analyzer/.github/rust.json
new file mode 100644
index 00000000000..ddaa1b0824b
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/rust.json
@@ -0,0 +1,33 @@
+{
+    "problemMatcher": [
+        {
+            "owner": "rustfmt",
+            "severity": "warning",
+            "pattern": [
+                {
+                    "regexp": "^(Diff in (.+)) at line (\\d+):$",
+                    "message": 1,
+                    "file": 2,
+                    "line": 3
+                }
+            ]
+        },
+        {
+            "owner": "clippy",
+            "pattern": [
+                {
+                    "regexp": "^(?:\\x1b\\[[\\d;]+m)*(warning|warn|error)(?:\\x1b\\[[\\d;]+m)*(\\[(.*)\\])?(?:\\x1b\\[[\\d;]+m)*:(?:\\x1b\\[[\\d;]+m)* ([^\\x1b]*)(?:\\x1b\\[[\\d;]+m)*$",
+                    "severity": 1,
+                    "message": 4,
+                    "code": 3
+                },
+                {
+                    "regexp": "^(?:\\x1b\\[[\\d;]+m)*\\s*(?:\\x1b\\[[\\d;]+m)*\\s*--> (?:\\x1b\\[[\\d;]+m)*(.*):(\\d*):(\\d*)(?:\\x1b\\[[\\d;]+m)*$",
+                    "file": 1,
+                    "line": 2,
+                    "column": 3
+                }
+            ]
+        }
+    ]
+}
diff --git a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
new file mode 100644
index 00000000000..4b97637088c
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
@@ -0,0 +1,60 @@
+name: autopublish
+on:
+  workflow_dispatch: # We can add version input when 1.0 is released and scheduled releases are removed
+
+  #   schedule:
+  #     - cron: "0 0 * * *" # midnight UTC
+
+  push:
+    branches:
+      - release
+
+jobs:
+  publish:
+    name: publish
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+
+      # https://github.com/jlumbroso/free-disk-space/blob/main/action.yml
+      - name: Free up some disk space
+        run: sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc /usr/local/.ghcup
+
+      - name: Install Rust toolchain
+        run: rustup update --no-self-update stable
+
+      - name: Install cargo-workspaces
+        run: cargo install cargo-workspaces
+
+      - name: Publish Crates
+        env:
+          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
+          RUN_NUMBER: ${{ github.run_number }}
+        shell: bash
+        run: |
+          git config --global user.email "runner@gha.local"
+          git config --global user.name "GitHub Action"
+          rm Cargo.lock
+          # Fix names for crates that were published before switch to kebab-case.
+          cargo workspaces rename --from base-db base_db
+          cargo workspaces rename --from hir-def hir_def
+          cargo workspaces rename --from hir-expand hir_expand
+          cargo workspaces rename --from hir-ty hir_ty
+          cargo workspaces rename --from ide-assists ide_assists
+          cargo workspaces rename --from ide-completion ide_completion
+          cargo workspaces rename --from ide-db ide_db
+          cargo workspaces rename --from ide-diagnostics ide_diagnostics
+          cargo workspaces rename --from ide-ssr ide_ssr
+          cargo workspaces rename --from proc-macro-api proc_macro_api
+          cargo workspaces rename --from proc-macro-srv proc_macro_srv
+          cargo workspaces rename --from project-model project_model
+          cargo workspaces rename --from test-utils test_utils
+          cargo workspaces rename --from text-edit text_edit
+          # Remove library crates from the workspaces so we don't auto-publish them as well
+          sed -i 's/ "lib\/\*",//' ./Cargo.toml
+          cargo workspaces rename ra_ap_%n
+          find crates/rust-analyzer -type f -name '*.rs' -exec sed -i 's/rust_analyzer/ra_ap_rust_analyzer/g' {} +
+          cargo workspaces publish --yes --force '*' --exact --no-git-commit --allow-dirty --skip-published custom 0.0.$(($RUN_NUMBER + 133))
diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml
new file mode 100644
index 00000000000..08ad10c2971
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml
@@ -0,0 +1,256 @@
+# Please make sure that the `needs` fields for both `end-success` and `end-failure`
+# are updated when adding new jobs!
+
+name: CI
+on:
+  pull_request:
+  push:
+    branches:
+      - auto
+      - try
+      - automation/bors/try
+
+env:
+  CARGO_INCREMENTAL: 0
+  CARGO_NET_RETRY: 10
+  CI: 1
+  RUST_BACKTRACE: short
+  RUSTFLAGS: "-D warnings -W unreachable-pub -W bare-trait-objects"
+  RUSTUP_MAX_RETRIES: 10
+
+jobs:
+  changes:
+    runs-on: ubuntu-latest
+    permissions:
+      pull-requests: read
+    outputs:
+      typescript: ${{ steps.filter.outputs.typescript }}
+      proc_macros: ${{ steps.filter.outputs.proc_macros }}
+    steps:
+      - uses: actions/checkout@v4
+      - uses: dorny/paths-filter@1441771bbfdd59dcd748680ee64ebd8faab1a242
+        id: filter
+        with:
+          filters: |
+            typescript:
+              - 'editors/code/**'
+            proc_macros:
+              - 'crates/proc-macro-api/**'
+              - 'crates/proc-macro-srv/**'
+              - 'crates/proc-macro-srv-cli/**'
+
+  rust:
+    needs: changes
+    if: github.repository == 'rust-lang/rust-analyzer'
+    name: Rust
+    runs-on: ${{ matrix.os }}
+    env:
+      CC: deny_c
+      RUST_CHANNEL: "${{ needs.changes.outputs.proc_macros == 'true' && 'nightly' || 'stable' }}"
+      USE_SYSROOT_ABI: "${{ needs.changes.outputs.proc_macros == 'true' && '--features sysroot-abi' || '' }}"
+
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, windows-latest, macos-latest]
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ github.event.pull_request.head.sha }}
+
+      - name: Install Rust toolchain
+        run: |
+          rustup update --no-self-update ${{ env.RUST_CHANNEL }}
+          rustup component add --toolchain ${{ env.RUST_CHANNEL }} rustfmt rust-src
+          rustup default ${{ env.RUST_CHANNEL }}
+      # https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/rust.json
+      - name: Install Rust Problem Matcher
+        if: matrix.os == 'ubuntu-latest'
+        run: echo "::add-matcher::.github/rust.json"
+
+      - name: Cache Dependencies
+        uses: Swatinem/rust-cache@640a22190e7a783d4c409684cea558f081f92012
+        with:
+          key: ${{ env.RUST_CHANNEL }}
+
+      - name: Bump opt-level
+        if: matrix.os == 'ubuntu-latest'
+        run: sed -i '/\[profile.dev]/a opt-level=1' Cargo.toml
+
+      - name: Codegen checks (rust-analyzer)
+        run: cargo codegen --check
+
+      - name: Compile (tests)
+        run: cargo test --no-run --locked ${{ env.USE_SYSROOT_ABI }}
+
+      # It's faster to `test` before `build` ¯\_(ツ)_/¯
+      - name: Compile (rust-analyzer)
+        if: matrix.os == 'ubuntu-latest'
+        run: cargo build --quiet ${{ env.USE_SYSROOT_ABI }}
+
+      - name: Test
+        if: matrix.os == 'ubuntu-latest' || github.event_name == 'push'
+        run: cargo test ${{ env.USE_SYSROOT_ABI }} -- --nocapture --quiet
+
+      - name: Switch to stable toolchain
+        run: |
+          rustup update --no-self-update stable
+          rustup component add --toolchain stable rust-src clippy
+          rustup default stable
+
+      - name: Run analysis-stats on rust-analyzer
+        if: matrix.os == 'ubuntu-latest'
+        run: target/${{ matrix.target }}/debug/rust-analyzer analysis-stats .
+
+      - name: Run analysis-stats on rust std library
+        if: matrix.os == 'ubuntu-latest'
+        env:
+          RUSTC_BOOTSTRAP: 1
+        run: target/${{ matrix.target }}/debug/rust-analyzer analysis-stats --with-deps $(rustc --print sysroot)/lib/rustlib/src/rust/library/std
+
+      - name: clippy
+        if: matrix.os == 'windows-latest'
+        run: cargo clippy --all-targets -- -D clippy::disallowed_macros -D clippy::dbg_macro -D clippy::todo -D clippy::print_stdout -D clippy::print_stderr
+
+      - name: rustfmt
+        if: matrix.os == 'ubuntu-latest'
+        run: cargo fmt -- --check
+
+  # Weird targets to catch non-portable code
+  rust-cross:
+    if: github.repository == 'rust-lang/rust-analyzer'
+    name: Rust Cross
+    runs-on: ubuntu-latest
+
+    env:
+      targets: "powerpc-unknown-linux-gnu x86_64-unknown-linux-musl"
+      # The rust-analyzer binary is not expected to compile on WASM, but the IDE
+      # crate should
+      targets_ide: "wasm32-unknown-unknown"
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+
+      - name: Install Rust toolchain
+        run: |
+          rustup update --no-self-update stable
+          rustup target add ${{ env.targets }} ${{ env.targets_ide }}
+
+      - name: Cache Dependencies
+        uses: Swatinem/rust-cache@640a22190e7a783d4c409684cea558f081f92012
+
+      - name: Check
+        run: |
+          for target in ${{ env.targets }}; do
+            cargo check --target=$target --all-targets
+          done
+          for target in ${{ env.targets_ide }}; do
+            cargo check -p ide --target=$target --all-targets
+          done
+
+  typescript:
+    needs: changes
+    if: github.repository == 'rust-lang/rust-analyzer'
+    name: TypeScript
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, windows-latest]
+
+    runs-on: ${{ matrix.os }}
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        if: needs.changes.outputs.typescript == 'true'
+
+      - name: Install Nodejs
+        uses: actions/setup-node@v4
+        with:
+          node-version: 18
+        if: needs.changes.outputs.typescript == 'true'
+
+      - name: Install xvfb
+        if: matrix.os == 'ubuntu-latest' && needs.changes.outputs.typescript == 'true'
+        run: sudo apt-get install -y xvfb
+
+      - run: npm ci
+        working-directory: ./editors/code
+        if: needs.changes.outputs.typescript == 'true'
+
+      #    - run: npm audit || { sleep 10 && npm audit; } || { sleep 30 && npm audit; }
+      #      if: runner.os == 'Linux'
+      #      working-directory: ./editors/code
+
+      # If this steps fails, your code's type integrity might be wrong at some places at TypeScript level.
+      - run: npm run typecheck
+        working-directory: ./editors/code
+        if: needs.changes.outputs.typescript == 'true'
+
+      # You may fix the code automatically by running `npm run lint:fix` if this steps fails.
+      - run: npm run lint
+        working-directory: ./editors/code
+        if: needs.changes.outputs.typescript == 'true'
+
+      # To fix this steps, please run `npm run format`.
+      - run: npm run format:check
+        working-directory: ./editors/code
+        if: needs.changes.outputs.typescript == 'true'
+
+      - name: Run VS Code tests (Linux)
+        if: matrix.os == 'ubuntu-latest' && needs.changes.outputs.typescript == 'true'
+        env:
+          VSCODE_CLI: 1
+        run: xvfb-run npm test
+        working-directory: ./editors/code
+
+      - name: Run VS Code tests (Windows)
+        if: matrix.os == 'windows-latest' && needs.changes.outputs.typescript == 'true'
+        env:
+          VSCODE_CLI: 1
+        run: npm test
+        working-directory: ./editors/code
+
+      - run: npm run package --scripts-prepend-node-path
+        working-directory: ./editors/code
+        if: needs.changes.outputs.typescript == 'true'
+
+  typo-check:
+    name: Typo Check
+    runs-on: ubuntu-latest
+    timeout-minutes: 10
+    env:
+      FORCE_COLOR: 1
+      TYPOS_VERSION: v1.18.0
+    steps:
+      - name: download typos
+        run: curl -LsSf https://github.com/crate-ci/typos/releases/download/$TYPOS_VERSION/typos-$TYPOS_VERSION-x86_64-unknown-linux-musl.tar.gz | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin
+
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ github.event.pull_request.head.sha }}
+
+      - name: check for typos
+        run: typos
+
+  end-success:
+    name: bors build finished
+    if: github.event.pusher.name == 'bors' && success()
+    runs-on: ubuntu-latest
+    needs: [rust, rust-cross, typescript, typo-check]
+    steps:
+      - name: Mark the job as successful
+        run: exit 0
+
+  end-failure:
+    name: bors build finished
+    if: github.event.pusher.name == 'bors' && !success()
+    runs-on: ubuntu-latest
+    needs: [rust, rust-cross, typescript, typo-check]
+    steps:
+      - name: Mark the job as a failure
+        run: exit 1
diff --git a/src/tools/rust-analyzer/.github/workflows/fuzz.yml b/src/tools/rust-analyzer/.github/workflows/fuzz.yml
new file mode 100644
index 00000000000..f88c7f95d5c
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/workflows/fuzz.yml
@@ -0,0 +1,43 @@
+name: Fuzz
+on:
+  schedule:
+    # Once a week
+    - cron: '0 0 * * 0'
+  push:
+    paths:
+    - '.github/workflows/fuzz.yml'
+  # Allow manual trigger
+  workflow_dispatch:
+
+env:
+  CARGO_INCREMENTAL: 0
+  CARGO_NET_RETRY: 10
+  CI: 1
+  RUST_BACKTRACE: short
+  RUSTFLAGS: "-D warnings -W unreachable-pub -W bare-trait-objects"
+  RUSTUP_MAX_RETRIES: 10
+
+jobs:
+  rust:
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
+    name: Rust
+    runs-on: ubuntu-latest
+    env:
+      CC: deny_c
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          ref: ${{ github.event.pull_request.head.sha }}
+          fetch-depth: 1
+
+      - name: Install Rust toolchain
+        run: |
+          rustup install --profile minimal nightly
+
+      - name: Build fuzzers
+        run: |
+          cargo install cargo-fuzz
+          cd crates/syntax
+          cargo +nightly fuzz build
diff --git a/src/tools/rust-analyzer/.github/workflows/metrics.yaml b/src/tools/rust-analyzer/.github/workflows/metrics.yaml
new file mode 100644
index 00000000000..de61b2389ae
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/workflows/metrics.yaml
@@ -0,0 +1,153 @@
+name: metrics
+on:
+  push:
+    branches:
+      - master
+
+env:
+  CARGO_INCREMENTAL: 0
+  CARGO_NET_RETRY: 10
+  RUSTFLAGS: "-D warnings -W unreachable-pub"
+  RUSTUP_MAX_RETRIES: 10
+
+jobs:
+  setup_cargo:
+    if: github.repository == 'rust-lang/rust-analyzer'
+    runs-on: ubuntu-latest
+    steps:
+      - name: Install Rust toolchain
+        run: |
+          rustup update --no-self-update stable
+          rustup component add rustfmt rust-src
+          rustup default stable
+      - name: Cache cargo
+        uses: actions/cache@v4
+        with:
+          path: |
+            ~/.cargo/bin/
+            ~/.cargo/registry/index/
+            ~/.cargo/registry/cache/
+            ~/.cargo/git/db/
+          key: ${{ runner.os }}-cargo-${{ github.sha }}
+
+  build_metrics:
+    runs-on: ubuntu-latest
+    needs: setup_cargo
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+
+      - name: Restore cargo cache
+        uses: actions/cache@v4
+        with:
+          path: |
+            ~/.cargo/bin/
+            ~/.cargo/registry/index/
+            ~/.cargo/registry/cache/
+            ~/.cargo/git/db/
+          key: ${{ runner.os }}-cargo-${{ github.sha }}
+
+      - name: Collect build metrics
+        run: cargo xtask metrics build
+
+      - name: Cache target
+        uses: actions/cache@v4
+        with:
+          path: target/
+          key: ${{ runner.os }}-target-${{ github.sha }}
+
+      - name: Upload build metrics
+        uses: actions/upload-artifact@v3
+        with:
+          name: build-${{ github.sha }}
+          path: target/build.json
+          if-no-files-found: error
+
+  other_metrics:
+    strategy:
+      matrix:
+        names: [self, ripgrep-13.0.0, webrender-2022, diesel-1.4.8, hyper-0.14.18]
+    runs-on: ubuntu-latest
+    needs: [setup_cargo, build_metrics]
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+
+      - name: Restore cargo cache
+        uses: actions/cache@v4
+        with:
+          path: |
+            ~/.cargo/bin/
+            ~/.cargo/registry/index/
+            ~/.cargo/registry/cache/
+            ~/.cargo/git/db/
+          key: ${{ runner.os }}-cargo-${{ github.sha }}
+
+      - name: Restore target cache
+        uses: actions/cache@v4
+        with:
+          path: target/
+          key: ${{ runner.os }}-target-${{ github.sha }}
+
+      - name: Collect metrics
+        run: cargo xtask metrics "${{ matrix.names }}"
+
+      - name: Upload metrics
+        uses: actions/upload-artifact@v3
+        with:
+          name: ${{ matrix.names }}-${{ github.sha }}
+          path: target/${{ matrix.names }}.json
+          if-no-files-found: error
+
+  generate_final_metrics:
+    runs-on: ubuntu-latest
+    needs: [build_metrics, other_metrics]
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+
+      - name: Download build metrics
+        uses: actions/download-artifact@v3
+        with:
+          name: build-${{ github.sha }}
+
+      - name: Download self metrics
+        uses: actions/download-artifact@v3
+        with:
+          name: self-${{ github.sha }}
+
+      - name: Download ripgrep-13.0.0 metrics
+        uses: actions/download-artifact@v3
+        with:
+          name: ripgrep-13.0.0-${{ github.sha }}
+
+      - name: Download webrender-2022 metrics
+        uses: actions/download-artifact@v3
+        with:
+          name: webrender-2022-${{ github.sha }}
+
+      - name: Download diesel-1.4.8 metrics
+        uses: actions/download-artifact@v3
+        with:
+          name: diesel-1.4.8-${{ github.sha }}
+
+      - name: Download hyper-0.14.18 metrics
+        uses: actions/download-artifact@v3
+        with:
+          name: hyper-0.14.18-${{ github.sha }}
+
+      - name: Combine json
+        run: |
+          mkdir ~/.ssh
+          echo "${{ secrets.METRICS_DEPLOY_KEY }}" > ~/.ssh/id_ed25519
+          chmod 600 ~/.ssh/id_ed25519
+          chmod 700 ~/.ssh
+
+          git clone --depth 1 git@github.com:rust-analyzer/metrics.git
+          jq -s ".[0] * .[1] * .[2] * .[3] * .[4] * .[5]" build.json self.json ripgrep-13.0.0.json webrender-2022.json diesel-1.4.8.json hyper-0.14.18.json -c >> metrics/metrics.json
+          cd metrics
+          git add .
+          git -c user.name=Bot -c user.email=dummy@example.com commit --message 📈
+          git push origin master
diff --git a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
new file mode 100644
index 00000000000..34ca53e2e53
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
@@ -0,0 +1,36 @@
+name: publish-libs
+on:
+  workflow_dispatch:
+  push:
+    branches:
+      - master
+    paths:
+      - "lib/**"
+
+jobs:
+  publish-libs:
+    name: publish
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+
+      - name: Install Rust toolchain
+        run: rustup update --no-self-update stable
+
+      - name: Install cargo-workspaces
+        run: cargo install cargo-workspaces
+
+      - name: Publish Crates
+        env:
+          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
+        shell: bash
+        run: |
+          git config --global user.email "runner@gha.local"
+          git config --global user.name "GitHub Action"
+          # Remove r-a crates from the workspaces so we don't auto-publish them as well
+          sed -i 's/ "crates\/\*"//' ./Cargo.toml
+          sed -i 's/ "xtask\/"//' ./Cargo.toml
+          cargo workspaces publish --yes --exact --from-git --no-git-commit --allow-dirty
diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml
new file mode 100644
index 00000000000..11014338d72
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/workflows/release.yaml
@@ -0,0 +1,280 @@
+name: release
+on:
+  schedule:
+    - cron: "0 0 * * *" # midnight UTC
+
+  workflow_dispatch:
+
+  push:
+    branches:
+      - release
+      - trigger-nightly
+
+env:
+  CARGO_INCREMENTAL: 0
+  CARGO_NET_RETRY: 10
+  RUSTFLAGS: "-D warnings -W unreachable-pub"
+  RUSTUP_MAX_RETRIES: 10
+  FETCH_DEPTH: 0 # pull in the tags for the version string
+  MACOSX_DEPLOYMENT_TARGET: 10.15
+  CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
+  CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
+
+jobs:
+  dist:
+    strategy:
+      matrix:
+        include:
+          - os: windows-latest
+            target: x86_64-pc-windows-msvc
+            code-target: win32-x64
+          - os: windows-latest
+            target: i686-pc-windows-msvc
+          - os: windows-latest
+            target: aarch64-pc-windows-msvc
+            code-target: win32-arm64
+          - os: ubuntu-20.04
+            target: x86_64-unknown-linux-gnu
+            code-target: linux-x64
+            container: rockylinux:8
+          - os: ubuntu-20.04
+            target: aarch64-unknown-linux-gnu
+            code-target: linux-arm64
+          - os: ubuntu-20.04
+            target: arm-unknown-linux-gnueabihf
+            code-target: linux-armhf
+          - os: macos-12
+            target: x86_64-apple-darwin
+            code-target: darwin-x64
+          - os: macos-12
+            target: aarch64-apple-darwin
+            code-target: darwin-arm64
+
+    name: dist (${{ matrix.target }})
+    runs-on: ${{ matrix.os }}
+    container: ${{ matrix.container }}
+
+    env:
+      RA_TARGET: ${{ matrix.target }}
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: ${{ env.FETCH_DEPTH }}
+
+      - name: Install toolchain dependencies
+        if: matrix.container == 'rockylinux:8'
+        shell: bash
+        run: |
+          dnf install -y gcc
+          curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --profile minimal --default-toolchain none -y
+          echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH
+
+      - name: Install Rust toolchain
+        run: |
+          rustup update --no-self-update stable
+          rustup target add ${{ matrix.target }}
+          rustup component add rust-src
+
+      - name: Install Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version: 18
+
+      - name: Update apt repositories
+        if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf'
+        run: sudo apt-get update
+
+      - name: Install AArch64 target toolchain
+        if: matrix.target == 'aarch64-unknown-linux-gnu'
+        run: sudo apt-get install gcc-aarch64-linux-gnu
+
+      - name: Install ARM target toolchain
+        if: matrix.target == 'arm-unknown-linux-gnueabihf'
+        run: sudo apt-get install gcc-arm-linux-gnueabihf
+
+      - name: Dist
+        run: cargo xtask dist --client-patch-version ${{ github.run_number }}
+
+      - run: npm ci
+        working-directory: editors/code
+
+      - name: Package Extension (release)
+        if: github.ref == 'refs/heads/release' && matrix.code-target
+        run: npx vsce package -o "../../dist/rust-analyzer-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }}
+        working-directory: editors/code
+
+      - name: Package Extension (nightly)
+        if: github.ref != 'refs/heads/release' && matrix.code-target
+        run: npx vsce package -o "../../dist/rust-analyzer-${{ matrix.code-target }}.vsix" --target ${{ matrix.code-target }} --pre-release
+        working-directory: editors/code
+
+      - if: matrix.target == 'x86_64-unknown-linux-gnu'
+        run: rm -rf editors/code/server
+
+      - if: matrix.target == 'x86_64-unknown-linux-gnu' && github.ref == 'refs/heads/release'
+        run: npx vsce package -o ../../dist/rust-analyzer-no-server.vsix
+        working-directory: editors/code
+
+      - if: matrix.target == 'x86_64-unknown-linux-gnu' && github.ref != 'refs/heads/release'
+        run: npx vsce package -o ../../dist/rust-analyzer-no-server.vsix --pre-release
+        working-directory: editors/code
+
+      - name: Run analysis-stats on rust-analyzer
+        if: matrix.target == 'x86_64-unknown-linux-gnu'
+        run: target/${{ matrix.target }}/release/rust-analyzer analysis-stats .
+
+      - name: Run analysis-stats on rust std library
+        if: matrix.target == 'x86_64-unknown-linux-gnu'
+        env:
+          RUSTC_BOOTSTRAP: 1
+        run: target/${{ matrix.target }}/release/rust-analyzer analysis-stats --with-deps $(rustc --print sysroot)/lib/rustlib/src/rust/library/std
+
+      - name: Upload artifacts
+        uses: actions/upload-artifact@v1
+        with:
+          name: dist-${{ matrix.target }}
+          path: ./dist
+
+  dist-x86_64-unknown-linux-musl:
+    name: dist (x86_64-unknown-linux-musl)
+    runs-on: ubuntu-latest
+    env:
+      RA_TARGET: x86_64-unknown-linux-musl
+      # For some reason `-crt-static` is not working for clang without lld
+      RUSTFLAGS: "-C link-arg=-fuse-ld=lld -C target-feature=-crt-static"
+    container:
+      image: rust:alpine
+      volumes:
+        - /usr/local/cargo/registry:/usr/local/cargo/registry
+
+    steps:
+      - name: Install dependencies
+        run: apk add --no-cache git clang lld musl-dev nodejs npm
+
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: ${{ env.FETCH_DEPTH }}
+
+      - name: Dist
+        run: cargo xtask dist --client-patch-version ${{ github.run_number }}
+
+      - run: npm ci
+        working-directory: editors/code
+
+      - name: Package Extension (release)
+        if: github.ref == 'refs/heads/release'
+        run: npx vsce package -o "../../dist/rust-analyzer-alpine-x64.vsix" --target alpine-x64
+        working-directory: editors/code
+
+      - name: Package Extension (nightly)
+        if: github.ref != 'refs/heads/release'
+        run: npx vsce package -o "../../dist/rust-analyzer-alpine-x64.vsix" --target alpine-x64 --pre-release
+        working-directory: editors/code
+
+      - run: rm -rf editors/code/server
+
+      - name: Upload artifacts
+        uses: actions/upload-artifact@v1
+        with:
+          name: dist-x86_64-unknown-linux-musl
+          path: ./dist
+
+  publish:
+    name: publish
+    runs-on: ubuntu-latest
+    needs: ["dist", "dist-x86_64-unknown-linux-musl"]
+    steps:
+      - name: Install Nodejs
+        uses: actions/setup-node@v4
+        with:
+          node-version: 20
+
+      - run: echo "TAG=$(date --iso -u)" >> $GITHUB_ENV
+        if: github.ref == 'refs/heads/release'
+      - run: echo "TAG=nightly" >> $GITHUB_ENV
+        if: github.ref != 'refs/heads/release'
+      - run: 'echo "TAG: $TAG"'
+
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: ${{ env.FETCH_DEPTH }}
+
+      - run: echo "HEAD_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
+      - run: 'echo "HEAD_SHA: $HEAD_SHA"'
+
+      - uses: actions/download-artifact@v1
+        with:
+          name: dist-aarch64-apple-darwin
+          path: dist
+      - uses: actions/download-artifact@v1
+        with:
+          name: dist-x86_64-apple-darwin
+          path: dist
+      - uses: actions/download-artifact@v1
+        with:
+          name: dist-x86_64-unknown-linux-gnu
+          path: dist
+      - uses: actions/download-artifact@v1
+        with:
+          name: dist-x86_64-unknown-linux-musl
+          path: dist
+      - uses: actions/download-artifact@v1
+        with:
+          name: dist-aarch64-unknown-linux-gnu
+          path: dist
+      - uses: actions/download-artifact@v1
+        with:
+          name: dist-arm-unknown-linux-gnueabihf
+          path: dist
+      - uses: actions/download-artifact@v1
+        with:
+          name: dist-x86_64-pc-windows-msvc
+          path: dist
+      - uses: actions/download-artifact@v1
+        with:
+          name: dist-i686-pc-windows-msvc
+          path: dist
+      - uses: actions/download-artifact@v1
+        with:
+          name: dist-aarch64-pc-windows-msvc
+          path: dist
+      - run: ls -al ./dist
+
+      - name: Publish Release
+        uses: ./.github/actions/github-release
+        with:
+          files: "dist/*"
+          name: ${{ env.TAG }}
+          token: ${{ secrets.GITHUB_TOKEN }}
+
+      - run: rm dist/rust-analyzer-no-server.vsix
+
+      - run: npm ci
+        working-directory: ./editors/code
+
+      - name: Publish Extension (Code Marketplace, release)
+        if: github.ref == 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
+        working-directory: ./editors/code
+        # token from https://dev.azure.com/rust-analyzer/
+        run: npx vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
+
+      - name: Publish Extension (OpenVSX, release)
+        if: github.ref == 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
+        working-directory: ./editors/code
+        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
+        timeout-minutes: 2
+
+      - name: Publish Extension (Code Marketplace, nightly)
+        if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
+        working-directory: ./editors/code
+        run: npx vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix --pre-release
+
+      - name: Publish Extension (OpenVSX, nightly)
+        if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
+        working-directory: ./editors/code
+        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
+        timeout-minutes: 2
diff --git a/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml b/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml
new file mode 100644
index 00000000000..12a1a791fda
--- /dev/null
+++ b/src/tools/rust-analyzer/.github/workflows/rustdoc.yaml
@@ -0,0 +1,34 @@
+name: rustdoc
+on:
+  push:
+   branches:
+   - master
+
+env:
+  CARGO_INCREMENTAL: 0
+  CARGO_NET_RETRY: 10
+  RUSTFLAGS: "-D warnings -W unreachable-pub"
+  RUSTUP_MAX_RETRIES: 10
+
+jobs:
+  rustdoc:
+    if: github.repository == 'rust-lang/rust-analyzer'
+    runs-on: ubuntu-latest
+
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v4
+
+    - name: Install Rust toolchain
+      run: rustup update --no-self-update stable
+
+    - name: Build Documentation
+      run: cargo doc --all --no-deps
+
+    - name: Deploy Docs
+      uses: peaceiris/actions-gh-pages@364c31d33bb99327c77b3a5438a83a357a6729ad # v3.4.0
+      with:
+        github_token: ${{ secrets.GITHUB_TOKEN }}
+        publish_branch: gh-pages
+        publish_dir: ./target/doc
+        force_orphan: true