name: elixir
on:
push:
branches:
- main
tags:
- v*
pull_request:
workflow_dispatch:
inputs:
hex_repo:
description: "hex repo to publish to"
default: staging
required: true
options:
- staging
- prod
permissions:
contents: read
env:
cache_key: init
package_artifact_base: ts_elixir-${{ github.sha }}
is_tag_push: ${{ startsWith(github.ref, 'refs/tags/') }}
is_dispatch: ${{ github.event_name == 'workflow_dispatch' }}
hex_environment: &hex_environment ${{ case(inputs.hex_repo == 'prod', 'hex.pm', startsWith(github.ref, 'refs/tags/'), 'hex.pm', 'staging.hex.pm') }}
latest_elixir: &latest_elixir 1.19.5
latest_otp: &latest_otp 28.4.2
latest_rust: &latest_rust 1.95.0
defaults:
run:
working-directory: ts_elixir
shell: bash
jobs:
build_test:
name: compile, test, static checks (elixir ${{ matrix.elixir.label }}, otp ${{ matrix.otp.label }}, rust ${{ matrix.rust_toolchain.label }}, platform ${{ matrix.platform.name }})
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
elixir:
- version: *latest_elixir
label: latest
otp:
- version: *latest_otp
label: latest
rust_toolchain:
- version: *latest_rust
label: latest
platform:
- name: linux (x86_64)
runner: linux-x86_64-16cpu
triple: x86_64-unknown-linux-gnu
- name: linux (aarch64)
runner: linux-arm64-16cpu
triple: aarch64-unknown-linux-gnu
- name: macos
runner: macos-26
triple: aarch64-apple-darwin
- name: windows (x86_64)
runner: windows-8vcpu
triple: x86_64-pc-windows-msvc
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Cache mix
id: cache-mix
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae with:
path: |
~/.mix
ts_elixir/_build/
ts_elixir/deps/
key: ${{ matrix.platform.triple }}-mix-${{ env.cache_key }}-elixir-${{ matrix.elixir.version }}-otp-${{ matrix.otp.version }}-${{ hashFiles('**/mix.lock') }}
- name: Install elixir
id: install-elixir
uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 with:
otp-version: ${{ matrix.otp.version }}
elixir-version: ${{ matrix.elixir.version }}
- name: Setup rust
id: setup-rust
uses: ./.github/actions/setup-rust
with:
toolchain-version: ${{ matrix.rust_toolchain.version }}
builder-triple: ${{ matrix.platform.triple }}
- name: Install dependencies
run: mix deps.get
- name: Compile dependencies
run: mix deps.compile
- name: Compile (MIX_ENV=dev)
run: mix compile --warnings-as-errors
- name: Compile (MIX_ENV=prod)
run: mix compile --warnings-as-errors
env:
MIX_ENV: prod
- name: Test
run: mix test
env:
TS_RS_TEST_NET: 0
- &detach_cargo_toml
name: Detach Cargo.toml from workspace
working-directory: ts_elixir/native/ts_elixir
run: |
pip install tomli-w
python deworkspace_cargo_toml.py \
--root ../../../Cargo.toml \
--repo_sha ${{ github.sha }} \
< Cargo.toml > Cargo.toml.new
mv Cargo.toml.new Cargo.toml
echo generated Cargo.toml:
cat Cargo.toml
- name: Build Hex package (no publish)
run: mix hex.build --unpack -o tailscale
env:
MIX_ENV: prod
- name: Upload package tarball
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with:
name: ${{ env.package_artifact_base }}-${{ matrix.platform.triple }}
path: ts_elixir/tailscale
arch_independent:
name: arch-independent checks
runs-on: linux-x86_64-16cpu
env:
target_triple: x86_64-unknown-linux-gnu
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Cache mix
id: cache-mix
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae with:
path: |
~/.mix
ts_elixir/_build/
ts_elixir/deps/
key: ${{ env.target_triple }}-mix-${{ env.cache_key }}-elixir-${{ env.latest_elixir }}-otp-${{ env.latest_otp }}-${{ hashFiles('**/mix.lock') }}
- name: Install elixir
id: install-elixir
uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 with:
otp-version: ${{ env.latest_otp }}
elixir-version: ${{ env.latest_elixir }}
- name: Setup rust
id: setup-rust
uses: ./.github/actions/setup-rust
with:
toolchain-version: ${{ env.latest_rust }}
builder-triple: ${{ env.target_triple }}
- name: Install dependencies
run: mix deps.get
- name: Compile dependencies
run: mix deps.compile
- name: Format
run: mix format --check-formatted
- name: Dialyzer
run: mix dialyzer --format github
- name: Credo
run: mix credo list --format oneline
- name: Docs
run: mix docs --warnings-as-errors
- name: Upload docs
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with:
name: exdoc-${{ github.sha }}
path: ts_elixir/doc
retention-days: 7
publish:
name: publish
runs-on: linux-x86_64-16cpu
needs:
- build_test
- arch_independent
if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
environment: *hex_environment
env:
target_triple: x86_64-unknown-linux-gnu
permissions:
attestations: write
id-token: write
contents: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Cache mix
id: cache-mix
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae with:
path: |
~/.mix
ts_elixir/_build/
ts_elixir/deps/
key: ${{ runner.os }}-mix-${{ env.cache_key }}-elixir-${{ env.latest_elixir }}-otp-${{ env.latest_otp }}-${{ hashFiles('**/mix.lock') }}
- name: Install elixir
id: install-elixir
uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 with:
otp-version: ${{ env.latest_otp }}
elixir-version: ${{ env.latest_elixir }}
- name: Setup rust
id: setup-rust
uses: ./.github/actions/setup-rust
with:
toolchain-version: ${{ env.latest_rust }}
builder-triple: ${{ env.target_triple }}
- name: Install dependencies
run: mix deps.get
- name: Compile dependencies
run: mix deps.compile
- name: Download built package
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c with:
name: ${{ env.package_artifact_base }}-${{ env.target_triple }}
path: ts_elixir/tailscale
- name: Generate attestation
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 with:
subject-path: ts_elixir/tailscale
- *detach_cargo_toml
- name: Publish deps to staging.hex.pm
if: ${{ env.hex_environment == 'staging.hex.pm' }}
run: python staging_publish_deps.py
env:
HEX_API_URL: ${{ vars.HEX_API_URL }}
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
- name: Publish (dry run)
run: mix hex.publish --dry-run --yes
env:
HEX_API_URL: ${{ vars.HEX_API_URL }}
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
- name: Publish
run: mix hex.publish --yes
env:
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
HEX_API_URL: ${{ vars.HEX_API_URL }}