diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..233b9aa --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,83 @@ +# Exstatic Release Process + +This document outlines the steps required to release a new version of Exstatic, ensuring that both Elixir and native Rust code are properly updated and distributed via precompiled NIFs. + +## **1️⃣ Bump version in `mix.exs`** + +After you've made your code changes, update the version in mix.exs (`@version "x.y.z"`) + +Now follow the steps below to release the update. + +## **2️⃣ Merge Changes to `main`** + +- Open a **Pull Request** including: + - Code changes (including the version bump in mix.exs) + - A CHANGELOG.md entry for this release. + +Once approved and CI passes - **merge to `main`**. + +## **3️⃣ Tag & Create a GitHub Release** + +1. To create a release, check out the latest `origin/main` (this should be what you just merged), tag the new version and push it: + + ```sh + git tag -a vX.Y.Z -m "Release version X.Y.Z" + git push origin vX.Y.Z + ``` + + Ensure the tag (`vX.Y.Z`) matches the version in `mix.exs`, otherwise, precompiled binaries might not align correctly. + +2. **Go to GitHub → Releases → Create New Release** + + - Use `vX.Y.Z` as the tag. + - Copy the corresponding section from CHANGELOG.md as the release notes. + +This triggers the `release.yml` GitHub Action, which: + +- ✅ Builds precompiled NIFs. +- ✅ Uploads them to GitHub Releases. +- ✅ Makes them available for `RustlerPrecompiled`. + +## **4️⃣ Generate & Include Checksum File** + +**After the GitHub release is live and the CI has built the precompiled NIFs**, you need to generate the checksum file: + +```sh +mix rustler_precompiled.download Exstatic.Native --all --print +``` + +This pulls the NIF binaries from the latest GitHub release and uses them to generate a `checksum-Elixir.Exstatic.Native.exs` file. + +Run the following command to verify the package contents before publishing: + +```sh +mix hex.build --unpack +``` + +You should see `checksum-Elixir.Exstatic.Native.exs` included in th list of files. Don't check the checksum file into version control. + +## **5️⃣ Publish to Hex.pm** + +Once the GitHub release is live and the checksum file is included, publish the package to Hex.pm: + +```sh +mix hex.user auth # Authenticate if not already logged in +mix hex.publish # Publish the package +``` + +### Important Notes: +- You **must have write access** to Zappi's Hex registry to publish (ask Brendon if you don't). +- **Ensure you are on the `main` branch**, and it matches `origin/main`, as `mix hex.publish` publishes from your **local copy**, not GitHub. + +## **6️⃣ Verify Installation** + +To confirm users can fetch precompiled NIFs **without needing Rust**, test in a fresh clone: + +```sh +git clone https://github.com/Intellection/exstatic.git +cd exstatic +mix deps.get +mix compile # Should download precompiled NIFs instead of compiling Rust +``` + +If this works **without recompiling Rust**, the release is successful! 🎉 diff --git a/docs/checksum.md b/docs/checksum.md new file mode 100644 index 0000000..988a14f --- /dev/null +++ b/docs/checksum.md @@ -0,0 +1,49 @@ +# **Checksum in Exstatic** + +The `checksum-Elixir.Exstatic.Native.exs` file is used to verify the integrity of the precompiled NIFs when users install Exstatic. This ensures that the correct binaries are downloaded and prevents tampering or corruption. + +## **How the Checksum is Used** + +### **Where is the Checksum File Used?** + +#### **During Release Process** +1. The precompiled NIFs are built by **GitHub Actions** when a new release is created. +2. Once all precompiled binaries are available in the GitHub release, the checksum file must be **manually generated** using: + ```sh + mix rustler_precompiled.download Exstatic.Native --all --print + ``` +3. This command fetches all precompiled binaries and generates a `checksum-Elixir.Exstatic.Native.exs` file. +4. The generated checksum file is **included in the Hex package** but is **not committed to the repository**. + +#### **When Users Install Exstatic** +1. RustlerPrecompiled automatically downloads the appropriate precompiled NIF. +2. The NIF's SHA-256 checksum is **verified** against the `checksum-Elixir.Exstatic.Native.exs` file. +3. If the checksum matches, the precompiled binary is used. +4. If the checksum does **not** match (e.g., due to corruption or missing binary), Rustler falls back to compiling the Rust code locally. + +--- + +## **Example `checksum-Elixir.Exstatic.Native.exs` File** +Below is an example of what the `checksum-Elixir.Exstatic.Native.exs` file looks like for multiple architectures: + +```elixir +%{ + "libexstatic-v0.1.1-nif-2.16-aarch64-apple-darwin.so.tar.gz" => "sha256:a2f7de6bae6f0562649f6e1c0a376978623f50a0be17aec92928355a534a906a", + "libexstatic-v0.1.1-nif-2.16-x86_64-apple-darwin.so.tar.gz" => "sha256:b5c8d1e2f12a4747d03c4d92e913c8b9d5b8ea2c93a31492a123456789abcdef", + "libexstatic-v0.1.1-nif-2.16-aarch64-unknown-linux-gnu.so.tar.gz" => "sha256:c3d7e5f8a1b2c34d56e7f890123abcde0987654321f4e56789abcdef01234567", + "libexstatic-v0.1.1-nif-2.16-x86_64-unknown-linux-gnu.so.tar.gz" => "sha256:d4e5f6a7b8c9d01234567890abcdef1234567890abcdef1234567890abcdef12" +} +``` + +Each entry in the map corresponds to a precompiled NIF binary, with its respective SHA-256 checksum. These checksums ensure the integrity of the binaries when downloaded and used in different environments. + +--- + +## **Important Notes** +- The checksum file **must be generated manually** after the precompiled NIFs are available in the GitHub release. +- The file must be **included in the Hex package** by ensuring `"checksum-*.exs"` is listed in the `files` field of `mix.exs`. +- You can verify that the checksum file is included before publishing with: + ```sh + mix hex.build --unpack + ``` +- If any **native Rust code changes**, you **must** regenerate the checksum file before the next release. diff --git a/docs/github_token_guide.md b/docs/github_token_guide.md new file mode 100644 index 0000000..2f95b14 --- /dev/null +++ b/docs/github_token_guide.md @@ -0,0 +1,37 @@ +# Setting Up a GitHub Personal Access Token for Exstatic + +This guide walks you through creating a **GitHub Personal Access Token (PAT)** to allow Exstatic to authenticate and fetch precompiled NIFs from a private repository. + +## 1️⃣ Generate a New Token + +1. **Go to GitHub Token Settings:** + - Navigate to [GitHub Personal Access Tokens](https://github.com/settings/tokens). + - Click **"Generate new token (classic)"**. + +## 2️⃣ Configure Token Permissions + +1. **Token Name:** + - Give it a meaningful name like `exstatic-release-access`. + +2. **Expiration:** + - Choose an expiration date. + +3. **Select Scopes:** + - The following scopes are required for accessing private repositories: + + ✅ **repo** → Full read access to private repositories + ✅ **read:packages** → Read access to GitHub Packages (under write:packages) + +## 3️⃣ Generate and Store the Token + +1. Click **"Generate token"**. +2. **Copy the token** – it will not be shown again. + +--- + +### 4️⃣ Set Environment Variable +1. Exstatic needs this to during installation: + + ```sh + export EXSTATIC_GITHUB_TOKEN="your-token-here" + ```