dsh-jenkins
开发工具 活跃维护

dsh-jenkins

jsoncode/dsh-jenkins

支持可视化配置多台Jenkins服务器与Token,支持模型工具触发构建,提供工作区级Jenkins Job执行入口,全TypeScript编写无硬编码路径,界面中英双语跟随主系统,可发布至npm或GitHub。

0
Stars 标星
0
Forks 分支
0
Watchers 关注
0
Open Issues
JavaScript
主要语言
None
开源协议
1.1 MB
仓库大小
1 个月前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:jsoncode/dsh-jenkins
git clone https://github.com/jsoncode/dsh-jenkins.git
git clone git@github.com:jsoncode/dsh-jenkins.git
README.md master

dsh-jenkins

A DeepSeek Harness plugin (dual-face: host + browser) for managing multiple Jenkins
servers and triggering jobs — from a Settings page, from model tools, and from a
per-workspace "Run Jenkins Job" entry. No hardcoded paths, TypeScript throughout,
publishable to npm / GitHub. UI copy is bilingual (Chinese / English, following the host UI language).

中文文档

Features

  • Settings → Jenkins Config page (settings.section): add / edit / delete
    multiple servers (URL, username, Token), test connections, skip TLS verification.
    Only Server URL and Token are required (username defaults to admin).
  • Workspace entry (sidebar.footer.action): a footer group with the Jenkins
    logo button
    (opens the Run Jenkins Job modal) and a History button (clock
    icon, publish history of the last 50 runs across all workspaces, filterable by
    workspace — defaults to All) appears when the current workspace root contains a
    dsh-jenkins.{json,js,ts} config file.
    The modal has searchable dropdowns for server / job, a parameter form
    pre-filled from the config, build triggering, and status polling (queued →
    building → result, with a 10-minute timeout). The server dropdown shows the
    intersection of the servers referenced by the config and the servers configured
    in the plugin
    ; selecting a server auto-selects the configured job and echoes its
    parameters. The last submitted server / job / parameters are remembered per
    workspace and auto-echoed the next time the modal opens (browser localStorage).
    A missing or invalid config file is treated as "not configured" — no entry is shown.
  • Model tools (docs/develop/basic/tool): dsh_jenkins_build, dsh_jenkins_status.
  • Config (docs/develop/basic/config): Schemastery Config + a settings namespace
    that persists UI edits to $DSH_HOME/settings.yaml (server list stored as JSON text
    to avoid frozen-array pitfalls).
  • Packaging (docs/develop/basic/publish): dsh.bundle + dsh.client(web) manifests.

Structure

├── src/host/*.ts       # Host half source: index.ts (entry), jenkins.ts (curl core), ops.ts (op dispatch), workspace-config.ts, types.ts
├── src/client/*.tsx    # Browser half source (React TSX components): Settings page, footer entry, run-job modal, history modal
├── lib/index.js        # Host half build artifact (tsdown, ESM), committed for git installs
├── lib/client.js       # Browser half build artifact (tsdown → __ModuleLoader__ factory), committed
├── lib/types/          # Type declarations (generated by tsc -b)
├── scripts/            # verify-client.mjs (host-seed simulation check)
├── tsdown.config.ts    # tsdown build config (node half + client bundle banner wrapper)
├── tsconfig.json       # solution: references tsconfig.host.json / tsconfig.client.json
├── cordis.patch.yml    # Bundle patch: plugin row referenced by package name (no paths)
├── package.json        # dsh.bundle + dsh.client(web) manifests + peerDependencies
├── README.md           # This file (English)
└── README.zh.md        # 中文文档

Workspace config file (dsh-jenkins.json / .js / .ts)

Place it in the workspace root. It is an array; each element is one deploy
target (job + server + environments params). .json is parsed directly; .js / .ts
are evaluated with node (CJS module.exports or ESM export default):

[
  {
    "job": "build-app",
    "server": "http://uat.example.com",
    "environments": { "BRANCH": "main", "DEPLOY": false }
  },
  {
    "job": "build-app",
    "server": "http://prod.example.com",
    "environments": { "BRANCH": "release-1.0", "DEPLOY": true }
  }
]
  • Every element requires job (Jenkins job path, e.g. build-app or
    folder/build-app) and server (the server name / id / URL as configured in
    Settings → Jenkins).
  • environments (optional): the parameter map for this target (booleans render as
    checkboxes, everything else as text fields).
  • The modal's server dropdown shows the intersection of the servers referenced
    by the config and the servers configured in the plugin; selecting a server
    auto-selects the matching job (left empty when absent from the Jenkins job list,
    letting the user choose) and echoes its parameters. If the intersection is empty,
    the dropdown degrades to all servers with a hint. A missing or invalid config is
    treated as "not configured" — the entry is hidden.

Installation

# Local development
dsh plugin --profile web add ./dsh-jenkins

# Published: npm / tarball / GitHub
dsh plugin --profile web add dsh-jenkins
dsh plugin --profile web add ./dsh-jenkins-0.1.4.tgz
dsh plugin --profile web add github:you/dsh-jenkins#<sha>

dsh --profile web --dump-config   # verify the layer
dsh --profile web                 # start (restart required for the host half to reload)

Local development dependencies: the host loads index.js through native Node ESM, so
@deepseek-ai/schemastery, @deepseek-ai/dsh-tools and @deepseek-ai/dsh-settings must be
resolvable from the plugin directory (node_modules is gitignored). Either:

  1. run pnpm install inside the plugin directory (these three are declared as
    devDependencies); or
  2. junction the host's flat fallback copies, e.g.:
    New-Item -ItemType Directory "$PWD\node_modules\@deepseek-ai" -Force
    foreach ($p in 'schemastery','dsh-tools','dsh-settings') {
     New-Item -ItemType Junction "$PWD\node_modules\@deepseek-ai\$p" -Target "$env:DSH_HOME\profiles\node_modules\@deepseek-ai\$p"
    }

Static server defaults can also be set in the profile's cordis.patch.yml:

- insert:
    - id: dsh-jenkins
      name: dsh-jenkins
      config:
        servers:
          - id: prod
            name: 生产环境
            baseUrl: https://jenkins.example.com
            username: admin
            token: <API Token or password>
            insecure: false

Publish

The build toolchain is tsc + tsdown (same as @lemcae/dsh-balance and other
similar plugins — no vite): tsc -b type-checks and emits declarations, while
tsdown (Rolldown core) bundles the host half (lib/index.js, ESM) and the
browser half (lib/client.js, single-file CJS __ModuleLoader__ factory with
auto banner wrapping). Dependency management uses pnpm 10 (Node 26; the
pnpm-lock.yaml is committed and CI installs with --frozen-lockfile):

pnpm install     # install per pnpm-lock.yaml
pnpm run build   # clean lib → tsc -b (types + declarations) → tsdown (both halves)
pnpm run verify  # simulate the host module table to check lib/client.js (optional)
pnpm publish     # or pnpm pack / git push origin main (lib/ is committed; git installs need no build)

Automated publishing (GitHub Actions)

Pushing a v* tag (pnpm run release bumps the patch version, rebuilds the
artifact, and tags it automatically) triggers
.github/workflows/publish.yml:

  • release job: Setup Node 26 → pnpm install --frozen-lockfile
    pnpm run check (tsc -b) → pnpm run build (tsc -b && tsdown) →
    pnpm pack → creates a GitHub Release (auto-generated changelog, tarball
    attached);
  • publish-npm job: publishes to npm — requires the NPM_TOKEN repository
    secret (Settings → Secrets and variables → Actions); fails fast with a hint
    when it is missing.

Development

Requirements: Node ≥ 26 + pnpm 10 (the packageManager field in
package.json pins the pnpm version).

pnpm install           # devDependencies: typescript, tsdown, @types/react, @deepseek-ai/* type packages, etc.
pnpm run check         # whole-tree TypeScript type check (tsc -b)
pnpm run build         # rebuild both halves after editing source (tsc -b && tsdown)
pnpm run watch         # tsdown watch mode (rebuild on src/client changes)
pnpm run verify        # simulate the host seed table to check lib/client.js loads
  • Host half lives in src/host/; browser half in src/client/ (build entry
    src/client/index.ts, exporting { name, inject, apply } directly);
  • The window.__ModuleLoader__.load factory wrapper of lib/client.js is
    generated by tsdown's banner/intro/footer options (no hand-written wrap
    script);
  • External dependencies in the artifact (react,
    @deepseek-ai/dsh-client-ui-primitives, ...) stay external and resolve from
    the host module table (seed) at runtime.

Implementation notes

  • Jenkins REST via curl.exe through the host shell service: Basic auth + CSRF crumb
    • --data-binary @- (form body over stdin, UTF-8 without BOM); -D - parses status
      and the Location header.
  • Browser ↔ host transport: ctx.remote.commands.execute(sessionId, '/dsh-jenkins <json>'),
    host errors carry a code that the client localizes (fallback to the raw message).
  • Peer dependencies (@deepseek-ai/cordis, dsh-tools, schemastery, dsh-settings,
    dsh-commands, dsh-session, dsh-api-remotes, client runtime/ui-slots/ui-settings/
    cordis-client-runner, react) are resolved by the host at install time.
  • The official deepseek-harness project is not modified; all features use existing
    slots (sidebar.footer.action, settings.section, shell.overlay) and the command
    transport.