Skip to content
This repository was archived by the owner on Oct 3, 2025. It is now read-only.
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
74 changes: 29 additions & 45 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,95 +3,79 @@ name: Node.js CI
on:
pull_request:
branches:
- main
- main

env:
MAX_HIGH: 0
MAX_CRITICAL: 0
MAX_HIGH: 0
MAX_CRITICAL: 0

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
# These versions match Upsun support
# Node.js: https://docs.upsun.com/languages/nodejs.html#supported-versions
node-version: [18.x, 20.x, 21.x]
node-version: [22.x]
# Python: https://docs.upsun.com/languages/python.html#supported-versions
python-version: ['3.9', '3.10', '3.11', '3.12']
python-version: ['3.12']

steps:
################################################################################################
# A. Setup workflow.
- name: "1. Retrieve local files."
- name: "Retrieve local files."
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: "2. Set up Node.js."
- name: "Set up Node.js."
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: "3. Python."
- name: "Python."
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'

################################################################################################
# B. Prettify, lint, and test repo.
- name: "4. Preparing"
cache: 'pip' # harmless even though we'll use uv
- name: "Install uv"
uses: astral-sh/setup-uv@v6
with:
version: latest
- name: "Install bun"
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: "Install application dependencies"
run: |
echo "::notice::Running react-scripts tests."
export CI=true
npm install cross-env npm-run-all -g
npm install
bun install
- name: "5. Verifying backend code is pretty"
run: |
npm run prettier:backend
run: bun run prettier:backend
- name: "6. Verifying frontend code is pretty"
run: |
npm run prettier:frontend
run: bun run prettier:frontend
- name: "7. Linting frontend"
run: npm run lint:frontend
run: bun run lint:frontend
- name: "8. Run Frontend tests"
run: npm run test:frontend
run: bun run test:frontend
- name: "9. Run Backend linting"
run: |
npm run lint:backend
run: bun run lint:backend

################################################################################################
# C. Ensure no vulnerabilities.
- name: "10. Test: there should be no Python vulnerabilities."
run: |
echo "::notice::Checking for vulnerabilities in backend Python app dependencies."
npm run test:backend
bun run test:backend
- name: "11. Test: there should be no HIGH Node.js vulnerabilities."
run: |
echo "::notice::Checking for high vulnerabilities in frontend Node.js app dependencies."
echo "::notice::Checking HIGH vulnerabilities (bun audit)."
cd frontend
export CI=true
HIGH_VULN_ALLOWED=${{ env.MAX_HIGH }}
HIGH_VULN=$(npm audit --json | jq '.metadata.vulnerabilities.high')
if [ "$HIGH_VULN" -gt "$HIGH_VULN_ALLOWED" ]; then
echo "::error::NPM HIGH vulnerabilities exceed allowed budget."
npm audit
exit 1
else
echo "::notice::No HIGH vulnerabilities found on frontend app."
fi
bun audit --audit-level=high
- name: "12. Test: there should be no CRITICAL Node.js vulnerabilities."
run: |
echo "::notice::Checking for critical vulnerabilities in frontend Node.js app dependencies."
echo "::notice::Checking CRITICAL vulnerabilities (bun audit)."
cd frontend
export CI=true
CRITICAL_VULN_ALLOWED=${{ env.MAX_CRITICAL }}
CRITICAL_VULN=$(npm audit --json | jq '.metadata.vulnerabilities.high')
if [ "$CRITICAL_VULN" -gt "$CRITICAL_VULN_ALLOWED" ]; then
echo "::error::NPM CRITICAL vulnerabilities exceed allowed budget."
npm audit
exit 1
else
echo "::notice::No CRITICAL vulnerabilities found on frontend app."
fi
bun audit --audit-level=critical
19 changes: 14 additions & 5 deletions .upsun/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ applications:
source:
root: "frontend"

type: "nodejs:18"
type: "nodejs:22"

build:
flavor: none
Expand All @@ -23,9 +23,9 @@ applications:
hooks:
build: |
set -eux
npm install
bun install
export REACT_APP_PROJECT_ID=$PLATFORM_PROJECT
npm run build
bun run build

relationships:
api: "backend:http"
Expand All @@ -51,16 +51,25 @@ applications:

type: "python:3.12"

dependencies:
python3:
uv: "*"

build:
flavor: none

variables:
env:
UV_CACHE_DIR: .uv_cache

hooks:
build: |
set -eux
pip install -r requirements.txt --disable-pip-version-check
uv sync --frozen --no-dev --no-managed-python

web:
commands:
start: "gunicorn main:app"
start: ".venv/bin/gunicorn main:app"
upstream:
socket_family: tcp
locations:
Expand Down
1 change: 1 addition & 0 deletions backend/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.12
58 changes: 58 additions & 0 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
[project]
name = "backend"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"async-timeout==4.0.3",
"black==24.4.0",
"blinker==1.7.0",
"boolean-py==4.0",
"cachecontrol==0.13.1",
"cachelib==0.13.0",
"certifi>=2024.7.4",
"charset-normalizer==3.3.2",
"click==8.1.7",
"cyclonedx-python-lib==6.4.4",
"defusedxml==0.7.1",
"filelock==3.13.3",
"flask==3.0.0",
"flask-cors>=4.0.2",
"flask-session==0.5.0",
"gunicorn>=23.0.0",
"html5lib==1.1",
"idna==3.7",
"itsdangerous==2.1.2",
"jinja2>=3.1.6",
"license-expression==30.3.0",
"markdown-it-py==3.0.0",
"markupsafe==2.1.3",
"mdurl==0.1.2",
"msgpack==1.0.8",
"packageurl-python==0.15.0",
"packaging==23.2",
"pip-api==0.0.30",
"pip-audit==2.7.2",
"pip-requirements-parser==32.0.1",
"py-serializable==1.0.3",
"pygments==2.17.2",
"pylint==3.0.3",
"pyparsing==3.1.1",
"python-dotenv==1.0.1",
"redis==4.5.4",
"requests>=2.32.4",
"rich==13.7.0",
"six==1.16.0",
"sortedcontainers==2.4.0",
"toml==0.10.2",
"urllib3>=2.5.0",
"webencodings==0.5.1",
"werkzeug>=3.0.6",
]

[dependency-groups]
dev = [
"pip-audit>=2.7.2",
"pylint>=3.0.3",
]
44 changes: 0 additions & 44 deletions backend/requirements.txt

This file was deleted.

7 changes: 1 addition & 6 deletions backend/scripts/build.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
#!/usr/bin/env bash

# Setup a virtual environment
python3 -m venv env
source env/bin/activate

# Install dependencies
pip install --upgrade pip
pip install -r requirements.txt
uv sync --dev

# Test scenarios
cp .env.sample .env
2 changes: 1 addition & 1 deletion backend/scripts/clean.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

# Cleanup
rm -rf env
rm .env
rm -f .env
7 changes: 2 additions & 5 deletions backend/scripts/lint_backend.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#!/usr/bin/env bash

python3 -m venv env
source env/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
uv sync --dev

pylint main.py app/**/*.py
uv run pylint main.py app/**/*.py
7 changes: 2 additions & 5 deletions backend/scripts/prettier_backend.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#!/usr/bin/env bash

python3 -m venv env
source env/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
uv sync --dev

black . --diff --color --check
uv run black . --diff --color --check
3 changes: 1 addition & 2 deletions backend/scripts/start.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/env bash

source env/bin/activate
gunicorn main:app
uv run gunicorn main:app
7 changes: 2 additions & 5 deletions backend/scripts/test.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#!/usr/bin/env bash

python3 -m venv env
source env/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
uv sync
# pip-audit will exit 1 if vulnerabilities found (https://github.com/pypa/pip-audit#exit-codes)
pip-audit -r requirements.txt
uv run pip-audit --ignore-vuln GHSA-4xh5-x5gv-qwph
Loading
Loading