Skip to content

Commit

Permalink
Setup CI (#4)
Browse files Browse the repository at this point in the history
* setup CI with test and linter
* auto format with ktlint -F
* add dependabot for vulnerability updates

---------
Co-authored-by: Darwin D Wu <[email protected]>
  • Loading branch information
darwin67 authored Feb 22, 2024
1 parent 414c5a2 commit 10ad216
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 94 deletions.
11 changes: 9 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_size = 2
indent_style = space
insert_final_newline = false
insert_final_newline = true
max_line_length = 120
tab_width = 2

[*.{kt,kts}]
indent_size = 4
tab_width = 4

[Makefile]
indent_style = tab
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
- package-ecosystem: gradle
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
42 changes: 42 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: CI

on:
push:
branches:
- main
pull_request:

jobs:
test:
name: Test (Java ${{ matrix.java }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
java: ["8", "11", "17", "21"]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ matrix.java }}
java-package: jdk
cache: gradle

- name: Test
run: make test

lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: ktlint
uses: ScaCap/action-ktlint@master
with:
fail_on_error: true
github_token: ${{ secrets.github_token }}
reporter: github-pr-review

# TODO: run integration tests
# integration:
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ dev:
.PHONY: test
test:
gradle test inngest-core:test

.PHONY: lint
lint:
ktlint --color

.PHONY: fmt
fmt:
ktlint -F
37 changes: 21 additions & 16 deletions inngest-core/src/main/kotlin/com/inngest/Comm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,35 @@ data class CommError(
)

class CommHandler(val functions: HashMap<String, InngestFunction>) {

private fun getHeaders(): Map<String, String> {
return mapOf(
"Content-Type" to "application/json",
"x-inngest-sdk" to "inngest-kt:v0.0.1", // TODO - Get this from the build
"x-inngest-framework" to "ktor", // TODO - Pull this from options
// TODO - Get this from the build
"x-inngest-sdk" to "inngest-kt:v0.0.1",
// TODO - Pull this from options
"x-inngest-framework" to "ktor",
)
}

fun callFunction(functionId: String, requestBody: String): CommResponse {
fun callFunction(
functionId: String,
requestBody: String,
): CommResponse {
println(requestBody)

try {
val payload = Klaxon().parse<ExecutionRequestPayload>(requestBody)
// TODO - check that payload is not null and throw error
val function = functions[functionId] ?: throw Exception("Function not found")

val ctx = FunctionContext(
event = payload!!.event,
events = payload.events,
runId = payload.ctx.runId,
fnId = payload.ctx.fnId,
attempt = payload.ctx.attempt,
)
val ctx =
FunctionContext(
event = payload!!.event,
events = payload.events,
runId = payload.ctx.runId,
fnId = payload.ctx.fnId,
attempt = payload.ctx.attempt,
)

val result =
function.call(
Expand All @@ -85,19 +90,19 @@ class CommHandler(val functions: HashMap<String, InngestFunction>) {
return CommResponse(
body = Klaxon().toJsonString(body),
statusCode = result.statusCode,
headers = getHeaders()
headers = getHeaders(),
)
} catch (e: Exception) {
val err =
CommError(
name = e.toString(),
message = e.message,
stack = e.stackTrace.joinToString(separator = "\n")
stack = e.stackTrace.joinToString(separator = "\n"),
)
return CommResponse(
body = Klaxon().toJsonString(err),
statusCode = ResultStatusCode.Error,
headers = getHeaders()
headers = getHeaders(),
)
}
}
Expand All @@ -118,7 +123,7 @@ class CommHandler(val functions: HashMap<String, InngestFunction>) {
sdk = "kotlin",
url = "http://localhost:8080/api/inngest",
v = "0.0.1",
functions = getFunctionConfigs()
functions = getFunctionConfigs(),
)
val requestBody = Klaxon().toJsonString(requestPayload)

Expand All @@ -145,7 +150,7 @@ class CommHandler(val functions: HashMap<String, InngestFunction>) {
sdk = "kotlin",
url = "http://localhost:8080/api/inngest",
v = "0.0.1",
functions = getFunctionConfigs()
functions = getFunctionConfigs(),
)
return Klaxon().toJsonString(requestPayload)
}
Expand Down
2 changes: 1 addition & 1 deletion inngest-core/src/main/kotlin/com/inngest/Event.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ data class Event(
data class EventAPIResponse(
val ids: Array<String>,
val status: String,
)
)
58 changes: 30 additions & 28 deletions inngest-core/src/main/kotlin/com/inngest/Function.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ enum class OpCode {
// FUTURE:
WaitForEvent,
StepNotFound,

}

enum class ResultStatusCode(val code: Int, val message: String) {
Expand All @@ -33,7 +32,6 @@ enum class ResultStatusCode(val code: Int, val message: String) {
Error(500, "Function Error"),
}


abstract class StepOp(
// The hashed ID of a step
open val id: String = "",
Expand Down Expand Up @@ -69,7 +67,7 @@ data class FunctionConfig(
val id: String,
val name: String,
val triggers: Array<FunctionTrigger>,
val steps: Map<String, StepConfig>
val steps: Map<String, StepConfig>,
)

/**
Expand All @@ -86,6 +84,7 @@ data class FunctionContext(
)

// TODO - Determine if we should merge config + trigger

/**
* A function that can be called by the Inngest system
*
Expand All @@ -94,11 +93,14 @@ data class FunctionContext(
*/
open class InngestFunction(
val config: FunctionOptions,
val handler: (ctx: FunctionContext, step: Step) -> kotlin.Any?
val handler: (ctx: FunctionContext, step: Step) -> kotlin.Any?,
) {
// TODO - Validate options and trigger

fun call(ctx: FunctionContext, requestBody: String): StepOp {
fun call(
ctx: FunctionContext,
requestBody: String,
): StepOp {
val state = State(requestBody)
val step = Step(state)

Expand All @@ -112,16 +114,15 @@ open class InngestFunction(
id = "",
name = "",
op = OpCode.StepRun,
statusCode = ResultStatusCode.FunctionComplete
statusCode = ResultStatusCode.FunctionComplete,
)
} catch (e: StepInterruptSleepException) {
return StepOptions(
opts = hashMapOf("duration" to e.data),

id = e.hashedId,
name = e.id,
op = OpCode.Sleep,
statusCode = ResultStatusCode.StepComplete
statusCode = ResultStatusCode.StepComplete,
)
} catch (e: StepInterruptException) {
// NOTE - Currently this error could be caught in the user's own function
Expand All @@ -132,7 +133,7 @@ open class InngestFunction(
id = e.hashedId,
name = e.id,
op = OpCode.StepRun,
statusCode = ResultStatusCode.StepComplete
statusCode = ResultStatusCode.StepComplete,
)
} catch (e: StepInvalidStateTypeException) {
// TODO - Handle this with the proper op code
Expand All @@ -141,7 +142,7 @@ open class InngestFunction(
id = e.hashedId,
name = e.id,
op = OpCode.StepStateFailed,
statusCode = ResultStatusCode.Error
statusCode = ResultStatusCode.Error,
)
}
}
Expand All @@ -152,24 +153,25 @@ open class InngestFunction(
name = config.name,
triggers = config.triggers,
steps =
mapOf(
"step" to
StepConfig(
id = "step",
name = "step",
retries =
mapOf(
"attempts" to 3
), // TODO - Pull from FunctionOptions
runtime =
hashMapOf(
"type" to "http",
// TODO - Create correct URL
"url" to
"http://localhost:8080/api/inngest?fnId=${config.id}&stepId=step"
)
)
)
mapOf(
"step" to
StepConfig(
id = "step",
name = "step",
retries =
mapOf(
// TODO - Pull from FunctionOptions
"attempts" to 3,
),
runtime =
hashMapOf(
"type" to "http",
// TODO - Create correct URL
"url" to
"http://localhost:8080/api/inngest?fnId=${config.id}&stepId=step",
),
),
),
)
}
}
11 changes: 3 additions & 8 deletions inngest-core/src/main/kotlin/com/inngest/Inngest.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package com.inngest

import com.beust.klaxon.Klaxon

//import okhttp3.RequestBody.Companion.toRequestBody

// import okhttp3.RequestBody.Companion.toRequestBody

class Inngest {

constructor(
app_id: String,

) {
) {
// TODO - Fetch INNGEST_EVENT_KEY env variable
}

Expand All @@ -26,4 +21,4 @@ class Inngest {
// val body = Klaxon().parse<EventAPIResponse>(response)
// return body;
// }
}
}
11 changes: 4 additions & 7 deletions inngest-core/src/main/kotlin/com/inngest/State.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package com.inngest

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import java.security.MessageDigest


class StateNotFound() : Throwable("State not found for id")

class State(val payloadJson: String) {

fun getHashFromId(id: String): String {
val bytes = id.toByteArray(Charsets.UTF_8)
val digest = MessageDigest.getInstance("SHA-1")
Expand All @@ -26,14 +24,13 @@ class State(val payloadJson: String) {
val stepResult = node.path("steps").get(hashedId) ?: throw StateNotFound()
if (stepResult.has("data")) {
val dataNode = stepResult.get("data")
return mapper.treeToValue(dataNode, T::class.java);
return mapper.treeToValue(dataNode, T::class.java)
} else if (stepResult.has("error")) {
// TODO - Parse the error and throw it
return null
}
// NOTE - Sleep steps will be stored as null
// TODO - Check the state is actually null
return null;
return null
}

}
}
Loading

0 comments on commit 10ad216

Please sign in to comment.