Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/next config workflows #1840

Merged
merged 4 commits into from
Nov 22, 2024
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
2 changes: 1 addition & 1 deletion backend/controllers/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (d DiggerController) UpdateRepoCache(c *gin.Context) {

// update the cache here, do it async for immediate response
go func() {
err = utils.CloneGitRepoAndDoAction(cloneUrl, branch, *token, func(dir string) error {
err = utils.CloneGitRepoAndDoAction(cloneUrl, branch, "", *token, func(dir string) error {
diggerYmlBytes, err := os.ReadFile(path.Join(dir, "digger.yml"))
diggerYmlStr = string(diggerYmlBytes)
config, _, _, err = dg_configuration.LoadDiggerConfig(dir, true, nil)
Expand Down
2 changes: 1 addition & 1 deletion backend/controllers/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ func GetDiggerConfigForBranch(gh utils.GithubClientProvider, installationId int6
var diggerYmlStr string
var dependencyGraph graph.Graph[string, dg_configuration.Project]

err = utils.CloneGitRepoAndDoAction(cloneUrl, branch, *token, func(dir string) error {
err = utils.CloneGitRepoAndDoAction(cloneUrl, branch, "", *token, func(dir string) error {
diggerYmlBytes, err := os.ReadFile(path.Join(dir, "digger.yml"))
diggerYmlStr = string(diggerYmlBytes)
config, _, dependencyGraph, err = dg_configuration.LoadDiggerConfig(dir, true, changedFiles)
Expand Down
6 changes: 5 additions & 1 deletion backend/utils/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,18 @@ func createTempDir() string {

type action func(string) error

func CloneGitRepoAndDoAction(repoUrl string, branch string, token string, action action) error {
func CloneGitRepoAndDoAction(repoUrl string, branch string, commitHash string, token string, action action) error {
dir := createTempDir()
git := NewGitShellWithTokenAuth(dir, token)
err := git.Clone(repoUrl, branch)
if err != nil {
return err
}

if commitHash != "" {
git.Checkout(commitHash)
}

defer func() {
log.Printf("removing cloned directory %v", dir)
ferr := os.RemoveAll(dir)
Expand Down
8 changes: 4 additions & 4 deletions backend/utils/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ func init() {

func TestGithubCloneWithInvalidTokenThrowsErr(t *testing.T) {
f := func(d string) error { return nil }
err := CloneGitRepoAndDoAction("https://github.com/diggerhq/private-repo", "main", "invalid-token", f)
err := CloneGitRepoAndDoAction("https://github.com/diggerhq/private-repo", "main", "", "invalid-token", f)
assert.NotNil(t, err)
}

func TestGithubCloneWithPublicRepoThrowsNoError(t *testing.T) {
token := os.Getenv("GITHUB_PAT_TOKEN")
f := func(d string) error { return nil }
err := CloneGitRepoAndDoAction("https://github.com/diggerhq/digger", "develop", token, f)
err := CloneGitRepoAndDoAction("https://github.com/diggerhq/digger", "develop", "", token, f)
assert.Nil(t, err)
}

Expand All @@ -32,13 +32,13 @@ func TestGithubCloneWithPrivateRepoAndValidTokenThrowsNoError(t *testing.T) {
return
}
f := func(d string) error { return nil }
err := CloneGitRepoAndDoAction("https://github.com/diggerhq/infra-gcp", "main", token, f)
err := CloneGitRepoAndDoAction("https://github.com/diggerhq/infra-gcp", "main", "", token, f)
assert.Nil(t, err)
}

func TestGithubCloneWithInvalidBranchThrowsError(t *testing.T) {
token := os.Getenv("GITHUB_PAT_TOKEN")
f := func(d string) error { return nil }
err := CloneGitRepoAndDoAction("https://github.com/diggerhq/digger", "not-a-branch", token, f)
err := CloneGitRepoAndDoAction("https://github.com/diggerhq/digger", "not-a-branch", "", token, f)
assert.NotNil(t, err)
}
2 changes: 1 addition & 1 deletion backend/utils/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func GetDiggerConfigForBranch(gh GitlabProvider, projectId int, repoFullName str
log.Printf("Error getting changed files: %v", err)
return "", nil, nil, fmt.Errorf("error getting changed files")
}
err = CloneGitRepoAndDoAction(cloneUrl, branch, token, func(dir string) error {
err = CloneGitRepoAndDoAction(cloneUrl, branch, "", token, func(dir string) error {
diggerYmlBytes, err := os.ReadFile(path.Join(dir, "digger.yml"))
diggerYmlStr = string(diggerYmlBytes)
config, _, dependencyGraph, err = dg_configuration.LoadDiggerConfig(dir, true, changedFiles)
Expand Down
7 changes: 7 additions & 0 deletions backend/utils/gitshell.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ func (g *GitShell) runCommand(args ...string) (string, error) {
return strings.TrimSpace(stdout.String()), nil
}

func (g *GitShell) Checkout(branchOrCommit string) error {
args := []string{"checkout"}
args = append(args, branchOrCommit)
_, err := g.runCommand(args...)
return err
}

// Clone with authentication
func (g *GitShell) Clone(repoURL, branch string) error {
authURL, err := g.formatAuthURL(repoURL)
Expand Down
7 changes: 7 additions & 0 deletions cli/pkg/spec/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ func RunSpec(
usage.ReportErrorAndExit(spec.VCS.Actor, fmt.Sprintf("could not get backend api: %v", err), 1)
}

// for additional output reporting
diggerOutPath := os.Getenv("DIGGER_OUT")
if diggerOutPath == "" {
diggerOutPath = os.Getenv("RUNNER_TEMP") + "/digger-out.log"
os.Setenv("DIGGER_OUT", diggerOutPath)
}

if spec.Job.Commit != "" {
// checking out to the commit ID
log.Printf("fetching commit ID %v", spec.Job.Commit)
Expand Down
2 changes: 1 addition & 1 deletion ee/backend/controllers/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func handlePushEvent(gh utils.GitlabProvider, payload *gitlab.PushEvent, organis
isMainBranch = false
}

err = utils.CloneGitRepoAndDoAction(cloneURL, pushBranch, token, func(dir string) error {
err = utils.CloneGitRepoAndDoAction(cloneURL, pushBranch, "", token, func(dir string) error {
config, err := dg_configuration.LoadDiggerConfigYaml(dir, true, nil)
if err != nil {
log.Printf("ERROR load digger.yml: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion ee/drift/tasks/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func LoadProjectsFromGithubRepo(gh utils2.GithubClientProvider, installationId s
return fmt.Errorf("error getting github service")
}

err = utils3.CloneGitRepoAndDoAction(cloneUrl, branch, *token, func(dir string) error {
err = utils3.CloneGitRepoAndDoAction(cloneUrl, branch, "", *token, func(dir string) error {
config, err := dg_configuration.LoadDiggerConfigYaml(dir, true, nil)
if err != nil {
log.Printf("ERROR load digger.yml: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion ee/drift/utils/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func GetDiggerConfigForBranch(gh utils.GithubClientProvider, installationId int6

var changedFiles []string = nil

err = utils2.CloneGitRepoAndDoAction(cloneUrl, branch, *token, func(dir string) error {
err = utils2.CloneGitRepoAndDoAction(cloneUrl, branch, "", *token, func(dir string) error {
diggerYmlBytes, err := os.ReadFile(path.Join(dir, "digger.yml"))
diggerYmlStr = string(diggerYmlBytes)
config, _, dependencyGraph, err = dg_configuration.LoadDiggerConfig(dir, true, changedFiles)
Expand Down
27 changes: 24 additions & 3 deletions libs/digger_config/digger_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,30 @@ type FileSystemTerragruntDirWalker struct {
type FileSystemModuleDirWalker struct {
}

func CheckOrCreateDiggerFile(dir string) error {
// Check for digger.yml
ymlPath := filepath.Join(dir, "digger.yml")
yamlPath := filepath.Join(dir, "digger.yaml")

// Check if either file exists
if _, err := os.Stat(ymlPath); err == nil {
return nil // digger.yml exists
}
if _, err := os.Stat(yamlPath); err == nil {
return nil // digger.yaml exists
}

// Neither file exists, create digger.yml
file, err := os.Create(ymlPath)
if err != nil {
return err
}
defer file.Close()

// File is created empty by default
return nil
}

func GetFilesWithExtension(workingDir string, ext string) ([]string, error) {
var files []string
listOfFiles, err := os.ReadDir(workingDir)
Expand Down Expand Up @@ -363,9 +387,6 @@ func LoadDiggerConfigYaml(workingDir string, generateProjects bool, changedFiles
}

func ValidateDiggerConfigYaml(configYaml *DiggerConfigYaml, fileName string) error {
if (configYaml.Projects == nil || len(configYaml.Projects) == 0) && configYaml.GenerateProjectsConfig == nil {
return fmt.Errorf("no projects digger_config found in '%s'", fileName)
}
if configYaml.DependencyConfiguration != nil {
if configYaml.DependencyConfiguration.Mode != DependencyConfigurationHard && configYaml.DependencyConfiguration.Mode != DependencyConfigurationSoft {
return fmt.Errorf("dependency digger_config mode can only be '%s' or '%s'", DependencyConfigurationHard, DependencyConfigurationSoft)
Expand Down
11 changes: 6 additions & 5 deletions libs/digger_config/digger_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,9 @@ func TestMissingProjectsReturnsError(t *testing.T) {
`
deleteFile := createFile(path.Join(tempDir, "digger.yaml"), diggerCfg)
defer deleteFile()
_, _, _, err := LoadDiggerConfig(tempDir, true, nil)
assert.ErrorContains(t, err, "no projects digger_config found")
config, _, _, err := LoadDiggerConfig(tempDir, true, nil)
assert.Nil(t, err)
assert.Equal(t, len(config.Projects), 0)
}

func TestDiggerConfigCustomWorkflow(t *testing.T) {
Expand Down Expand Up @@ -941,9 +942,9 @@ func TestDiggerGenerateProjectsEmptyParameters(t *testing.T) {
diggerCfg := `
generate_projects:
`
_, _, _, err := LoadDiggerConfigFromString(diggerCfg, "./")
assert.Error(t, err)
assert.Equal(t, "no projects digger_config found in 'loaded_yaml_string'", err.Error())
config, _, _, err := LoadDiggerConfigFromString(diggerCfg, "./")
assert.Nil(t, err)
assert.Equal(t, 0, len(config.Projects))
}

// TestDiggerGenerateProjectsTooManyParameters include/exclude and blocks of include/exclude can't be used together
Expand Down
39 changes: 17 additions & 22 deletions next/controllers/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,19 @@ func (d DiggerController) GithubAppWebHook(c *gin.Context) {
err := handlePullRequestEvent(gh, event, d.CiBackendProvider)
if err != nil {
log.Printf("handlePullRequestEvent error: %v", err)
c.String(http.StatusInternalServerError, err.Error())
return
}
c.String(http.StatusAccepted, err.Error())
return

case *github.PushEvent:
log.Printf("Got push event for %d", event.Repo.URL)
handlePushEventApplyAfterMerge(gh, event)
if err != nil {
log.Printf("handlePushEvent error: %v", err)
c.String(http.StatusInternalServerError, err.Error())
return
}
c.String(http.StatusAccepted, err.Error())
return

default:
log.Printf("Unhandled event, event type %v", reflect.TypeOf(event))
}
Expand Down Expand Up @@ -357,30 +359,23 @@ func handlePullRequestEvent(gh next_utils.GithubClientProvider, payload *github.
}

projectsGraph, err := dg_configuration.CreateProjectDependencyGraph(dgprojects)
workflows, err := services.GetWorkflowsForRepoAndBranch(gh, repo.ID, sourceBranch, commitSha)
if err != nil {
log.Printf("error getting workflows from config: %v", err)
return fmt.Errorf("error getting workflows from config")
}
var config *dg_configuration.DiggerConfig = &dg_configuration.DiggerConfig{
ApplyAfterMerge: true,
AllowDraftPRs: false,
CommentRenderMode: "",
DependencyConfiguration: dg_configuration.DependencyConfiguration{
Mode: dg_configuration.DependencyConfigurationHard,
},
PrLocks: false,
Projects: dgprojects,
AutoMerge: false,
Telemetry: false,
Workflows: map[string]dg_configuration.Workflow{
"default": dg_configuration.Workflow{
EnvVars: nil,
Plan: nil,
Apply: nil,
Configuration: &dg_configuration.WorkflowConfiguration{
OnPullRequestPushed: []string{"digger plan"},
OnPullRequestClosed: []string{},
OnPullRequestConvertedToDraft: []string{},
OnCommitToDefault: []string{},
},
},
},
PrLocks: false,
Projects: dgprojects,
AutoMerge: false,
Telemetry: false,
Workflows: workflows,
MentionDriftedProjectsInPR: false,
TraverseToNestedProjects: false,
}
Expand Down Expand Up @@ -540,7 +535,7 @@ func getDiggerConfigForBranch(gh next_utils.GithubClientProvider, installationId
log.Printf("Error getting changed files: %v", err)
return "", nil, nil, nil, fmt.Errorf("error getting changed files")
}
err = backend_utils.CloneGitRepoAndDoAction(cloneUrl, branch, *token, func(dir string) error {
err = backend_utils.CloneGitRepoAndDoAction(cloneUrl, branch, "", *token, func(dir string) error {
diggerYmlBytes, err := os.ReadFile(path.Join(dir, "digger.yml"))
diggerYmlStr = string(diggerYmlBytes)
config, _, dependencyGraph, err = dg_configuration.LoadDiggerConfig(dir, true, changedFiles)
Expand Down
28 changes: 11 additions & 17 deletions next/controllers/github_after_merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
dg_configuration "github.com/diggerhq/digger/libs/digger_config"
"github.com/diggerhq/digger/libs/scheduler"
"github.com/diggerhq/digger/next/dbmodels"
"github.com/diggerhq/digger/next/services"
nextutils "github.com/diggerhq/digger/next/utils"
"github.com/google/go-github/v61/github"
"log"
Expand Down Expand Up @@ -66,30 +67,23 @@ func handlePushEventApplyAfterMerge(gh nextutils.GithubClientProvider, payload *
}
}
projectsGraph, err := dg_configuration.CreateProjectDependencyGraph(dgprojects)
workflows, err := services.GetWorkflowsForRepoAndBranch(gh, repo.ID, targetBranch, commitId)
if err != nil {
log.Printf("error getting workflows from config: %v", err)
return fmt.Errorf("error getting workflows from config")
}
var config *dg_configuration.DiggerConfig = &dg_configuration.DiggerConfig{
ApplyAfterMerge: true,
AllowDraftPRs: false,
CommentRenderMode: "",
DependencyConfiguration: dg_configuration.DependencyConfiguration{
Mode: dg_configuration.DependencyConfigurationHard,
},
PrLocks: false,
Projects: dgprojects,
AutoMerge: false,
Telemetry: false,
Workflows: map[string]dg_configuration.Workflow{
"default": dg_configuration.Workflow{
EnvVars: nil,
Plan: nil,
Apply: nil,
Configuration: &dg_configuration.WorkflowConfiguration{
OnPullRequestPushed: []string{"digger plan"},
OnPullRequestClosed: []string{},
OnPullRequestConvertedToDraft: []string{},
OnCommitToDefault: []string{},
},
},
},
PrLocks: false,
Projects: dgprojects,
AutoMerge: false,
Telemetry: false,
Workflows: workflows,
MentionDriftedProjectsInPR: false,
TraverseToNestedProjects: false,
}
Expand Down
63 changes: 63 additions & 0 deletions next/services/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package services

import (
"fmt"
utils3 "github.com/diggerhq/digger/backend/utils"
dg_configuration "github.com/diggerhq/digger/libs/digger_config"
"github.com/diggerhq/digger/next/dbmodels"
"github.com/diggerhq/digger/next/utils"
"log"
)

func GetWorkflowsForRepoAndBranch(gh utils.GithubClientProvider, repoId int64, branch string, commitHash string) (map[string]dg_configuration.Workflow, error) {
r := dbmodels.DB.Query.Repo
repo, err := dbmodels.DB.Query.Repo.Where(r.ID.Eq(repoId)).First()
if err != nil {
log.Printf("could not find repo: %v : %v", repoId, err)
return nil, fmt.Errorf("could not find repo: %v: %v", repoId, err)
}
repoOwner := repo.RepoOrganisation
repoFullName := repo.RepoFullName
repoName := repo.RepoName
orgId := repo.OrganizationID

appInstallation, err := dbmodels.DB.GetGithubAppInstallationByOrgAndRepo(orgId, repoFullName, dbmodels.GithubAppInstallActive)
if err != nil {
log.Printf("error retrieving app installation")
return nil, fmt.Errorf("error retrieving app installation %v", err)
}
installationId := appInstallation.GithubInstallationID
log.Printf("installation id is: %v", installationId)

cloneUrl := fmt.Sprintf("https://%v/%v", utils.GetGithubHostname(), repo.RepoFullName)

_, token, err := utils.GetGithubService(gh, installationId, repoFullName, repoOwner, repoName)
if err != nil {
log.Printf("could not get github service :%v", err)
return nil, fmt.Errorf("could not get github service :%v", err)
}

var config *dg_configuration.DiggerConfig

err = utils3.CloneGitRepoAndDoAction(cloneUrl, branch, commitHash, *token, func(dir string) error {
// we create a blank file if it does not exist
err := dg_configuration.CheckOrCreateDiggerFile(dir)
if err != nil {
log.Printf("Error creating blank digger.yml if not exists: %v", err)
return err
}
config, _, _, err = dg_configuration.LoadDiggerConfig(dir, false, nil)
if err != nil {
log.Printf("Error loading digger config: %v", err)
return err
}
return nil
})

if err != nil {
log.Printf("could not load digger config :%v", err)
return nil, fmt.Errorf("could not load digger config :%v", err)
}

return config.Workflows, nil
}
Loading
Loading