Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add lint and pipes #1

Merged
merged 11 commits into from
Mar 22, 2024
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
12 changes: 12 additions & 0 deletions .clj-kondo/config.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{:config-paths ["com.github.seancorfield/next.jdbc"
"nubank/state-flow"
"marick/midje"
"metosin/malli-types"]
:hooks {:analyze-call {integration.microservice-boilerplate.aux/init-flow nubank.state-flow/defflow
state-flow.api/defflow nubank.state-flow/defflow}}
:linters {:unsorted-required-namespaces {:level :warning}
:unresolved-var {:exclude [honeysql.helpers/select
honeysql.helpers/from]}}
:lint-as {honeysql.helpers/defhelper clj-kondo.lint-as/def-catch-all
clojure.test.check.properties/for-all clojure.core/let
clojure.test.check.clojure-test/defspec clojure.test/deftest}}
51 changes: 46 additions & 5 deletions .github/workflows/tests-backend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@ on:
# Triggers the workflow on push or pull request events but only for the main branch
pull_request:
branches: [ main ]
paths:
- 'src/**'
- 'resources/**'
- 'test/**'

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
tests:
needs: changes
strategy:
matrix:
operating-system: [ubuntu-latest]
Expand Down Expand Up @@ -44,3 +39,49 @@ jobs:

- name: Run test ${{ matrix.test-to-run }}
run: clojure -M:test ${{ matrix.test-to-run }}

check-lint:

strategy:
matrix:
operating-system: [ubuntu-latest]

runs-on: ${{ matrix.operating-system }}

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

- name: Install clojure cli
uses: DeLaGuardo/setup-clojure@master
with:
cli: 1.11.1.1435

- name: Setup clojure-lsp
uses: clojure-lsp/setup-clojure-lsp@v1
with:
clojure-lsp-version: 2024.03.01-11.37.51

- name: Execute lint checks
run: |
clojure-lsp format --dry
clojure-lsp clean-ns --dry
clojure-lsp diagnostics

security:

strategy:
matrix:
operating-system: [ubuntu-latest]

runs-on: ${{ matrix.operating-system }}

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

- name: Scan
uses: clj-holmes/clj-holmes-action@main
with:
output-type: 'stdout'
fail-on-result: 'true'
10 changes: 10 additions & 0 deletions .lsp/config.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{:clean {:ns-inner-blocks-indentation :same-line}
:cljfmt {:indents {mlet [[:block 1]]
facts [[:block 1]]
fact [[:block 1]]
flow [[:block 1]]
flow-with-defaults [[:block 1]]
flow-as-of [[:block 1]]
flow-without-validation [[:block 1]]
inter-fn [[:inner 0]
[:inner 1]]}}}
24 changes: 24 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <https://unlicense.org>
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Requirements
# ------------------------------------------

# .PHONY: ensures target used rather than matching file name
# https://makefiletutorial.com/#phony
.PHONY: deps

deps: deps.edn ## Prepare dependencies for test and dist targets
$(info --------- Download test and service libraries ---------)
clojure -P -X:build

# to build the yml service

# to build the api service
build-template: build-uberjar-api ## Build and package Clojure service
$(info --------- Build and Package Clojure service ---------)

build-uberjar-api: ## Build a uberjar archive of Clojure project & Clojure runtime
$(info --------- Build service Uberjar ---------)
clojure -T:build uberjar

147 changes: 147 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Readme Template

This is a clojure microservice template: Components, Reitit, Pedestal, Malli, Postgresql and Tests.


## About this template
- **template**: An example of how use the template, it's a simple job post api, which you can create, list all or list one job by id.

- [common/components](https://github.com/easybootstrap/common): Foundation to create new services in clojure,
you can find components for database, http, webserver and tools for db migrations.

Verb | URL | Description
-----| ------------------ | ------------------------------------------------
GET | /job/ | get all job
POST | /job/ | create a new job post
GET | /job/:id | get the job by id

## Directory Structure
```
./
├── .clj-kondo -- clj-kondo configuration and classes
├── .lsp -- clojure-lsp configuration
├── .github
│ └── workflows -- Github workflows folder.
├── docker -- docker and docker-compose files for the database
├── resources -- Application resources assets folder and configuration files.
│ └── migrations -- Current database schemas, synced on service startup.
│ └── config.edn -- Application config.
├── src -- Library source code and headers.
│ └── io/easybootstrap/template -- Source for the service example job template.
└── test -- Test source code.
├── integration -- Integration tests source (uses state-flow).
│ └── io/easybootstrap/template/ -- Tests for service integration.
└── unit -- Unity tests source (uses clojure.test).
└── io/easybootstrap/template/ -- Tests for service unit.
```

## Repl
To open a nrepl
```bash
clj -M:nrepl
```
To open a nrepl with all test extra-deps on it
```bash
clj -M:test:nrepl
```
## Run dev
To open a dev nrepl
```bash
clj -M:dev:nrepl
```

Then go to `dev/user.clj` and eval `(start)`

## Run Tests
To run unit tests inside `./test/unit`
```bash
clj -M:test :unit
```
To run integration tests inside `./test/integration`
```bash
clj -M:test :integration
```
To run all tests inside `./test`
```bash
clj -M:test
```
To generate a coverage report
```bash
clj -M:test --plugin kaocha.plugin/cloverage

|----------------------------------------------------+---------+---------|
| Namespace | % Forms | % Lines |
|----------------------------------------------------+---------+---------|
| io.easybootstrap.template.adapters.job | 65.71 | 61.54 |
| io.easybootstrap.template.controllers.job | 100.00 | 100.00 |
| io.easybootstrap.template.mediator.db.postgres.job | 100.00 | 100.00 |
| io.easybootstrap.template.mediator.http-in | 100.00 | 100.00 |
| io.easybootstrap.template.server | 14.93 | 31.82 |
| io.easybootstrap.template.wire.common | 100.00 | 100.00 |
| io.easybootstrap.template.wire.db.job | 100.00 | 100.00 |
| io.easybootstrap.template.wire.in.job | 100.00 | 100.00 |
| io.easybootstrap.template.wire.out.job | 100.00 | 100.00 |
|----------------------------------------------------+---------+---------|
| ALL FILES | 84.42 | 86.58 |
```

## Lint fix and format

```bash
clj -M:clojure-lsp format
clj -M:clojure-lsp clean-ns
clj -M:clojure-lsp diagnostics
```

## Migrations
To create a new migration with a name
```bash
clj -M:migratus create migration-name
```
To execute all pending migrations
```bash
clj -M:migratus migrate
```
To rollback the latest migration
```bash
clj -M:migratus rollback
```
See [Migratus Usage](https://github.com/yogthos/migratus#usage) for documentation on each command.

## Docker
Start containers with postgres `user: postgres, password: postgres, hostname: db, port: 5432`
and [pg-admin](http://localhost:5433) `email: [email protected], password: pg, port: 5433`
```bash
docker-compose -f docker/docker-compose.yml up -d
```
Stop containers
```bash
docker-compose -f docker/docker-compose.yml stop
```

## Running the server
First you need to have the database running, for this you can use the docker command in the step above.

### Repl
You can start a repl open and evaluate the file `src/microservice_boilerplate/server.clj` and execute following code:
```clojure
(start-system! (build-system-map))
```

### Uberjar
You can generate an uberjar and execute it via java in the terminal:
```bash
# genarate a target/service.jar
clj -T:build uberjar
# execute it via java
java -jar target/service.jar
```
## Related

Based on [this](https://github.com/parenthesin/microservice-boilerplate-malli)

## License
This is free and unencumbered software released into the public domain.
For more information, please refer to <http://unlicense.org>


35 changes: 35 additions & 0 deletions build.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(ns build
(:refer-clojure :exclude [test])
(:require [clojure.tools.build.api :as b]))

(def default-lib 'com.github.easybootstrap/microservice-template)
(def default-main 'io.easybootstrap.template.server)
(def default-version "0.0.1-SNAPSHOT")
(def class-dir "target/classes")

(defn- uber-opts [{:keys [lib main uber-file version] :as opts}]
(let [actual-lib (or lib default-lib)
actual-main (or main default-main)
actual-version (or version default-version)
actual-uber-file (or uber-file (format "target/%s-%s.jar"
actual-lib
actual-version))]
(assoc opts
:lib actual-lib
:main actual-main
:uber-file actual-uber-file
:basis (b/create-basis {})
:class-dir class-dir
:src-dirs ["src"]
:ns-compile [actual-main])))

(defn uberjar "Build the Uberjar." [opts]
(b/delete {:path "target"})
(let [{:keys [main uber-file] :as opts} (uber-opts opts)]
(println "\nCopying source" class-dir)
(b/copy-dir {:src-dirs ["resources" "src"] :target-dir class-dir})
(println (str "\nCompiling " main))
(b/compile-clj opts)
(println "\nBuilding JAR on" uber-file)
(b/uber opts))
opts)
16 changes: 16 additions & 0 deletions dev/user.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
(ns user
(:require [io.easybootstrap.tempalte.server]
[malli.dev :as dev]
[malli.dev.pretty :as pretty]))

(defn start
[]
(dev/start! {:report (pretty/thrower)}))

(defn stop
[]
(dev/stop!))

(comment
(start)
(stop))
56 changes: 56 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
FROM clojure:temurin-17-alpine AS builder

RUN mkdir -p /build
WORKDIR /build

# Cache and install Clojure dependencies
# Add before copying code to cache the layer even if code changes
COPY deps.edn Makefile /build/
RUN make deps

# Copy project to working directory
# .dockerignore file excludes all but essential files
COPY ./ /build

# - uses command `clojure -T:build uberjar :uber-file api`
RUN make build-template

# Official OpenJDK Image
FROM eclipse-temurin:17-alpine

LABEL org.opencontainers.image.authors="[email protected]"

# Create Non-root group and user to run service securely
RUN addgroup -S admin && adduser -S admin -G admin

# Create directory to contain service archive, owned by non-root user
RUN mkdir -p /service && chown -R admin. /service

# Tell docker that all future commands should run as the appuser user
USER admin

# Copy service archive file from Builder image
WORKDIR /service
COPY --from=builder /build/target/service.jar /service/service.jar

# ------------------------
# Set Service Environment variables

# optional over-rides for Integrant configuration
# ENV HTTP_SERVER_PORT=
# ENV MYSQL_DATABASE=
ENV PROFILE=prod

# Expose port of HTTP Server
EXPOSE 3000

# ------------------------
# Run service

# JDK_JAVA_OPTIONS environment variable for setting JVM options
# Use JVM options that optomise running in a container
# For very low latency, use the Z Garbage collector "-XX:+UseZGC"
ENV JDK_JAVA_OPTIONS "-XshowSettings:system -XX:+UseContainerSupport -XX:MaxRAMPercentage=90"

# (overrides `jshell` entrypoint - default in eclipse-temuring image)
ENTRYPOINT ["java", "-jar", "/service/service.jar"]
Loading
Loading