diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 49102ae6..0995626a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -53,6 +53,7 @@ jobs: if: ${{ needs.release.outputs.release_created }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NEXTLS_RELEASE_MODE: "burrito" steps: - uses: actions/checkout@v4 - uses: DeterminateSystems/nix-installer-action@main diff --git a/README.md b/README.md index b5b5d4d8..97059948 100644 --- a/README.md +++ b/README.md @@ -51,16 +51,28 @@ mix test ## Production release +### Burrito + +Burrito is the classic way of building Next LS, it produces a single executable that fully wraps Elixir, OTP, and your application. + Executables are output to `./burrito_out`. ```bash # produces executables for all the targets specified in the `mix.exs` file -MIX_ENV=prod mix release +NEXTLS_RELEASE_MODE="burrito" MIX_ENV=prod mix release # produce an executable for a single target BURRITO_TARGET=linux_amd64 MIX_ENV=prod mix release ``` +### Traditional + +You can also build Next LS as a traditional Mix release. + +```bash +MIX_ENV=prod mix release plain +``` + ## Contributing This project follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) and will "Squash and Merge" pull requests. diff --git a/config/runtime.exs b/config/runtime.exs index ce04f4b4..51307dcc 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -1,5 +1,13 @@ import Config +case System.get_env("NEXTLS_RELEASE_MODE", "plain") do + "burrito" -> + config :next_ls, arg_parser: {Burrito.Util.Args, :get_arguments, []} + + "plain" -> + config :next_ls, arg_parser: {System, :argv, []} +end + if System.get_env("NEXTLS_OTEL") == "1" do config :next_ls, otel: true diff --git a/flake.nix b/flake.nix index e672362a..6ac8abc1 100644 --- a/flake.nix +++ b/flake.nix @@ -18,12 +18,9 @@ # Helper to provide system-specific attributes forAllSystems = f: - lib.genAttrs (builtins.attrNames burritoExe) (system: let + lib.genAttrs systems (system: let pkgs = nixpkgs.legacyPackages.${system}; beamPackages = pkgs.beam_minimal.packages.erlang_26; - beam = fetchTarball beams.${system}; - rawmusl = musls.${system}; - musl = lib.optionals nixpkgs.legacyPackages.${system}.stdenv.isLinux (builtins.fetchurl (nixpkgs.lib.attrsets.getAttrs ["url" "sha256"] musls.${system})); otp = (pkgs.beam.packagesWith beamPackages.erlang).extend (final: prev: { elixir_1_17 = prev.elixir_1_16.override { rev = "e3b6a91b173f7e836401a6a75c3906c26bd7fd39"; @@ -39,64 +36,21 @@ }); elixir = otp.elixir; in - f {inherit system pkgs beamPackages elixir beam rawmusl musl;}); - - burritoExe = { - "aarch64-darwin" = "darwin_arm64"; - "x86_64-darwin" = "darwin_amd64"; - "x86_64-linux" = "linux_amd64"; - "aarch64-linux" = "linux_arm64"; - }; - - beams = { - "aarch64-darwin" = { - url = "https://beam-machine-universal.b-cdn.net/OTP-26.2.1/macos/universal/otp_26.2.1_macos_universal_ssl_3.1.4.tar.gz?please-respect-my-bandwidth-costs=thank-you"; - sha256 = "0sdadkl80pixj9q3l71zxamh9zgmnmawsc4hpllgvx9r9hl30f40"; - }; - "x86_64-darwin" = { - url = "https://beam-machine-universal.b-cdn.net/OTP-26.2.1/macos/universal/otp_26.2.1_macos_universal_ssl_3.1.4.tar.gz?please-respect-my-bandwidth-costs=thank-you"; - sha256 = "0sdadkl80pixj9q3l71zxamh9zgmnmawsc4hpllgvx9r9hl30f40"; - }; - "x86_64-linux" = { - url = "https://beam-machine-universal.b-cdn.net/OTP-26.2.1/linux/x86_64/any/otp_26.2.1_linux_any_x86_64_ssl_3.1.4.tar.gz?please-respect-my-bandwidth-costs=thank-you"; - sha256 = "11z50xrmngsn0bzg7vn7w5h76iwmhscx01vij9ir2ivybjc8niky"; - }; - "aarch64-linux" = { - url = "https://beam-machine-universal.b-cdn.net/OTP-26.2.1/linux/aarch64/any/otp_26.2.1_linux_any_aarch64_ssl_3.1.4.tar.gz?please-respect-my-bandwidth-costs=thank-you"; - sha256 = "0ich3xkhbb3sb82m7sncg0pr1d3z92klpwrlh8csr8i1qjhg40h5"; - }; - }; - - musls = { - "x86_64-linux" = { - url = "https://beam-machine-universal.b-cdn.net/musl/libc-musl-17613ec13d9aa9e5e907e6750785c5bbed3ad49472ec12281f592e2f0f2d3dbd.so?please-respect-my-bandwidth-costs=thank-you"; - sha256 = "1g9x5l7jybjr3wl15v3jjka3mvdvqn2hfxg60zlybacs7p0kwq8p"; - file = "libc-musl-17613ec13d9aa9e5e907e6750785c5bbed3ad49472ec12281f592e2f0f2d3dbd.so"; - }; - "aarch64-linux" = { - url = "https://beam-machine-universal.b-cdn.net/musl/libc-musl-939d11dcd3b174a8dee05047f2ae794c5c43af54720c352fa946cd8b0114627a.so?please-respect-my-bandwidth-costs=thank-you"; - sha256 = "0yk22h0qpka6m4pka33jajpl6p2cg6pg4ishw3gahx5isgf137ck"; - file = "libc-musl-939d11dcd3b174a8dee05047f2ae794c5c43af54720c352fa946cd8b0114627a.so"; - }; - }; + f {inherit system pkgs beamPackages elixir;}); + + systems = [ + "aarch64-darwin" + "x86_64-darwin" + "x86_64-linux" + "aarch64-linux" + ]; in { packages = forAllSystems ({ pkgs, system, beamPackages, - beam, - musl, - rawmusl, elixir, - }: let - aliased_7zz = pkgs.symlinkJoin { - name = "7zz-aliased"; - paths = [pkgs._7zz]; - postBuild = '' - ln -s ${pkgs._7zz}/bin/7zz $out/bin/7z - ''; - }; - in { + }: { default = lib.makeOverridable ({ localBuild, beamPackages, @@ -106,11 +60,10 @@ pname = "next-ls"; src = self.outPath; mixEnv = "prod"; + removeCookie = false; inherit version elixir; inherit (beamPackages) erlang; - nativeBuildInputs = [pkgs.xz pkgs.zig_0_11 aliased_7zz beam]; - mixFodDeps = beamPackages.fetchMixDeps { src = self.outPath; inherit version elixir; @@ -119,30 +72,10 @@ mixEnv = "prod"; }; - BURRITO_ERTS_PATH = "/tmp/beam/"; - BURRITO_TARGET = lib.optional localBuild burritoExe.${system}; - - preBuild = - '' - export HOME="$TEMPDIR" - mkdir -p /tmp/beam/otp - cp -r --no-preserve=ownership,timestamps ${beam}/. /tmp/beam/otp - '' - + ( - if (pkgs.stdenv.isLinux) - then '' - cp --no-preserve=ownership,timestamps ${musl} /tmp/${rawmusl.file} - chmod +x /tmp/${rawmusl.file} - '' - else "" - ); - - postInstall = '' - chmod +x ./burrito_out/* - cp -r ./burrito_out "$out" - rm -rf "$out/bin" - mv "$out/burrito_out" "$out/bin" - mv "$out/bin/next_ls_${burritoExe.${system}}" "$out/bin/nextls" + installPhase = '' + mix release --no-deps-check --path $out plain + echo "$out/bin/plain eval \"System.no_halt(true); Application.ensure_all_started(:next_ls)\" \"\$@\"" > "$out/bin/nextls" + chmod +x "$out/bin/nextls" ''; meta = with lib; { @@ -155,8 +88,6 @@ inherit beamPackages elixir; localBuild = true; }; - - ci = self.packages.${system}.default.override {localBuild = false;}; }); devShells = forAllSystems ({ diff --git a/lib/next_ls/lsp_supervisor.ex b/lib/next_ls/lsp_supervisor.ex index 7815c871..69393b1d 100644 --- a/lib/next_ls/lsp_supervisor.ex +++ b/lib/next_ls/lsp_supervisor.ex @@ -14,8 +14,7 @@ defmodule NextLS.LSPSupervisor do if @env == :test do :ignore else - {m, f, a} = - if @env == :prod, do: {Burrito.Util.Args, :get_arguments, []}, else: {System, :argv, []} + {m, f, a} = Application.get_env(:next_ls, :arg_parser) argv = apply(m, f, a) diff --git a/mix.exs b/mix.exs index 6d9c24a1..a2982a40 100644 --- a/mix.exs +++ b/mix.exs @@ -13,6 +13,7 @@ defmodule NextLS.MixProject do elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, releases: releases(), + default_release: :next_ls, package: package(), deps: deps(), docs: [ @@ -38,6 +39,7 @@ defmodule NextLS.MixProject do def releases do [ + plain: [], next_ls: [ steps: [:assemble, &Burrito.wrap/1], burrito: [