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
142 changes: 142 additions & 0 deletions .github/workflows/post-merge-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Deploys Scribe-server Node.js app to Azure Web Apps after merge
name: Post-merge-deploy
on:
push:
branches:
- main
workflow_dispatch:
inputs:
environment:
description: Environment to deploy to
required: true
default: dev
type: choice
options:
- dev
- prod

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Node.js version
uses: actions/setup-node@v4
with:
node-version: 22.15.0
cache: npm

- name: Install all dependencies
run: npm install --legacy-peer-deps

- name: Lint and format check
run: |
npm run lint
npm run format:check

- name: Type check
run: npm run typecheck

- name: Run tests
run: npm run test

- name: Build application
run: npm run build

- name: Create deployment package directory
run: |
mkdir -p deployment
cp -r dist deployment/
cp package.json deployment/
cp package-lock.json deployment/ || true

- name: Install production dependencies
run: |
cd deployment
npm install --prod --legacy-peer-deps

- name: Upload artifact for deployment job
uses: actions/upload-artifact@v4
with:
name: node-app
path: deployment/

deploy-dev:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'dev')
environment:
name: Development
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v4
with:
name: node-app
path: deployment/

- name: Deploy to Azure Web App
id: deploy-to-webapp
uses: azure/webapps-deploy@v3
with:
app-name: scribe-server-dev
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_947D34B0D69C4986A7E211253893C796 }}
package: deployment/
clean: true

- name: Verify deployment
run: |
sleep 30
for i in $(seq 1 10); do
response=$(curl -s -o /dev/null -w "%{http_code}" ${{ steps.deploy-to-webapp.outputs.webapp-url }})
if [ "$response" -ge 200 ] && [ "$response" -lt 400 ]; then
echo "Dev deployment successful (HTTP $response)"
exit 0
else
echo "App not ready yet (HTTP $response). Retrying in 10 seconds..."
sleep 10
fi
done
echo "Dev deployment verification failed"
exit 1

deploy-prod:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'prod'
environment:
name: Production
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v4
with:
name: node-app
path: deployment/

- name: Deploy to Azure Web App
id: deploy-to-webapp
uses: azure/webapps-deploy@v3
with:
app-name: scribe-server-prod
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_PROD }}
package: deployment/
clean: true

- name: Verify deployment
run: |
sleep 45
for i in $(seq 1 12); do
response=$(curl -s -o /dev/null -w "%{http_code}" ${{ steps.deploy-to-webapp.outputs.webapp-url }})
if [ "$response" -ge 200 ] && [ "$response" -lt 400 ]; then
echo "Production deployment successful (HTTP $response)"
exit 0
else
echo "App not ready yet (HTTP $response). Retrying in 15 seconds..."
sleep 15
fi
done
echo "Production deployment verification failed"
exit 1
17 changes: 17 additions & 0 deletions .github/workflows/pr-closed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Auto-cleanup merged branches after PR is closed
name: PR closed

on:
pull_request:
types: [closed]

jobs:
cleanup:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Delete merged branch
uses: dawidd6/action-delete-branch@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branches: ${{ github.event.pull_request.head.ref }}
37 changes: 37 additions & 0 deletions .github/workflows/pre-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Validates Pull Requests by running linting, testing, and type checking
name: Pre-merge
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches: [main]

jobs:
validate:
runs-on: ubuntu-latest
Comment thread
vipinpaul marked this conversation as resolved.
if: ${{ !github.event.pull_request.draft }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Node.js version
uses: actions/setup-node@v4
with:
node-version: 22.15.0
cache: npm

- name: Install dependencies
run: npm install --legacy-peer-deps

- name: Lint and format check
run: |
npm run lint
npm run format:check

- name: Type check
run: npm run typecheck

- name: Run tests
run: npm run test

- name: Build test
run: npm run build
57 changes: 29 additions & 28 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ src/
1. **Install dependencies:**

```bash
pnpm install
npm install
```

2. **Set up environment variables:**
Expand All @@ -70,18 +70,18 @@ src/
3. **Push database schema:**

```bash
pnpm drizzle-kit push
npx drizzle-kit push
```

4. **Start development server:**

```bash
pnpm dev
npm run dev
```

5. **Run tests:**
```bash
pnpm test
npm run test
```

## Adding a New Feature
Expand Down Expand Up @@ -212,7 +212,7 @@ export default server;
To add a new feature (e.g., "Users"), follow these steps using the tasks implementation as your guide:

1. **Database Schema**: Add your table to `src/db/schema.ts` following the `tasks` table pattern
2. **Database Migration**: Run `pnpm drizzle-kit push` to apply schema changes
2. **Database Migration**: Run `npx drizzle-kit push` to apply schema changes
3. **Handler Functions**: Create `src/handlers/[feature].handler.ts` following `task.handler.ts` patterns
4. **Route Definitions**: Create `src/routes/[feature].route.ts` following `task.route.ts` patterns
5. **Application Import**: Add your route import to `src/app.ts`
Expand All @@ -224,8 +224,9 @@ Routes are defined using `createRoute` from `@hono/zod-openapi` and registered w

```typescript
import { createRoute } from '@hono/zod-openapi';
import { server } from '@/server/server';

import * as featureHandler from '@/handlers/feature.handler';
import { server } from '@/server/server';

const listRoute = createRoute({
tags: ['Feature'],
Expand All @@ -249,8 +250,8 @@ Handlers contain pure business logic and database operations:

```typescript
import { db } from '@/db';
import { logger } from '@/lib/logger';
import { features } from '@/db/schema';
import { logger } from '@/lib/logger';

export async function getAllFeatures(): Promise<Feature[]> {
logger.debug('Fetching all features');
Expand All @@ -277,7 +278,7 @@ We use **Vitest** for testing. Tests are placed next to the code they test:
Use the shared test utilities in `src/test/utils/test-helpers.ts`:

```typescript
import { createMockContext, sampleTasks, resetAllMocks } from '@/test/utils/test-helpers';
import { createMockContext, resetAllMocks, sampleTasks } from '@/test/utils/test-helpers';
```

Available utilities:
Expand All @@ -291,8 +292,9 @@ Available utilities:
Follow the existing test patterns in `src/handlers/task.handler.test.ts`:

```typescript
import { describe, it, expect, beforeEach } from 'vitest';
import { createMockContext, sampleTasks, resetAllMocks } from '@/test/utils/test-helpers';
import { beforeEach, describe, expect, it } from 'vitest';

import { createMockContext, resetAllMocks, sampleTasks } from '@/test/utils/test-helpers';

describe('Feature Handler', () => {
beforeEach(() => {
Expand All @@ -309,22 +311,22 @@ describe('Feature Handler', () => {

```bash
# Run all tests
pnpm test
npm run test

# Run tests in watch mode
pnpm test --watch
npm run test --watch

# Run tests with coverage
pnpm test --coverage
npm run test --coverage
```

## Database Changes

### Schema Changes

1. Update `src/db/schema.ts` with new tables or columns
2. Push schema changes: `pnpm drizzle-kit push`
3. For production, generate proper migrations: `pnpm drizzle-kit generate`
2. Push schema changes: `npx drizzle-kit push`
3. For production, generate proper migrations: `npx drizzle-kit generate`

### Environment Variables

Expand All @@ -344,21 +346,21 @@ The project uses ESLint with `@antfu/eslint-config` and Prettier:

```bash
# Check linting
pnpm lint
npm run lint

# Fix linting issues
pnpm lint:fix
npm run lint:fix

# Format code
pnpm format
npm run format

# Check formatting
pnpm format:check
npm run format:check
```

### TypeScript

- Strict TypeScript configuration (`pnpm typecheck`)
- Strict TypeScript configuration (`npm run typecheck`)
- Prefer `type` over `interface` for type definitions
- Use proper typing for all functions and variables

Expand All @@ -376,13 +378,12 @@ Organize imports following the existing pattern:
```typescript
import type { Context } from 'hono';

import { createRoute } from '@hono/zod-openapi';
import { z } from '@hono/zod-openapi';
import { createRoute, z } from '@hono/zod-openapi';
import * as HttpStatusCodes from 'stoker/http-status-codes';

import { selectTasksSchema } from '@/db/schema';
import { logger } from '@/lib/logger';
import * as taskHandler from '@/handlers/task.handler';
import { logger } from '@/lib/logger';
import { server } from '@/server/server';
```

Expand Down Expand Up @@ -412,19 +413,19 @@ refactor: simplify route error handling

```bash
# Type checking
pnpm typecheck
npm run typecheck

# Linting
pnpm lint
npm run lint

# Testing
pnpm test
npm run test

# Formatting
pnpm format:check
npm run format:check

# Build
pnpm build
npm run build
```

## Getting Help
Expand Down
Loading