Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(git rev-parse --show-toplevel)"
cd "$ROOT_DIR"

find_asdf() {
if command -v asdf >/dev/null 2>&1; then
command -v asdf
return 0
fi

for candidate in "$HOME/.asdf/bin/asdf" /opt/homebrew/bin/asdf /usr/local/bin/asdf; do
if [ -x "$candidate" ]; then
echo "$candidate"
return 0
fi
done

local cellar_asdf
cellar_asdf="$(ls -1 /opt/homebrew/Cellar/asdf/*/bin/asdf 2>/dev/null | tail -n 1 || true)"
if [ -n "$cellar_asdf" ] && [ -x "$cellar_asdf" ]; then
echo "$cellar_asdf"
return 0
fi

return 1
}

ASDF_BIN="$(find_asdf || true)"
if [ -z "$ASDF_BIN" ]; then
echo "[pre-commit] asdf was not found; install or expose it on PATH."
exit 1
fi

export ASDF_DATA_DIR="${ASDF_DATA_DIR:-$HOME/.asdf}"
ERLANG_DIR="$("$ASDF_BIN" where erlang 2>/dev/null || true)"
ELIXIR_DIR="$("$ASDF_BIN" where elixir 2>/dev/null || true)"

if [ -z "$ERLANG_DIR" ] || [ -z "$ELIXIR_DIR" ]; then
echo "[pre-commit] Erlang/Elixir versions are not installed for this repo. Run 'asdf install'."
exit 1
fi

export PATH="$ERLANG_DIR/bin:$ELIXIR_DIR/bin:$PATH"

if ! mix hex.info >/dev/null 2>&1; then
echo "[pre-commit] Bootstrapping Hex/Rebar..."
mix local.hex --force >/dev/null
mix local.rebar --force >/dev/null
fi

echo "[pre-commit] Running test suite..."
mix test

echo "[pre-commit] Running Credo..."
mix credo --strict

echo "[pre-commit] Running Dialyzer..."
mix dialyzer

echo "[pre-commit] All checks passed."
89 changes: 15 additions & 74 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,79 +5,20 @@ on:
push:
branches:
- main
- "codex/**"

jobs:
test-matrix:
name: Test (Elixir ${{ matrix.elixir }} / OTP ${{ matrix.otp }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- elixir: "1.17.3"
otp: "26.2"
- elixir: "1.18.4"
otp: "27.3"

defaults:
run:
working-directory: project

steps:
- uses: actions/checkout@v4

- name: Setup Elixir
uses: erlef/setup-beam@v1
with:
elixir-version: ${{ matrix.elixir }}
otp-version: ${{ matrix.otp }}

- name: Cache deps and build
uses: actions/cache@v4
with:
path: |
project/deps
project/_build
key: ${{ runner.os }}-${{ matrix.elixir }}-${{ matrix.otp }}-${{ hashFiles('project/mix.lock') }}

- name: Install dependencies
run: mix deps.get

- name: Run CI gate
run: mix ci

- name: Run tests
run: mix test

static-analysis:
name: Static Analysis
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

defaults:
run:
working-directory: project

steps:
- uses: actions/checkout@v4

- name: Setup Elixir
uses: erlef/setup-beam@v1
with:
elixir-version: "1.18.4"
otp-version: "27.3"

- name: Install dependencies
run: mix deps.get

- name: Format check
run: mix format --check-formatted

- name: Compile with warnings as errors
run: mix compile --warnings-as-errors

- name: Credo
run: mix credo --strict

- name: Dialyzer
run: mix dialyzer --format short
jobs:
lint:
name: Lint
uses: agentjido/github-actions/.github/workflows/elixir-lint.yml@main

test:
name: Test
uses: agentjido/github-actions/.github/workflows/elixir-test.yml@main
with:
otp_versions: '["27", "28"]'
elixir_versions: '["1.18", "1.19"]'
test_command: mix test
119 changes: 26 additions & 93 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,98 +3,31 @@ name: Release
on:
workflow_dispatch:
inputs:
version:
description: "Version to release (for example 0.1.1)"
required: true
type: string
push:
tags:
- "v*"
dry_run:
description: "Dry run (no git push, no tag, no GitHub release, no Hex publish)"
required: false
type: boolean
default: false
hex_dry_run:
description: "Hex dry run only (run all git/release steps, but skip actual Hex publish)"
required: false
type: boolean
default: false
skip_tests:
description: "Skip tests before release"
required: false
type: boolean
default: false

permissions:
contents: write

jobs:
verify:
runs-on: ubuntu-latest
defaults:
run:
working-directory: project

steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
elixir-version: "1.18.4"
otp-version: "27.3"
- run: mix deps.get
- run: mix ci

create-notes:
runs-on: ubuntu-latest
needs: verify
defaults:
run:
working-directory: project

steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
elixir-version: "1.18.4"
otp-version: "27.3"
- run: mix deps.get
- name: Update changelog
run: mix jido.changelog --version "${{ github.ref_name }}"
- name: Generate release notes
run: mix jido.release_notes --version "${{ github.ref_name }}"
- name: Upload release artifacts
uses: actions/upload-artifact@v4
with:
name: release-notes
path: |
project/CHANGELOG.md
project/RELEASE_NOTES.md

signed-tag:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
needs: verify
steps:
- uses: actions/checkout@v4
- name: Import GPG key
if: ${{ secrets.RELEASE_GPG_PRIVATE_KEY != '' && secrets.RELEASE_GPG_PASSPHRASE != '' }}
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.RELEASE_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.RELEASE_GPG_PASSPHRASE }}
- name: Create signed tag
if: ${{ secrets.RELEASE_GPG_PRIVATE_KEY != '' && secrets.RELEASE_GPG_PASSPHRASE != '' }}
run: |
VERSION="v${{ github.event.inputs.version }}"
git tag -s "$VERSION" -m "Release $VERSION"
git push origin "$VERSION"

publish:
runs-on: ubuntu-latest
needs: create-notes
defaults:
run:
working-directory: project

steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
elixir-version: "1.18.4"
otp-version: "27.3"
- run: mix deps.get
- name: Build docs
run: mix docs
- name: Publish package to Hex
if: ${{ secrets.HEX_API_KEY != '' }}
env:
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
run: mix hex.publish --yes
- name: Publish docs to HexDocs
if: ${{ secrets.HEX_API_KEY != '' }}
env:
HEX_API_KEY: ${{ secrets.HEX_API_KEY }}
run: mix hex.publish docs --yes
release:
name: Release
uses: agentjido/github-actions/.github/workflows/elixir-release.yml@main
with:
dry_run: ${{ inputs.dry_run }}
hex_dry_run: ${{ inputs.hex_dry_run }}
skip_tests: ${{ inputs.skip_tests }}
secrets: inherit