| Project | Contant |
|---|---|
| Which course does this assignment belong to | Course Community |
| Where are the requirements for this assignment | Assignment Requirements |
| My goals in this course | Team collaboration, division of labor to complete the full software development process |
| How this assignment helps me achieve my goals | By completing CI/CD practice |
1. Option Selection and Rationale
Selected Solution
Solution A: GitHub Actions as the CI/CD tool.
Rationale
Our code is hosted on GitHub, and GitHub Actions is convenient to run with a simple workflow.
2. CI/CD Configuration Files
Separate workflow files were written for the backend and frontend, respectively.
Backend CI Configuration (backend-ci.yml)
name: Backend CI
on:
push:
branches: [main, dev]
paths:
- "backend/**"
- ".github/workflows/backend-ci.yml"
pull_request:
branches: [main, dev]
paths:
- "backend/**"
jobs:
lint-and-test:
name: Lint & Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"]
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_pass
POSTGRES_DB: test_db
ports:
- 5432:5432
options: >-
--health-cmd="pg_isready -U test_user"
--health-interval=10s
--health-timeout=5s
--health-retries=5
redis:
image: redis:7
ports:
- 6379:6379
options: >-
--health-cmd="redis-cli ping"
--health-interval=10s
--health-timeout=5s
--health-retries=5
defaults:
run:
working-directory: backend
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip packages
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('backend/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Lint with Ruff
run: |
ruff check --fix app/ tests/
ruff format app/ tests/
- name: Type check with mypy
run: mypy app/ --ignore-missing-imports
- name: Run tests with pytest
env:
DATABASE_URL: postgresql://test_user:test_pass@localhost:5432/test_db
REDIS_URL: redis://localhost:6379/0
TESTING: "1"
run: pytest tests/ -v --cov=app --cov-report=term-missing --cov-report=xml
- name: Upload coverage report
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: backend/coverage.xml
Frontend CI Configuration (frontend-ci.yml)
name: Frontend CI
on:
push:
branches: [main, dev]
paths:
- "frontend/**"
- ".github/workflows/frontend-ci.yml"
pull_request:
branches: [main, dev]
paths:
- "frontend/**"
jobs:
lint-and-build:
name: Lint & Build
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Cache node_modules
uses: actions/cache@v4
with:
path: frontend/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm install
- name: Lint
run: npm run lint
- name: Build (WeChat Mini Program)
run: npm run build:mp-weixin
- name: Upload build artifact
if: github.ref == 'refs/heads/main'
uses: actions/upload-artifact@v4
with:
name: mp-weixin-dist
path: frontend/dist/build/mp-weixin/
retention-days: 7
3. Implementation Approach and Rationale
Branch Strategy
| Branch | Purpose |
|---|---|
main |
Stable release branch |
dev |
Daily collaborative development branch |
Both branches are configured with CI checks.
Trigger Conditions
- Push: Triggers when code is directly pushed to the
mainordevbranches. Suitable for quick validation during daily development. - Pull Request: Triggers when a Pull Request is opened against
mainordev. Suitable for quality control before code merging. - Path Filtering: Using
pathsto trigger the respective CI onlly when files in the corresponding directory change. Changes underbackend/only trigger Backend CI, while changes underfrontend/only trigger Frontend CI.
Rationale: Early in the project, push triggers are used for rapid iteration. As the team's collaboration matures, we will rely more on PR triggers for code review. Path filtering is especially important for monorepo structures because the backend and frontend change frequency can differ, allowing them to be decoupled and not interfere with each other.
Pipeline Steps
Backend CI Pipeline
| Step | Tool | Purpose |
|---|---|---|
| Code Style Check | Ruff | Checks Python code style (PEP 8) and import ordering |
| Type Checking | mypy | Static type analysis to catch type errors early |
| Unit Testing | pytest | Runs test cases to verify API functional correctness |
The backend CI also configures PostgreSQL and Redis service containers to provide a realistic database environment for integration tests.
Frontend CI Pipeline
| Step | Tool | Purpose |
|---|---|---|
| Code Style Check | ESLint | Checks TypeScript/Vue code conventions |
| Build Verification | uni-app CLI | Builds the WeChat Mini Program artifact to verify compilation |
Rationale: Ruff is currently the fastest linter in the Python community, 10-100 times faster than flake8 + isort, making it ideal for CI environments. pytest is the most mainstream testing framework for Python and works well with FastAPI. For the frontend, ESLint is the standard configuration for Vue/TypeScript projects.