From 59b15b8e2c7101669e9c1cecc4fb86d90718be8c Mon Sep 17 00:00:00 2001 From: Pascal Charbonneau Date: Sat, 28 Feb 2026 08:36:49 -0700 Subject: [PATCH] Sync git hooks and GitHub workflows from jido_skill --- .githooks/pre-commit | 62 ++++++++++++++++++ .github/workflows/ci.yml | 89 +++++-------------------- .github/workflows/release.yml | 119 ++++++++-------------------------- 3 files changed, 103 insertions(+), 167 deletions(-) create mode 100755 .githooks/pre-commit diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..d27ca96 --- /dev/null +++ b/.githooks/pre-commit @@ -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." diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61909c8..b48beb2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index efb5f9f..746b02f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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