Skip to content

Commit

Permalink
chore: merge branch 'master' into mve-next
Browse files Browse the repository at this point in the history
  • Loading branch information
jmgilman committed Oct 31, 2024
2 parents 5ac8b92 + 74a0df4 commit 9c5befb
Show file tree
Hide file tree
Showing 18 changed files with 1,574 additions and 51 deletions.
8 changes: 7 additions & 1 deletion blueprint.cue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@ global: {
path: "global/ci/deploy"
}

github: registry: "ghcr.io"
github: {
credentials: {
provider: "aws"
path: "global/ci/github"
}
registry: "ghcr.io"
}
}
secrets: [
{
Expand Down
13 changes: 13 additions & 0 deletions cli/pkg/events/always.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package events

import (
"cuelang.org/go/cue"
"github.com/input-output-hk/catalyst-forge/lib/project/project"
)

// AlwaysEvent fires always.
type AlwaysEvent struct{}

func (m *AlwaysEvent) Firing(p *project.Project, config cue.Value) (bool, error) {
return true, nil
}
14 changes: 8 additions & 6 deletions cli/pkg/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import (
type EventType string

const (
MergeEventName EventType = "merge"
TagEventName EventType = "tag"
AlwaysEventName EventType = "always"
MergeEventName EventType = "merge"
TagEventName EventType = "tag"
)

// Event represents a CI event.
Expand All @@ -37,9 +38,9 @@ type DefaultEventHandler struct {

// Fires returns true if any of the given events are firing.
func (r *DefaultEventHandler) Firing(p *project.Project, events map[string]cue.Value) bool {
for event, config := range events {
r.logger.Debug("checking event", "event", event)
event, ok := r.store[EventType(event)]
for eventName, config := range events {
r.logger.Debug("checking event", "event", eventName)
event, ok := r.store[EventType(eventName)]
if !ok {
r.logger.Error("unknown event", "event", event)
continue
Expand All @@ -52,7 +53,7 @@ func (r *DefaultEventHandler) Firing(p *project.Project, events map[string]cue.V
}

if firing {
r.logger.Debug("event is firing", "event", event)
r.logger.Debug("event is firing", "event", eventName)
return true
}
}
Expand All @@ -65,6 +66,7 @@ func NewDefaultEventHandler(logger *slog.Logger) DefaultEventHandler {
return DefaultEventHandler{
logger: logger,
store: map[EventType]Event{
AlwaysEventName: &AlwaysEvent{},
MergeEventName: &MergeEvent{
logger: logger,
},
Expand Down
5 changes: 5 additions & 0 deletions docs/src/reference/releases/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ Doing so helps prevent merging a potentially broken release configuration.

The supported events are documented below.

#### `always` event

The `always` event is the most straight-forward event in that it always triggers, no matter what.
This is sometimes useful for previewing or debugging a release.

#### `merge` event

| Field | Description | Type | Default |
Expand Down
2 changes: 2 additions & 0 deletions lib/project/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/aws/aws-sdk-go-v2/config v1.27.40
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4
github.com/go-git/go-git/v5 v5.12.0
github.com/google/go-github/v66 v66.0.0
github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0
github.com/spf13/afero v1.11.0
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -39,6 +40,7 @@ require (
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions lib/project/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,13 @@ github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v66 v66.0.0 h1:ADJsaXj9UotwdgK8/iFZtv7MLc8E8WBl62WLd/D/9+M=
github.com/google/go-github/v66 v66.0.0/go.mod h1:+4SO9Zkuyf8ytMj0csN1NR/5OTR+MfqPp8P8dVlcvY4=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
Expand Down Expand Up @@ -213,6 +218,7 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
48 changes: 29 additions & 19 deletions lib/project/project/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (
"cuelang.org/go/cue/cuecontext"
"github.com/input-output-hk/catalyst-forge/lib/project/blueprint"
"github.com/input-output-hk/catalyst-forge/lib/project/injector"
"github.com/input-output-hk/catalyst-forge/lib/project/providers"
"github.com/input-output-hk/catalyst-forge/lib/project/schema"
"github.com/input-output-hk/catalyst-forge/lib/project/secrets"
"github.com/input-output-hk/catalyst-forge/lib/tools/earthfile"
"github.com/input-output-hk/catalyst-forge/lib/tools/git"
"github.com/input-output-hk/catalyst-forge/lib/tools/walker"
Expand Down Expand Up @@ -46,6 +48,13 @@ func (p *DefaultProjectLoader) Load(projectPath string) (Project, error) {
return Project{}, fmt.Errorf("failed to find git root: %w", err)
}

p.logger.Info("Loading blueprint", "path", projectPath)
rbp, err := p.blueprintLoader.Load(projectPath, gitRoot)
if err != nil {
p.logger.Error("Failed to load blueprint", "error", err, "path", projectPath)
return Project{}, fmt.Errorf("failed to load blueprint: %w", err)
}

p.logger.Info("Loading repository", "path", gitRoot)
rl := git.NewCustomDefaultRepoLoader(p.fs)
repo, err := rl.Load(gitRoot)
Expand All @@ -54,13 +63,6 @@ func (p *DefaultProjectLoader) Load(projectPath string) (Project, error) {
return Project{}, fmt.Errorf("failed to load repository: %w", err)
}

p.logger.Info("Loading blueprint", "path", projectPath)
rbp, err := p.blueprintLoader.Load(projectPath, gitRoot)
if err != nil {
p.logger.Error("Failed to load blueprint", "error", err, "path", projectPath)
return Project{}, fmt.Errorf("failed to load blueprint: %w", err)
}

efPath := filepath.Join(projectPath, "Earthfile")
exists, err := afero.Exists(p.fs, efPath)
if err != nil {
Expand Down Expand Up @@ -128,19 +130,22 @@ func (p *DefaultProjectLoader) Load(projectPath string) (Project, error) {
p.logger.Debug("No git tag found")
}

partialProject := Project{
Earthfile: ef,
Name: name,
Path: projectPath,
RawBlueprint: rbp,
Repo: repo,
RepoRoot: gitRoot,
Tag: tag,
ctx: p.ctx,
logger: p.logger,
}

p.logger.Info("Gathering runtime data")
runtimeData := make(map[string]cue.Value)
for _, r := range p.runtimes {
d := r.Load(&Project{
Earthfile: ef,
Path: projectPath,
RawBlueprint: rbp,
Repo: repo,
RepoRoot: gitRoot,
Tag: tag,
ctx: p.ctx,
logger: p.logger,
})
d := r.Load(&partialProject)

for k, v := range d {
runtimeData[k] = v
Expand Down Expand Up @@ -187,18 +192,23 @@ func NewDefaultProjectLoader(
}

ctx := cuecontext.New()
fs := afero.NewOsFs()
bl := blueprint.NewDefaultBlueprintLoader(ctx, logger)
rl := git.NewDefaultRepoLoader()
store := secrets.NewDefaultSecretStore()
ghp := providers.NewGithubProvider(fs, logger, &store)
return DefaultProjectLoader{
blueprintLoader: &bl,
ctx: ctx,
fs: afero.NewOsFs(),
fs: fs,
injectors: []injector.BlueprintInjector{
injector.NewBlueprintEnvInjector(ctx, logger),
},
logger: logger,
repoLoader: &rl,
runtimes: GetDefaultRuntimes(logger),
runtimes: []RuntimeData{
NewGitRuntime(&ghp, logger),
},
}
}

Expand Down
7 changes: 6 additions & 1 deletion lib/project/project/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/go-git/go-git/v5/storage/filesystem"
"github.com/input-output-hk/catalyst-forge/lib/project/blueprint"
"github.com/input-output-hk/catalyst-forge/lib/project/injector"
"github.com/input-output-hk/catalyst-forge/lib/project/providers"
"github.com/input-output-hk/catalyst-forge/lib/tools/testutils"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
Expand All @@ -20,6 +21,7 @@ import (

func TestDefaultProjectLoaderLoad(t *testing.T) {
ctx := cuecontext.New()
githubProvider := providers.NewGithubProvider(nil, testutils.NewNoopLogger(), nil)

earthfile := `
VERSION 0.8
Expand Down Expand Up @@ -136,7 +138,10 @@ project: {
injector.NewBlueprintEnvInjector(ctx, testutils.NewNoopLogger()),
},
runtimes: []RuntimeData{
NewGitRuntime(testutils.NewNoopLogger()),
NewGitRuntime(
&githubProvider,
testutils.NewNoopLogger(),
),
},
env: map[string]string{},
initGit: true,
Expand Down
4 changes: 2 additions & 2 deletions lib/project/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ type Project struct {
// TagInfo is the project tag information.
//TagInfo *TagInfo

logger *slog.Logger
ctx *cue.Context
logger *slog.Logger
}

// GetRelativePath returns the relative path of the project from the repo root.
Expand Down Expand Up @@ -118,8 +118,8 @@ func NewProject(
Path: path,
Repo: repo,
RepoRoot: repoRoot,
Tag: tag,
ctx: ctx,
logger: logger,
Tag: tag,
}
}
66 changes: 51 additions & 15 deletions lib/project/project/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (

"cuelang.org/go/cue"
"github.com/go-git/go-git/v5"
"github.com/google/go-github/v66/github"
"github.com/input-output-hk/catalyst-forge/lib/project/providers"
)

// RuntimeData is an interface for runtime data loaders.
Expand All @@ -15,14 +17,15 @@ type RuntimeData interface {

// GitRuntime is a runtime data loader for git related data.
type GitRuntime struct {
logger *slog.Logger
provider *providers.GithubProvider
logger *slog.Logger
}

func (g *GitRuntime) Load(project *Project) map[string]cue.Value {
g.logger.Debug("Loading git runtime data")
data := make(map[string]cue.Value)

hash, err := getCommitHash(project.Repo)
hash, err := g.getCommitHash(project.Repo)
if err != nil {
g.logger.Warn("Failed to get commit hash", "error", err)
} else {
Expand All @@ -39,22 +42,47 @@ func (g *GitRuntime) Load(project *Project) map[string]cue.Value {
return data
}

// NewGitRuntime creates a new GitRuntime.
func NewGitRuntime(logger *slog.Logger) *GitRuntime {
return &GitRuntime{
logger: logger,
}
}
// getCommitHash returns the commit hash of the HEAD commit.
func (g *GitRuntime) getCommitHash(repo *git.Repository) (string, error) {
if g.provider.HasEvent() {
if g.provider.GetEventType() == "pull_request" {
g.logger.Debug("Found GitHub pull request event")
event, err := g.provider.GetEventPayload()
if err != nil {
return "", fmt.Errorf("failed to get event payload: %w", err)
}

pr, ok := event.(*github.PullRequestEvent)
if !ok {
return "", fmt.Errorf("unexpected event type")
}

if pr.PullRequest.Head.SHA == nil {
return "", fmt.Errorf("pull request head SHA is empty")
}

return *pr.PullRequest.Head.SHA, nil
} else if g.provider.GetEventType() == "push" {
g.logger.Debug("Found GitHub push event")
event, err := g.provider.GetEventPayload()
if err != nil {
return "", fmt.Errorf("failed to get event payload: %w", err)
}

push, ok := event.(*github.PushEvent)
if !ok {
return "", fmt.Errorf("unexpected event type")
}

// GetDefaultRuntimes returns the default runtime data loaders.
func GetDefaultRuntimes(logger *slog.Logger) []RuntimeData {
return []RuntimeData{
NewGitRuntime(logger),
if push.After == nil {
return "", fmt.Errorf("push event after SHA is empty")
}

return *push.After, nil
}
}
}

// getCommitHash returns the commit hash of the HEAD commit.
func getCommitHash(repo *git.Repository) (string, error) {
g.logger.Debug("No GitHub event found, getting commit hash from git repository")
ref, err := repo.Head()
if err != nil {
return "", fmt.Errorf("failed to get HEAD: %w", err)
Expand All @@ -67,3 +95,11 @@ func getCommitHash(repo *git.Repository) (string, error) {

return obj.Hash.String(), nil
}

// NewGitRuntime creates a new GitRuntime.
func NewGitRuntime(githubProvider *providers.GithubProvider, logger *slog.Logger) *GitRuntime {
return &GitRuntime{
logger: logger,
provider: githubProvider,
}
}
Loading

0 comments on commit 9c5befb

Please sign in to comment.