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
38 changes: 38 additions & 0 deletions blueprint/Earthfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
VERSION 0.8

deps:
FROM golang:1.23.0-alpine3.19

WORKDIR /work

RUN mkdir -p /go/cache && mkdir -p /go/modcache
ENV GOCACHE=/go/cache
ENV GOMODCACHE=/go/modcache
CACHE --persist --sharing shared /go

COPY ../cuetools+src/src /cuetools

COPY go.mod go.sum .
RUN go mod download

src:
FROM +deps

CACHE --persist --sharing shared /go

COPY --dir internal pkg schema .

RUN go generate ./...

SAVE ARTIFACT . src

check:
FROM +src

RUN gofmt -l . | grep . && exit 1 || exit 0
RUN go vet ./...

test:
FROM +src

RUN go test ./...
13 changes: 13 additions & 0 deletions blueprint/schema/_embed/schema.cue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ package schema
registry: (_ | *"") & {
string
} @go(Registry)
secrets: {
[string]: #Secret
} @go(Secrets,map[string]Secret)
targets: {
[string]: #Target
} @go(Targets,map[string]Target)
Expand All @@ -18,6 +21,15 @@ package schema
string
} @go(Satellite)
}

// Secret contains the secret provider and a list of mappings
#Secret: {
path: string @go(Path)
provider: string @go(Provider)
maps: {
[string]: string
} @go(Maps,map[string]string)
}
version: "1.0"

// Target contains the configuration for a single target.
Expand All @@ -33,4 +45,5 @@ version: "1.0"
retries: (_ | *0) & {
int
} @go(Retries)
secrets: [...#Secret] @go(Secrets,[]Secret)
}
9 changes: 9 additions & 0 deletions blueprint/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Blueprint struct {
Version string `json:"version"`
Global Global `json:"global"`
Registry string `json:"registry"`
Secrets map[string]Secret `json:"secrets"`
Targets map[string]Target `json:"targets"`
}

Expand All @@ -23,9 +24,17 @@ type Global struct {
Satellite string `json:"satellite"`
}

// Secret contains the secret provider and a list of mappings
type Secret struct {
Path string `json:"path"`
Provider string `json:"provider"`
Maps map[string]string `json:"maps"`
}

// Target contains the configuration for a single target.
type Target struct {
Args map[string]string `json:"args"`
Privileged bool `json:"privileged"`
Retries int `json:"retries"`
Secrets []Secret `json:"secrets"`
}
9 changes: 9 additions & 0 deletions blueprint/schema/schema_go_gen.cue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package schema
version: string @go(Version)
global: #Global @go(Global)
registry: string @go(Registry)
secrets: {[string]: #Secret} @go(Secrets,map[string]Secret)
targets: {[string]: #Target} @go(Targets,map[string]Target)
}

Expand All @@ -17,9 +18,17 @@ package schema
satellite: string @go(Satellite)
}

// Secret contains the secret provider and a list of mappings
#Secret: {
path: string @go(Path)
provider: string @go(Provider)
maps: {[string]: string} @go(Maps,map[string]string)
}

// Target contains the configuration for a single target.
#Target: {
args: {[string]: string} @go(Args,map[string]string)
privileged: bool @go(Privileged)
retries: int @go(Retries)
secrets: [...#Secret] @go(Secrets,[]Secret)
}
35 changes: 35 additions & 0 deletions cuetools/Earthfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
VERSION 0.8

deps:
FROM golang:1.23.0-alpine3.19

WORKDIR /work

RUN mkdir -p /go/cache && mkdir -p /go/modcache
ENV GOCACHE=/go/cache
ENV GOMODCACHE=/go/modcache
CACHE --persist --sharing shared /go

COPY go.mod go.sum .
RUN go mod download

src:
FROM +deps

CACHE --persist --sharing shared /go

COPY --dir pkg .
RUN go generate ./...

SAVE ARTIFACT . src

check:
FROM +src

RUN gofmt -l . | grep . && exit 1 || exit 0
RUN go vet ./...

test:
FROM +src

RUN go test ./...
4 changes: 4 additions & 0 deletions forge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Forge

Forge is the subsystem within Catalyst Forge that powers the CI process.
It ships with both a CLI and a set of Github Actions that can be used to create CI pipelines.
61 changes: 61 additions & 0 deletions forge/cli/Earthfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
VERSION 0.8

deps:
FROM golang:1.23.0-alpine3.19

WORKDIR /work/cli

RUN mkdir -p /go/cache && mkdir -p /go/modcache
ENV GOCACHE=/go/cache
ENV GOMODCACHE=/go/modcache
CACHE --persist --sharing shared /go

COPY ../../blueprint+src/src /blueprint
COPY ../../cuetools+src/src /cuetools

COPY go.mod go.sum .
RUN go mod download

src:
FROM +deps

CACHE --persist --sharing shared /go

COPY --dir cmd internal pkg .
RUN go generate ./...

check:
FROM +src

RUN gofmt -l . | grep . && exit 1 || exit 0
RUN go vet ./...

build:
FROM +src

ARG version="0.0.0"

ENV CGO_ENABLED=0
RUN go build -ldflags="-extldflags=-static -X main.version=$version" -o bin/forge cmd/main.go

SAVE ARTIFACT bin/forge forge

test:
FROM +build

RUN go test ./...

release:
FROM +build

SAVE ARTIFACT bin/forge forge

publish:
FROM debian:bookworm-slim
WORKDIR /workspace
ARG tag=latest

COPY +build/forge /usr/local/bin/forge

ENTRYPOINT ["/usr/local/bin/forge"]
SAVE IMAGE --push forge:${tag}
27 changes: 27 additions & 0 deletions forge/cli/cmd/cmds/config_dump.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package cmds

import (
"fmt"
"log/slog"
"os"
"path/filepath"
)

type DumpCmd struct {
Config string `arg:"" help:"Path to the configuration file."`
Pretty bool `help:"Pretty print JSON output."`
}

func (c *DumpCmd) Run(logger *slog.Logger) error {
if _, err := os.Stat(c.Config); os.IsNotExist(err) {
return fmt.Errorf("configuration file does not exist: %s", c.Config)
}

config, err := loadBlueprint(filepath.Dir(c.Config), logger)
if err != nil {
return err
}

printJson(config, c.Pretty)
return nil
}
25 changes: 25 additions & 0 deletions forge/cli/cmd/cmds/config_validate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package cmds

import (
"fmt"
"log/slog"
"os"
"path/filepath"
)

type ValidateCmd struct {
Config string `arg:"" help:"Path to the configuration file."`
}

func (c *ValidateCmd) Run(logger *slog.Logger) error {
if _, err := os.Stat(c.Config); os.IsNotExist(err) {
return fmt.Errorf("configuration file does not exist: %s", c.Config)
}

_, err := loadBlueprint(filepath.Dir(c.Config), logger)
if err != nil {
return err
}

return nil
}
57 changes: 57 additions & 0 deletions forge/cli/cmd/cmds/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package cmds

import (
"fmt"
"log/slog"
"strings"

"github.com/input-output-hk/catalyst-forge/forge/cli/pkg/earthly"
"github.com/input-output-hk/catalyst-forge/forge/cli/pkg/executor"
"github.com/input-output-hk/catalyst-forge/forge/cli/pkg/secrets"
)

type RunCmd struct {
Artifact bool `short:"a" help:"Enable artifact collection."`
Local bool `short:"l" help:"Forces the target to run locally (ignores satellite)."`
Path string `arg:"" help:"The path to the target to execute (i.e., ./dir1+test)."`
Pretty bool `help:"Pretty print JSON output."`
}

func (c *RunCmd) Run(logger *slog.Logger) error {
if !strings.Contains(c.Path, "+") {
return fmt.Errorf("invalid Earthfile+Target pair: %s", c.Path)
}

earthfileDir := strings.Split(c.Path, "+")[0]
target := strings.Split(c.Path, "+")[1]

config, err := loadBlueprint(earthfileDir, logger)
if err != nil {
return err
}

localExec := executor.NewLocalExecutor(
logger,
executor.WithRedirect(),
)

opts := generateOpts(target, c, &config)
earthlyExec := earthly.NewEarthlyExecutor(
earthfileDir,
target,
localExec,
secrets.NewDefaultSecretStore(),
logger,
opts...,
)

logger.Info("Executing Earthly target", "earthfile", earthfileDir, "target", target)
result, err := earthlyExec.Run()
if err != nil {
return err
}

printJson(result, c.Pretty)

return nil
}
Loading