diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 00000000..96768db6 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,75 @@ + + +# Dev Container + +This directory contains a [dev container](https://containers.dev/) configuration for AshAuthentication. It provides a fully configured development environment with Elixir, Erlang, and PostgreSQL. + +## Getting Started + +### VS Code + +1. Install the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) +2. Open the project in VS Code +3. When prompted, click "Reopen in Container" (or run the **Dev Containers: Reopen in Container** command) + +### Devcontainer CLI + +```sh +devcontainer up --workspace-folder . +devcontainer exec --workspace-folder . bash +``` + +## What's Included + +- **Elixir & Erlang** — installed via asdf, versions defined in `.tool-versions` +- **PostgreSQL 16** — running as a separate container, available at host `db` +- **GitHub CLI** — for working with pull requests and issues +- **Zsh** — configured as the default shell + +The setup script automatically installs asdf plugins, language versions, and fetches Hex/Rebar dependencies. + +## Environment Variables + +The following environment variables are forwarded from your local environment into the container: + +| Variable | Purpose | +|---|---| +| `OAUTH2_CLIENT_ID` | OAuth2 test client ID | +| `OAUTH2_CLIENT_SECRET` | OAuth2 test client secret | +| `OAUTH2_SITE` | OAuth2 test site URL | +| `HEX_API_KEY` | Hex.pm API key for publishing | +| `GITHUB_CLIENT_ID` | GitHub OAuth client ID | +| `GITHUB_CLIENT_SECRET` | GitHub OAuth client secret | +| `OAUTH2_TEST_CREDS` | OAuth2 test credentials | + +Set these in your local shell environment before opening the container. + +## Dotfiles + +The dev container supports automatically cloning and installing your personal dotfiles. This is useful for bringing in your shell configuration, Git aliases, editor settings, etc. + +### VS Code + +Add the following to your VS Code user settings (`settings.json`): + +```json +{ + "dotfiles.repository": "your-github-username/dotfiles", + "dotfiles.targetPath": "~/dotfiles", + "dotfiles.installCommand": "install.sh" +} +``` + +- **`dotfiles.repository`** — any valid git URL, or a GitHub shorthand like `username/dotfiles` (which expands to `https://github.com/username/dotfiles.git`). Full URLs for other hosts work too, e.g. `https://gitlab.com/user/dotfiles.git`. +- **`dotfiles.targetPath`** — where to clone the repo (defaults to `~/dotfiles`) +- **`dotfiles.installCommand`** — script to run after cloning (defaults to `install.sh`). If not found, the container will try `setup.sh`, `bootstrap.sh`, and several other common names before falling back to symlinking dotfiles to your home directory. + +### Devcontainer CLI + +```sh +devcontainer up --workspace-folder . --dotfiles-repository https://github.com/your-username/dotfiles +``` diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..1dd3736d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,33 @@ +{ + "name": "AshAuthentication", + "dockerComposeFile": "docker-compose.yml", + "service": "app", + "workspaceFolder": "/workspaces/ash_authentication", + "forwardPorts": [4000, "db:5432"], + "portsAttributes": { + "4000": { + "label": "Phoenix Dev Server" + }, + "5432": { + "label": "Postgres" + } + }, + "features": { + "ghcr.io/devcontainers/features/github-cli": {}, + "ghcr.io/devcontainers-extra/features/apt-packages:1": { + "packages": "autoconf,m4,libwxgtk3.2-dev,libwxgtk-webview3.2-dev,libgl1-mesa-dev,libglu1-mesa-dev,libpng-dev,libssh-dev,unixodbc-dev,xsltproc,fop,libxml2-utils,libncurses-dev" + }, + "ghcr.io/devcontainer-community/devcontainer-features/asdf-vm.com:1": {} + }, + "onCreateCommand": "bash .devcontainer/setup.sh", + "remoteEnv": { + "DATABASE_HOST": "db", + "OAUTH2_CLIENT_ID": "${localEnv:OAUTH2_CLIENT_ID}", + "OAUTH2_CLIENT_SECRET": "${localEnv:OAUTH2_CLIENT_SECRET}", + "OAUTH2_SITE": "${localEnv:OAUTH2_SITE}", + "HEX_API_KEY": "${localEnv:HEX_API_KEY}", + "GITHUB_CLIENT_ID": "${localEnv:GITHUB_CLIENT_ID}", + "GITHUB_CLIENT_SECRET": "${localEnv:GITHUB_CLIENT_SECRET}", + "OAUTH2_TEST_CREDS": "${localEnv:OAUTH2_TEST_CREDS}" + } +} diff --git a/.devcontainer/devcontainer.json.license b/.devcontainer/devcontainer.json.license new file mode 100644 index 00000000..f66b5ef4 --- /dev/null +++ b/.devcontainer/devcontainer.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2022 Alembic Pty Ltd + +SPDX-License-Identifier: MIT diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 00000000..e9d50540 --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,35 @@ +# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd +# +# SPDX-License-Identifier: MIT + +services: + app: + image: mcr.microsoft.com/devcontainers/base:debian + volumes: + - ..:/workspaces/ash_authentication:cached + - dialyzer-plt:/home/vscode/.mix + command: sleep infinity + environment: + DATABASE_HOST: db + depends_on: + db: + condition: service_healthy + + db: + image: postgres:16 + restart: unless-stopped + volumes: + - postgres-data:/var/lib/postgresql/data + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: ash_authentication_dev + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 5s + retries: 5 + +volumes: + postgres-data: + dialyzer-plt: diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh new file mode 100755 index 00000000..46b3f160 --- /dev/null +++ b/.devcontainer/setup.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd +# +# SPDX-License-Identifier: MIT + +if [ -e .asdf-plugins ]; then + source .asdf-plugins +fi + +if [ ! -e .tool-versions ]; then + echo "No .tool-versions file found!" + exit 1 +fi + +set -euo pipefail + +PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH" +REQUIRED_PLUGINS=$(cat .tool-versions | cut -d \ -f 1) +INSTALLED_PLUGINS=$(asdf plugin list || echo "") + +echo -n "==> Installing/updating required plugins: " +for PLUGIN in $REQUIRED_PLUGINS; do + if [[ $INSTALLED_PLUGINS =~ (^|[[:space:]])"$PLUGIN"($|[[:space:]]) ]]; then + asdf plugin update $PLUGIN + else + asdf plugin add $PLUGIN + fi + echo -n "$PLUGIN " +done +echo + +echo "==> Installing tools: " +asdf install + +echo "==> Setting up Hex and Rebar" +mix local.hex --force +mix local.rebar --force + +echo "==> Fetching dependencies..." +mix deps.get + +echo "==> Setup complete!" diff --git a/config/dev.exs b/config/dev.exs index 6d17a056..9e69d4cd 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -22,7 +22,7 @@ config :ash_authentication, ecto_repos: [Example.Repo], ash_domains: [Example, E config :ash_authentication, Example.Repo, username: "postgres", password: "postgres", - hostname: "localhost", + hostname: System.get_env("DATABASE_HOST", "localhost"), database: "ash_authentication_dev", stacktrace: true, show_sensitive_data_on_connection_error: true, diff --git a/config/test.exs b/config/test.exs index e01ac39c..3dc142fa 100644 --- a/config/test.exs +++ b/config/test.exs @@ -9,7 +9,7 @@ config :ash_authentication, ecto_repos: [Example.Repo], ash_domains: [Example, E config :ash_authentication, Example.Repo, username: "postgres", password: "postgres", - hostname: "localhost", + hostname: System.get_env("DATABASE_HOST", "localhost"), database: "ash_authentication_test#{System.get_env("MIX_TEST_PARTITION")}", pool: Ecto.Adapters.SQL.Sandbox, pool_size: 10