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
43 changes: 43 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
FROM elixir:1.18-slim

# Args for setting up non-root user
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID

# Install apt packages
RUN apt-get update \
&& export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends \
build-essential \
curl \
git \
inotify-tools \
nodejs \
npm \
ca-certificates \
gnupg \
openssh-client \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Install hex and rebar
RUN mix local.hex --force && \
mix local.rebar --force

# Create non-root user
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
&& apt-get update \
&& apt-get install -y sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME

# Setup working directory
WORKDIR /workspace

# Give ownership to our user
RUN chown -R $USERNAME:$USERNAME /workspace

# Set the default user
USER $USERNAME
28 changes: 28 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "Lora Card Game",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace",
"customizations": {
"vscode": {
"extensions": [
"jakebecker.elixir-ls",
"phoenixframework.phoenix",
"bradlc.vscode-tailwindcss",
"ms-azuretools.vscode-docker",
"hbenl.vscode-test-explorer",
"pantajoe.vscode-elixir-credo"
],
"settings": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "jakebecker.elixir-ls",
"elixirLS.dialyzerEnabled": true,
"elixirLS.fetchDeps": true,
"elixirLS.suggestSpecs": true
}
}
},
"forwardPorts": [4000],
"postCreateCommand": "mix do deps.get, compile",
"remoteUser": "vscode"
}
13 changes: 13 additions & 0 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '3'

services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ..:/workspace:cached
command: sleep infinity
environment:
- MIX_ENV=dev
network_mode: host
60 changes: 60 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Lora CI

on:
push:
branches: [ main, master, develop ]
pull_request:
branches: [ main, master, develop ]

jobs:
test:
name: Build and Test
runs-on: ubuntu-latest

env:
MIX_ENV: test

steps:
- uses: actions/checkout@v3

- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
elixir-version: "1.18.2" # [Required] Define the Elixir version
otp-version: "27.2.1" # [Required] Define the Erlang/OTP version

- name: Restore dependencies cache
uses: actions/cache@v4
with:
path: |
deps
_build
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
- name: Install dependencies
run: |
mix local.rebar --force
mix local.hex --force
mix deps.get

- name: Run formatter check
run: mix format --check-formatted

- name: Compile (with warnings as errors)
run: mix compile --warnings-as-errors

# - name: Run Dialyzer
# run: mix dialyzer

- name: Run tests with coverage
run: mix test.with_coverage


- name: Archive code coverage results
uses: actions/upload-artifact@v4
with:
name: code-coverage-report
path: |
cover/
retention-days: 21

39 changes: 0 additions & 39 deletions .github/workflows/elixir.yml

This file was deleted.

74 changes: 74 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Build stage
FROM elixir:1.17-slim AS builder

# Install build dependencies
RUN apt-get update && \
apt-get install -y build-essential git npm nodejs && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Set environment variables
ENV MIX_ENV=prod \
LANG=C.UTF-8

# Install hex and rebar
RUN mix local.hex --force && \
mix local.rebar --force

# Create and set working directory
WORKDIR /app

# Copy over the mix.exs and mix.lock files to load dependencies
COPY mix.exs mix.lock ./
COPY apps/lora/mix.exs ./apps/lora/
COPY apps/lora_web/mix.exs ./apps/lora_web/
COPY config config

# Install dependencies
RUN mix deps.get --only prod
RUN mix deps.compile

# Copy over the remaining application code
COPY . .

# Build and digest assets
RUN cd apps/lora_web/assets && \
npm ci --progress=false --no-audit --loglevel=error && \
npm run deploy && \
cd ../../.. && \
mix assets.deploy

# Compile and build release
RUN mix do compile, release

# Release stage
FROM debian:bullseye-slim AS app

RUN apt-get update && \
apt-get install -y openssl libncurses5 locales && \
apt-get clean && rm -rf /var/lib/apt/lists/*

# Set locale
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

# Create a non-root user and group
RUN groupadd --gid 1000 lora && \
useradd --uid 1000 --gid lora --shell /bin/bash --create-home lora

WORKDIR /app
COPY --from=builder /app/_build/prod/rel/lora ./

# Set ownership to non-root user
RUN chown -R lora:lora /app
USER lora

EXPOSE 4000

ENV RELEASE_NODE=lora@127.0.0.1
ENV PHX_SERVER=true
ENV PHX_HOST=localhost

CMD ["bin/lora", "start"]
86 changes: 86 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,87 @@
# Lora Card Game

A real-time implementation of the Serbian card game Lora using Elixir and Phoenix LiveView.

## About the Game

Lora is a 4-player card game played with a 32-card deck (7, 8, 9, 10, J, Q, K, A in all four suits). The game consists of 28 deals with 7 different contracts (Minimum, Maximum, Queens, Hearts, Jack of Clubs, King of Hearts plus Last Trick, and Lora), each played 4 times with different dealers.

## Features

- Real-time multiplayer gameplay with Phoenix LiveView
- In-memory game state with GenServer
- 7 different contracts with unique rules
- Player reconnection support
- Responsive design for desktop browsers

## Requirements

- Elixir 1.17 or newer
- Phoenix 1.8 or newer
- Phoenix LiveView 1.1 or newer
- Node.js and npm for assets

## Development Setup

### Option 1: Local Setup

1. Install dependencies:

```bash
mix deps.get
cd apps/lora_web/assets && npm install && cd ../../..
```

2. Start the Phoenix server:

```bash
mix phx.server
```

Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.

### Option 2: Using Dev Containers (Recommended)

This project includes a dev container configuration for Visual Studio Code, which provides a consistent development environment.

1. Install the [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension for VS Code.
2. Open the project folder in VS Code.
3. When prompted to "Reopen in Container", click "Reopen in Container".
4. Once the container is built and running, the development environment is ready.
5. Open a terminal in VS Code and start the Phoenix server:

```bash
mix phx.server
```

## Running Tests

```bash
mix test
```

For test coverage:

```bash
mix coveralls.html
```

## Deployment

### Using Docker

1. Build the Docker image:

```bash
docker build -t lora-game .
```

2. Run the container:

```bash
docker run -p 4000:4000 -e PHX_HOST=your-domain.com lora-game
```

## License

This project is licensed under the MIT License - see the LICENSE file for details.
Loading
Loading