Skip to content

Commit 7e2c041

Browse files
committed
ci: add GitHub Actions workflows and improve dev tooling
- Add CI workflow for tests, linting, and Docker builds - Add publish workflow for Docker image releases to GHCR - Refactor backend routes to use type-only imports - Add dev:fullstack npm script for full-stack development - Update docker-run.sh default project path - Add backend/public/ to .gitignore
1 parent d92f06f commit 7e2c041

File tree

11 files changed

+142
-9
lines changed

11 files changed

+142
-9
lines changed

.github/workflows/ci.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: CI - Tests and Linting
2+
3+
on:
4+
pull_request:
5+
branches: [main, develop]
6+
push:
7+
branches: [main, develop]
8+
9+
jobs:
10+
lint-and-test:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
matrix:
15+
node-version: [20.x]
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Setup Node.js ${{ matrix.node-version }}
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: ${{ matrix.node-version }}
25+
cache: 'npm'
26+
27+
- name: Install dependencies
28+
run: npm ci
29+
30+
- name: Run ESLint
31+
run: npm run lint
32+
33+
- name: Run TypeScript type check - Backend
34+
run: npx tsc --noEmit
35+
working-directory: ./backend
36+
37+
- name: Run TypeScript type check - Frontend
38+
run: npx tsc --noEmit
39+
working-directory: ./frontend
40+
41+
- name: Run unit tests
42+
run: npm test -- --silent
43+
44+
- name: Build backend
45+
run: npm run build:backend
46+
47+
- name: Build frontend
48+
run: npm run build:frontend
49+
50+
docker-build-test:
51+
runs-on: ubuntu-latest
52+
53+
steps:
54+
- name: Checkout code
55+
uses: actions/checkout@v4
56+
57+
- name: Set up Docker Buildx
58+
uses: docker/setup-buildx-action@v3
59+
60+
- name: Build Docker image (test)
61+
uses: docker/build-push-action@v5
62+
with:
63+
context: .
64+
push: false
65+
tags: pabawi:test
66+
cache-from: type=gha
67+
cache-to: type=gha,mode=max

.github/workflows/publish.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Publish Docker Image
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
8+
env:
9+
REGISTRY: ghcr.io
10+
IMAGE_NAME: ${{ github.repository }}
11+
12+
jobs:
13+
build-and-publish:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
packages: write
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Set up Docker Buildx
24+
uses: docker/setup-buildx-action@v3
25+
26+
- name: Log in to GitHub Container Registry
27+
uses: docker/login-action@v3
28+
with:
29+
registry: ${{ env.REGISTRY }}
30+
username: ${{ github.actor }}
31+
password: ${{ secrets.GITHUB_TOKEN }}
32+
33+
- name: Extract metadata
34+
id: meta
35+
uses: docker/metadata-action@v5
36+
with:
37+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
38+
tags: |
39+
type=semver,pattern={{version}}
40+
type=semver,pattern={{major}}.{{minor}}
41+
type=semver,pattern={{major}}
42+
type=sha,prefix={{branch}}-
43+
44+
- name: Build and push Docker image
45+
uses: docker/build-push-action@v5
46+
with:
47+
context: .
48+
push: true
49+
tags: ${{ steps.meta.outputs.tags }}
50+
labels: ${{ steps.meta.outputs.labels }}
51+
cache-from: type=gha
52+
cache-to: type=gha,mode=max
53+
platforms: linux/amd64,linux/arm64
54+
55+
- name: Generate artifact attestation
56+
uses: actions/attest-build-provenance@v1
57+
with:
58+
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
59+
subject-digest: ${{ steps.build.outputs.digest }}
60+
push-to-registry: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package-lock.json
77
# Build outputs
88
dist/
99
build/
10+
backend/public/
1011

1112
# Environment variables
1213
.env

backend/src/routes/commands.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { Router, type Request, type Response } from 'express';
22
import { z } from 'zod';
3-
import { BoltService } from '../bolt/BoltService';
4-
import { ExecutionRepository } from '../database/ExecutionRepository';
5-
import { CommandWhitelistService, CommandNotAllowedError } from '../validation/CommandWhitelistService';
3+
import type { BoltService } from '../bolt/BoltService';
4+
import type { ExecutionRepository } from '../database/ExecutionRepository';
5+
import type { CommandWhitelistService} from '../validation/CommandWhitelistService';
6+
import { CommandNotAllowedError } from '../validation/CommandWhitelistService';
67
import {
78
BoltInventoryNotFoundError,
89
} from '../bolt/types';

backend/src/routes/executions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Router, type Request, type Response } from 'express';
22
import { z } from 'zod';
3-
import { ExecutionRepository, type ExecutionFilters } from '../database/ExecutionRepository';
3+
import type { ExecutionRepository} from '../database/ExecutionRepository';
4+
import { type ExecutionFilters } from '../database/ExecutionRepository';
45

56
/**
67
* Request validation schemas

backend/src/routes/facts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Router, type Request, type Response } from 'express';
22
import { z } from 'zod';
3-
import { BoltService } from '../bolt/BoltService';
3+
import type { BoltService } from '../bolt/BoltService';
44
import {
55
BoltNodeUnreachableError,
66
BoltExecutionError,

backend/src/routes/inventory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Router, type Request, type Response } from 'express';
22
import { z } from 'zod';
3-
import { BoltService } from '../bolt/BoltService';
3+
import type { BoltService } from '../bolt/BoltService';
44
import {
55
BoltInventoryNotFoundError,
66
BoltExecutionError,

backend/src/routes/tasks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Router, type Request, type Response } from 'express';
22
import { z } from 'zod';
3-
import { BoltService } from '../bolt/BoltService';
4-
import { ExecutionRepository } from '../database/ExecutionRepository';
3+
import type { BoltService } from '../bolt/BoltService';
4+
import type { ExecutionRepository } from '../database/ExecutionRepository';
55
import {
66
BoltExecutionError,
77
BoltParseError,

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
"install:all": "npm install && npm install --workspace=frontend && npm install --workspace=backend",
1212
"dev:frontend": "npm run dev --workspace=frontend",
1313
"dev:backend": "npm run dev --workspace=backend",
14+
"dev:fullstack": "npm run build:frontend && npm run copy:frontend && npm run dev:backend",
1415
"build:frontend": "npm run build --workspace=frontend",
1516
"build:backend": "npm run build --workspace=backend",
1617
"build": "npm run build:frontend && npm run build:backend",
18+
"copy:frontend": "rm -rf backend/public && cp -r frontend/dist backend/public",
1719
"test": "npm run test --workspace=backend && npm run test --workspace=frontend",
1820
"lint": "npm run lint --workspace=backend && npm run lint --workspace=frontend",
1921
"lint:fix": "npm run lint:fix --workspace=backend && npm run lint:fix --workspace=frontend"

scripts/docker-run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ set -e
88
IMAGE_NAME="${IMAGE_NAME:-pabawi:latest}"
99
CONTAINER_NAME="${CONTAINER_NAME:-pabawi}"
1010
PORT="${PORT:-3000}"
11-
BOLT_PROJECT_PATH="${BOLT_PROJECT_PATH:-./test-bolt-project}"
11+
BOLT_PROJECT_PATH="${BOLT_PROJECT_PATH:-./}"
1212
DATA_PATH="${DATA_PATH:-./data}"
1313

1414
# Create data directory if it doesn't exist

0 commit comments

Comments
 (0)