Skip to content

Commit

Permalink
Merge pull request #1 from amokan/0.2.0
Browse files Browse the repository at this point in the history
0.2.0
  • Loading branch information
amokan authored Mar 27, 2022
2 parents 812194c + 1a35f1b commit 110c953
Show file tree
Hide file tree
Showing 12 changed files with 418 additions and 130 deletions.
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2
updates:
- package-ecosystem: mix
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 5

- package-ecosystem: cargo
directory: "/native/human_name_nif"
schedule:
interval: daily
open-pull-requests-limit: 5
38 changes: 22 additions & 16 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
name: CI

on:
push:
branches: [main]
pull_request:
push:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
runs-on: ubuntu-18.04

name: Elixir ${{ matrix.pair.elixir }} / OTP ${{ matrix.pair.otp }}

strategy:
matrix:
Expand All @@ -24,25 +25,30 @@ jobs:
otp-version: ${{ matrix.otp }}
elixir-version: ${{ matrix.elixir }}

- name: Retrieve mix dependencies cache
uses: actions/cache@v1
id: mix-cache
- name: Install minimal stable Rust toolchain
uses: actions-rs/toolchain@v1
with:
path: deps
key: ${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }}
profile: minimal
toolchain: stable

- name: Install Dependencies
if: steps.mix-cache.outputs.cache-hit != 'true'
run: |
mix local.rebar --force
mix local.hex --force
mix deps.get
run: mix deps.get

- run: mix format --check-formatted

- name: Check formatting
run: mix format --check-formatted
- run: mix deps.unlock --check-unused

- run: mix deps.compile
env:
HUMAN_NAME_BUILD: 1

- run: mix compile --warnings-as-errors
env:
HUMAN_NAME_BUILD: 1
MIX_ENV: test

- name: Run Tests
run: mix coveralls.github
run: HUMAN_NAME_BUILD=1 mix coveralls.github
env:
MIX_ENV: test
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
205 changes: 205 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
name: Build precompiled NIFs

env:
NIF_DIRECTORY: "native/human_name_nif"

on:
push:
branches:
- main
tags:
- "*"

defaults:
run:
# Sets the working dir for "run" scripts.
# Note that this won't change the directory for actions (tasks with "uses").
working-directory: "./native/human_name_nif"

jobs:
build_release:
name: NIF ${{ matrix.job.nif }} - ${{ matrix.job.target }} (${{ matrix.job.os }})
runs-on: ${{ matrix.job.os }}
strategy:
fail-fast: false
matrix:
job:
# NIF version 2.16
- {
target: arm-unknown-linux-gnueabihf,
os: ubuntu-20.04,
nif: "2.16",
use-cross: true,
}
- {
target: aarch64-unknown-linux-gnu,
os: ubuntu-20.04,
nif: "2.16",
use-cross: true,
}
- { target: aarch64-apple-darwin, os: macos-11, nif: "2.16" }
- { target: x86_64-apple-darwin, os: macos-11, nif: "2.16" }
- { target: x86_64-unknown-linux-gnu, os: ubuntu-20.04, nif: "2.16" }
- {
target: x86_64-unknown-linux-musl,
os: ubuntu-20.04,
nif: "2.16",
use-cross: true,
}
- { target: x86_64-pc-windows-gnu, os: windows-2019, nif: "2.16" }
- { target: x86_64-pc-windows-msvc, os: windows-2019, nif: "2.16" }
# NIF version 2.15
- {
target: arm-unknown-linux-gnueabihf,
os: ubuntu-20.04,
nif: "2.15",
use-cross: true,
}
- {
target: aarch64-unknown-linux-gnu,
os: ubuntu-20.04,
nif: "2.15",
use-cross: true,
}
- { target: aarch64-apple-darwin, os: macos-11, nif: "2.15" }
- { target: x86_64-apple-darwin, os: macos-11, nif: "2.15" }
- { target: x86_64-unknown-linux-gnu, os: ubuntu-20.04, nif: "2.15" }
- {
target: x86_64-unknown-linux-musl,
os: ubuntu-20.04,
nif: "2.15",
use-cross: true,
}
- { target: x86_64-pc-windows-gnu, os: windows-2019, nif: "2.15" }
- { target: x86_64-pc-windows-msvc, os: windows-2019, nif: "2.15" }
# # NIF version 2.14
- {
target: arm-unknown-linux-gnueabihf,
os: ubuntu-20.04,
nif: "2.14",
use-cross: true,
}
- {
target: aarch64-unknown-linux-gnu,
os: ubuntu-20.04,
nif: "2.14",
use-cross: true,
}
- { target: aarch64-apple-darwin, os: macos-11, nif: "2.14" }
- { target: x86_64-apple-darwin, os: macos-11, nif: "2.14" }
- { target: x86_64-unknown-linux-gnu, os: ubuntu-20.04, nif: "2.14" }
- {
target: x86_64-unknown-linux-musl,
os: ubuntu-20.04,
nif: "2.14",
use-cross: true,
}
- { target: x86_64-pc-windows-gnu, os: windows-2019, nif: "2.14" }
- { target: x86_64-pc-windows-msvc, os: windows-2019, nif: "2.14" }

env:
RUSTLER_NIF_VERSION: ${{ matrix.job.nif }}
steps:
- name: Checkout source code
uses: actions/checkout@v2

- name: Install prerequisites
shell: bash
run: |
case ${{ matrix.job.target }} in
arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
esac
- name: Extract crate information
shell: bash
run: |
echo "PROJECT_NAME=$(sed -n 's/^name = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV
# Get the project version from mix.exs
echo "PROJECT_VERSION=$(sed -n 's/^ @version "\(.*\)"/\1/p' ../../mix.exs | head -n1)" >> $GITHUB_ENV
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: ${{ matrix.job.target }}
override: true
profile: minimal

- name: Show version information (Rust, cargo, GCC)
shell: bash
run: |
gcc --version || true
rustup -V
rustup toolchain list
rustup default
cargo -V
rustc -V
rustc --print=cfg
- name: Download cross from GitHub releases
uses: giantswarm/[email protected]
if: ${{ matrix.job.use-cross }}
with:
binary: "cross"
version: "v0.2.1"
download_url: "https://github.com/rust-embedded/cross/releases/download/${version}/cross-${version}-x86_64-unknown-linux-gnu.tar.gz"
tarball_binary_path: "${binary}"
smoke_test: "${binary} --version"

- name: Build
shell: bash
run: |
if [ "${{ matrix.job.use-cross }}" == "true" ]; then
cross build --release --target=${{ matrix.job.target }}
else
cargo build --release --target=${{ matrix.job.target }}
fi
- name: Rename lib to the final name
id: rename
shell: bash
run: |
LIB_PREFIX="lib"
case ${{ matrix.job.target }} in
*-pc-windows-*) LIB_PREFIX="" ;;
esac;
# Figure out suffix of lib
# See: https://doc.rust-lang.org/reference/linkage.html
LIB_SUFFIX=".so"
case ${{ matrix.job.target }} in
*-apple-darwin) LIB_SUFFIX=".dylib" ;;
*-pc-windows-*) LIB_SUFFIX=".dll" ;;
esac;
CICD_INTERMEDIATES_DIR=$(mktemp -d)
# Setup paths
LIB_DIR="${CICD_INTERMEDIATES_DIR}/released-lib"
mkdir -p "${LIB_DIR}"
LIB_NAME="${LIB_PREFIX}${{ env.PROJECT_NAME }}${LIB_SUFFIX}"
LIB_PATH="${LIB_DIR}/${LIB_NAME}"
# Copy the release build lib to the result location
cp "target/${{ matrix.job.target }}/release/${LIB_NAME}" "${LIB_DIR}"
# Final paths
# In the end we use ".so" for MacOS in the final build
# See: https://www.erlang.org/doc/man/erlang.html#load_nif-2
LIB_FINAL_SUFFIX="${LIB_SUFFIX}"
case ${{ matrix.job.target }} in
*-apple-darwin) LIB_FINAL_SUFFIX=".so" ;;
esac;
LIB_FINAL_NAME="${LIB_PREFIX}${PROJECT_NAME}-v${PROJECT_VERSION}-nif-${RUSTLER_NIF_VERSION}-${{ matrix.job.target }}${LIB_FINAL_SUFFIX}"
# Copy lib to final name on this directory
cp "${LIB_PATH}" "${LIB_FINAL_NAME}"
tar -cvzf "${LIB_FINAL_NAME}.tar.gz" "${LIB_FINAL_NAME}"
# Passes the path relative to the root of the project.
LIB_FINAL_PATH="${NIF_DIRECTORY}/${LIB_FINAL_NAME}.tar.gz"
# Let subsequent steps know where to find the lib
echo ::set-output name=LIB_FINAL_PATH::${LIB_FINAL_PATH}
echo ::set-output name=LIB_FINAL_NAME::${LIB_FINAL_NAME}.tar.gz
- name: "Artifact upload"
uses: actions/upload-artifact@v2
with:
name: ${{ steps.rename.outputs.LIB_FINAL_NAME }}
path: ${{ steps.rename.outputs.LIB_FINAL_PATH }}

- name: Publish archives and packages
uses: softprops/action-gh-release@v1
with:
files: |
${{ steps.rename.outputs.LIB_FINAL_PATH }}
if: startsWith(github.ref, 'refs/tags/')
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v0.2.0 (2022-03-27)

* Now [`rustler_precompiled`](https://hex.pm/packages/rustler_precompiled) as dependency.

## v0.1.2 (2021-09-18)

* Fixed `mix.exs` file to include the rust source files and cargo config
Expand Down
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,29 @@ Elixir bindings for the [human-name](https://crates.io/crates/human_name) crate

## Installation

_Be sure to [install Rust](https://www.rust-lang.org/tools/install)._

This package can be installed by adding `human_name` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[
{:human_name, "~> 0.1.2"}
{:human_name, "~> 0.2.0"}
]
end
```

By default **you do not need Rust installed** because the lib will try to download a precompiled NIF file.

In case you want to force compilation set the
`HUMAN_NAME_BUILD` environment variable to `true` or `1`.

To run tests locally, you could do a `HUMAN_NAME_BUILD=1 mix test`.

Alternatively you can also set the application env `:build_from_source` to `true` in order to force the build:

```elixir
config :human_name, HumanName, build_from_source: true
```

## Usage

```elixir
Expand Down
17 changes: 17 additions & 0 deletions RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Release checklist

In order to release a new version to Hex.pm we first need to:

1. write the changes in the `CHANGELOG.md` file
2. update the `README.md`, `CHANGELOG.md` and `mix.exs` with the new version
3. commit and create a tag for that version
4. push the changes to the repository with: `git push origin master --tags`
5. wait the CI to build all release files
6. run `mix rustler.download HumanName.Native --all --print`
7. copy the output of the mix task and add to the release notes
8. run `mix hex.publish` and **make sure the checksum file is present**
in the list of files to be published.

It's important to ensure that we publish the checksum file with the
package because otherwise the users won't be able to use the lib
with precompiled files. They will need to always enforce compilation.
17 changes: 16 additions & 1 deletion lib/human_name/native.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,22 @@ end

defmodule HumanName.Native do
@moduledoc false
use Rustler, otp_app: :human_name, crate: "human_name_nif"
require Logger

mix_config = Mix.Project.config()
version = mix_config[:version]
github_url = mix_config[:package][:links]["GitHub"]

env_config = Application.get_env(:human_name, HumanName, [])

use RustlerPrecompiled,
otp_app: :human_name,
crate: "human_name_nif",
mode: :release,
base_url: "#{github_url}/releases/download/v#{version}",
force_build:
System.get_env("HUMAN_NAME_BUILD") in ["1", "true"] or env_config[:build_from_source],
version: version

@doc false
def first_initial(_full_name), do: err()
Expand Down
Loading

0 comments on commit 110c953

Please sign in to comment.