feat(dagger): added build, test, and lint using dagger

This commit is contained in:
Patrick Sy 2024-10-14 13:01:06 +02:00
parent 206aebe832
commit 7746219c43
Signed by: Patrick.Sy
GPG key ID: DDDC8EC51823195E
12 changed files with 1420 additions and 5 deletions

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
main
helloworld
# Created by https://www.toptal.com/developers/gitignore/api/go,vim,intellij+all
# Edit at https://www.toptal.com/developers/gitignore?templates=go,vim,intellij+all

View file

@ -1 +1,3 @@
go 1.23.2
golangci-lint 1.61.0
dagger 0.13.5

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Deutsche Telekom MMS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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 OR COPYRIGHT HOLDERS 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.

View file

@ -1,3 +1,81 @@
## Hello World
## Hello Dagger
A simple hello world app
An example repo demonstrating [Dagger](https://dagger.io).
### What is Dagger?
Dagger is not a CI/CD Runner like GitHub Actions or Gitlab CI. It is an
abstraction that uses and composes containers to run commands. Think of it as
somewhere between `just`, `nix`, and writing custom programs for your build
plus containers all over the place.
It exists as a cli tool which either starts a Dagger Engine locally or connects
to an existing one (in the cloud). This engine runs as a container and runs all
tasks inside the engine as a container as well. The cli tool communicates via
GraphQL with the engine.
Besides the TUI, Dagger Cloud is a commercial offering that is basically a
fancy add-on. It provides web-visualizations of errors during a dagger
execution and of performance metrics (profiling), as well as some caching
features.
The TUI and engine are published under the Apache 2 License and thus can be
used free of charge.
Besides using containers, Dagger's main selling point is the ability to program
tasks in high level languages like Go or Typescript instead of configuring them
in json or yaml. Dagger provides a DSL-like API that reminds one of
`Dockerfile` commands + FP (even though it isn't). Combined with the ecosystem
of the base language nearly anything can be coded and containerized fairly
easy.
### Walkthrough
This repo uses `mise` / `asdf` for setup, see `.tool-versions`.
Initialize the existing repo with dagger:
```shell
dagger init --sdk=typescript --source=./dagger
```
Typescript is just one option to write the config in, Python and Go are also
currently available with more to follow.
> Note: For some reason it wants to create a `LICENSE` file...
> LSPs should work properly out of the box as the dagger config is located in
> the `./dagger` directory. When using TS this is a self-sufficient node/yarn
> project.
To get an overview of available functions to call:
```shell
dagger functions
```
Run a function:
```shell
dagger call build --source=.
```
This runs the `build` function defined in `dagger/src/index.ts` and passes `.`
as the `source` parameter of that function.
> Camel Case function names in the TS setup are available in Kebab Case on the
> shell (same applies for Go and Python). This does not only apply to your own
> declared functions but to all functions available on the returned data types.
>
> ```typescript
> this.build(source).asService().up({ ports: "8080:8080" });
> ```
>
> becomes
>
> ```shell
> dagger call build --source=. as-service up --ports=8080:8080
> ```
> After running a dagger command the Dagger Engine stays alive as a local
> container waiting for the next call.

6
dagger.json Normal file
View file

@ -0,0 +1,6 @@
{
"name": "hello-dagger",
"sdk": "typescript",
"source": "dagger",
"engineVersion": "v0.13.5"
}

1
dagger/.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
/sdk/** linguist-generated

3
dagger/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/sdk
/**/node_modules/**
/**/.pnpm-store/**

8
dagger/package.json Normal file
View file

@ -0,0 +1,8 @@
{
"type": "module",
"dependencies": {
"typescript": "^5.5.4",
"@dagger.io/dagger": "./sdk"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}

58
dagger/src/index.ts Normal file
View file

@ -0,0 +1,58 @@
/**
* Dagger build and deploy functions
*/
import { dag, Container, Directory, object, func } from "@dagger.io/dagger";
@object()
class HelloDagger {
/**
* Return the result of running unit tests
*/
@func()
build(source: Directory): Container {
const executable = this.buildEnv(source)
.withExec(["go", "build"])
.file("./helloworld");
return dag
.container()
.from("ubuntu:latest")
.withFile("/usr/bin/helloworld", executable)
.withExposedPort(9000)
.withEntrypoint(["helloworld"]);
}
/**
* Return the result of running unit tests
*/
@func()
async test(source: Directory): Promise<string> {
return this.buildEnv(source).withExec(["go", "test"]).stdout();
}
/**
* Build a ready-to-use development environment
*/
@func()
lint(source: Directory): Container {
return dag
.container()
.from("golangci/golangci-lint:v1.61.0")
.withDirectory("/src", source)
.withWorkdir("/src")
.withExec(["golangci-lint", "run", "-v"])
;
}
/**
* Build a ready-to-use development environment
*/
@func()
buildEnv(source: Directory): Container {
return dag
.container()
.from("golang:1.23")
.withDirectory("/src", source)
.withWorkdir("/src");
}
}

11
dagger/tsconfig.json Normal file
View file

@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "ES2022",
"moduleResolution": "Node",
"experimentalDecorators": true,
"paths": {
"@dagger.io/dagger": ["./sdk"],
"@dagger.io/dagger/telemetry": ["./sdk/telemetry"]
}
}
}

1219
dagger/yarn.lock Normal file

File diff suppressed because it is too large Load diff

13
main.go
View file

@ -2,8 +2,9 @@ package main
import (
"fmt"
log "github.com/sirupsen/logrus"
"net/http"
log "github.com/sirupsen/logrus"
)
func main() {
@ -12,10 +13,16 @@ func main() {
log.Info("Starting on port ", port)
http.ListenAndServe(fmt.Sprint(":", port), nil)
err := http.ListenAndServe(fmt.Sprint(":", port), nil)
if err != nil {
log.Error("Something bad happened")
}
}
func helloWorldHandler(w http.ResponseWriter, r *http.Request) {
log.Info("Request from", r.RemoteAddr)
w.Write([]byte("Hello World"))
_, err := w.Write([]byte("Hello World"))
if err != nil {
log.Error("Unable to write hello world")
}
}