Skip to content

Commit 4ea5673

Browse files
authored
feat(project): adds support for parsing GitHub event data (#93)
1 parent a94019f commit 4ea5673

File tree

15 files changed

+1548
-45
lines changed

15 files changed

+1548
-45
lines changed

blueprint.cue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ global: {
3737
path: "global/ci/deploy"
3838
}
3939

40-
github: registry: "ghcr.io"
40+
github: {
41+
credentials: {
42+
provider: "aws"
43+
path: "global/ci/github"
44+
}
45+
registry: "ghcr.io"
46+
}
4147
}
4248
secrets: [
4349
{

lib/project/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
github.com/aws/aws-sdk-go-v2/config v1.27.40
88
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.33.4
99
github.com/go-git/go-git/v5 v5.12.0
10+
github.com/google/go-github/v66 v66.0.0
1011
github.com/input-output-hk/catalyst-forge/lib/tools v0.0.0
1112
github.com/spf13/afero v1.11.0
1213
github.com/stretchr/testify v1.9.0
@@ -39,6 +40,7 @@ require (
3940
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
4041
github.com/go-git/go-billy/v5 v5.5.0 // indirect
4142
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
43+
github.com/google/go-querystring v1.1.0 // indirect
4244
github.com/google/uuid v1.6.0 // indirect
4345
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
4446
github.com/kevinburke/ssh_config v1.2.0 // indirect

lib/project/go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,13 @@ github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7
8282
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
8383
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
8484
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
85+
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
8586
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
8687
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
88+
github.com/google/go-github/v66 v66.0.0 h1:ADJsaXj9UotwdgK8/iFZtv7MLc8E8WBl62WLd/D/9+M=
89+
github.com/google/go-github/v66 v66.0.0/go.mod h1:+4SO9Zkuyf8ytMj0csN1NR/5OTR+MfqPp8P8dVlcvY4=
90+
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
91+
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
8792
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
8893
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
8994
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
@@ -213,6 +218,7 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
213218
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
214219
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
215220
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
221+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
216222
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
217223
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
218224
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

lib/project/project/loader.go

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import (
1111
"cuelang.org/go/cue/cuecontext"
1212
"github.com/input-output-hk/catalyst-forge/lib/project/blueprint"
1313
"github.com/input-output-hk/catalyst-forge/lib/project/injector"
14+
"github.com/input-output-hk/catalyst-forge/lib/project/providers"
1415
"github.com/input-output-hk/catalyst-forge/lib/project/schema"
16+
"github.com/input-output-hk/catalyst-forge/lib/project/secrets"
1517
"github.com/input-output-hk/catalyst-forge/lib/tools/earthfile"
1618
"github.com/input-output-hk/catalyst-forge/lib/tools/git"
1719
"github.com/input-output-hk/catalyst-forge/lib/tools/walker"
@@ -46,6 +48,13 @@ func (p *DefaultProjectLoader) Load(projectPath string) (Project, error) {
4648
return Project{}, fmt.Errorf("failed to find git root: %w", err)
4749
}
4850

51+
p.logger.Info("Loading blueprint", "path", projectPath)
52+
rbp, err := p.blueprintLoader.Load(projectPath, gitRoot)
53+
if err != nil {
54+
p.logger.Error("Failed to load blueprint", "error", err, "path", projectPath)
55+
return Project{}, fmt.Errorf("failed to load blueprint: %w", err)
56+
}
57+
4958
p.logger.Info("Loading repository", "path", gitRoot)
5059
rl := git.NewCustomDefaultRepoLoader(p.fs)
5160
repo, err := rl.Load(gitRoot)
@@ -54,13 +63,6 @@ func (p *DefaultProjectLoader) Load(projectPath string) (Project, error) {
5463
return Project{}, fmt.Errorf("failed to load repository: %w", err)
5564
}
5665

57-
p.logger.Info("Loading blueprint", "path", projectPath)
58-
rbp, err := p.blueprintLoader.Load(projectPath, gitRoot)
59-
if err != nil {
60-
p.logger.Error("Failed to load blueprint", "error", err, "path", projectPath)
61-
return Project{}, fmt.Errorf("failed to load blueprint: %w", err)
62-
}
63-
6466
efPath := filepath.Join(projectPath, "Earthfile")
6567
exists, err := afero.Exists(p.fs, efPath)
6668
if err != nil {
@@ -128,19 +130,22 @@ func (p *DefaultProjectLoader) Load(projectPath string) (Project, error) {
128130
p.logger.Debug("No git tag found")
129131
}
130132

133+
partialProject := Project{
134+
Earthfile: ef,
135+
Name: name,
136+
Path: projectPath,
137+
RawBlueprint: rbp,
138+
Repo: repo,
139+
RepoRoot: gitRoot,
140+
Tag: tag,
141+
ctx: p.ctx,
142+
logger: p.logger,
143+
}
144+
131145
p.logger.Info("Gathering runtime data")
132146
runtimeData := make(map[string]cue.Value)
133147
for _, r := range p.runtimes {
134-
d := r.Load(&Project{
135-
Earthfile: ef,
136-
Path: projectPath,
137-
RawBlueprint: rbp,
138-
Repo: repo,
139-
RepoRoot: gitRoot,
140-
Tag: tag,
141-
ctx: p.ctx,
142-
logger: p.logger,
143-
})
148+
d := r.Load(&partialProject)
144149

145150
for k, v := range d {
146151
runtimeData[k] = v
@@ -187,18 +192,23 @@ func NewDefaultProjectLoader(
187192
}
188193

189194
ctx := cuecontext.New()
195+
fs := afero.NewOsFs()
190196
bl := blueprint.NewDefaultBlueprintLoader(ctx, logger)
191197
rl := git.NewDefaultRepoLoader()
198+
store := secrets.NewDefaultSecretStore()
199+
ghp := providers.NewGithubProvider(fs, logger, &store)
192200
return DefaultProjectLoader{
193201
blueprintLoader: &bl,
194202
ctx: ctx,
195-
fs: afero.NewOsFs(),
203+
fs: fs,
196204
injectors: []injector.BlueprintInjector{
197205
injector.NewBlueprintEnvInjector(ctx, logger),
198206
},
199207
logger: logger,
200208
repoLoader: &rl,
201-
runtimes: GetDefaultRuntimes(logger),
209+
runtimes: []RuntimeData{
210+
NewGitRuntime(&ghp, logger),
211+
},
202212
}
203213
}
204214

lib/project/project/loader_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/go-git/go-git/v5/storage/filesystem"
1212
"github.com/input-output-hk/catalyst-forge/lib/project/blueprint"
1313
"github.com/input-output-hk/catalyst-forge/lib/project/injector"
14+
"github.com/input-output-hk/catalyst-forge/lib/project/providers"
1415
"github.com/input-output-hk/catalyst-forge/lib/tools/testutils"
1516
"github.com/spf13/afero"
1617
"github.com/stretchr/testify/assert"
@@ -20,6 +21,7 @@ import (
2021

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

2426
earthfile := `
2527
VERSION 0.8
@@ -136,7 +138,10 @@ project: {
136138
injector.NewBlueprintEnvInjector(ctx, testutils.NewNoopLogger()),
137139
},
138140
runtimes: []RuntimeData{
139-
NewGitRuntime(testutils.NewNoopLogger()),
141+
NewGitRuntime(
142+
&githubProvider,
143+
testutils.NewNoopLogger(),
144+
),
140145
},
141146
env: map[string]string{},
142147
initGit: true,

lib/project/project/project.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ type Project struct {
4242
// TagInfo is the project tag information.
4343
//TagInfo *TagInfo
4444

45-
logger *slog.Logger
4645
ctx *cue.Context
46+
logger *slog.Logger
4747
}
4848

4949
// GetRelativePath returns the relative path of the project from the repo root.
@@ -118,8 +118,8 @@ func NewProject(
118118
Path: path,
119119
Repo: repo,
120120
RepoRoot: repoRoot,
121+
Tag: tag,
121122
ctx: ctx,
122123
logger: logger,
123-
Tag: tag,
124124
}
125125
}

lib/project/project/runtime.go

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66

77
"cuelang.org/go/cue"
88
"github.com/go-git/go-git/v5"
9+
"github.com/google/go-github/v66/github"
10+
"github.com/input-output-hk/catalyst-forge/lib/project/providers"
911
)
1012

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

1618
// GitRuntime is a runtime data loader for git related data.
1719
type GitRuntime struct {
18-
logger *slog.Logger
20+
provider *providers.GithubProvider
21+
logger *slog.Logger
1922
}
2023

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

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

42-
// NewGitRuntime creates a new GitRuntime.
43-
func NewGitRuntime(logger *slog.Logger) *GitRuntime {
44-
return &GitRuntime{
45-
logger: logger,
46-
}
47-
}
45+
// getCommitHash returns the commit hash of the HEAD commit.
46+
func (g *GitRuntime) getCommitHash(repo *git.Repository) (string, error) {
47+
if g.provider.HasEvent() {
48+
if g.provider.GetEventType() == "pull_request" {
49+
g.logger.Debug("Found GitHub pull request event")
50+
event, err := g.provider.GetEventPayload()
51+
if err != nil {
52+
return "", fmt.Errorf("failed to get event payload: %w", err)
53+
}
54+
55+
pr, ok := event.(*github.PullRequestEvent)
56+
if !ok {
57+
return "", fmt.Errorf("unexpected event type")
58+
}
59+
60+
if pr.PullRequest.Head.SHA == nil {
61+
return "", fmt.Errorf("pull request head SHA is empty")
62+
}
63+
64+
return *pr.PullRequest.Head.SHA, nil
65+
} else if g.provider.GetEventType() == "push" {
66+
g.logger.Debug("Found GitHub push event")
67+
event, err := g.provider.GetEventPayload()
68+
if err != nil {
69+
return "", fmt.Errorf("failed to get event payload: %w", err)
70+
}
71+
72+
push, ok := event.(*github.PushEvent)
73+
if !ok {
74+
return "", fmt.Errorf("unexpected event type")
75+
}
4876

49-
// GetDefaultRuntimes returns the default runtime data loaders.
50-
func GetDefaultRuntimes(logger *slog.Logger) []RuntimeData {
51-
return []RuntimeData{
52-
NewGitRuntime(logger),
77+
if push.After == nil {
78+
return "", fmt.Errorf("push event after SHA is empty")
79+
}
80+
81+
return *push.After, nil
82+
}
5383
}
54-
}
5584

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

6896
return obj.Hash.String(), nil
6997
}
98+
99+
// NewGitRuntime creates a new GitRuntime.
100+
func NewGitRuntime(githubProvider *providers.GithubProvider, logger *slog.Logger) *GitRuntime {
101+
return &GitRuntime{
102+
logger: logger,
103+
provider: githubProvider,
104+
}
105+
}

0 commit comments

Comments
 (0)