Skip to content
This repository was archived by the owner on Dec 27, 2025. It is now read-only.

Commit b12c416

Browse files
committed
feat: Extract CLI from probitas monorepo
Split the command-line interface into a standalone package with: - Main entry point and command dispatcher - `run` command for scenario execution with worker pool - `list` command for scenario discovery - Configuration file loader (probitas.json/jsonc) - GitHub Actions workflows for testing and releases
1 parent c8c0882 commit b12c416

28 files changed

+5138
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
name: Release Assets
2+
3+
env:
4+
DENO_VERSION: 2.x
5+
6+
on:
7+
release:
8+
types: [published]
9+
workflow_dispatch:
10+
inputs:
11+
tag:
12+
description: "Release tag to attach assets to (e.g., v0.7.0)"
13+
required: true
14+
type: string
15+
16+
jobs:
17+
build:
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
include:
22+
- target: x86_64-unknown-linux-gnu
23+
os: ubuntu-latest
24+
platform: linux-x86_64
25+
archive: tar.gz
26+
- target: aarch64-unknown-linux-gnu
27+
os: ubuntu-latest
28+
platform: linux-arm64
29+
archive: tar.gz
30+
- target: x86_64-pc-windows-msvc
31+
os: ubuntu-latest
32+
platform: windows-x86_64
33+
archive: zip
34+
- target: x86_64-apple-darwin
35+
os: macos-latest
36+
platform: macos-x86_64
37+
archive: tar.gz
38+
- target: aarch64-apple-darwin
39+
os: macos-latest
40+
platform: macos-arm64
41+
archive: tar.gz
42+
43+
runs-on: ${{ matrix.os }}
44+
timeout-minutes: 30
45+
46+
permissions:
47+
contents: write
48+
49+
steps:
50+
- uses: actions/checkout@v4
51+
52+
- uses: denoland/setup-deno@v2
53+
with:
54+
deno-version: ${{ env.DENO_VERSION }}
55+
56+
- name: Get version from tag
57+
id: version
58+
run: |
59+
TAG="${{ inputs.tag || github.ref_name }}"
60+
# Remove 'v' prefix if present (e.g., v0.7.1 -> 0.7.1)
61+
VERSION="${TAG#v}"
62+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
63+
64+
- name: Update deno.json version
65+
run: |
66+
deno eval "
67+
const path = './deno.json';
68+
const config = JSON.parse(Deno.readTextFileSync(path));
69+
config.version = '${{ steps.version.outputs.version }}';
70+
Deno.writeTextFileSync(path, JSON.stringify(config, null, 2) + '\n');
71+
"
72+
73+
- name: Set archive name
74+
id: archive
75+
run: |
76+
echo "name=probitas-${{ steps.version.outputs.version }}-${{ matrix.platform }}.${{ matrix.archive }}" >> "$GITHUB_OUTPUT"
77+
78+
- name: Compile binary
79+
shell: bash
80+
run: |
81+
mkdir -p dist
82+
if [[ "${{ matrix.archive }}" == "zip" ]]; then
83+
OUTPUT="dist/probitas.exe"
84+
else
85+
OUTPUT="dist/probitas"
86+
fi
87+
deno compile \
88+
--allow-all \
89+
--unstable-kv \
90+
--target ${{ matrix.target }} \
91+
--output "$OUTPUT" \
92+
./mod.ts
93+
94+
- name: Prepare distribution files
95+
run: |
96+
cp README.md dist/ 2>/dev/null || true
97+
cp LICENSE dist/ 2>/dev/null || true
98+
99+
- name: Create archive (tar.gz)
100+
if: matrix.archive == 'tar.gz'
101+
run: |
102+
tar -czvf ${{ steps.archive.outputs.name }} -C dist .
103+
104+
- name: Create archive (zip)
105+
if: matrix.archive == 'zip'
106+
run: |
107+
cd dist && zip -r ../${{ steps.archive.outputs.name }} .
108+
109+
- name: Upload to release
110+
uses: softprops/action-gh-release@v2
111+
with:
112+
tag_name: ${{ inputs.tag || github.ref_name }}
113+
files: ${{ steps.archive.outputs.name }}

.github/workflows/test.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Test
2+
3+
env:
4+
DENO_VERSION: 2.x
5+
6+
on:
7+
push:
8+
branches:
9+
- main
10+
pull_request:
11+
workflow_dispatch:
12+
13+
jobs:
14+
check:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v6
18+
- uses: denoland/setup-deno@v2
19+
with:
20+
deno-version: ${{ env.DENO_VERSION }}
21+
- run: deno fmt --check
22+
- run: deno lint
23+
- run: deno task check
24+
25+
test:
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v6
29+
- uses: denoland/setup-deno@v2
30+
with:
31+
deno-version: ${{ env.DENO_VERSION }}
32+
- run: deno task test
33+
timeout-minutes: 5

LICENSE

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright 2025 Alisue <[email protected]>
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.
20+

README.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Probitas CLI
2+
3+
Command-line interface for
4+
[Probitas](https://github.com/jsr-probitas/probitas) - a scenario-based testing
5+
& workflow execution framework.
6+
7+
## Installation
8+
9+
```bash
10+
curl -fsSL https://raw.githubusercontent.com/jsr-probitas/cli/main/install.sh | bash
11+
```
12+
13+
Options via environment variables:
14+
15+
```bash
16+
# Install specific version
17+
curl -fsSL https://raw.githubusercontent.com/jsr-probitas/cli/main/install.sh | PROBITAS_VERSION=0.7.1 bash
18+
19+
# Install to custom directory
20+
curl -fsSL https://raw.githubusercontent.com/jsr-probitas/cli/main/install.sh | PROBITAS_INSTALL_DIR=/usr/local/bin bash
21+
```
22+
23+
## Usage
24+
25+
```bash
26+
# Run all scenarios
27+
probitas run
28+
29+
# Run scenarios with specific tag
30+
probitas run -s tag:example
31+
32+
# Run with JSON reporter
33+
probitas run --reporter json
34+
35+
# List scenarios without running
36+
probitas list
37+
38+
# Show help
39+
probitas --help
40+
```
41+
42+
## Commands
43+
44+
### `probitas run [paths...] [options]`
45+
46+
Execute scenario files and report results.
47+
48+
**Options:**
49+
50+
- `--select, -s <pattern>` - Filter scenarios by selector (can repeat)
51+
- `--reporter, -r <type>` - Output format: list, json (default: list)
52+
- `--concurrency, -c <n>` - Max parallel scenarios (0 = unlimited)
53+
- `--max-failures, -f <n>` - Stop after N failures (0 = continue all)
54+
- `--log-level, -l <level>` - Log verbosity: fatal, warning, info, debug
55+
- `--include <glob>` - Include files matching pattern
56+
- `--exclude <glob>` - Exclude files matching pattern
57+
- `--timeout <duration>` - Scenario timeout (e.g., "30s", "5m")
58+
59+
### `probitas list [paths...] [options]`
60+
61+
List discovered scenarios without running them.
62+
63+
**Options:**
64+
65+
- `--select, -s <pattern>` - Filter scenarios by selector
66+
- `--json` - Output as JSON
67+
68+
## Selectors
69+
70+
Selectors filter scenarios by name or tags:
71+
72+
- `login` - Match scenarios with "login" in name
73+
- `tag:api` - Match scenarios tagged with "api"
74+
- `!tag:slow` - Exclude scenarios tagged with "slow"
75+
- `tag:api,tag:critical` - Match both tags (AND)
76+
- Multiple `-s` flags combine with OR logic
77+
78+
## Exit Codes
79+
80+
- `0` - Success (all scenarios passed)
81+
- `1` - Failure (one or more scenarios failed)
82+
- `2` - Usage error (invalid arguments)
83+
- `4` - No scenarios found
84+
85+
## Configuration
86+
87+
Create a `probitas.json` file in your project root:
88+
89+
```json
90+
{
91+
"includes": ["probitas/**/*.probitas.ts"],
92+
"excludes": ["**/*.skip.probitas.ts"],
93+
"reporter": "list",
94+
"maxConcurrency": 4,
95+
"timeout": "30s",
96+
"selectors": ["!tag:wip"]
97+
}
98+
```
99+
100+
## Development
101+
102+
```bash
103+
# Run tests
104+
deno task test
105+
106+
# Run all checks
107+
deno task verify
108+
```
109+
110+
## License
111+
112+
See [LICENSE](LICENSE) file for details.

assets/usage-list.txt

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
probitas list - List available scenarios
2+
3+
Usage: probitas list [options] [paths...]
4+
5+
Arguments:
6+
[paths...] Scenario files or directories
7+
Defaults to current directory
8+
9+
Options:
10+
-h, --help Show help message
11+
--include <pattern> Include pattern for file discovery (can be specified multiple times)
12+
--exclude <pattern> Exclude pattern for file discovery (can be specified multiple times)
13+
-s, --selector <selector> Select scenarios by selector (can be specified multiple times)
14+
Supports ! prefix for negation
15+
--json Output in JSON format
16+
--config <path> Path to config file (deno.json/deno.jsonc)
17+
-r, --reload Reload dependencies before running
18+
19+
Selector Format:
20+
[!][type:]value
21+
22+
Types:
23+
tag - Match by tag (e.g., tag:api)
24+
name - Match by scenario name (default, e.g., Login or name:Login)
25+
26+
Matching is case-insensitive (e.g., "login" matches "Login", "LOGIN", "login")
27+
Multiple selectors with -s: OR logic
28+
Comma-separated within selector: AND logic
29+
! prefix: Negation (exclude matching scenarios)
30+
31+
Examples:
32+
probitas list List all scenarios
33+
probitas list api/ List scenarios in api directory
34+
probitas list test.probitas.ts List specific file
35+
36+
# Filter by file pattern
37+
probitas list --include "e2e/**/*.probitas.ts" List scenarios in e2e directory
38+
probitas list --exclude "**/*.skip.probitas.ts" Exclude skip files
39+
probitas list api/ --include "**/*.test.ts" List test files in api directory
40+
41+
# Select by tag
42+
probitas list -s tag:smoke List scenarios with @smoke tag
43+
probitas list -s tag:smoke -s tag:api List @smoke OR @api tag scenarios
44+
45+
# Select by name
46+
probitas list -s "Login" List scenarios matching "Login"
47+
probitas list -s "Login" -s "API" List matching "Login" OR "API"
48+
49+
# Combine (AND within selector)
50+
probitas list -s "tag:api,tag:critical" List @api AND @critical tags
51+
probitas list -s "tag:api,User" List @api tag AND name containing "User"
52+
53+
# Exclude scenarios using negation
54+
probitas list -s "!tag:slow" List all except @slow tag
55+
probitas list -s "!wip" List all except matching "wip"
56+
probitas list -s "tag:api,!tag:slow" List @api excluding @slow
57+
58+
# Combined with positive selectors
59+
probitas list -s "tag:smoke" -s "!tag:skip" List @smoke OR (NOT @skip)
60+
61+
# Combine file patterns with selectors
62+
probitas list --include "api/**/*.ts" -s "tag:smoke" API files with smoke tag
63+
probitas list --exclude "**/*.skip.ts" -s "!tag:slow" Exclude skip files and slow scenarios
64+
65+
# JSON output
66+
probitas list --json Output as JSON
67+
probitas list --reload Reload dependencies before listing
68+
69+
Note: Uses patterns from config file or defaults to "**/*.probitas.ts"
70+
71+
Documentation: https://jsr-probitas.github.io/documents/

0 commit comments

Comments
 (0)