Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 28 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ jobs:
packages: ${{ steps.classify.outputs.packages }}
test-packages: ${{ steps.classify.outputs.test-packages }}
typecheck-packages: ${{ steps.classify.outputs.typecheck-packages }}
dependency-policy: ${{ steps.classify.outputs.dependency-policy }}
typecheck-selected: ${{ steps.classify.outputs.typecheck-selected }}
unit-matrix: ${{ steps.test-plan.outputs.unit-matrix }}
unit-selected: ${{ steps.test-plan.outputs.unit-selected }}
daemon: ${{ steps.classify.outputs.daemon }}
web: ${{ steps.classify.outputs.web }}
steps:
Expand Down Expand Up @@ -81,6 +84,8 @@ jobs:
packages: JSON.stringify(scope.packages),
"test-packages": JSON.stringify(scope.testPackages),
"typecheck-packages": JSON.stringify(scope.typecheckPackages),
"dependency-policy": String(scope.dependencyPolicy),
"typecheck-selected": String(scope.typecheckPackages.length > 0),
daemon: String(scope.daemon),
web: String(scope.web),
};
Expand All @@ -107,6 +112,10 @@ jobs:
--timings=.codex-artifacts/ci/timings.json \
--output=.codex-artifacts/ci/test-plan.json)"
printf 'unit-matrix=%s\n' "$unit_matrix" >> "$GITHUB_OUTPUT"
UNIT_MATRIX="$unit_matrix" node --input-type=module <<'NODE' >> "$GITHUB_OUTPUT"
const matrix = JSON.parse(process.env.UNIT_MATRIX);
console.log(`unit-selected=${matrix.include.length > 0}`);
NODE

- name: Publish the immutable test plan for every shard
if: steps.policy.outputs.execution-tier == 'complete' && steps.classify.outputs.mode != 'docs'
Expand Down Expand Up @@ -145,7 +154,7 @@ jobs:
run: node scripts/check-public-repo-safety.mjs

- name: Check scanner boundaries, execution policy, classification, and platform CI gates
run: node --test scripts/check-public-repo-safety.test.mjs scripts/ci/*.test.mjs scripts/native-execution-engines/verify-codex.test.mjs
run: node --test scripts/check-public-repo-safety.test.mjs scripts/ci/*.test.mjs scripts/ci/*.test.ts scripts/native-execution-engines/verify-codex.test.mjs

# Final file scope cannot exclude secrets introduced and later deleted.
- name: Scan Git history for secrets
Expand Down Expand Up @@ -184,7 +193,7 @@ jobs:
dependency-policy:
name: Dependency policy and security checks
needs: scope
if: needs.scope.outputs.execution-tier == 'complete' && needs.scope.outputs.mode != 'docs'
if: needs.scope.outputs.execution-tier == 'complete' && needs.scope.outputs.dependency-policy == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
Expand Down Expand Up @@ -317,7 +326,7 @@ jobs:
typecheck:
name: Typecheck selected packages
needs: [scope, build]
if: ${{ !cancelled() && needs.scope.outputs.execution-tier == 'complete' && needs.scope.outputs.mode != 'docs' && needs.build.result == 'success' }}
if: ${{ !cancelled() && needs.scope.outputs.execution-tier == 'complete' && needs.scope.outputs.typecheck-selected == 'true' && needs.build.result == 'success' }}
runs-on: ubuntu-latest
timeout-minutes: 20
env:
Expand Down Expand Up @@ -357,10 +366,13 @@ jobs:
- name: Typecheck selected packages without rebuilding dependencies
run: node scripts/ci/run-packages.mjs --task=typecheck:ci --packages="$SELECTED_PACKAGES"

- name: Typecheck CI tool tests
run: corepack pnpm typecheck:ci-tests

unit-tests:
name: Unit tests and Web checks (${{ matrix.suite }} ${{ matrix.shard }})
needs: [scope, build]
if: ${{ !cancelled() && needs.scope.outputs.execution-tier == 'complete' && needs.scope.outputs.mode != 'docs' && needs.build.result == 'success' }}
if: ${{ !cancelled() && needs.scope.outputs.execution-tier == 'complete' && needs.scope.outputs.unit-selected == 'true' && needs.build.result == 'success' }}
runs-on: ubuntu-latest
timeout-minutes: 25
strategy:
Expand Down Expand Up @@ -705,37 +717,42 @@ jobs:
LINUX_CONTRACT_RESULT: ${{ needs.daemon-linux-contracts.result }}
MACOS_NATIVE_RESULT: ${{ needs.restricted-command-macos.result }}
DAEMON_SELECTED: ${{ needs.scope.outputs.daemon }}
DEPENDENCY_SELECTED: ${{ needs.scope.outputs.dependency-policy }}
TYPECHECK_SELECTED: ${{ needs.scope.outputs.typecheck-selected }}
UNIT_SELECTED: ${{ needs.scope.outputs.unit-selected }}
shell: bash
run: |
set -euo pipefail
node scripts/ci/execution-policy.mjs --check-quality

- name: Download the shared test plan for coverage verification
if: needs.scope.outputs.execution-tier == 'complete' && (needs.scope.outputs.daemon == 'true' || contains(needs.scope.outputs.test-packages, '"@ling-stack/core"'))
if: ${{ !cancelled() && needs.scope.result == 'success' && needs.scope.outputs.execution-tier == 'complete' && (needs.scope.outputs.daemon == 'true' || contains(needs.scope.outputs.test-packages, '"@ling-stack/core"')) }}
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333
with:
name: ci-test-plan
path: .codex-artifacts/ci

- name: Download all successful shard reports
if: needs.scope.outputs.execution-tier == 'complete' && (needs.scope.outputs.daemon == 'true' || contains(needs.scope.outputs.test-packages, '"@ling-stack/core"'))
- name: Download all shard reports
if: ${{ !cancelled() && needs.scope.result == 'success' && needs.scope.outputs.execution-tier == 'complete' && (needs.scope.outputs.daemon == 'true' || contains(needs.scope.outputs.test-packages, '"@ling-stack/core"')) }}
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333
with:
pattern: ci-test-report-*
merge-multiple: true
path: .codex-artifacts/ci/reports

- name: Verify every planned file passed exactly once and collect timings
if: needs.scope.outputs.execution-tier == 'complete' && (needs.scope.outputs.daemon == 'true' || contains(needs.scope.outputs.test-packages, '"@ling-stack/core"'))
id: test-timings
if: ${{ !cancelled() && needs.scope.result == 'success' && needs.scope.outputs.execution-tier == 'complete' && (needs.scope.outputs.daemon == 'true' || contains(needs.scope.outputs.test-packages, '"@ling-stack/core"')) }}
run: >-
node scripts/ci/test-shard-plan.mjs
--plan=.codex-artifacts/ci/test-plan.json --reports=.codex-artifacts/ci/reports
--output=.codex-artifacts/ci/timings.json

# Only validated default-branch runs publish hints. PRs consume them but
# cannot replace the baseline; all shards use the same uploaded plan.
# Timing evidence can survive an unrelated policy failure; the required
# gate above still fails the job. Only test-complete default-branch runs
# publish hints. PRs consume but cannot replace the shared baseline.
- name: Save trusted default-branch test timings
if: needs.scope.outputs.execution-tier == 'complete' && needs.scope.outputs.mode != 'docs' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
if: ${{ !cancelled() && steps.test-timings.outcome == 'success' && needs.scope.outputs.execution-tier == 'complete' && needs.scope.outputs.mode != 'docs' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830
with:
path: .codex-artifacts/ci/timings.json
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/installer-contracts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ name: Native installer contracts
on:
pull_request:
paths:
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
- apps/desktop/package.json
- apps/desktop/build/installer.nsh
- apps/desktop/build/icon.ico
- scripts/release/verify-nsis-plugins.mjs
- scripts/release/nsis-extractor.mjs
- scripts/ci/desktop-bun-entry.test.mjs
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/model-cache-contracts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
paths:
- scripts/gstack/testsavant-model-*.mjs
- scripts/gstack/testsavant-model-pin.json
- scripts/gstack/testsavant-gs-client.mjs
- scripts/gstack/testsavant-client.mjs
- .github/workflows/model-cache-contracts.yml
workflow_dispatch:

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sync-provider-model-catalog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1
with:
node-version: 22.15.0
node-version: 22.22.1

- name: Check catalog PR synchronization safety
run: node --test scripts/ci/provider-model-catalog-pr.test.mjs
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sync-translation-catalogs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1
with:
node-version: 22.15.0
node-version: 22.22.1
cache: pnpm

- name: Check automation PR selection safety
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/translate-pr-catalogs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1
with:
node-version: 22.15.0
node-version: 22.22.1
cache: pnpm

- name: Install locked dependencies
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ open-source baseline onward.
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and future
release versions will follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.2] - 2026-11-03

### Changed

- Pull requests run checks affected by their complete change set, avoiding unrelated
test suites while retaining full regression for shared infrastructure and scheduled
or manual runs. The CI maintenance guide documents the selection rules.
- Daemon validation avoids repeated workspace setup and idle file workers without
reducing recovery, security or native-platform coverage.

### Fixed

- Selected CI checks fail when skipped or missing, preventing incomplete validation
from appearing successful.

## [0.2.1] - 2026-11-02

### Fixed
Expand Down
6 changes: 4 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,10 @@ use package filters for a scoped change and state which checks ran. The default
Web setup above does not establish that all native or browser test fixtures are
available. CI selects and builds the affected package graph separately.

See [CI maintenance](docs/maintenance/ci.md) for PR scope, scheduled validation,
CodeQL scanning, and rerun policy.
See the [CI maintenance guide](docs/maintenance/ci.md) for PR scope, Draft and
complete quality gates, scheduled validation, CodeQL scanning, and rerun policy,
and the [CI test execution reference](scripts/ci/README.md) for test execution
details.

Web changes should also run:

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.1
0.2.2
2 changes: 1 addition & 1 deletion apps/desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ling-stack/desktop",
"version": "0.2.1",
"version": "0.2.2",
"description": "Ling Stack desktop shell with shared Web UI and Computer Use picture-in-picture.",
"license": "MIT",
"author": "Ling Stack contributors",
Expand Down
Loading
Loading