Skip to content

Commit 6af1c37

Browse files
committed
Enhance CI workflow for Excalidraw: add linting steps for both server and client pipelines, implement platform-specific builds for Tauri desktop applications, and update README with detailed pipeline architecture and artifact information. Introduce ESLint configuration for TypeScript and React, ensuring code quality across multiple platforms.
1 parent b0ed922 commit 6af1c37

File tree

8 files changed

+4159
-326
lines changed

8 files changed

+4159
-326
lines changed

.github/workflows/README.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# CI/CD Pipeline
2+
3+
## Overview
4+
5+
This CI pipeline builds and tests the Excalidraw application for multiple platforms in parallel.
6+
7+
## Pipeline Architecture
8+
9+
```
10+
┌─────────────────────────┐
11+
│ Push to main / PR │
12+
└─────────────────────────┘
13+
14+
┌─────────────────────┼─────────────────────┐
15+
│ │ │
16+
▼ ▼ ▼
17+
┌──────────┐ ┌──────────┐ ┌──────────┐
18+
│ Server │ │ Client │ │ Client │
19+
│ (Go) │ │ (Linux) │ │ (macOS) │
20+
└──────────┘ └──────────┘ └──────────┘
21+
│ │ │
22+
│ │ ┌──────────┐
23+
│ │ │ Client │
24+
│ │ │(Windows) │
25+
│ │ └──────────┘
26+
│ │ │
27+
▼ ▼ ▼
28+
```
29+
30+
## Server Pipeline
31+
32+
**Platform:** Ubuntu Latest
33+
**Language:** Go 1.21
34+
35+
### Steps:
36+
37+
1. 🔍 **Lint** - golangci-lint
38+
2. 🧪 **Test** - Run Go tests
39+
3. 🔨 **Build** - Compile Go binary
40+
4. 📦 **Upload** - Server executable
41+
42+
**Artifact:** `excalidraw-server` (Linux binary)
43+
44+
## Client Pipeline
45+
46+
**Platforms:** Linux, macOS, Windows (matrix build)
47+
**Language:** TypeScript + Rust (Tauri)
48+
49+
### Steps (per platform):
50+
51+
1. 🔍 **Lint** - ESLint (warnings allowed)
52+
2. 🧪 **Test** - Vitest (147 tests)
53+
3. 🔨 **Build** - Tauri desktop app
54+
4. 📦 **Upload** - Platform-specific executables
55+
56+
### Artifacts:
57+
58+
#### Linux (`excalidraw-linux`)
59+
60+
- `*.deb` - Debian package
61+
- `*.AppImage` - Universal Linux app
62+
63+
#### macOS (`excalidraw-macos`)
64+
65+
- `*.dmg` - macOS disk image
66+
- `*.app` - macOS application bundle
67+
68+
#### Windows (`excalidraw-windows`)
69+
70+
- `*.msi` - Windows installer
71+
- `*.exe` - NSIS installer
72+
73+
## Parallel Execution
74+
75+
All builds run simultaneously:
76+
77+
- **Server build** (1 job)
78+
- **Linux client build** (1 job)
79+
- **macOS client build** (1 job)
80+
- **Windows client build** (1 job)
81+
82+
**Total:** 4 parallel jobs
83+
84+
## Downloading Artifacts
85+
86+
After a successful CI run, you can download the built applications:
87+
88+
1. Go to **Actions** tab in GitHub
89+
2. Click on the latest workflow run
90+
3. Scroll to **Artifacts** section
91+
4. Download platform-specific builds:
92+
- `excalidraw-server` - Go server
93+
- `excalidraw-linux` - Linux apps (.deb, .AppImage)
94+
- `excalidraw-macos` - macOS apps (.dmg, .app)
95+
- `excalidraw-windows` - Windows installers (.msi, .exe)
96+
97+
## Triggers
98+
99+
The pipeline runs on:
100+
101+
- **Push** to `main` branch
102+
- **Pull requests** to `main` branch
103+
104+
## Estimated Duration
105+
106+
- **Server pipeline:** ~2-3 minutes
107+
- **Client pipeline (per platform):** ~10-15 minutes
108+
- **Total (parallel):** ~10-15 minutes
109+
110+
## Success Criteria
111+
112+
All jobs must pass:
113+
114+
- ✅ No lint errors (warnings allowed for client)
115+
- ✅ All tests pass
116+
- ✅ Builds complete successfully
117+
- ✅ Artifacts uploaded
118+
119+
## Local Testing
120+
121+
### Server
122+
123+
```bash
124+
cd excalidraw-server
125+
golangci-lint run
126+
go test ./...
127+
go build
128+
```
129+
130+
### Client
131+
132+
```bash
133+
cd excalidraw-app
134+
npm run lint
135+
npm test
136+
npm run tauri build
137+
```

.github/workflows/ci.yml

Lines changed: 90 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
branches: [main]
88

99
jobs:
10-
# Pipeline A: Server (test → build)
10+
# Pipeline A: Server (lint → test → build)
1111
server-pipeline:
1212
name: Server Pipeline
1313
runs-on: ubuntu-latest
@@ -21,6 +21,12 @@ jobs:
2121
with:
2222
go-version: "1.21"
2323

24+
- name: 🔍 Run golangci-lint
25+
uses: golangci/golangci-lint-action@v6
26+
with:
27+
version: latest
28+
working-directory: excalidraw-server
29+
2430
- name: Make test script executable
2531
run: chmod +x tests/server/run.sh
2632

@@ -39,10 +45,24 @@ jobs:
3945
name: excalidraw-server
4046
path: excalidraw-server/excalidraw-server
4147

42-
# Pipeline B: Client (test → build)
48+
# Pipeline B: Client (lint → test → build)
4349
client-pipeline:
44-
name: Client Pipeline
45-
runs-on: ubuntu-latest
50+
name: Client Pipeline - ${{ matrix.platform }}
51+
runs-on: ${{ matrix.os }}
52+
53+
strategy:
54+
fail-fast: false
55+
matrix:
56+
include:
57+
- platform: linux
58+
os: ubuntu-latest
59+
rust-target: x86_64-unknown-linux-gnu
60+
- platform: macos
61+
os: macos-latest
62+
rust-target: x86_64-apple-darwin
63+
- platform: windows
64+
os: windows-latest
65+
rust-target: x86_64-pc-windows-msvc
4666

4767
steps:
4868
- name: Checkout code
@@ -55,21 +75,79 @@ jobs:
5575
cache: "npm"
5676
cache-dependency-path: excalidraw-app/package-lock.json
5777

78+
- name: Install dependencies
79+
run: |
80+
cd excalidraw-app
81+
npm ci
82+
83+
- name: 🔍 Run ESLint
84+
continue-on-error: true
85+
run: |
86+
cd excalidraw-app
87+
npm run lint
88+
5889
- name: Make test script executable
90+
if: matrix.platform != 'windows'
5991
run: chmod +x tests/client/run.sh
6092

61-
- name: 🧪 Run client tests
93+
- name: 🧪 Run client tests (Unix)
94+
if: matrix.platform != 'windows'
6295
run: tests/client/run.sh
6396

64-
- name: 🔨 Build client
97+
- name: 🧪 Run client tests (Windows)
98+
if: matrix.platform == 'windows'
6599
run: |
66100
cd excalidraw-app
67-
npm ci
68-
npm run build
69-
echo "✅ Client built successfully"
101+
npm test
102+
103+
- name: Install Rust
104+
uses: dtolnay/rust-toolchain@stable
105+
with:
106+
targets: ${{ matrix.rust-target }}
107+
108+
- name: Install Tauri dependencies (Linux)
109+
if: matrix.platform == 'linux'
110+
run: |
111+
sudo apt-get update
112+
sudo apt-get install -y libwebkit2gtk-4.1-dev \
113+
build-essential \
114+
curl \
115+
wget \
116+
file \
117+
libxdo-dev \
118+
libssl-dev \
119+
libayatana-appindicator3-dev \
120+
librsvg2-dev
121+
122+
- name: 🔨 Build Tauri app
123+
run: |
124+
cd excalidraw-app
125+
npm run tauri build
126+
echo "✅ Tauri app built successfully for ${{ matrix.platform }}"
127+
128+
- name: Upload Linux artifacts
129+
if: matrix.platform == 'linux'
130+
uses: actions/upload-artifact@v4
131+
with:
132+
name: excalidraw-linux
133+
path: |
134+
excalidraw-app/src-tauri/target/release/bundle/deb/*.deb
135+
excalidraw-app/src-tauri/target/release/bundle/appimage/*.AppImage
136+
137+
- name: Upload macOS artifacts
138+
if: matrix.platform == 'macos'
139+
uses: actions/upload-artifact@v4
140+
with:
141+
name: excalidraw-macos
142+
path: |
143+
excalidraw-app/src-tauri/target/release/bundle/dmg/*.dmg
144+
excalidraw-app/src-tauri/target/release/bundle/macos/*.app
70145
71-
- name: Upload client artifact
146+
- name: Upload Windows artifacts
147+
if: matrix.platform == 'windows'
72148
uses: actions/upload-artifact@v4
73149
with:
74-
name: excalidraw-client
75-
path: excalidraw-app/dist
150+
name: excalidraw-windows
151+
path: |
152+
excalidraw-app/src-tauri/target/release/bundle/msi/*.msi
153+
excalidraw-app/src-tauri/target/release/bundle/nsis/*.exe

excalidraw-app/eslint.config.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import js from '@eslint/js';
2+
import globals from 'globals';
3+
import reactHooks from 'eslint-plugin-react-hooks';
4+
import reactRefresh from 'eslint-plugin-react-refresh';
5+
import tseslint from 'typescript-eslint';
6+
7+
export default tseslint.config(
8+
{ ignores: ['dist', 'node_modules', 'src-tauri', '**/*.test.ts', '**/*.test.tsx', '**/__tests__'] },
9+
{
10+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
11+
files: ['**/*.{ts,tsx}'],
12+
languageOptions: {
13+
ecmaVersion: 2020,
14+
globals: globals.browser,
15+
},
16+
plugins: {
17+
'react-hooks': reactHooks,
18+
'react-refresh': reactRefresh,
19+
},
20+
rules: {
21+
...reactHooks.configs.recommended.rules,
22+
'react-refresh/only-export-components': [
23+
'warn',
24+
{ allowConstantExport: true },
25+
],
26+
'@typescript-eslint/no-unused-vars': ['warn', {
27+
argsIgnorePattern: '^_',
28+
varsIgnorePattern: '^_'
29+
}],
30+
'@typescript-eslint/no-explicit-any': 'warn',
31+
'@typescript-eslint/no-use-before-define': 'off',
32+
'react-hooks/rules-of-hooks': 'warn',
33+
'react-hooks/exhaustive-deps': 'warn',
34+
},
35+
},
36+
);
37+

0 commit comments

Comments
 (0)