From 181b880d081a5adc912c169b0739c21b5ac0f63d Mon Sep 17 00:00:00 2001 From: Brook <71849503+Primebrook@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:31:08 +0000 Subject: [PATCH 1/3] simpler asset download --- lib/exstatic/native.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/exstatic/native.ex b/lib/exstatic/native.ex index cd7072a..c274fea 100644 --- a/lib/exstatic/native.ex +++ b/lib/exstatic/native.ex @@ -1,14 +1,14 @@ defmodule Exstatic.Native do @moduledoc false - version = Mix.Project.config()[:version] + config = Mix.Project.config() use RustlerPrecompiled, otp_app: :exstatic, crate: "exstatic", - base_url: {Exstatic.ReleaseHelper, :github_release_url!}, + base_url: "#{config[:source_url]}/releases/download/v#{config[:version]}", force_build: System.get_env("EXSTATIC_BUILD") == "true", nif_versions: ["2.16"], - version: version, + version: config[:version], targets: ~w( aarch64-apple-darwin x86_64-apple-darwin From 18ad98eabf8f22ad4afe192e1ebf665dbec1e340 Mon Sep 17 00:00:00 2001 From: Brook <71849503+Primebrook@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:38:14 +0000 Subject: [PATCH 2/3] bump --- CHANGELOG.md | 13 +++-- README.md | 2 +- lib/exstatic/release_helper.ex | 99 ---------------------------------- mix.exs | 2 +- 4 files changed, 11 insertions(+), 105 deletions(-) delete mode 100644 lib/exstatic/release_helper.ex diff --git a/CHANGELOG.md b/CHANGELOG.md index 660ee53..807eee6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,14 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [v0.1.3] - 2024-02-10 +## [v.0.2.0] - 2025-02-13 + +### Changed +- The way precompiled binaries are downloaded from Github releases. + +## [v0.1.3] - 2025-02-10 ### Fixed - Includes the native source code in the hex release if folks want to build rust backend locally (can be done by setting `EXSTATIC_BUILD=true` -## [v0.1.2] - 2024-02-08 +## [v0.1.2] - 2025-02-08 ### Fixed @@ -22,7 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Exstatic is a private, direct public URLs are not an option. In v0.1.2 we implement GitHub's private asset download flow, for retrieving the NIF binaries. - Users must provide a Github Personal Access Token (PAT) (in `EXSTATIC_GITHUB_TOKEN` env var) with sufficient priveleges to download precompiled binaries. -## [v0.1.1] - 2024-02-07 +## [v0.1.1] - 2025-02-07 ### Added @@ -40,7 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - PRs that modify native code or the `release.yml` file. - Uploads precompiled NIFs to GitHub Releases when a tag is pushed. -## [v0.1.0] - 2024-02-07 +## [v0.1.0] - 2025-02-07 ### Added Initial Release: Introduced Exstatic, a statistical distribution library for Elixir with native Rust implementations. diff --git a/README.md b/README.md index b98ce8a..8dbdc8a 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Add `exstatic` to your list of dependencies in `mix.exs`: ```elixir def deps do [ - {:exstatic, "~> 0.1.3", organization: "zappi"} + {:exstatic, "~> 0.2.0", organization: "zappi"} ] end ``` diff --git a/lib/exstatic/release_helper.ex b/lib/exstatic/release_helper.ex deleted file mode 100644 index 8b0d9ae..0000000 --- a/lib/exstatic/release_helper.ex +++ /dev/null @@ -1,99 +0,0 @@ -defmodule Exstatic.ReleaseHelper do - @moduledoc """ - A helper module for fetching precompiled assets from a private GitHub release. - - If/when Exstatic becomes a public repo this will not be necessary. - - This module is designed to work with `RustlerPrecompiled`, allowing it to dynamically - fetch the correct precompiled NIF binaries from a GitHub release using the GitHub API. - It retrieves the asset ID for a given file name and constructs a download URL with the - necessary authentication headers. - - ## Required Environment Variables - - - `EXSTATIC_GITHUB_TOKEN` – A GitHub personal access token (PAT) with access to private repositories. - """ - - @config Mix.Project.config() - @tag "v#{@config[:version]}" - - @doc """ - Retrieves the GitHub asset download URL and authentication headers. - - ## Parameters - - - `file_name` (String.t()): The name of the asset file to download. - - ## Returns - - - `{download_url, headers}` (tuple): A tuple containing the GitHub asset URL and headers. - - ## Raises - - - `RuntimeError`: If the `EXSTATIC_GITHUB_TOKEN` environment variable is missing or if the asset ID cannot be found. - - ## Example - - iex> Exstatic.ReleaseHelper.github_release_url!("libexstatic-v0.1.1-nif-2.16-aarch64-apple-darwin.so.tar.gz") - {"https://api.github.com/repos/Intellection/exstatic/releases/assets/227243824", - [{"Authorization", "token MY_TOKEN"}, {"Accept", "application/octet-stream"}, {"User-Agent", "exstatic-bot"}]} - """ - @spec github_release_url!(String.t()) :: {String.t(), [{String.t(), String.t()}]} - def github_release_url!(file_name) do - token = github_personal_access_token!() - - case fetch_github_asset_id(file_name, token) do - {:ok, asset_id} -> - {asset_url(asset_id), - [ - {"Authorization", "token #{token}"}, - {"Accept", "application/octet-stream"}, - {"User-Agent", "exstatic-bot"} - ]} - - {:error, reason} -> - raise "Failed to fetch GitHub asset ID: #{reason}" - end - end - - defp fetch_github_asset_id(file_name, token) do - headers = [ - {"Authorization", "token #{token}"}, - {"Accept", "application/vnd.github+json"}, - {"User-Agent", "exstatic-bot"} - ] - - case Tesla.get(release_url(), headers: headers) do - {:ok, %Tesla.Env{status: 200, body: release}} -> - release - |> :json.decode() - |> find_asset_id(file_name) - - {:ok, %Tesla.Env{status: status, body: body}} -> - {:error, "Failed to fetch releases: #{status} #{inspect(body)}"} - - {:error, reason} -> - {:error, reason} - end - end - - defp asset_url(asset_id) do - "https://api.github.com/repos/#{@config[:repo]}/releases/assets/#{asset_id}" - end - - defp release_url, do: "https://api.github.com/repos/#{@config[:repo]}/releases/tags/#{@tag}" - - defp find_asset_id(release, file_name) do - case Enum.find(release["assets"], fn asset -> asset["name"] == file_name end) do - nil -> {:error, "Asset not found: #{file_name} in release #{@tag}"} - asset -> {:ok, asset["id"]} - end - end - - defp github_personal_access_token! do - case System.get_env("EXSTATIC_GITHUB_TOKEN") do - nil -> raise "Missing EXSTATIC_GITHUB_TOKEN environment variable." - token -> token - end - end -end diff --git a/mix.exs b/mix.exs index 99fb5c3..0589cde 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Exstatic.MixProject do use Mix.Project - @version "0.1.3" + @version "0.2.0" @repo "Intellection/exstatic" @source_url "https://github.com/#{@repo}" From 6653ef17943f418835e0cfe579336223028ca6c4 Mon Sep 17 00:00:00 2001 From: Brook <71849503+Primebrook@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:40:11 +0000 Subject: [PATCH 3/3] update references --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 807eee6..c3fe1cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,7 +50,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added Initial Release: Introduced Exstatic, a statistical distribution library for Elixir with native Rust implementations. -[Unreleased]: https://github.com/Intellection/exstatic/compare/v0.1.3...HEAD +[Unreleased]: https://github.com/Intellection/exstatic/compare/v0.2.0...HEAD +[v0.2.0]: https://github.com/Intellection/exstatic/compare/v0.2.0...v0.1.3 [v0.1.3]: https://github.com/Intellection/exstatic/compare/v0.1.3...v0.1.2 [v0.1.2]: https://github.com/Intellection/exstatic/compare/v0.1.2...v0.1.1 [v0.1.1]: https://github.com/Intellection/exstatic/compare/v0.1.1...v0.1.0