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
12 changes: 9 additions & 3 deletions .github/workflows/actions-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,32 @@ jobs:
uses: ./.github/workflows/ci-changes.yml

test:
name: Build action suite
name: Build action suite${{ matrix.node == 26 && ' (Node 26)' || '' }}
needs: changes
if: ${{ needs.changes.outputs.build_action == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [24, 26]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 24
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: actions/build/package-lock.json
- run: npm ci --ignore-scripts
- run: npm ci --ignore-scripts --engine-strict
working-directory: actions/build
- run: npm run lint
working-directory: actions/build
- run: actions/build/node_modules/.bin/playwright install --with-deps chromium
- run: npm test --prefix actions/build
- name: Prepare composite action fixture
if: ${{ matrix.node == 24 }}
run: cp actions/build/test/fixture/package.json actions/build/test/fixture/package-lock.json actions/build/test/fixture/fixture-build.mjs .
- uses: ./actions/build
if: ${{ matrix.node == 24 }}

result:
name: Replica action tests
Expand Down
71 changes: 48 additions & 23 deletions .github/workflows/hub-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ jobs:
uses: ./.github/workflows/ci-changes.yml

rails_test:
name: Rails tests
name: Rails tests${{ matrix.node == 26 && ' (Node 26)' || '' }}
needs: changes
if: ${{ needs.changes.outputs.hub == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [24, 26]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
Expand All @@ -29,13 +33,13 @@ jobs:
working-directory: hub
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version-file: hub/package.json
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: |
hub/package-lock.json
actions/build/package-lock.json
- run: npm ci
- run: npm ci --ignore-scripts --omit=dev
- run: npm ci --engine-strict
- run: npm ci --ignore-scripts --omit=dev --engine-strict
working-directory: actions/build
- run: ../actions/build/node_modules/.bin/playwright install --with-deps chromium
- run: bundle exec vite build
Expand Down Expand Up @@ -119,43 +123,52 @@ jobs:
- run: bin/bundler-audit check --update

typecheck:
name: TypeScript types
name: TypeScript types${{ matrix.node == 26 && ' (Node 26)' || '' }}
needs: changes
if: ${{ needs.changes.outputs.hub == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [24, 26]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version-file: hub/package.json
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: hub/package-lock.json
- run: npm ci
- run: npm ci --engine-strict
- run: npm run typecheck

frontend_lint:
name: Frontend lint
name: Frontend lint${{ matrix.node == 26 && ' (Node 26)' || '' }}
needs: changes
if: ${{ needs.changes.outputs.hub == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [24, 26]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version-file: hub/package.json
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: hub/package-lock.json
- run: npm ci
- run: npm ci --engine-strict
- run: npm run lint

frontend_test_shard:
name: Frontend tests shard ${{ matrix.shard }}/4
name: Frontend tests shard ${{ matrix.shard }}/4${{ matrix.node == 26 && ' (Node 26)' || '' }}
needs: changes
if: ${{ always() }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [24, 26]
shard: [1, 2, 3, 4]
steps:
- name: Require valid suite selection
Expand All @@ -174,28 +187,32 @@ jobs:
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
if: ${{ needs.changes.outputs.hub == 'true' }}
with:
node-version-file: hub/package.json
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: hub/package-lock.json
- run: npm ci
- run: npm ci --engine-strict
if: ${{ needs.changes.outputs.hub == 'true' }}
- run: npm test -- --shard=${{ matrix.shard }}/4
if: ${{ needs.changes.outputs.hub == 'true' }}

frontend_integration_test:
name: Controls and extension tests
name: Controls and extension tests${{ matrix.node == 26 && ' (Node 26)' || '' }}
needs: changes
if: ${{ needs.changes.outputs.hub == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [24, 26]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version-file: hub/package.json
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: hub/package-lock.json
- run: npm ci
- run: npm ci --ignore-scripts --omit=dev
- run: npm ci --engine-strict
- run: npm ci --ignore-scripts --omit=dev --engine-strict
working-directory: actions/build
- run: ../actions/build/node_modules/.bin/playwright install --with-deps chromium
- run: npm run controls:test
Expand Down Expand Up @@ -227,35 +244,43 @@ jobs:
esac

frontend_build:
name: Frontend build
name: Frontend build${{ matrix.node == 26 && ' (Node 26)' || '' }}
needs: changes
if: ${{ needs.changes.outputs.hub == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [24, 26]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version-file: hub/package.json
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: hub/package-lock.json
- run: npm ci
- run: npm ci --engine-strict
- run: npm run build
- run: npm run controls:assets:check
- run: npm run extension:assets:check

storybook_build:
name: Storybook build
name: Storybook build${{ matrix.node == 26 && ' (Node 26)' || '' }}
needs: changes
if: ${{ needs.changes.outputs.hub == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [24, 26]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version-file: hub/package.json
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: hub/package-lock.json
- run: npm ci
- run: npm ci --engine-strict
- run: npm run storybook:build

production_database:
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/learning-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,23 @@ permissions:

jobs:
test:
name: Learning checks
name: Learning checks${{ matrix.node == 26 && ' (Node 26)' || '' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [24, 26]
defaults:
run:
working-directory: packages/learning
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 24
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: packages/learning/package-lock.json
- run: npm ci --ignore-scripts
- run: npm ci --ignore-scripts --engine-strict
- run: npm run schema:check
- run: npm test
- run: npm run demo
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/starter-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,23 @@ permissions:

jobs:
test:
name: Starter checks
name: Starter checks${{ matrix.node == 26 && ' (Node 26)' || '' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [24, 26]
defaults:
run:
working-directory: starter
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 24
node-version: ${{ matrix.node }}
cache: npm
cache-dependency-path: starter/package-lock.json
- run: npm ci
- run: npm ci --engine-strict
- run: npm run format:check
- run: npm run typecheck
- run: npm test
Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ For improvements, explain the problem you want to solve and who would benefit. D

## Set up the development environment

Each Node.js project's `engines.node` declares its supported versions. The existing Hub, Starter, build-action, and Learning CI checks run on both supported Node majors. The devcontainer, production image, and composite build action retain their pinned runtime defaults; choosing another supported major locally does not change them.

### Replica Hub

Replica Hub uses a devcontainer so contributors run the same Ruby, Node, SQLite, GitHub CLI, and Chromium versions.
Expand Down Expand Up @@ -85,7 +87,7 @@ npm test

### Replica learning

The learning package requires Node.js 24, npm, and Git:
The learning package requires npm, Git, and a Node.js version matching `engines.node` in [packages/learning/package.json](packages/learning/package.json):

```sh
cd packages/learning
Expand Down
2 changes: 1 addition & 1 deletion actions/build/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion actions/build/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"type": "module",
"engines": {
"node": "^24.0.0"
"node": "^24.15.0 || ^26.0.0"
},
"scripts": {
"lint": "eslint . && prettier --check .",
Expand Down
6 changes: 5 additions & 1 deletion docs/testing-and-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,14 @@ The [shared selection workflow](../.github/workflows/ci-changes.yml) calls [the
| Root contributor documents, shared and Hub guides, skills, and documentation assets | Neither |
| Workflow changes, selector changes, and unclassified paths | Both |

The workflows preserve the existing required check names; skipping an entire workflow with a path filter could leave those checks pending. Static jobs use job-level conditions. The four required Vitest shard jobs always expand their matrix and validate selection, but skip checkout, setup, and tests when Hub is unaffected. The required `Frontend tests`, `Production image`, and `Replica action tests` result jobs accept omitted work only after successful selection explicitly excluded it. The production-image matrix checks AMD64 and ARM64 independently without cancelling the other architecture on failure. Selection failures, invalid outputs, and failures in selected suites fail those result checks. Keep required-check configuration unchanged.
The workflows preserve the existing required check names; skipping an entire workflow with a path filter could leave those checks pending. Static jobs use job-level conditions. The Vitest shard jobs always expand their Node and shard matrix and validate selection, but skip checkout, setup, and tests when Hub is unaffected. The required `Frontend tests`, `Production image`, and `Replica action tests` result jobs accept omitted work only after successful selection explicitly excluded it. The frontend and build-action result jobs require every selected Node version to pass. The production-image matrix checks AMD64 and ARM64 independently without cancelling the other architecture on failure. Selection failures, invalid outputs, and failures in selected suites fail those result checks. Keep required-check configuration unchanged.

When adding a shared dependency or a new project, update the selector and its behavioral tests together. Unclassified paths deliberately run both suites until their dependencies are known. Run `node --test scripts/select-ci-suites.test.mjs` and `ruby scripts/check-ci-workflows.rb` from the repository root. The latter reads the actual workflow gates and checks their success, failure, cancellation, and missing-output behavior; both commands run before CI selects suites. Check changed workflows with `actionlint` when available. Actual job skipping and check reporting still need verification on GitHub after publishing.

Existing Node-dependent jobs in Hub, Starter, build-action, and Learning CI use a Node 24 and 26 matrix rather than a separate compatibility workflow. Each check keeps its existing name on Node 24 and adds a `(Node 26)` suffix on Node 26. A failure does not cancel the other version. npm installation enforces dependency engines, and `scripts/check-ci-workflows.rb` checks the supported ranges, matching lockfile metadata, and matrix wiring. These checks track the supported majors, not their exact minimum patch releases.

Ruby-only jobs, CI selection, and container builds retain their configured runtimes. The build-action suite tests its JavaScript and browser capture on both Node versions, but runs the composite-action smoke test only on Node 24: the composite action pins that runtime itself and uploads a single named artifact. Container and composite-action runtime defaults are unchanged.

## Update dependencies

Hub and the shared build action wait seven days before resolving newly published dependencies. npm enforces the delay through each project's committed `.npmrc`. Hub's RubyGems source in `Gemfile` applies the delay to Bundler. Dependabot applies the same cooldown to npm, Bundler, and GitHub Actions updates across the repository. The starter manages its dependency resolution independently.
Expand Down
2 changes: 1 addition & 1 deletion hub/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion hub/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"type": "module",
"engines": {
"node": "^24.0.0"
"node": "^24.15.0 || ^26.0.0"
},
"scripts": {
"controls:build": "node script/build-controls-bridge.mjs",
Expand Down
4 changes: 2 additions & 2 deletions packages/learning/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Replica learning

`@github/replica-learning` lets Replica learn from review evidence without training a model. It owns the version 1 learning contracts, the memory provider interface, built-in SQLite, JSON Lines, and in-memory providers, two reference consolidators, a conformance suite, the `replica-learning` command, and an example that plugs in [Agent Memory Repo](examples/agent-memory-repo/README.md). It isn't published to npm yet, so run it from a Replica checkout with Node.js 24.
`@github/replica-learning` lets Replica learn from review evidence without training a model. It owns the version 1 learning contracts, the memory provider interface, built-in SQLite, JSON Lines, and in-memory providers, two reference consolidators, a conformance suite, the `replica-learning` command, and an example that plugs in [Agent Memory Repo](examples/agent-memory-repo/README.md). It isn't published to npm yet, so run it from a Replica checkout with a Node.js version matching `engines.node` in [package.json](package.json).

The design and its trade-offs are in [ADR 0001](../../docs/adr/0001-learning-extension-architecture.md).

Expand Down Expand Up @@ -135,7 +135,7 @@ The module must be inside the checkout and export `createMemoryProvider(options)

| Provider | Choose it with | Stores | Redaction |
| --- | --- | --- | --- |
| SQLite, the default | `"sqlite"` | One database file, with the SQLite driver built into Node.js 24 | Yes |
| SQLite, the default | `"sqlite"` | One database file, with the SQLite driver built into Node.js | Yes |
| JSON Lines | `"jsonl"` | One file per stream that a person can read | Yes |
| In memory | `"in-memory"` | Process memory, for tests | Yes |
| Single file | [`test/fixtures/json-file-provider.mjs`](test/fixtures/json-file-provider.mjs) | One JSON file, written only from the contract with no imports from this package | No |
Expand Down
2 changes: 1 addition & 1 deletion packages/learning/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/learning/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"demo:agent-memory-repo": "node examples/agent-memory-repo/demo.mjs"
},
"engines": {
"node": ">=24 <25"
"node": "^24.15.0 || ^26.0.0"
},
"devDependencies": {
"ajv": "8.20.0"
Expand Down
Loading
Loading