diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..a5817d0 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,65 @@ +name: Coverage + +on: + push: + branches: [main] + paths: + - 'crates/**' + - 'tests/**' + - 'scripts/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'rust-toolchain.toml' + - '.github/workflows/coverage.yml' + pull_request: + branches: [main] + paths: + - 'crates/**' + - 'tests/**' + - 'scripts/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'rust-toolchain.toml' + - '.github/workflows/coverage.yml' + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: coverage-${{ github.ref }} + cancel-in-progress: true + +jobs: + coverage: + name: Linux line coverage + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: 1.97.1 + components: llvm-tools-preview + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@4076c08d76dba979c11a7285295b0716c1d67908 # v2 + with: + tool: cargo-llvm-cov@0.9.1 + - name: Install official Lua compilers + run: bash scripts/install_ci_compilers.sh + - name: Measure workspace and CLI subprocess coverage + run: bash scripts/coverage.sh "${RUNNER_TEMP}/lcov.info" + - name: Retain coverage report + uses: actions/upload-artifact@v4 + with: + name: linux-coverage + path: ${{ runner.temp }}/lcov.info + if-no-files-found: error + retention-days: 7 + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ${{ runner.temp }}/lcov.info + disable_search: true + fail_ci_if_error: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 543392f..9c5cb71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes are documented here. `luad` is a 0.x experimental tool: no dialect is promoted to a supported tier and no interface carries a compatibility promise yet. +## Unreleased + +- Add the project logo and CI, Codecov, release, and dual-license badges to the README. + Publish measured Linux line coverage from the workspace suite and instrumented CLI + subprocesses through a separate coverage workflow. + ## 0.3.0 — 2026-09-18 - Emit closed `prototype` expressions with child prototype paths and physical PC diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 71a0000..346065d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,6 +37,33 @@ update package metadata, CI evidence, release documentation, and the changelog t `scripts/check.sh` runs the aggregate repository checks. It is necessary before handoff, but it is not proof that oracle-backed claims are correct; each work package must also pass its canonical gate. +### Line coverage + +The separate [Coverage workflow](.github/workflows/coverage.yml) runs on hosted Linux +for code, fixture, toolchain, or coverage-workflow changes. It installs the required +official Lua compilers and runs the entire workspace test suite with LLVM +instrumentation, including the CLI subprocesses exercised by integration tests. +It uploads an LCOV report through `codecov/codecov-action@v5`, using the repository's +`CODECOV_TOKEN` Actions secret, and retains a copy as an Actions artifact. Upload +failures fail the coverage job rather than silently leaving stale data. + +For a local report, install the `cargo-llvm-cov` version pinned in that workflow, add +`llvm-tools-preview` to the repository's Rust toolchain with `rustup component add +llvm-tools-preview`, and run: + +```console +bash scripts/coverage.sh +``` + +The report is `artifacts/coverage/lcov.info`. It includes the CLI and libraries; +the `luad-oracle` tooling crate and cargo-llvm-cov's default test/dependency exclusions +are omitted from the report, while their tests still run. The badge measures Linux +line coverage, not branch coverage, semantic correctness, or supported-target status. +Containment tests deliberately terminate child processes, so some coverage writes can +be incomplete. Report merging warns about invalid profiles and retains the valid ones; +it fails if none can be merged. Counters from interrupted processes may be absent. +Coverage tooling is optional for contributors and does not change `scripts/check.sh`. + Dependency changes must also pass the pinned `cargo-deny` policy: ```console diff --git a/README.md b/README.md index 873c6ee..a94f4df 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,17 @@ -# `luad` +

+ + luad: a smiling crescent moon inside a magnifying glass + +

+ +

luad

+ +

+ CI + Codecov coverage + Latest release + License: MIT OR Apache-2.0 +

`luad` reads compiled Lua bytecode and tells you what is in it: the exact format it was built for, the instructions, the constants, the closure bindings, and where every one of @@ -231,8 +244,8 @@ delete the document in the same change and update this index. | [`README.md`](README.md) | What `luad` is, install, first commands, honest limitations, and the documentation index. | 2026-09-18 | Public scope, support status, setup, primary commands, or the documentation set changes. | | [`AGENTS.md`](AGENTS.md) | Binding repository instructions, product-batch boundaries, and safety constraints for coding agents. | 2026-08-27 | Development workflow, proof policy, current priority, or repository invariants change. | | [`ARCHITECTURE.md`](ARCHITECTURE.md) | Crate responsibilities, model boundaries, trust layers, and architectural invariants. | 2026-08-27 | Crates, ownership boundaries, core representations, or evidence layers change. | -| [`CHANGELOG.md`](CHANGELOG.md) | Backward-facing record of released user-visible changes. | 2026-09-18 | Every user-visible change or release; never use it as a forward plan. | -| [`CONTRIBUTING.md`](CONTRIBUTING.md) | Contributor verification commands, test taxonomy, fixture provenance, and definition of done. | 2026-09-17 | Toolchain, test commands, gates, fixture policy, or contribution workflow changes. | +| [`CHANGELOG.md`](CHANGELOG.md) | Backward-facing record of released and unreleased user-visible changes. | 2026-09-18 | Every user-visible change or release; never use it as a forward plan. | +| [`CONTRIBUTING.md`](CONTRIBUTING.md) | Contributor verification commands, test taxonomy, fixture provenance, and definition of done. | 2026-09-18 | Toolchain, test commands, gates, fixture policy, or contribution workflow changes. | | [`PRD.md`](PRD.md) | Product users, firmware-tree workflows, factual analysis boundary, requirements, non-goals, and release outcomes. | 2026-09-06 | Product scope, target users, supported workflows, factual-analysis boundary, or product-level requirements change. | | [`ROADMAP.md`](ROADMAP.md) | Release completion boundary, future researcher outcomes, sequencing, and target support boundaries. | 2026-09-17 | Release scope, dependencies, parallel ownership, acceptance criteria, support boundaries, or exclusions change. | | [`SECURITY.md`](SECURITY.md) | Supported-version policy, the planned 1.0 target matrix, vulnerability reporting, and hostile-input threat model. | 2026-09-16 | Support policy, the planned target matrix, reporting channel, trust boundary, or threat model changes. | diff --git a/scripts/coverage.sh b/scripts/coverage.sh new file mode 100644 index 0000000..84fbaaf --- /dev/null +++ b/scripts/coverage.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "${repo_dir}" +report="${1:-${repo_dir}/artifacts/coverage/lcov.info}" +mkdir -p "$(dirname "${report}")" + +# Apply instrumentation to both the test executables and the CLI they spawn. +coverage_env="$(cargo llvm-cov show-env --sh)" +eval "${coverage_env}" +cargo llvm-cov clean --workspace +cargo build --locked -p luad-cli --bin luad +target_dir="$(cargo metadata --locked --no-deps --format-version 1 | jq -r .target_directory)" +export CARGO_BIN_EXE_luad="${target_dir}/debug/luad" +cargo test --locked --workspace +# Containment tests deliberately kill children, which can interrupt profile writes. +# Retain valid profiles; LLVM still fails if none can be merged. +cargo llvm-cov report --lcov \ + --failure-mode all --ignore-filename-regex '(^|/)crates/luad-oracle/' \ + --output-path "${report}" + +test -s "${report}" +grep -Eq '^SF:.*crates/luad-cli/src/' "${report}" +grep -Eq '^SF:.*crates/luad-core/src/' "${report}" +grep -Eq '^LH:[1-9][0-9]*$' "${report}"