Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 3 additions & 2 deletions .github/workflows/build-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
build:
if: github.ref == 'refs/heads/main'
name: ${{ matrix.name }}
timeout-minutes: 45
runs-on: ubuntu-24.04
permissions:
contents: read
Expand Down Expand Up @@ -111,8 +112,8 @@ jobs:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
build-args: |
SENTRY_ORG=${{ vars.SENTRY_ORG }}
SENTRY_PROJECT=${{ vars.SENTRY_PROJECT }}
Expand Down
144 changes: 140 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches: [main]
pull_request:
workflow_dispatch:
workflow_call:

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
Expand Down Expand Up @@ -32,6 +33,7 @@ jobs:

lint:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -55,6 +57,7 @@ jobs:

i18n:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -80,6 +83,7 @@ jobs:

openapi:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -105,6 +109,7 @@ jobs:

typecheck:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -128,6 +133,7 @@ jobs:

unit:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -149,7 +155,7 @@ jobs:
- name: Test release security controls
run: |
docker pull nginx:1.29.5-alpine
node --test scripts/security/*.test.mjs
node --test scripts/security/*.test.mjs scripts/ci/*.test.mjs

- name: Run unit tests
env:
Expand All @@ -159,6 +165,7 @@ jobs:

build:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -180,7 +187,11 @@ jobs:
- name: Build monorepo
run: pnpm build

- name: Check site metadata and internal links
run: pnpm --filter @kaneo/site seo:check

integration:
timeout-minutes: 15
runs-on: ubuntu-24.04
services:
postgres:
Expand Down Expand Up @@ -226,19 +237,144 @@ jobs:

docker-build:
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

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

- name: Build kaneo image (smoke test)
- name: Build bundled image for runtime tests
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7
with:
context: .
file: ./Dockerfile.kaneo
platforms: linux/amd64
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
load: true
tags: kaneo:ci
cache-from: type=gha,scope=kaneo
cache-to: type=gha,mode=max,scope=kaneo

- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
with:
version: 10.32.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 24.19.0
cache: pnpm
- run: pnpm install --frozen-lockfile --ignore-scripts --filter @kaneo/api...
- run: npm ci --ignore-scripts
working-directory: scripts/ui-review-bot
- run: scripts/ui-review-bot/node_modules/.bin/playwright install --with-deps chromium
- name: Start bundled image without Redis
run: docker compose --env-file /dev/null -p kaneo-ci -f scripts/ci/compose.yml up -d --wait --wait-timeout 120 postgres minio app
- name: Browser regression and workspace isolation
run: node scripts/ci/browser.mjs http://127.0.0.1:55173
- name: Verify realtime without Redis
run: node scripts/ci/realtime.mjs http://127.0.0.1:55173
- name: Start two API instances with Redis
env:
KANEO_CI_REDIS_URL: redis://redis:6379
run: docker compose --env-file /dev/null -p kaneo-ci -f scripts/ci/compose.yml --profile realtime up -d --wait --wait-timeout 120 app second redis
- name: Verify Redis fan-out
run: node scripts/ci/realtime.mjs http://127.0.0.1:55173 http://127.0.0.1:55174
- name: Upgrade from the latest stable release
env:
GH_TOKEN: ${{ github.token }}
run: bash scripts/ci/upgrade.sh
- name: Save container logs
if: always()
run: |
mkdir -p .cache/ci-results
docker compose --env-file /dev/null -p kaneo-ci -f scripts/ci/compose.yml --profile realtime --profile upgrade logs --no-color > .cache/ci-results/containers.log
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
if: failure()
with:
name: runtime-failures
path: .cache/ci-results/
include-hidden-files: true
retention-days: 7
- name: Remove disposable test services and data
if: always()
run: docker compose --env-file /dev/null -p kaneo-ci -f scripts/ci/compose.yml --profile realtime --profile upgrade down -v

workflows:
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install verified actionlint
run: |
curl --fail --silent --show-error --location --max-time 60 \
https://github.com/rhysd/actionlint/releases/download/v1.7.12/actionlint_1.7.12_linux_amd64.tar.gz \
-o "$RUNNER_TEMP/actionlint.tar.gz"
echo "8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 $RUNNER_TEMP/actionlint.tar.gz" | sha256sum --check --strict
tar -xzf "$RUNNER_TEMP/actionlint.tar.gz" -C "$RUNNER_TEMP" actionlint
- name: Lint workflows and embedded shell scripts
run: |
shellcheck --version
"$RUNNER_TEMP/actionlint" -color
shellcheck scripts/ci/*.sh

storage:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
with:
version: 10.32.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 24.19.0
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Start disposable S3 storage
run: |
docker run -d --name kaneo-storage-ci \
-p 127.0.0.1:59039:9000 \
-e MINIO_ROOT_USER=local-test-access \
-e MINIO_ROOT_PASSWORD=local-test-secret-only \
-e MINIO_BROWSER=off -e MINIO_UPDATE=off \
quay.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e \
server /data --address :9000
curl --fail --retry 30 --retry-connrefused --retry-delay 1 --max-time 5 \
http://127.0.0.1:59039/minio/health/ready
- name: Verify signed uploads against real storage
env:
KANEO_STORAGE_TEST_ENDPOINT: http://127.0.0.1:59039
run: pnpm --filter @kaneo/api exec vitest run --config vitest.storage.config.ts
- name: Storage logs
if: failure()
run: docker logs kaneo-storage-ci
- name: Remove disposable storage
if: always()
run: docker rm -f -v kaneo-storage-ci

split-images:
runs-on: ubuntu-24.04
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
name: [api, web]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4
- name: Build standalone image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7
with:
context: .
file: ./apps/${{ matrix.name }}/Dockerfile
platforms: linux/amd64
push: false
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
1 change: 1 addition & 0 deletions .github/workflows/helm-chart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
pull_request:
paths:
- "charts/kaneo/**"
- "scripts/security/check-helm-secrets.rb"
- ".github/workflows/helm-chart.yml"
- ".github/workflows/helm-validate.yml"
workflow_call:
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/helm-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ env:
jobs:
validate:
name: ${{ matrix.name }}
timeout-minutes: 5
runs-on: ubuntu-24.04
permissions:
contents: read
Expand Down Expand Up @@ -61,3 +62,7 @@ jobs:

- name: Render chart (${{ matrix.name }})
run: helm template kaneo "$CHART_PATH" --set kaneo.env.clientUrl=https://kaneo.example.com ${{ matrix.args }}

- name: Check secret preservation and security settings
if: matrix.name == 'default'
run: ruby scripts/security/check-helm-secrets.rb
54 changes: 1 addition & 53 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,59 +17,7 @@ jobs:
verify:
name: Verify nightly build
if: ${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
runs-on: ubuntu-24.04
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: kaneo_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres -d kaneo_test"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
NODE_ENV: test
AUTH_SECRET: test-secret-with-at-least-32-chars
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/kaneo_test
KANEO_API_URL: http://localhost:1337
KANEO_CLIENT_URL: http://localhost:5173
DISABLE_GUEST_ACCESS: "false"
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false

- name: Setup pnpm
uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
with:
version: 10.32.1

- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 24.19.0
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run Biome
run: pnpm exec biome ci .

- name: Run unit tests
run: pnpm test

- name: Run API integration tests
run: pnpm test:integration

- name: Build monorepo
run: pnpm build
uses: ./.github/workflows/ci.yml

publish-images:
name: Publish nightly images
Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/pr-title.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: PR title

on:
pull_request:
types: [opened, edited, synchronize, reopened, ready_for_review]

permissions:
contents: read

concurrency:
group: pr-title-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
title:
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
# Validate using the target branch's policy, not code supplied by the PR.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.pull_request.base.sha }}
persist-credentials: false
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
with:
version: 10.32.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 24.19.0
cache: pnpm
- run: pnpm install --frozen-lockfile --ignore-scripts --filter kaneo
- name: Validate Conventional Commit title
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: printf '%s\n' "$PR_TITLE" | pnpm exec commitlint
Loading
Loading