Skip to content
Merged
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
132 changes: 132 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,86 +14,218 @@ jobs:
# --------------------------------------------------------------------------
# Elixir / Mix: all umbrella apps
# --------------------------------------------------------------------------
_elixir-self-hosted:
name: "Elixir tests (self-hosted)"
runs-on: [self-hosted, ubuntu-latest]
continue-on-error: true
timeout-minutes: 15
outputs:
passed: ${{ steps.mark.outputs.passed }}
steps:
- uses: actions/checkout@v4

- uses: erlef/setup-beam@v1
with:
otp-version: "27"
elixir-version: "1.17"

- name: Install dependencies (excluding musician_tui — ratatouille→ex_termbox uses removed Python imp module)
run: mix deps.get --exclude-apps musician_tui

- name: Remove broken transitive deps and update lock
run: |
rm -rf deps/ex_termbox deps/ratatouille _build/MIX/@lib/musician_tui 2>/dev/null || true
mix lock --remove ratatouille 2>/dev/null || true

- name: Run tests with coverage and generate XML
run: bash .github/workflows/gen-coverage.sh

- name: Check coverage thresholds
run: elixir .github/workflows/check-coverage.exs

- id: mark
if: success()
run: echo "passed=true" >> "$GITHUB_OUTPUT"

elixir:
name: Elixir tests
needs: _elixir-self-hosted
if: always()
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Route
run: echo "self-hosted passed=${{ needs._elixir-self-hosted.outputs.passed }}"

- uses: actions/checkout@v4
if: needs._elixir-self-hosted.outputs.passed != 'true'

- uses: erlef/setup-beam@v1
if: needs._elixir-self-hosted.outputs.passed != 'true'
with:
otp-version: "27"
elixir-version: "1.17"

- name: Install dependencies (excluding musician_tui — ratatouille→ex_termbox uses removed Python imp module)
if: needs._elixir-self-hosted.outputs.passed != 'true'
run: mix deps.get --exclude-apps musician_tui

- name: Remove broken transitive deps and update lock
if: needs._elixir-self-hosted.outputs.passed != 'true'
run: |
rm -rf deps/ex_termbox deps/ratatouille _build/MIX/@lib/musician_tui 2>/dev/null || true
mix lock --remove ratatouille 2>/dev/null || true

- name: Run tests with coverage and generate XML
if: needs._elixir-self-hosted.outputs.passed != 'true'
run: bash .github/workflows/gen-coverage.sh

- name: Check coverage thresholds
if: needs._elixir-self-hosted.outputs.passed != 'true'
run: elixir .github/workflows/check-coverage.exs

# --------------------------------------------------------------------------
# Node.js: tests + archgate ADR check
# --------------------------------------------------------------------------
_node-self-hosted:
name: "Node.js tests & ADR check (self-hosted)"
# archgate ships no linux/arm64 binary; route to the macOS (darwin/arm64) self-hosted runner where it is supported.
runs-on: [self-hosted, macOS]
continue-on-error: true
timeout-minutes: 15
outputs:
passed: ${{ steps.mark.outputs.passed }}
steps:
- uses: actions/checkout@v4

- uses: jdx/mise-action@v2
with:
cache: true

- name: Install Node.js dependencies
run: npm ci --ignore-scripts

- name: Run tests with coverage
run: npx vitest run --coverage

- name: Archgate ADR compliance check
run: npx --yes archgate@latest check

- id: mark
if: success()
run: echo "passed=true" >> "$GITHUB_OUTPUT"

node:
name: Node.js tests & ADR check
needs: _node-self-hosted
if: always()
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Route
run: echo "self-hosted passed=${{ needs._node-self-hosted.outputs.passed }}"

- uses: actions/checkout@v4
if: needs._node-self-hosted.outputs.passed != 'true'

- uses: jdx/mise-action@v2
if: needs._node-self-hosted.outputs.passed != 'true'
with:
cache: true

- name: Install Node.js dependencies
if: needs._node-self-hosted.outputs.passed != 'true'
run: npm ci --ignore-scripts

- name: Run tests with coverage
if: needs._node-self-hosted.outputs.passed != 'true'
run: npx vitest run --coverage

- name: Archgate ADR compliance check
if: needs._node-self-hosted.outputs.passed != 'true'
run: npx --yes archgate@latest check

# --------------------------------------------------------------------------
# Python: pipeline runner tests + lint
# --------------------------------------------------------------------------
_python-self-hosted:
name: "Python pipeline-runner (self-hosted)"
runs-on: [self-hosted, ubuntu-latest]
continue-on-error: true
timeout-minutes: 10
defaults:
run:
working-directory: tools/pipeline_runner
outputs:
passed: ${{ steps.mark.outputs.passed }}
steps:
- uses: actions/checkout@v4

- uses: jdx/mise-action@v2
with:
cache: true

- name: Install Poetry
run: pipx install poetry

- name: Install dependencies
run: poetry install --no-interaction

- name: Ruff lint
run: poetry run ruff check .

- name: Mypy type check
run: poetry run mypy pipeline_runner

- name: Run tests
run: poetry run pytest --tb=short

- id: mark
if: success()
working-directory: ${{ github.workspace }}
run: echo "passed=true" >> "$GITHUB_OUTPUT"

python:
name: Python pipeline-runner
needs: _python-self-hosted
if: always()
runs-on: ubuntu-latest
timeout-minutes: 10
defaults:
run:
working-directory: tools/pipeline_runner

steps:
- name: Route
working-directory: ${{ github.workspace }}
run: echo "self-hosted passed=${{ needs._python-self-hosted.outputs.passed }}"

- uses: actions/checkout@v4
if: needs._python-self-hosted.outputs.passed != 'true'

- uses: jdx/mise-action@v2
if: needs._python-self-hosted.outputs.passed != 'true'
with:
cache: true

- name: Install Poetry
if: needs._python-self-hosted.outputs.passed != 'true'
run: pipx install poetry

- name: Install dependencies
if: needs._python-self-hosted.outputs.passed != 'true'
run: poetry install --no-interaction

- name: Ruff lint
if: needs._python-self-hosted.outputs.passed != 'true'
run: poetry run ruff check .

- name: Mypy type check
if: needs._python-self-hosted.outputs.passed != 'true'
run: poetry run mypy pipeline_runner

- name: Run tests
if: needs._python-self-hosted.outputs.passed != 'true'
run: poetry run pytest --tb=short

# --------------------------------------------------------------------------
Expand Down
Loading