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
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v7
with:
python-version: '3.14'
cache: pip
Expand All @@ -28,9 +28,9 @@ jobs:
run: python -m unittest discover -s tests -v

- name: Set up Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v7
with:
node-version: '22'
node-version: '26'
cache: npm
cache-dependency-path: web/package-lock.json

Expand All @@ -52,7 +52,7 @@ jobs:

- name: Upload browser diagnostics on failure
if: failure()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: browser-test-results
path: web/test-results
Expand All @@ -62,13 +62,13 @@ jobs:
needs: test-and-build
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4

- name: Build image
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .
file: deploy/Dockerfile
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@v4

- name: Log in to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Docker metadata
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@v6
with:
images: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/factgraph
tags: |
Expand All @@ -40,7 +40,7 @@ jobs:
type=sha

- name: Build and push
uses: docker/build-push-action@v6
uses: docker/build-push-action@v7
with:
context: .
file: deploy/Dockerfile
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ With Docker Compose from the repository:
docker compose -f deploy/compose.yaml up --build
```

Directly with Python 3.11+ (the Docker image and CI use 3.14) and Node.js 20+:
Directly with Python 3.11+ and Node.js 20+ (the Docker image and CI use Python 3.14 and Node.js 26):

```bash
python3 -m venv .venv
Expand Down
2 changes: 1 addition & 1 deletion deploy/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# The frontend bundle is platform independent: build it natively instead of under arm64 emulation.
FROM --platform=$BUILDPLATFORM node:22-alpine AS frontend
FROM --platform=$BUILDPLATFORM node:26-alpine AS frontend
WORKDIR /build/web
COPY web/package.json web/package-lock.json ./
RUN npm ci
Expand Down
8 changes: 5 additions & 3 deletions web/e2e/workflows.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ async function setup(page:Page,request:APIRequestContext) {
const id=randomUUID();await page.goto(`/boards/${id}`)
await expect(page.getByText('1 online',{exact:true})).toBeVisible()
const token=await page.evaluate(id=>sessionStorage.getItem(`factgraph:sessionToken:${id}`)!,id)
const call=async(method:string,path:string,body?:object)=>{
const result=await request.fetch(`${base}/api/boards/${id}${path}`,{method,data:body,headers:{'X-FactGraph-Token':token}})
// timeout: for the few calls that legitimately take longer than an action (large imports); default actionTimeout.
const call=async(method:string,path:string,body?:object,timeout?:number)=>{
const result=await request.fetch(`${base}/api/boards/${id}${path}`,{method,data:body,headers:{'X-FactGraph-Token':token},...(timeout?{timeout}:{})})
expect(result.ok(),await result.text()).toBeTruthy();return result.json()
}
return {id,token,call,graph:()=>call('GET','/graph')}
Expand Down Expand Up @@ -219,7 +220,8 @@ test('layout preserves pinned positions; browser back navigates views without un
test('large import retains 10000 evidence rows and renders a 1000-node graph',async({page,request})=>{
const {call,graph}=await setup(page,request)
const rows=Array.from({length:10000},(_,i)=>({EventId:String(i),IPAddress:'10.0.0.5',FilePath:`repo/file-${i%999}`,TimeGenerated:'2026-09-28T10:00:00Z'}))
await call('POST','/imports/kql',{query:'AccessLogs',rows,title:'Large result'})
// 10,000 rows: the browser stores them in 50 acknowledged chunks, which on shared CI runners can take longer than 10 s.
await call('POST','/imports/kql',{query:'AccessLogs',rows,title:'Large result'},60_000)
const data=await graph()
expect(data.entities).toHaveLength(1000)
expect(data.facts.flatMap((f:any)=>f.assertions)).toHaveLength(10000)
Expand Down
Loading