Skip to content

feat(cli): generate through installed WASM backends #1692

feat(cli): generate through installed WASM backends

feat(cli): generate through installed WASM backends #1692

Workflow file for this run

name: CI
on:
push:
branches:
- main
- setup/**
pull_request:
branches:
- main
# Cancel in-progress runs when a new run supersedes them. Pull requests are keyed
# by number rather than by head branch: two forks can both offer a branch called
# `main`, and keying on the branch name would let one fork's push cancel the
# other's run.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
jobs:
# Detect what files changed to enable fast-path for docs-only changes
changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
rust: ${{ steps.filter.outputs.rust }}
docs: ${{ steps.filter.outputs.docs }}
release: ${{ steps.filter.outputs.release }}
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Check for file changes
uses: dorny/paths-filter@v4
id: filter
with:
filters: |
rust:
- 'Cargo.toml'
- 'Cargo.lock'
- 'crates/**'
# crates/morphir path-depends on crates inside this submodule,
# so a ref bump changes compiled source
- 'ecosystem/morphir-rust'
# crates/morphir tests the configured Elm process extension
- 'ecosystem/morphir-elm'
# crates/morphir acquires and runs the Scala Elm process extension
- 'ecosystem/morphir-scala'
- '.gitmodules'
# pins the Rust toolchain these jobs build with
- '.config/mise/**'
# generated CLI docs are diff-checked against the CLI source
- 'docs/cli/**'
- 'docs/man/**'
- 'completions/**'
# asserts every workspace package follows the current Rust baseline
- 'tests/rust/test_workspace_rust_baseline.py'
- '.github/workflows/ci.yml'
docs:
- 'website/**'
- 'docs/**'
- '**/*.md'
# the script the Docs job runs
- '.config/mise/tasks/ci/validate_docs.py'
- '.github/workflows/ci.yml'
release:
- '.github/workflows/release.yml'
- 'Cargo.toml'
- 'Cargo.lock'
- 'crates/morphir/Cargo.toml'
- 'tests/ci/test_release_workflow.py'
- 'tests/ci/test_scala_extension_workflow.py'
- 'tests/ci/test_select_release_assets.py'
- '.github/scripts/select_release_assets.py'
- '.github/workflows/ci.yml'
# morphir: CLI tool (depends on extism via morphir-daemon)
morphir-cli:
name: morphir CLI
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.rust == 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Install mise
uses: jdx/mise-action@v4
- name: Initialize environment
run: mise run init -- --ci
- name: Add Rust components
run: rustup component add rustfmt clippy
- name: Set up GraalVM for the Morphir Scala provider
uses: graalvm/setup-graalvm@v1
with:
java-version: "25"
distribution: graalvm-community
github-token: ${{ secrets.GITHUB_TOKEN }}
native-image-job-reports: "true"
- name: Cache Scala dependencies
uses: coursier/cache-action@v8
- name: Install Morphir Elm tools
env:
MISE_AUTO_INSTALL: "false"
run: |
mise -C ecosystem/morphir-elm install
test "$(mise -C ecosystem/morphir-elm exec -- bun --version)" = "1.4.0"
test "$(mise -C ecosystem/morphir-elm exec -- elm --version)" = "0.19.1"
- name: Install Morphir Elm dependencies
env:
MISE_AUTO_INSTALL: "false"
run: >-
mise -C ecosystem/morphir-elm exec --
bun install --frozen-lockfile --ignore-scripts
- name: Build Morphir Elm process extension
env:
MISE_AUTO_INSTALL: "false"
run: mise -C ecosystem/morphir-elm run build:mep-extension
- name: Build Morphir Scala Elm process extension
working-directory: ecosystem/morphir-scala
run: |
./mill --no-server --ticker false \
morphir.langkit.elm.compiler.mep.jvm.nativeImage
provider_version=$(./mill --no-server --ticker false show \
morphir.langkit.elm.compiler.mep.jvm.mepProviderVersion |
python3 -c 'import json, sys; print(json.load(sys.stdin))')
printf 'MORPHIR_SCALA_ELM_EXTENSION_VERSION=%s\n' \
"$provider_version" >> "$GITHUB_ENV"
- name: Cache cargo
uses: Swatinem/rust-cache@v2
with:
workspaces: ". -> target"
key: morphir-cli
- name: Check formatting
run: cargo fmt --package morphir --package integration-tests --check
- name: Run clippy
run: cargo clippy --locked --package morphir --package integration-tests --all-targets -- -D warnings
- name: Run tests
run: cargo test --locked --package morphir
- name: Build
run: cargo build --locked --release --package morphir
- name: Run Morphir Elm CLI integration tests
env:
MORPHIR_ELM_EXTENSION_BIN: >-
${{ github.workspace }}/ecosystem/morphir-elm/dist/morphir-elm-extension/morphir-elm-extension
run: |
cargo test --locked --package integration-tests --test elm_extension \
-- --ignored --nocapture
cargo test --locked --package morphir --test cli_integration \
real_installed_morphir_elm_is_verified_and_activates_offline \
-- --ignored --nocapture
- name: Run Morphir Scala Elm CLI integration test
env:
MORPHIR_SCALA_ELM_EXTENSION_BIN: >-
${{ github.workspace }}/ecosystem/morphir-scala/out/morphir/langkit/elm/compiler/mep/jvm/nativeImage.dest/native-executable
run: >-
cargo test --locked --package morphir --test cli_integration
real_installed_morphir_scala_elm_is_selected_and_activates_offline
-- --ignored --exact --nocapture
- name: Run CLI integration tests
# integration-tests finds the CLI binary in target/release/morphir
run: cargo test --locked --package integration-tests
- name: Generate CLI docs
run: mise run docs:cli
- name: Check CLI docs are up to date
run: |
# --ignored=matching also surfaces generated outputs that a
# .gitignore rule would silently keep out of the repository
CHANGES=$(git status --porcelain --ignored=matching -- docs/cli docs/man completions)
if [ -n "$CHANGES" ]; then
echo "::error::Generated CLI documentation is out of date or untracked. Run 'mise run docs:cli' and commit the changes."
echo "$CHANGES"
git diff -- docs/cli docs/man completions
exit 1
fi
# Docs: lightweight job for documentation changes (fast-path)
# Note: This job intentionally does NOT install mise to stay fast
docs:
name: Docs
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.docs == 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Validate documentation
run: python3 .config/mise/tasks/ci/validate_docs.py
release-workflow:
name: Release workflow
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.release == 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Validate release workflow
run: python3 -B -m unittest discover -s tests/ci
check:
name: All Checks
runs-on: ubuntu-latest
needs: [changes, morphir-cli, docs, release-workflow]
if: always()
steps:
- name: Check results
run: |
# Check if rust jobs were required and passed
if [[ "${{ needs.changes.outputs.rust }}" == "true" ]]; then
if [[ "${{ needs.morphir-cli.result }}" != "success" ]]; then
echo "morphir-cli failed"
exit 1
fi
fi
# Check if docs job was required and passed
if [[ "${{ needs.changes.outputs.docs }}" == "true" ]]; then
if [[ "${{ needs.docs.result }}" != "success" ]]; then
echo "docs failed"
exit 1
fi
fi
if [[ "${{ needs.changes.outputs.release }}" == "true" ]]; then
if [[ "${{ needs.release-workflow.result }}" != "success" ]]; then
echo "release workflow validation failed"
exit 1
fi
fi
echo "All required checks passed!"