Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
49 changes: 49 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# =============================================================================
# Docker build context exclusions.
#
# Without this the context includes node_modules (Studio), bin/obj (six .NET
# projects), the Astro build output and git history — hundreds of MB that are
# never used by an image build and that invalidate the layer cache on every
# unrelated edit. Package *manifests* are deliberately NOT excluded: npm ci and
# dotnet restore both need them.
# =============================================================================

.git
.gitignore
.github
.opencode
**/.vs
**/.vscode
**/node_modules
**/bin
**/obj
**/.vite
**/test-results
**/playwright-report
**/.astro
**/.pytest_cache

# Build outputs — the image builds these itself.
src/hercules-studio/dist
src/hercules-web/dist

# Runtime state. HERCULES_DATA_ROOT is pinned inside the container, so a host
# data directory must never leak in and silently seed the test instance.
data
**/data
*.db
*.db-shm
*.db-wal

# Docs and assets not needed to run the agent.
docs
assets
examples
templates
deploy/raspberry-pi

# Not needed at runtime.
**/*.md
!**/README.md
LICENSE
LICENSE-COMMERCIAL.md
11 changes: 11 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# The `openapi` CI job regenerates openapi.json and fails on any diff, including
# line-ending-only changes. `core.autocrlf` is a per-machine Git setting, so without
# pinning this the job's result depends on whichever contributor pushed — a checkout
# with autocrlf=false produces CRLF, a Linux runner produces LF, and the job fails on
# content that is byte-identical apart from newlines.
#
# Both files below are generated artefacts that are committed and diffed, so their line
# endings are pinned rather than left to autocrlf.

src/agent/Hercules.WebApi/openapi.json text eol=lf
src/hercules-studio/renderer/src/sdk/openapi.d.ts text eol=lf
123 changes: 123 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: CI

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

# Cancel superseded runs on the same ref — this suite is fast enough that a stale
# result is worth less than the minutes it costs to keep computing it.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

env:
DOTNET_NOLOGO: "true"
DOTNET_CLI_TELEMETRY_OPTOUT: "true"
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "true"

jobs:
agent:
name: Agent (.NET)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-dotnet@v4
with:
global-json-file: global.json

- name: Restore
run: dotnet restore src/agent/Hercules.slnx

- name: Build
run: dotnet build src/agent/Hercules.slnx -c Release --no-restore

- name: Test
run: >-
dotnet test tests/Hercules.Agent.Tests
-c Release --no-build
--logger "trx;LogFileName=agent-tests.trx"

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: agent-test-results
path: "**/TestResults/*.trx"
if-no-files-found: ignore

openapi:
name: OpenAPI document is current
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-dotnet@v4
with:
global-json-file: global.json

# Studio's contract test (client.contract.test.ts) asserts every endpoint the
# client calls exists in the committed document. During the web-first migration
# that document was found stale — live routes were missing from it and only
# regeneration exposed that. This job makes the drift fail the build instead.
- name: Regenerate the document
run: dotnet build src/agent/Hercules.WebApi -p:OpenApiGenerateDocumentOnBuild=true

- name: Fail if the committed document drifted
run: |
if ! git diff --quiet -- src/agent/Hercules.WebApi/openapi.json; then
echo "::error::src/agent/Hercules.WebApi/openapi.json is stale. Regenerate and commit it with:"
echo " dotnet build src/agent/Hercules.WebApi -p:OpenApiGenerateDocumentOnBuild=true"
echo " cd src/hercules-studio && npm run generate:api"
git --no-pager diff -- src/agent/Hercules.WebApi/openapi.json | head -120
exit 1
fi

studio:
name: Studio (Node)
runs-on: ubuntu-latest
defaults:
run:
working-directory: src/hercules-studio
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
cache-dependency-path: src/hercules-studio/package-lock.json

- name: Install dependencies
run: npm ci

- name: Typecheck
run: npm run typecheck

- name: Lint
run: npm run lint

- name: Unit tests
run: npm test

- name: Build
run: npm run build

- name: Install Playwright browsers
run: npx playwright install --with-deps chromium

# The Playwright config starts its own preview server; agent calls are
# stubbed in-spec, so no Hercules agent is needed here.
- name: E2E tests
run: npm run test:e2e

- name: Upload Playwright report
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: src/hercules-studio/playwright-report
if-no-files-found: ignore
retention-days: 7
92 changes: 0 additions & 92 deletions .github/workflows/studio-ci.yml

This file was deleted.

9 changes: 6 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -424,11 +424,14 @@ FodyWeavers.xsd
# Astro / web build output
src/hercules-web/dist/

# Hercules Studio (Electron + Vue)
# E2E test secrets — real API keys must never be committed.
# Only README.md in that directory is tracked.
deploy/e2e/secrets/*
!deploy/e2e/secrets/README.md

# Hercules Studio (web-first Vue SPA — ADR-0009, no Electron shell)
src/hercules-studio/node_modules/
src/hercules-studio/dist/
src/hercules-studio/out/
src/hercules-studio/release/
src/hercules-studio/.vite/

# Windows Installer files from build outputs
Expand Down
Loading
Loading