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
63 changes: 63 additions & 0 deletions .github/workflows/flow_backend_build_push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Build & push backend container image

on:
workflow_call:
inputs:
service-build-context-path:
description: The path to the context to use when building the container image
default: ./backend
required: false
type: string
service-name:
description: The name of the service to build
required: true
type: string
push-image:
description: Whether to push the container image to the registry
default: false
required: false
type: boolean
image-tags:
description: The tags to pass to the "docker/metadata-action" action
required: true
type: string

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v3

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

- uses: docker/metadata-action@v5
name: Extract metadata (tags, labels) for Docker
id: meta
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ inputs.service-name }}
tags: ${{ inputs.image-tags }}
flavor: latest=false

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
push: ${{ inputs.push-image }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
context: "{{ defaultContext }}:${{ inputs.service-build-context-path }}"
build-args: SERVICE_NAME=${{ inputs.service-name }}
34 changes: 34 additions & 0 deletions .github/workflows/flow_backend_lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Lint backend

on:
workflow_call:
inputs:
gradle-root-project-path:
description: The path to the Gradle root project
default: ./backend
required: false
type: string

jobs:
lint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ inputs.gradle-root-project-path }}
steps:
- uses: actions/checkout@v4

- name: Use Java
uses: actions/setup-java@v3
with:
java-version: 17
distribution: corretto

- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- name: Lint Kotlin
run: ./gradlew ktlintCheck

- name: Execute Gradle build
run: ./gradlew build -x test
38 changes: 38 additions & 0 deletions .github/workflows/flow_front_lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Lint frontend

on:
workflow_call:
inputs:
app-dir-path:
description: The directory where the frontend application is stored
default: ./front
required: false
type: string

jobs:
lint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ inputs.app-dir-path }}
steps:
- uses: actions/checkout@v4

- name: Use Node.js 18
uses: actions/setup-node@v4
with:
node-version: 18
cache: 'npm'
cache-dependency-path: ${{ inputs.app-dir-path }}

- name: Install dependencies
run: npm ci

- name: Run Prettier
run: npm run prettier:check

- name: Run ESLint
run: npm run eslint:check

- name: Run TypeScript
run: npm run typescript:check
43 changes: 43 additions & 0 deletions .github/workflows/on_push_pr_main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Push & PR to the main branch

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

jobs:
lint_frontend:
name: Lint frontend
uses: ./.github/workflows/flow_front_lint.yml

lint_backend:
name: Lint backend
uses: ./.github/workflows/flow_backend_lint.yml

build_api_gateway:
name: Build & push Docker image of the API gateway
needs: lint_backend
uses: ./.github/workflows/flow_backend_build_push.yml
with:
service-name: api_gateway
push-image: ${{ github.event_name != 'pull_request' }}
image-tags: |
type=sha
type=ref,event=branch
type=edge,branch=main

build_jobs_service:
name: Build & push Docker image of the Jobs service
needs: lint_backend
uses: ./.github/workflows/flow_backend_build_push.yml
with:
service-name: jobs
push-image: ${{ github.event_name != 'pull_request' }}
image-tags: |
type=sha
type=ref,event=branch
type=edge
29 changes: 29 additions & 0 deletions .github/workflows/on_semver_tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Push a semver tag

on:
push:
tags:
- v*.*.*

jobs:
build_api_gateway:
name: Build & push Docker image of the API gateway
uses: ./.github/workflows/flow_backend_build_push.yml
with:
service-name: api_gateway
push-image: ${{ github.event_name != 'pull_request' }}
image-tags: |
type=sha
type=semver,pattern={{version}}
type=raw,value=latest

build_jobs_service:
name: Build & push Docker image of the Jobs service
uses: ./.github/workflows/flow_backend_build_push.yml
with:
service-name: jobs
push-image: ${{ github.event_name != 'pull_request' }}
image-tags: |
type=sha
type=semver,pattern={{version}}
type=raw,value=latest
21 changes: 21 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Build stage
FROM amazoncorretto:17-alpine AS build
ARG SERVICE_NAME
WORKDIR /app

COPY ./$SERVICE_NAME ./$SERVICE_NAME
COPY ./gradle ./gradle
COPY ./gradle.properties .
COPY ./gradlew .
COPY ./settings.gradle.kts .

RUN --mount=type=cache,target=/root/.gradle ./gradlew clean build -x test

# Run stage
FROM amazoncorretto:17-alpine AS run
ARG SERVICE_NAME
WORKDIR /app

COPY --from=build /app/$SERVICE_NAME/build/libs/*-SNAPSHOT.jar ./app.jar

ENTRYPOINT ["java", "-jar", "./app.jar"]
42 changes: 23 additions & 19 deletions backend/api_gateway/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,41 +1,45 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("org.springframework.boot")
id("io.spring.dependency-management")
kotlin("jvm")
kotlin("plugin.spring")
kotlin("plugin.jpa")
id("org.springframework.boot")
id("io.spring.dependency-management")
id("org.jlleitschuh.gradle.ktlint")
kotlin("jvm")
kotlin("plugin.spring")
kotlin("plugin.jpa")
}

group = "com.linkedout"
version = "1.0.0-SNAPSHOT"

java {
sourceCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_17
}

repositories {
mavenCentral()
mavenCentral()
}

dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-security:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-validation:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-web:3.1.5")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-test")
implementation("org.springframework.boot:spring-boot-starter-actuator:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-security:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-validation:3.1.5")
implementation("org.springframework.boot:spring-boot-starter-web:3.1.5")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.boot:spring-boot-testcontainers")
testImplementation("org.testcontainers:junit-jupiter")
testImplementation("org.testcontainers:postgresql")
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
jvmTarget = "17"
}
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
jvmTarget = "17"
}
}

tasks.withType<Test> {
useJUnitPlatform()
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAut
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter
import org.springframework.security.web.SecurityFilterChain


@Configuration
@EnableWebSecurity
@EnableMethodSecurity
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.linkedout.backend

import org.junit.jupiter.api.Test
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.DynamicPropertyRegistry
import org.springframework.test.context.DynamicPropertySource
import org.testcontainers.containers.PostgreSQLContainer
import org.testcontainers.junit.jupiter.Container
import org.testcontainers.junit.jupiter.Testcontainers

@SpringBootTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
internal class ApiGatewayApplicationTests {
companion object {
@Container
private val postgreSQLContainer = PostgreSQLContainer<Nothing>("postgres:latest")

@DynamicPropertySource
@JvmStatic
fun registerDynamicProperties(registry: DynamicPropertyRegistry) {
registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl)
registry.add("spring.datasource.username", postgreSQLContainer::getUsername)
registry.add("spring.datasource.password", postgreSQLContainer::getPassword)
}
}

@Test
fun contextLoads() {
}
}
Loading