Skip to content

Commit d0133c5

Browse files
committed
refactor: enhance CI/CD pipeline with improved change detection, caching, and security audits
1 parent ccf1baa commit d0133c5

File tree

1 file changed

+202
-105
lines changed

1 file changed

+202
-105
lines changed

.github/workflows/ci.yml

Lines changed: 202 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ jobs:
2828
backend: ${{ steps.changes.outputs.backend }}
2929
frontend: ${{ steps.changes.outputs.frontend }}
3030
tauri: ${{ steps.changes.outputs.tauri }}
31+
skip_ci: ${{ steps.changes.outputs.skip_ci }}
3132
steps:
3233
- name: Checkout Repository
3334
uses: actions/checkout@v4
@@ -53,72 +54,181 @@ jobs:
5354
- 'src-tauri/tauri.conf.json'
5455
- 'src-tauri/capabilities/**'
5556
- 'src-tauri/icons/**'
56-
57-
# Backend Rust tests and checks
58-
rust-backend:
59-
name: Rust Backend
57+
skip_ci:
58+
- '**.md'
59+
- '.gitignore'
60+
- 'LICENSE'
61+
- 'docs/**'
62+
63+
# Combined Full Stack Test and Build
64+
full-stack-test-build:
65+
name: Full Stack Test & Build
6066
runs-on: ${{ matrix.os }}
6167
needs: changes
62-
if: needs.changes.outputs.backend == 'true' || needs.changes.outputs.tauri == 'true'
68+
if: needs.changes.outputs.skip_ci == 'false' && (needs.changes.outputs.backend == 'true' || needs.changes.outputs.frontend == 'true' || needs.changes.outputs.tauri == 'true')
6369

6470
strategy:
6571
fail-fast: false
6672
matrix:
67-
os: [ ubuntu-latest, macos-latest, windows-latest ]
73+
os: [ macos-latest, windows-latest ]
6874

6975
steps:
7076
- name: Checkout Repository
7177
uses: actions/checkout@v4
7278

79+
# Setup all required tools
80+
- name: Setup pnpm
81+
uses: pnpm/action-setup@v4
82+
with:
83+
version: 9
84+
85+
- name: Setup Node.js
86+
uses: actions/setup-node@v4
87+
with:
88+
node-version: '20'
89+
cache: 'pnpm'
90+
7391
- name: Install Rust Toolchain
7492
uses: actions-rust-lang/setup-rust-toolchain@v1
7593
with:
7694
toolchain: stable
7795
components: rustfmt, clippy
7896
cache: true
7997

80-
- name: Install System Dependencies (Ubuntu)
81-
if: matrix.os == 'ubuntu-latest'
82-
run: |
83-
sudo apt-get update
84-
sudo apt-get install -y \
85-
libwebkit2gtk-4.0-dev \
86-
libwebkit2gtk-4.1-dev \
87-
libappindicator3-dev \
88-
librsvg2-dev \
89-
patchelf \
90-
libssl-dev \
91-
pkg-config
92-
93-
- name: Install System Dependencies (macOS)
94-
if: matrix.os == 'macos-latest'
98+
# Enhanced caching strategy
99+
- name: Get pnpm store directory
100+
shell: bash
95101
run: |
96-
# Most dependencies are already available on macOS runners
97-
echo "macOS dependencies already installed"
102+
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
98103
99-
- name: Cache Rust Dependencies
100-
uses: Swatinem/rust-cache@v2
104+
- name: Cache All Dependencies
105+
uses: actions/cache@v4
101106
with:
102-
workspaces: src-tauri
103-
cache-on-failure: true
104-
shared-key: ${{ matrix.os }}-rust-cache
107+
path: |
108+
${{ env.STORE_PATH }}
109+
~/.cargo/bin/
110+
~/.cargo/registry/index/
111+
~/.cargo/registry/cache/
112+
~/.cargo/git/db/
113+
src-tauri/target/
114+
node_modules
115+
dist/
116+
key: ${{ runner.os }}-fullstack-${{ hashFiles('**/Cargo.lock', '**/pnpm-lock.yaml') }}
117+
restore-keys: |
118+
${{ runner.os }}-fullstack-
119+
${{ runner.os }}-
120+
121+
# Install all dependencies
122+
- name: Install Frontend Dependencies
123+
run: pnpm install --frozen-lockfile
124+
125+
# Backend tests and checks (if backend changed)
126+
- name: Check Rust Formatting
127+
if: needs.changes.outputs.backend == 'true'
128+
run: |
129+
cd src-tauri
130+
cargo fmt --all -- --check
105131
106-
- name: Run Rust Tests
132+
- name: Run Clippy
133+
if: needs.changes.outputs.backend == 'true'
107134
run: |
108135
cd src-tauri
109-
cargo test --verbose --all-features
136+
cargo clippy --all-targets --all-features -- -D warnings
110137
111-
- name: Check Rust Build
138+
- name: Run Rust Unit Tests
139+
if: needs.changes.outputs.backend == 'true'
112140
run: |
113141
cd src-tauri
114-
cargo check --release
142+
cargo test --verbose --all-features --lib
143+
144+
# Frontend tests and checks (if frontend changed)
145+
- name: Type Check Frontend
146+
if: needs.changes.outputs.frontend == 'true'
147+
run: pnpm run type-check
148+
continue-on-error: false
149+
150+
- name: Lint Frontend
151+
if: needs.changes.outputs.frontend == 'true'
152+
run: pnpm run lint
153+
continue-on-error: false
154+
155+
- name: Run Frontend Unit Tests
156+
if: needs.changes.outputs.frontend == 'true'
157+
run: pnpm test
158+
env:
159+
NODE_ENV: test
160+
161+
# Build frontend first (required for Tauri)
162+
- name: Build Frontend
163+
run: pnpm run build
164+
165+
# Start backend for integration tests (if needed)
166+
- name: Start Backend for Integration Tests
167+
if: needs.changes.outputs.frontend == 'true' && needs.changes.outputs.backend == 'true'
168+
run: |
169+
cd src-tauri
170+
cargo build --release
171+
# Start backend in background for frontend integration tests
172+
cargo run --release &
173+
echo $! > backend.pid
174+
sleep 5 # Give backend time to start
175+
continue-on-error: true
176+
177+
# Run frontend integration tests that depend on backend
178+
- name: Run Frontend Integration Tests
179+
if: needs.changes.outputs.frontend == 'true' && needs.changes.outputs.backend == 'true'
180+
run: pnpm run test:integration
181+
env:
182+
NODE_ENV: test
183+
BACKEND_URL: http://localhost:8080
184+
continue-on-error: true
185+
186+
# Stop backend
187+
- name: Stop Backend
188+
if: needs.changes.outputs.frontend == 'true' && needs.changes.outputs.backend == 'true'
189+
run: |
190+
if [ -f backend.pid ]; then
191+
kill $(cat backend.pid) || true
192+
rm backend.pid
193+
fi
194+
continue-on-error: true
195+
196+
# Build Tauri application (includes both frontend and backend)
197+
- name: Build Tauri Application
198+
run: pnpm tauri build --verbose
199+
env:
200+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
201+
202+
# Run Tauri integration tests
203+
- name: Run Tauri Integration Tests
204+
run: |
205+
cd src-tauri
206+
cargo test --verbose --all-features --test integration
207+
continue-on-error: true
208+
209+
# Upload build artifacts
210+
- name: Upload Tauri Bundles
211+
uses: actions/upload-artifact@v4
212+
with:
213+
name: tauri-bundles-${{ matrix.os }}
214+
path: |
215+
src-tauri/target/release/bundle/
216+
retention-days: 7
217+
218+
- name: Upload Frontend Build
219+
if: matrix.os == 'macos-latest' # Only upload once
220+
uses: actions/upload-artifact@v4
221+
with:
222+
name: frontend-dist
223+
path: dist/
224+
retention-days: 3
115225

116-
# Frontend tests and checks
117-
frontend:
118-
name: Frontend
226+
# Quick validation job for PRs (runs on Ubuntu for speed)
227+
quick-validation:
228+
name: Quick Validation
119229
runs-on: ubuntu-latest
120230
needs: changes
121-
if: needs.changes.outputs.frontend == 'true' || needs.changes.outputs.tauri == 'true'
231+
if: github.event_name == 'pull_request' && needs.changes.outputs.skip_ci == 'false'
122232

123233
steps:
124234
- name: Checkout Repository
@@ -135,48 +245,36 @@ jobs:
135245
node-version: '20'
136246
cache: 'pnpm'
137247

138-
- name: Get pnpm store directory
139-
shell: bash
140-
run: |
141-
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
142-
143-
- name: Cache pnpm dependencies
144-
uses: actions/cache@v4
248+
- name: Install Rust Toolchain
249+
uses: actions-rust-lang/setup-rust-toolchain@v1
145250
with:
146-
path: ${{ env.STORE_PATH }}
147-
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
148-
restore-keys: |
149-
${{ runner.os }}-pnpm-store-
251+
toolchain: stable
252+
components: rustfmt, clippy
150253

151254
- name: Install Dependencies
152255
run: pnpm install --frozen-lockfile
153256

154-
- name: Run Frontend Tests
155-
run: pnpm test
156-
env:
157-
NODE_ENV: test
158-
159-
- name: Build Frontend
160-
run: pnpm run build
161-
162-
- name: Upload Build Artifacts
163-
uses: actions/upload-artifact@v4
164-
with:
165-
name: frontend-dist
166-
path: dist/
167-
retention-days: 1
257+
# Quick checks only
258+
- name: Quick Rust Check
259+
if: needs.changes.outputs.backend == 'true'
260+
run: |
261+
cd src-tauri
262+
cargo check --all-targets
263+
cargo fmt --all -- --check
168264
169-
# Integration tests with Tauri
170-
tauri-test-build:
171-
name: Tauri Build Development
172-
runs-on: ${{ matrix.os }}
173-
needs: [ changes, frontend ]
174-
if: needs.changes.outputs.tauri == 'true' || (needs.changes.outputs.backend == 'true' && needs.changes.outputs.frontend == 'true')
265+
- name: Quick Frontend Check
266+
if: needs.changes.outputs.frontend == 'true'
267+
run: |
268+
pnpm run type-check
269+
pnpm run build
175270
176-
strategy:
177-
fail-fast: false
178-
matrix:
179-
os: [ ubuntu-latest, macos-latest, windows-latest ]
271+
# Security audit (optional, runs separately to not block main flow)
272+
security-audit:
273+
name: Security Audit
274+
runs-on: ubuntu-latest
275+
needs: changes
276+
if: needs.changes.outputs.backend == 'true' || needs.changes.outputs.frontend == 'true'
277+
continue-on-error: true # Don't fail CI on audit issues
180278

181279
steps:
182280
- name: Checkout Repository
@@ -195,41 +293,40 @@ jobs:
195293

196294
- name: Install Rust Toolchain
197295
uses: actions-rust-lang/setup-rust-toolchain@v1
198-
with:
199-
toolchain: stable
200-
cache: true
201296

202-
- name: Install System Dependencies (Ubuntu)
203-
if: matrix.os == 'ubuntu-latest'
297+
- name: Install cargo-audit
298+
run: cargo install cargo-audit
299+
300+
- name: Frontend Security Audit
301+
if: needs.changes.outputs.frontend == 'true'
204302
run: |
205-
sudo apt-get update
206-
sudo apt-get install -y \
207-
libwebkit2gtk-4.0-dev \
208-
libwebkit2gtk-4.1-dev \
209-
libappindicator3-dev \
210-
librsvg2-dev \
211-
patchelf \
212-
libssl-dev \
213-
pkg-config
214-
215-
- name: Cache Dependencies
216-
uses: actions/cache@v4
217-
with:
218-
path: |
219-
~/.cargo/bin/
220-
~/.cargo/registry/index/
221-
~/.cargo/registry/cache/
222-
~/.cargo/git/db/
223-
src-tauri/target/
224-
node_modules
225-
key: ${{ runner.os }}-tauri-${{ hashFiles('**/Cargo.lock', '**/pnpm-lock.yaml') }}
226-
restore-keys: |
227-
${{ runner.os }}-tauri-
303+
pnpm install --frozen-lockfile
304+
pnpm audit
305+
continue-on-error: true
228306

229-
- name: Install Dependencies
230-
run: pnpm install --frozen-lockfile
307+
- name: Rust Security Audit
308+
if: needs.changes.outputs.backend == 'true'
309+
run: |
310+
cd src-tauri
311+
cargo audit
312+
continue-on-error: true
231313

232-
- name: Build Tauri Application
233-
run: pnpm tauri build --verbose
234-
env:
235-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
314+
# Final status check
315+
ci-success:
316+
name: CI Success
317+
runs-on: ubuntu-latest
318+
needs: [full-stack-test-build, quick-validation]
319+
if: always() && needs.changes.outputs.skip_ci == 'false'
320+
321+
steps:
322+
- name: Check CI Status
323+
run: |
324+
if [[ "${{ needs.full-stack-test-build.result }}" == "failure" ]]; then
325+
echo "Full stack build failed"
326+
exit 1
327+
elif [[ "${{ needs.quick-validation.result }}" == "failure" ]]; then
328+
echo "Quick validation failed"
329+
exit 1
330+
else
331+
echo "CI OK"
332+
fi

0 commit comments

Comments
 (0)