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
20 changes: 20 additions & 0 deletions .credo.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
%{
configs: [
%{
name: "default",
files: %{
included: ["lib/", "test/", "config/", "mix.exs"],
excluded: ["_build/", "deps/", "dist/"]
},
strict: true,
color: true,
checks: [
{Credo.Check.Design.TagTODO, false},
{Credo.Check.Readability.ModuleDoc, false},
{Credo.Check.Readability.Specs, false},
{Credo.Check.Refactor.CyclomaticComplexity, max_complexity: 15},
{Credo.Check.Refactor.Nesting, max_nesting: 3}
]
}
]
}
55 changes: 55 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: CI

on:
pull_request:
push:
branches:
- main

permissions:
contents: read

jobs:
lint-test-build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Elixir/OTP
uses: erlef/setup-beam@v1
with:
elixir-version: '1.19.4'
otp-version: '28.3'

- name: Restore Mix 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 deps.get

- name: Check formatting
run: mix format --check-formatted

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

- name: Run Credo
run: mix credo --strict

- name: Run tests
run: mix test

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build container image (amd64 smoke build)
run: docker buildx build --platform linux/amd64 --load -t codeline:ci -f docker/Dockerfile .
106 changes: 106 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Deploy

on:
workflow_dispatch:
workflow_run:
workflows:
- CI
types:
- completed
branches:
- main

permissions:
contents: read
packages: write

env:
IMAGE_REPO: ghcr.io/carverauto/codeline

jobs:
build-and-push:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
outputs:
image: ${{ steps.meta.outputs.image }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Compute image tag
id: meta
run: |
IMAGE_TAG="sha-$(git rev-parse --short=12 HEAD)"
echo "image=${IMAGE_REPO}:${IMAGE_TAG}" >> "$GITHUB_OUTPUT"

- name: Build and push amd64 image
run: |
docker buildx build \
--platform linux/amd64 \
--push \
-t "${{ steps.meta.outputs.image }}" \
-f docker/Dockerfile \
.

deploy-prod:
runs-on: ubuntu-latest
needs: build-and-push
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}

- name: Setup kubectl
uses: azure/setup-kubectl@v4

- name: Setup kustomize
uses: imranismail/setup-kustomize@v2
with:
kustomize-version: '5.4.3'

- name: Write kubeconfig
env:
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
run: |
mkdir -p "$HOME/.kube"
printf '%s' "$KUBE_CONFIG" > "$HOME/.kube/config"
chmod 600 "$HOME/.kube/config"

- name: Set image in prod overlay
working-directory: k8s/prod
run: |
kustomize edit set image ghcr.io/carverauto/codeline=${{ needs.build-and-push.outputs.image }}

- name: Ensure namespace exists
run: |
kubectl create namespace codeline --dry-run=client -o yaml | kubectl apply -f -

- name: Apply admin secret
env:
CODELINE_ADMIN_CODE: ${{ secrets.CODELINE_ADMIN_CODE }}
run: |
kubectl -n codeline create secret generic codeline-secret-prod \
--from-literal=CODELINE_ADMIN_CODE="$CODELINE_ADMIN_CODE" \
--dry-run=client -o yaml | kubectl apply -f -

- name: Apply manifests
run: kubectl apply -k k8s/prod

- name: Wait for rollout
run: kubectl -n codeline rollout status deployment/codeline-prod --timeout=300s
8 changes: 7 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule Codeline.MixProject do
version: "0.1.0",
elixir: "~> 1.16",
start_permanent: Mix.env() == :prod,
deps: []
deps: deps()
]
end

Expand All @@ -17,4 +17,10 @@ defmodule Codeline.MixProject do
mod: {Codeline.Application, []}
]
end

defp deps do
[
{:credo, "~> 1.7", only: [:dev, :test], runtime: false}
]
end
end
6 changes: 6 additions & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
%{
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
"credo": {:hex, :credo, "1.7.17", "f92b6aa5b26301eaa5a35e4d48ebf5aa1e7094ac00ae38f87086c562caf8a22f", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1eb5645c835f0b6c9b5410f94b5a185057bcf6d62a9c2b476da971cde8749645"},
"file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
}