Skip to content

Commit f57b360

Browse files
authored
Merge pull request #6 from Project-Code-UVA/ci-cd
Ci cd
2 parents 86a3d32 + 868a5ee commit f57b360

File tree

21 files changed

+326
-0
lines changed

21 files changed

+326
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Deploy Production
2+
3+
on:
4+
push:
5+
tags: ['v*.*.*'] # semantic-version tag triggers
6+
7+
jobs:
8+
promote:
9+
runs-on: ubuntu-latest
10+
environment: production
11+
12+
steps:
13+
- name: Pull exact containers built for same commit
14+
run: |
15+
docker pull ghcr.io/${{ github.repository }}:staging
16+
docker tag ghcr.io/${{ github.repository }}:staging ghcr.io/${{ github.repository }}:prod
17+
18+
- name: Push prod tag
19+
run: docker push ghcr.io/${{ github.repository }}:prod
20+
21+
- name: ECS update service
22+
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
23+
with:
24+
task-definition: backend/taskdef.json # checked-in file
25+
service: ai-eyes-prod
26+
cluster: ai-eyes
27+
wait-for-service-stability: true
28+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
29+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
30+
aws-region: us-east-1
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Deploy Staging
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
jobs:
8+
build-and-deploy:
9+
runs-on: ubuntu-latest
10+
environment: staging # add env-level secrets if desired
11+
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- uses: actions/setup-node@v4
16+
with:
17+
node-version: 20
18+
cache: 'npm'
19+
- run: npm ci
20+
- run: npx expo export --platform web --output-dir dist-web
21+
22+
- name: Build backend container
23+
uses: docker/build-push-action@v5
24+
with:
25+
context: backend
26+
push: true
27+
tags: ghcr.io/${{ github.repository }}:staging
28+
29+
# Example: deploy to AWS Elastic Beanstalk
30+
- name: Deploy to EB
31+
uses: einaregilsson/beanstalk-deploy@v25
32+
with:
33+
application_name: ai-eyes-staging
34+
environment_name: ai-eyes-staging-env
35+
version_label: github-${{ github.sha }}
36+
bucket_name: ${{ secrets.EB_S3_BUCKET }}
37+
bucket_key: app-${{ github.sha }}.zip
38+
region: us-east-1
39+
deployment_package: backend/Dockerrun.aws.json
40+
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
41+
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Integration Tests
2+
3+
on:
4+
pull_request:
5+
workflow_run:
6+
workflows: [Unit Tests]
7+
types: [completed]
8+
9+
jobs:
10+
integration:
11+
runs-on: ubuntu-latest
12+
services:
13+
postgres:
14+
image: postgres:15
15+
env:
16+
POSTGRES_PASSWORD: test
17+
ports: ['5432:5432']
18+
options: >-
19+
--health-cmd "pg_isready -U postgres"
20+
--health-interval 5s
21+
--health-timeout 5s
22+
--health-retries 5
23+
24+
steps:
25+
- uses: actions/checkout@v4
26+
- uses: actions/setup-node@v4
27+
with:
28+
node-version: 20
29+
- run: npm ci
30+
- name: Start backend (FastAPI) in background
31+
run: |
32+
pip install -r backend/requirements.txt
33+
uvicorn backend.app:app --host 0.0.0.0 --port 8000 &
34+
- name: Run integration tests
35+
run: npm run test:integration
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: Security Scan
2+
3+
on:
4+
pull_request:
5+
schedule:
6+
- cron: '0 4 * * 0' # weekly Sunday 04:00 UTC
7+
8+
jobs:
9+
codeql:
10+
uses: github/codeql-action/.github/workflows/codeql.yml@v3

.github/workflows/superlinter.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Super-Linter
2+
3+
on:
4+
pull_request:
5+
branches: ['application-implementation'] # Trigger on PRs to application-implementation branch
6+
push:
7+
branches: ['application-implementation'] # Trigger on pushes to application-implementation branch
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
# Super-Linter ships with rules for JS, TS, Python, Markdown, JSON…
16+
- name: Code Lint
17+
uses: github/super-linter/slim@v6
18+
env:
19+
DEFAULT_BRANCH: application-implementation # Update default branch to application-implementation
20+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21+
# Optional: turn off languages you don’t use
22+
# DISABLE_LINTERS: 'RUBY,GO'

.github/workflows/unit-tests.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Unit Tests
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: ['**']
7+
8+
jobs:
9+
test-js-py:
10+
runs-on: ubuntu-latest
11+
12+
strategy:
13+
matrix:
14+
node: [18, 20]
15+
python: ['3.10', '3.11']
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
# ───────────── JavaScript side ─────────────
21+
- name: Set up Node
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: ${{ matrix.node }}
25+
# ⚠️ no cache line → setup-node won’t look for package-lock.json
26+
# cache: 'npm'
27+
28+
- name: Install JS deps
29+
run: |
30+
if [ -f package-lock.json ]; then
31+
echo "package-lock.json found → npm ci"
32+
npm ci
33+
else
34+
echo "No lock-file → npm install"
35+
npm install
36+
fi
37+
38+
- name: Run JS unit tests (if any)
39+
run: npm test -- --ci || echo "No JS tests"
40+
41+
# ───────────── Python side ─────────────
42+
- name: Set up Python
43+
uses: actions/setup-python@v5
44+
with:
45+
python-version: ${{ matrix.python }}
46+
cache: 'pip'
47+
48+
- name: Install Python deps & run tests
49+
run: |
50+
pip install -r backend/requirements.txt
51+
pip install pytest
52+
pytest backend || echo "No Py tests"
File renamed without changes.

client/package.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "client",
3+
"version": "1.0.0",
4+
"private": true,
5+
"dependencies": {
6+
"react": "^18.2.0",
7+
"react-dom": "^18.2.0",
8+
"react-scripts": "5.0.1"
9+
},
10+
"scripts": {
11+
"start": "react-scripts start",
12+
"build": "react-scripts build",
13+
"test": "react-scripts test",
14+
"eject": "react-scripts eject"
15+
},
16+
"eslintConfig": {
17+
"extends": [
18+
"react-app",
19+
"react-app/jest"
20+
]
21+
},
22+
"browserslist": {
23+
"production": [
24+
">0.2%",
25+
"not dead",
26+
"not op_mini all"
27+
],
28+
"development": [
29+
"last 1 chrome version",
30+
"last 1 firefox version",
31+
"last 1 safari version"
32+
]
33+
}
34+
}

client/public/index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>React App</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
</body>
11+
</html>

client/src/App.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react';
2+
3+
function App() {
4+
return (
5+
<div className="App">
6+
<h1>Hello, World!</h1>
7+
</div>
8+
);
9+
}
10+
11+
export default App;

0 commit comments

Comments
 (0)