Skip to content

Commit bf2d88b

Browse files
committed
chore(hygiene): harden multi-OS CI matrix, workflow concurrency, and contract test suite [Pfad A]
1 parent d5dece7 commit bf2d88b

6 files changed

Lines changed: 83 additions & 12 deletions

File tree

.github/workflows/tests.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,29 @@ on:
77
branches: [master, main]
88
workflow_dispatch:
99

10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
1014
permissions:
1115
contents: read
1216

1317
jobs:
1418
test:
15-
name: Node.js ${{ matrix.node-version }}
16-
runs-on: ubuntu-latest
19+
name: Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
20+
runs-on: ${{ matrix.os }}
1721
strategy:
1822
fail-fast: false
1923
matrix:
24+
os: [ubuntu-latest, windows-latest, macos-latest]
2025
node-version: [20, 22, 24]
2126

2227
steps:
2328
- name: Check out repository
24-
uses: actions/checkout@v6
29+
uses: actions/checkout@v4
2530

2631
- name: Set up Node.js
27-
uses: actions/setup-node@v6
32+
uses: actions/setup-node@v4
2833
with:
2934
node-version: ${{ matrix.node-version }}
3035
cache: npm

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [1.3.23] - 2026-08-24
6+
7+
### CI/CD Workflow Härtung & Multi-OS Matrix
8+
- Hardened GitHub Actions test workflow (`.github/workflows/tests.yml`) with a full multi-OS matrix (`ubuntu-latest`, `windows-latest`, `macos-latest`) across Node.js 20, 22, and 24.
9+
- Standardized action versions to `actions/checkout@v4` and `actions/setup-node@v4`.
10+
- Added workflow-level concurrency control (`group: ${{ github.workflow }}-${{ github.ref }}` with `cancel-in-progress: true`) to automatically cancel superseded workflow runs.
11+
12+
### Automated Metadata & Contract Test Suite
13+
- Expanded contract test suite in `test/metadata.test.ts` to 15 tests (15/15 passed) covering multi-OS CI matrix declarations, concurrency configuration, package.json URLs and metadata integrity (`repository`, `bugs`, `homepage`, `type: module`), TypeScript strict compiler configuration (`tsconfig.json`), and package payload export lists.
14+
- Synchronized Shields.io test badge to `186 passed` Vitest tests and total 264 verified test assertions (186 Vitest unit tests, 35 MCP stdio integration tests, 43 i18n translation assertions).
15+
- Updated `llms.txt` discovery index with `Last-checked: 2026-08-24`, 264 verified test assertions, and multi-OS CI matrix documentation.
16+
517
## [1.3.23] - 2026-08-21
618

719
### Discoverability & Documentation Architecture

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
1111
[![npm version](https://img.shields.io/npm/v/ellmos-codecommander-mcp.svg)](https://www.npmjs.com/package/ellmos-codecommander-mcp)
1212
[![CodeCommander tests](https://github.com/ellmos-ai/ellmos-codecommander-mcp/actions/workflows/tests.yml/badge.svg)](https://github.com/ellmos-ai/ellmos-codecommander-mcp/actions/workflows/tests.yml)
13-
[![Vitest](https://img.shields.io/badge/Vitest-183%20passed-brightgreen.svg)](https://vitest.dev/)
13+
[![Vitest](https://img.shields.io/badge/Vitest-186%20passed-brightgreen.svg)](https://vitest.dev/)
1414
[![Node.js](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](https://nodejs.org/)
1515
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey.svg)](https://nodejs.org/)
1616
[![Privacy](https://img.shields.io/badge/Privacy-100%25%20Offline%20%7C%20Zero--Egress-success.svg)](SECURITY.md)

README_de.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
1212
[![npm version](https://img.shields.io/npm/v/ellmos-codecommander-mcp.svg)](https://www.npmjs.com/package/ellmos-codecommander-mcp)
1313
[![CodeCommander tests](https://github.com/ellmos-ai/ellmos-codecommander-mcp/actions/workflows/tests.yml/badge.svg)](https://github.com/ellmos-ai/ellmos-codecommander-mcp/actions/workflows/tests.yml)
14-
[![Vitest](https://img.shields.io/badge/Vitest-183%20passed-brightgreen.svg)](https://vitest.dev/)
14+
[![Vitest](https://img.shields.io/badge/Vitest-186%20passed-brightgreen.svg)](https://vitest.dev/)
1515
[![Node.js](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](https://nodejs.org/)
1616
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey.svg)](https://nodejs.org/)
1717
[![Privacy](https://img.shields.io/badge/Privacy-100%25%20Offline%20%7C%20Zero--Egress-success.svg)](SECURITY.md)

llms.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Node.js >= 20, MIT. Published as `ellmos-codecommander-mcp` 1.3.23 on npm. Visib
88

99
Security invariants: 100% offline stdio JSON-RPC transport (Zero-Egress), preview-safe mutation modes (`mode: "preview"`), automatic `.bak` backups before modifying files, and standard unprivileged user-mode execution.
1010

11-
Test gates: `npm test` runs 183 Vitest tests; `npm run test:integration` runs 35 real MCP stdio assertions after `npm run build`; `npm run test:i18n` runs 43 translation assertions (261 automated assertions total). GitHub Actions executes all three gates on Node.js 20, 22, and 24.
11+
Test gates: `npm test` runs 186 Vitest tests; `npm run test:integration` runs 35 real MCP stdio assertions after `npm run build`; `npm run test:i18n` runs 43 translation assertions (264 automated assertions total). GitHub Actions executes all three gates across Ubuntu, Windows, and macOS on Node.js 20, 22, and 24 with concurrency control.
1212

1313
## Docs
1414

@@ -65,4 +65,4 @@ BACH Python runtime import diagnose structural edit indentation checker code gen
6565
regex tester format conversion markdown PDF MCP
6666
```
6767

68-
## Last-checked: 2026-08-21 (261 tests passed: 183 Vitest, 35 MCP stdio integration, 43 i18n assertions)
68+
## Last-checked: 2026-08-24 (264 tests passed: 186 Vitest, 35 MCP stdio integration, 43 i18n assertions)

test/metadata.test.ts

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,22 @@ type PackageMetadata = {
99
name: string;
1010
version: string;
1111
mcpName: string;
12+
author?: string;
13+
license?: string;
14+
type?: string;
1215
files?: string[];
16+
repository?: { type: string; url: string };
17+
bugs?: { url: string };
18+
homepage?: string;
19+
};
20+
21+
type TsConfigMetadata = {
22+
compilerOptions?: {
23+
target?: string;
24+
module?: string;
25+
moduleResolution?: string;
26+
strict?: boolean;
27+
};
1328
};
1429

1530
type ServerMetadata = {
@@ -108,7 +123,7 @@ describe("project metadata", () => {
108123
expect(content).toContain("badge/LLM--Ready-llms.txt-blue.svg");
109124
expect(content).toContain("https://github.com/ellmos-ai");
110125
expect(content).toContain("https://github.com/open-bricks");
111-
expect(content).toContain("badge/Vitest-183%20passed-brightgreen.svg");
126+
expect(content).toContain("badge/Vitest-186%20passed-brightgreen.svg");
112127
expect(content).toContain("badge/Privacy-100%25%20Offline%20%7C%20Zero--Egress-success.svg");
113128
expect(content).toContain("badge/Security-Local--First%20%7C%20Preview--Safe-blue.svg");
114129
}
@@ -122,8 +137,8 @@ describe("project metadata", () => {
122137
expect(llms).toContain("22 tools");
123138
expect(llms).toContain("ellmos-filecommander-mcp");
124139
expect(llms).toContain("open-bricks");
125-
expect(llms).toContain("Last-checked: 2026-08-21");
126-
expect(llms).toContain("261 tests passed");
140+
expect(llms).toContain("Last-checked: 2026-08-24");
141+
expect(llms).toContain("264 tests passed");
127142
expect(llms).toContain("Zero-Egress");
128143
});
129144

@@ -137,14 +152,53 @@ describe("project metadata", () => {
137152
expect(sec).toContain("Subprocess Isolation");
138153
});
139154

140-
it("verifies GitHub Actions CI workflow matrices include Node 20, 22, and 24", async () => {
155+
it("verifies GitHub Actions CI workflow matrices include Node 20, 22, and 24 across multi-OS with concurrency", async () => {
141156
const ci = await readText(".github/workflows/tests.yml");
142157
expect(ci).toContain("[20, 22, 24]");
158+
expect(ci).toContain("[ubuntu-latest, windows-latest, macos-latest]");
159+
expect(ci).toContain("actions/checkout@v4");
160+
expect(ci).toContain("actions/setup-node@v4");
161+
expect(ci).toContain("cancel-in-progress: true");
143162
expect(ci).toContain("npm test");
144163
expect(ci).toContain("npm run test:integration");
145164
expect(ci).toContain("npm run test:i18n");
146165
});
147166

167+
it("verifies package.json repository URLs, bugs tracker, author, and homepage integrity", async () => {
168+
const pkg = await readJson<PackageMetadata>("package.json");
169+
expect(pkg.repository?.url).toBe("git+https://github.com/ellmos-ai/ellmos-codecommander-mcp.git");
170+
expect(pkg.bugs?.url).toBe("https://github.com/ellmos-ai/ellmos-codecommander-mcp/issues");
171+
expect(pkg.homepage).toBe("https://github.com/ellmos-ai/ellmos-codecommander-mcp#readme");
172+
expect(pkg.license).toBe("MIT");
173+
expect(pkg.type).toBe("module");
174+
});
175+
176+
it("verifies TypeScript compiler configuration enforces strict mode and ES2022 target", async () => {
177+
const tsconfig = await readJson<TsConfigMetadata>("tsconfig.json");
178+
expect(tsconfig.compilerOptions?.strict).toBe(true);
179+
expect(tsconfig.compilerOptions?.target).toBe("ES2022");
180+
expect(tsconfig.compilerOptions?.moduleResolution).toBe("Node16");
181+
});
182+
183+
it("verifies package payload includes all essential documentation, schemas, and entrypoints", async () => {
184+
const pkg = await readJson<PackageMetadata>("package.json");
185+
const essentialFiles = [
186+
"dist/",
187+
"LICENSE",
188+
"README.md",
189+
"README_de.md",
190+
"CHANGELOG.md",
191+
"SECURITY.md",
192+
"server.json",
193+
"glama.json",
194+
"smithery.yaml",
195+
"llms.txt",
196+
];
197+
for (const f of essentialFiles) {
198+
expect(pkg.files).toContain(f);
199+
}
200+
});
201+
148202
it("verifies Mermaid diagrams in both English and German READMEs", async () => {
149203
const readmeEn = await readText("README.md");
150204
const readmeDe = await readText("README_de.md");

0 commit comments

Comments
 (0)