Skip to content
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
121 changes: 121 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
name: ci

permissions:
contents: read

on:
pull_request:
push:
branches: [main]

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
- uses: actions/setup-node@v6
with:
node-version: '24'
cache: 'npm'
- name: Install npm dependencies
run: npm ci
- uses: pre-commit/action@v3.0.1

test:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Run tests with coverage thresholds
run: npm run test:coverage

build:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: "24"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build production bundle
run: npm run build

smoke-test:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- name: Build and start containers
run: docker compose up --build -d
- name: Wait for container health
run: |
for i in {1..60}; do
container_id="$(docker compose ps -q poker-solver)"
if [ -z "$container_id" ]; then
sleep 1
continue
fi

health_status="$(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}no-healthcheck{{end}}' "$container_id")"

if [ "$health_status" = "healthy" ]; then
echo "Container is healthy"
exit 0
fi

if [ "$health_status" = "unhealthy" ]; then
echo "Container is unhealthy"
docker compose logs --tail=200
exit 1
fi

sleep 1
done

echo "Timed out waiting for container health"
docker compose ps
docker compose logs --tail=200
exit 1
- name: Wait for and verify app response
run: |
for i in {1..30}; do
code="$(curl -sS -o /tmp/smoke.html -D /tmp/smoke.headers -w '%{http_code}' http://localhost:8080 || true)"
if [ "$code" = "200" ] && \
grep -qi '^content-type:.*text/html' /tmp/smoke.headers && \
grep -q '<title>Simplified Poker Solver</title>' /tmp/smoke.html && \
grep -q '<div id="root"></div>' /tmp/smoke.html; then
echo "Smoke check passed"
exit 0
fi
sleep 1
done
echo "Smoke check failed: app page did not match expected content within 30 seconds"
echo "Last headers:"
cat /tmp/smoke.headers || true
echo "Last body (first 120 lines):"
sed -n '1,120p' /tmp/smoke.html || true
exit 1
- name: Show container status and logs on failure
if: failure()
run: |
docker compose ps
docker compose logs --tail=200
- name: Teardown containers
if: always()
run: docker compose down -v
21 changes: 0 additions & 21 deletions .github/workflows/pre-commit.yaml

This file was deleted.

6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ repos:
- id: check-yaml
# NOTE: this repo is deprecated but still works fine
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
rev: v4.0.0-alpha.8
hooks:
- id: prettier
additional_dependencies:
- prettier@3.3.3
files: "\\.(js|jsx|ts|tsx|json|css|scss|md|html)$"
- repo: https://github.com/markdownlint/markdownlint
rev: v0.13.0
rev: v0.15.0
hooks:
- id: markdownlint
args: ['--style', '.markdownlint.rb']
language_version: system
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v9.39.1
rev: v10.0.2
hooks:
- id: eslint
files: \.[jt]sx?$
Expand Down
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ FROM nginx:alpine
# Copy the build output from the previous stage to the Nginx html directory
COPY --from=build /app/build /usr/share/nginx/html

# Mark the container healthy only when nginx is serving content.
HEALTHCHECK --interval=10s --timeout=3s --start-period=10s --retries=3 \
CMD wget -q -O /dev/null http://localhost/ || exit 1

# Expose port 80
EXPOSE 80

Expand Down
Loading
Loading