@perrylink/dsh-test-kit 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/action.yml ADDED
@@ -0,0 +1,160 @@
1
+ name: 'dsh-test-kit smoke'
2
+ description: 'Drive a DeepSeek Harness plugin target through an isolated install/patch/boot/uninstall loop outside DSH and emit Markdown + JUnit reports. Fails on fail/partial/unknown verdicts — placeholder or unknown JSON is never treated as success.'
3
+ author: 'PerryLink'
4
+
5
+ inputs:
6
+ target:
7
+ description: 'Plugin target: github:owner/repo#sha, git+https://..., npm:name, a local path, or a .tgz tarball.'
8
+ required: true
9
+ headless-task:
10
+ description: 'One-shot task for the boot-smoke stage. Empty (default) skips the smoke stage; install, patch, and uninstall still run.'
11
+ required: false
12
+ default: ''
13
+ dsh:
14
+ description: 'The dsh CLI to drive with: an absolute executable path, a bare command on PATH, or npm:<pkg>@<version>.'
15
+ required: false
16
+ default: 'dsh'
17
+ node-version:
18
+ description: 'Node.js version the kit runs on (the CLI needs >=22.19; the action defaults to 24).'
19
+ required: false
20
+ default: '24'
21
+ kit-version:
22
+ description: 'Published dsh-test-kit version used only when the action checkout does not contain the local kit package.'
23
+ required: false
24
+ default: 'latest'
25
+ allow-partial:
26
+ description: 'Treat a partial verdict as success (fail and unknown always fail the job).'
27
+ required: false
28
+ default: 'false'
29
+
30
+ outputs:
31
+ markdown:
32
+ description: 'Path to the Markdown report (PR comment body).'
33
+ value: ${{ steps.render.outputs.markdown }}
34
+ junit:
35
+ description: 'Path to the JUnit XML report (test-reporter input).'
36
+ value: ${{ steps.render.outputs.junit }}
37
+ verdict:
38
+ description: 'Overall verdict: pass, fail, partial, or unknown.'
39
+ value: ${{ steps.render.outputs.verdict }}
40
+ result:
41
+ description: 'Path to the frozen-schema dsh-test-drive/v1 JSON record.'
42
+ value: ${{ steps.run.outputs.result }}
43
+
44
+ runs:
45
+ using: composite
46
+ steps:
47
+ - name: Set up Node.js
48
+ uses: actions/setup-node@v4
49
+ with:
50
+ node-version: ${{ inputs.node-version }}
51
+
52
+ - name: Resolve or build the kit CLI
53
+ id: kit
54
+ shell: bash
55
+ env:
56
+ KIT_VERSION: ${{ inputs.kit-version }}
57
+ run: |
58
+ set -euo pipefail
59
+ # The standalone repository ships a prebuilt lib/cli.js at the action
60
+ # root, so `uses: PerryLink/dsh-test-kit@<ref>` needs no build. If the
61
+ # bundle is missing (a source checkout), build it here; otherwise fall
62
+ # back to the published npm package.
63
+ if [ -f "$GITHUB_ACTION_PATH/lib/cli.js" ]; then
64
+ echo "cli=$GITHUB_ACTION_PATH/lib/cli.js" >> "$GITHUB_OUTPUT"
65
+ exit 0
66
+ fi
67
+
68
+ build_local() {
69
+ local dir="$1"
70
+ echo "Building the local dsh-test-kit package at $dir"
71
+ cd "$dir"
72
+ npm install --no-save --no-package-lock --no-audit --no-fund --ignore-scripts
73
+ npm run build
74
+ echo "cli=$PWD/lib/cli.js" >> "$GITHUB_OUTPUT"
75
+ }
76
+
77
+ if [ -f "$GITHUB_ACTION_PATH/package.json" ] \
78
+ && node -e 'process.exit(require(process.argv[1]).name === "dsh-test-kit" ? 0 : 1)' "$GITHUB_ACTION_PATH/package.json"; then
79
+ build_local "$GITHUB_ACTION_PATH"
80
+ exit 0
81
+ fi
82
+ echo "Installing dsh-test-kit@$KIT_VERSION from npm"
83
+ npm install --no-save --no-package-lock --no-audit --no-fund "dsh-test-kit@$KIT_VERSION"
84
+ echo "cli=$GITHUB_WORKSPACE/node_modules/dsh-test-kit/lib/cli.js" >> "$GITHUB_OUTPUT"
85
+
86
+ - name: Run the isolated test drive
87
+ id: run
88
+ shell: bash
89
+ env:
90
+ KIT_CLI: ${{ steps.kit.outputs.cli }}
91
+ TARGET: ${{ inputs.target }}
92
+ HEADLESS_TASK: ${{ inputs.headless-task }}
93
+ DSH_SPEC: ${{ inputs.dsh }}
94
+ run: |
95
+ set +e
96
+ out="$RUNNER_TEMP/dsh-test-kit"
97
+ mkdir -p "$out"
98
+ args=(run "$TARGET" --dsh "$DSH_SPEC" --json "$out/result.json" --no-fail)
99
+ if [ -n "$HEADLESS_TASK" ]; then
100
+ args+=(--headless-task "$HEADLESS_TASK")
101
+ else
102
+ args+=(--no-smoke)
103
+ fi
104
+ node "$KIT_CLI" "${args[@]}"
105
+ code=$?
106
+ echo "exit=$code" >> "$GITHUB_OUTPUT"
107
+ # No record means the drive never ran (missing dsh, bad target, ...):
108
+ # fail loudly instead of rendering a placeholder.
109
+ if [ ! -f "$out/result.json" ]; then
110
+ echo "::error::dsh-test-kit produced no result record (exit $code)"
111
+ exit "$code"
112
+ fi
113
+ echo "result=$out/result.json" >> "$GITHUB_OUTPUT"
114
+
115
+ - name: Render Markdown and JUnit reports
116
+ id: render
117
+ shell: bash
118
+ env:
119
+ KIT_CLI: ${{ steps.kit.outputs.cli }}
120
+ RESULT: ${{ steps.run.outputs.result }}
121
+ run: |
122
+ set -euo pipefail
123
+ out="$RUNNER_TEMP/dsh-test-kit/reports"
124
+ rendered="$(node "$KIT_CLI" render --input "$RESULT" --out-dir "$out")"
125
+ echo "$rendered"
126
+ node -e '
127
+ const r = JSON.parse(process.argv[1]);
128
+ for (const key of ["markdown", "junit", "verdict"]) {
129
+ console.log(`${key}=${r[key] ?? ""}`);
130
+ }
131
+ ' "$rendered" >> "$GITHUB_OUTPUT"
132
+
133
+ - name: Enforce the verdict
134
+ shell: bash
135
+ env:
136
+ VERDICT: ${{ steps.render.outputs.verdict }}
137
+ ALLOW_PARTIAL: ${{ inputs.allow-partial }}
138
+ run: |
139
+ set -euo pipefail
140
+ case "$VERDICT" in
141
+ pass)
142
+ echo "::notice::dsh-test-kit verdict: pass"
143
+ ;;
144
+ partial)
145
+ if [ "$ALLOW_PARTIAL" = "true" ]; then
146
+ echo "::warning::dsh-test-kit verdict: partial (allowed by allow-partial)"
147
+ else
148
+ echo "::error::dsh-test-kit verdict: partial — the install passed but the patch/smoke/uninstall did not fully verify"
149
+ exit 1
150
+ fi
151
+ ;;
152
+ fail|unknown)
153
+ echo "::error::dsh-test-kit verdict: $VERDICT"
154
+ exit 1
155
+ ;;
156
+ *)
157
+ echo "::error::dsh-test-kit produced no usable verdict (got '${VERDICT:-<empty>}')"
158
+ exit 1
159
+ ;;
160
+ esac