{"id":15936116,"url":"https://github.com/lando/leia","last_synced_at":"2025-10-27T20:10:00.382Z","repository":{"id":44993364,"uuid":"159277728","full_name":"lando/leia","owner":"lando","description":"A testing utility that tests code blocks in documentation.","archived":false,"fork":false,"pushed_at":"2025-07-23T20:46:50.000Z","size":605,"stargazers_count":19,"open_issues_count":4,"forks_count":4,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-10-02T12:40:59.882Z","etag":null,"topics":["devops","lando","mocha","testing"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lando.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-11-27T04:49:23.000Z","updated_at":"2025-07-23T20:46:54.000Z","dependencies_parsed_at":"2023-02-07T03:46:14.782Z","dependency_job_id":"6dcbb420-1605-4793-8937-18324dd0d1fc","html_url":"https://github.com/lando/leia","commit_stats":{"total_commits":139,"total_committers":8,"mean_commits":17.375,"dds":0.5755395683453237,"last_synced_commit":"ed4e8a3942a401e87abddc97b009313fe8bab3f5"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/lando/leia","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lando%2Fleia","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lando%2Fleia/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lando%2Fleia/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lando%2Fleia/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lando","download_url":"https://codeload.github.com/lando/leia/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lando%2Fleia/sbom","scorecard":{"id":578367,"data":{"date":"2025-08-11","repo":{"name":"github.com/lando/leia","commit":"1ff94128dd3097268c281a8eebd679149daf1be5"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/15 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":3,"reason":"4 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/label-add-to-project.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/label-add-to-project.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pr-leia-tests.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/pr-leia-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pr-leia-tests.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/pr-leia-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pr-linter.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/pr-linter.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pr-linter.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/pr-linter.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pr-shell-tests.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/pr-shell-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pr-shell-tests.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/pr-shell-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pr-unit-tests.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/pr-unit-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pr-unit-tests.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/pr-unit-tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/lando/leia/release.yml/main?enable=pin","Info:   0 out of  11 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/label-add-to-project.yml:1","Warn: no topLevel permission defined: .github/workflows/pr-leia-tests.yml:1","Warn: no topLevel permission defined: .github/workflows/pr-linter.yml:1","Warn: no topLevel permission defined: .github/workflows/pr-shell-tests.yml:1","Warn: no topLevel permission defined: .github/workflows/pr-unit-tests.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:9"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 20 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"10 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5","Warn: Project is vulnerable to: GHSA-pq67-2wwv-3xjx","Warn: Project is vulnerable to: GHSA-8cj5-5rvv-wf4v","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T18:28:00.315Z","repository_id":44993364,"created_at":"2025-08-20T18:28:00.315Z","updated_at":"2025-08-20T18:28:00.315Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278838434,"owners_count":26054720,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devops","lando","mocha","testing"],"created_at":"2024-10-07T04:04:07.160Z","updated_at":"2025-10-07T20:10:09.156Z","avatar_url":"https://github.com/lando.png","language":"JavaScript","readme":"# Leia\n\nLeia is a testing utility that tests code blocks in documentation. This makes tests easy to write and also ensures documentation is up to date and working. Behind the scenes documentation is parsed and run as a series of `mocha` tests.\n\nLeia will\n\n* Consolidate code examples and tests into a single, easy to understand and write `markdown` file\n* Write functional tests quickly in an accessible and lowest common denominator language (eg `sh/bash/dash` etc)\n* Pass on exit status code `0`, fail on anything else\n* Work cross platform-ish, with some caveats, see [Shell Considerations](#shell-considerations) below\n* Keep [Lando](https://github.com/lando/lando) honest so he can be a real hero who doesn't betray his friends again\n\n## Installation\n\n```bash\n# With npm\nnpm install @lando/leia\n```\n\n## Basics\n\nA _very_ basic example of a valid Leia test is below. It _must_ have a single H1 header, at least one H2 header and then a code block\nwhere the comment is the human readable test description and the command below is the test.\n\n```md\n# Some Example\n\n## Testing\n\n# A description of my test\nthe command i am running\n```\n\n## Usage\n\nYou can invoke `leia` as a command line tool or directly `require` it in a module.\n\n### CLI\n\n```bash\nnpx leia\n\nCleverly converts markdown files into mocha cli tests\n\nUSAGE\n  $ leia \u003cfiles\u003e \u003cpatterns\u003e [--cleanup-header=\u003ccleanup-headers\u003e] [--debug] [--help] [--ignore=\u003cpatterns\u003e] [--retry=\u003ccount\u003e] [--setup-header=\u003csetup-headers\u003e] [--test-header=\u003ctest-headers\u003e]\n  [--shell=\u003cbash|cmd|powershell|pwsh|sh|zsh\u003e] [--stdin] [--timeout=\u003cseconds\u003e] [--version]\n\nARGUMENTS\n  TESTS  files or patterns to scan for test\n\nOPTIONS\n  -c, --cleanup-header=cleanup-header      [default: Clean,Tear,Burn] considers these h2 sections as cleanup commands\n  -i, --ignore=ignore                      files or patterns to ignore\n  -r, --retry=retry                        [default: 1] retries tests the given amount\n  -s, --setup-header=setup-header          [default: Start,Setup,This is the dawning] considers these h2 sections as setup commands\n  -t, --test-header=test-header            [default: Test,Validat,Verif] considers these h2 sections as tests\n  -v, --version                            shows version info\n  --debug                                  shows debug output\n  --help                                   shows help\n  --shell=bash|cmd|powershell|pwsh|sh|zsh  [default: /opt/homebrew/bin/zsh] runs tests with given shell, autodetected by default\n  --stdin                                  attachs stdin when the test is run\n  --timeout=timeout                        [default: 1800] seconds before tests time out\n\nEXAMPLES\n  leia README.md\n  leia README.md \"examples/**/*.md\" --retry 6 --test-header Tizzestin\n  leia \"examples/*.md\" --ignore BUTNOTYOU.md test --stdin --timeout 5\n  leia README.md --shell cmd\n```\n\n### Module\n\n```js\n# Instantiate a new leia\nconst Leia = require('@lando/leia');\nconst leia = new Leia();\n\n// Find some tests\nconst files = leia.find(['examples/**.md']);\n// Parse those files into leia test metadata\nconst sources = leia.parse(files);\n// Generate the mocha tests\nconst tests = leia.generate(sources);\n// Run the tests\nconst runner = leia.run(tests);\nrunner.run((failures) =\u003e process.exitCode = failures ? 1 : 0);\n```\n\nFor more details on specific options check out the code docs\n\n* [leia.find](https://github.com/lando/leia/blob/main/lib/leia.js)\n* [leia.generate](https://github.com/lando/leia/blob/main/lib/leia.js)\n* [leia.parse](https://github.com/lando/leia/blob/main/lib/leia.js)\n* [leia.run](https://github.com/lando/leia/blob/main/lib/leia.js)\n\n## Markdown Syntax\n\nIn order for your `markdown` file to be recognized as containing functional tests it needs to have at least the following\n\n#### 1. A h1 Header\n\n```md\n# Something to identify these tests\n```\n\n#### 2. A h2 Header\n\nBy default our parser will look for a section that beings with the word \"Testing\". This section will contain your tests.\n\n```md\n## Testing\n```\n\nYou can customize the word(s) that `leia` will look for to identify the testing section(s) using the `--test-header` option. You can also run `npm leia --help` to get a list of default words.\n\n#### 3. A code block with at least one command and comment\n\nUnder the above h2 sections you need to have a triple tick [markdown code block](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code) that contains at least one comment and one command. The comment will be the human readable description of what the test does.\n\nHere is a basic code block that runs one test\n\n```bash\n# Should cat a file\ncat test.txt\n```\n\nIf you want to learn more about the syntax and how `leia` puts together the above, check out [this example](https://github.com/lando/leia/blob/main/examples/basic-example.md)\n\n## Skipping\n\nYou can also skip tests. This is useful if you want to stub out a test for later.\n\n```bash\n# Should write this test later and dont want to forget it\nskip\n```\n\n## Environment Variables\n\n`leia` will also set the following environment variables for each test that is running so you can use them for stuff.\n\nHere are the values you would expect for the `Should set envvars with the test number` test in `examples/environment.md` running on Leia version `v1.0.0` with `--retry=1`.\n\n```bash\n# generic vars\nLEIA=true\nLEIA_ENVIRONMENT=true\nLEIA_VERSION=1.0.0\n\n# test vars\nLEIA_TEST_RUNNING=true\nLEIA_TEST_ID=environment\nLEIA_TEST_NUMBER=4\nLEIA_TEST_RETRY=1\nLEIA_TEST_STAGE=test\n```\n\nNote: `LEIA_TEST_STAGE` can be either `setup`, `test` or `cleanup` and `LEIA_TEST_NUMBER` resets to `1` for each `LEIA_TEST_STAGE`.\n\n## Shell considerations\n\n`leia` will autodetect your shell and use a `bashy` one if available.\n\n* On POSIX systems it will prefer `bash` or `zsh` if available with a fallback to `sh`.\n* On Windows systems it will prefer `bash` if available with a fallback to `cmd`.\n\nYou can also explicitly tell `leia` what shell to use with the `--shell` option. However, currently only `bash`, `sh`, `zsh`, `cmd`, `powershell` and `pwsh` are supported options.\n\n**In most use cases it's best to just let `leia` decide the shell to use automatically.**\n\n## Advanced Usage\n\nLeia also allows you to specify additional h2 sections in your `markdown` for setup and cleanup commands that run before and after your core tests. You can tell `leia` what words these headers should start with in order to be flagged as setup and cleanup commands using the `--setup-header` and `--cleanup-header` options.\n\n[Here](https://github.com/lando/leia/blob/main/examples/setup-cleanup-example.md) is an example of a markdown file with Setup, Testing and Cleanup sections. And [here](https://github.com/lando/leia/blob/main/examples) is a whole directory of examples that we test on every commit.\n\n## Issues, Questions and Support\n\nIf you have a question or would like some community support we recommend you [join us on Slack](https://launchpass.com/devwithlando). Note that this is the Slack community for [Lando](https://lando.dev) but we are more than happy to help with this module as well!\n\nIf you'd like to report a bug or submit a feature request then please [use the issue queue](https://github.com/lando/leia/issues/new/choose) in this repo.\n\n## Changelog\n\nWe try to log all changes big and small in both [THE CHANGELOG](https://github.com/lando/leia/blob/main/CHANGELOG.md) and the [release notes](https://github.com/lando/leia/releases).\n\n## Development\n\n* Requires [Node 18+](https://nodejs.org/dist/latest-v18.x/)\n\n```bash\ngit clone https://github.com/lando/leia.git \u0026\u0026 cd leia\nnpm install\n```\n\nIf you dont' want to install Node 18 for whatever reason you can install [Lando](https://docs.lando.dev/basics/installation.html) and use that:\n\n```bash\ngit clone https://github.com/lando/leia.git \u0026\u0026 cd leia\n# Install deps and get node\nlando start\n\n# Run commands\nlando node\nlando npm install\nlando npx leia\n```\n\n## Testing\n\n```bash\n# Lint the code\nnpm run lint\n\n# Run unit tests\nnpm run test:unit\n```\n\n## Releasing\n\nTo deploy and publish a new version of the package to the `npm` registry you need only [create a release on GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository) with a [semver](https://semver.org) tag.\n\nNote that prereleases will get pushed to the `edge` tag on the `npm` registry.\n\n## Maintainers\n\n* [@pirog](https://github.com/pirog)\n* [@reynoldsalec](https://github.com/reynoldsalec)\n\n## Contributors\n\n\u003ca href=\"https://github.com/lando/leia/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=lando/leia\" /\u003e\n\u003c/a\u003e\n\nMade with [contributors-img](https://contrib.rocks).\n\n## Legacy Version\n\nYou can still install the older version of  Leia eg `leia-parser`.\n\n```bash\nnpm install leia-parser\n```\n\nAnd its documentation lives on [here](https://github.com/lando/leia/tree/v0.4.0).\n\n## Other Resources\n\n* [LICENSE](/LICENSE)\n* [TERMS OF USE](https://docs.lando.dev/terms)\n* [PRIVACY POLICY](https://docs.lando.dev/privacy)\n* [CODE OF CONDUCT](https://docs.lando.dev/coc)\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flando%2Fleia","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flando%2Fleia","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flando%2Fleia/lists"}