diff --git a/cloud/deploy/bundle.go b/cloud/deploy/bundle.go index 734a29568..8c25d3e87 100644 --- a/cloud/deploy/bundle.go +++ b/cloud/deploy/bundle.go @@ -51,10 +51,15 @@ func DeployBundle(input *DeployBundleInput) error { } // retrieve metadata about the local Git checkout. returns nil if not available - gitMetadata := retrieveLocalGitMetadata(input.BundlePath) + deployGit, commitMessage := retrieveLocalGitMetadata(input.BundlePath) + + // if no description was provided, use the commit message from the local Git checkout + if input.Description == "" { + input.Description = commitMessage + } // initialize the deploy - deploy, err := createBundleDeploy(c.Organization, input, gitMetadata, input.CoreClient) + deploy, err := createBundleDeploy(c.Organization, input, deployGit, input.CoreClient) if err != nil { return err } @@ -210,82 +215,75 @@ func finalizeBundleDeploy(organizationID, deploymentID, deployID, tarballVersion return nil } -func retrieveLocalGitMetadata(bundlePath string) *astrocore.DeployGit { +func retrieveLocalGitMetadata(bundlePath string) (deployGit *astrocore.DeployGit, commitMessage string) { if git.HasUncommittedChanges(bundlePath) { - logrus.Warn("Local repository has uncommitted changes, skipping Git metadata retrieval") - return nil + fmt.Println("Local repository has uncommitted changes, skipping Git metadata retrieval") + return nil, "" } - gitMetadata := &astrocore.DeployGit{} + deployGit = &astrocore.DeployGit{} // get the remote repository details, assume the remote is named "origin" repoURL, err := git.GetRemoteRepository(bundlePath, "origin") if err != nil { logrus.Debugf("Failed to retrieve remote repository details, skipping Git metadata retrieval: %s", err) - return nil + return nil, "" } switch repoURL.Host { case "github.com": - gitMetadata.Provider = astrocore.DeployGitProviderGITHUB + deployGit.Provider = astrocore.DeployGitProviderGITHUB default: logrus.Debugf("Unsupported Git provider, skipping Git metadata retrieval: %s", repoURL.Host) - return nil + return nil, "" } urlPath := strings.TrimPrefix(repoURL.Path, "/") firstSlashIndex := strings.Index(urlPath, "/") if firstSlashIndex == -1 { logrus.Debugf("Failed to parse remote repository path, skipping Git metadata retrieval: %s", repoURL.Path) - return nil + return nil, "" } - gitMetadata.Account = urlPath[:firstSlashIndex] - gitMetadata.Repo = urlPath[firstSlashIndex+1:] + deployGit.Account = urlPath[:firstSlashIndex] + deployGit.Repo = urlPath[firstSlashIndex+1:] // get the path of the bundle within the repository path, err := git.GetLocalRepositoryPathPrefix(bundlePath, bundlePath) if err != nil { logrus.Debugf("Failed to retrieve local repository path prefix, skipping Git metadata retrieval: %s", err) - return nil + return nil, "" } if path != "" { - gitMetadata.Path = &path + deployGit.Path = &path } // get the branch of the local commit branch, err := git.GetBranch(bundlePath) if err != nil { logrus.Debugf("Failed to retrieve branch name, skipping Git metadata retrieval: %s", err) - return nil + return nil, "" } - gitMetadata.Branch = branch + deployGit.Branch = branch - // get the SHA of the local commit - sha, err := git.GetHeadCommitSHA(bundlePath) + // get the local commit + sha, message, authorName, _, err := git.GetHeadCommit(bundlePath) if err != nil { - logrus.Debugf("Failed to retrieve commit SHA, skipping Git metadata retrieval: %s", err) - return nil + logrus.Debugf("Failed to retrieve commit, skipping Git metadata retrieval: %s", err) + return nil, "" + } + deployGit.CommitSha = sha + if authorName != "" { + deployGit.AuthorName = &authorName } - gitMetadata.CommitSha = sha // derive the remote URL of the local commit switch repoURL.Host { case "github.com": - gitMetadata.CommitUrl = fmt.Sprintf("https://%s/%s/%s/commit/%s", repoURL.Host, gitMetadata.Account, gitMetadata.Repo, sha) + deployGit.CommitUrl = fmt.Sprintf("https://%s/%s/%s/commit/%s", repoURL.Host, deployGit.Account, deployGit.Repo, sha) default: logrus.Debugf("Unsupported Git provider, skipping Git metadata retrieval: %s", repoURL.Host) - return nil - } - - // get the author name of the local commit - authorName, _, err := git.GetHeadCommitAuthor(bundlePath) - if err != nil { - logrus.Debugf("Failed to retrieve commit author, skipping Git metadata retrieval: %s", err) - return nil - } - if authorName != "" { - gitMetadata.AuthorName = &authorName + return nil, "" } - logrus.Debugf("Retrieved Git metadata: %+v", gitMetadata) + logrus.Debugf("Retrieved Git metadata: %+v", deployGit) - return gitMetadata + return deployGit, message } diff --git a/cloud/deploy/bundle_test.go b/cloud/deploy/bundle_test.go index 5baab23f3..d5328ca42 100644 --- a/cloud/deploy/bundle_test.go +++ b/cloud/deploy/bundle_test.go @@ -13,6 +13,7 @@ import ( astrocore_mocks "github.com/astronomer/astro-cli/astro-client-core/mocks" astroplatformcore "github.com/astronomer/astro-cli/astro-client-platform-core" astroplatformcore_mocks "github.com/astronomer/astro-cli/astro-client-platform-core/mocks" + "github.com/astronomer/astro-cli/pkg/git" testUtil "github.com/astronomer/astro-cli/pkg/testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -121,11 +122,12 @@ func (s *BundleSuite) TestBundleDeploy_GitMetadataRetrieved() { mockGetDeployment(s.mockPlatformCoreClient, true, false) expectedAuthorName := "Test" + expectedDescription := strings.Repeat("a", git.MaxCommitMessageLineLength) expectedDeploy := &astrocore.CreateDeployRequest{ Type: astrocore.CreateDeployRequestTypeBUNDLE, BundleType: &input.BundleType, BundleMountPath: &input.MountPath, - Description: &input.Description, + Description: &expectedDescription, Git: &astrocore.CreateDeployGitRequest{ Provider: astrocore.CreateDeployGitRequestProviderGITHUB, Account: "account", @@ -280,7 +282,8 @@ func (s *BundleSuite) createTestGitRepository(withUncommittedFile bool) (sha, pa err = exec.Command("git", "-C", dir, "config", "user.name", "Test").Run() require.NoError(s.T(), err) - err = exec.Command("git", "-C", dir, "commit", "--allow-empty", "-m", "Initial commit").Run() + commitMessage := strings.Repeat("a", git.MaxCommitMessageLineLength+1) + "\n" + strings.Repeat("b", git.MaxCommitMessageLineLength+1) + err = exec.Command("git", "-C", dir, "commit", "--allow-empty", "-m", commitMessage).Run() require.NoError(s.T(), err) err = exec.Command("git", "-C", dir, "remote", "add", "origin", "https://github.com/account/repo.git").Run() diff --git a/pkg/git/git.go b/pkg/git/git.go index b428521ed..848ba7d42 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -8,6 +8,8 @@ import ( "strings" ) +const MaxCommitMessageLineLength = 72 + // HasUncommittedChanges checks repository for uncommitted changes func HasUncommittedChanges(path string) bool { if !IsGitRepository(path) { @@ -44,28 +46,35 @@ func GetBranch(path string) (string, error) { return runGitCommand(path, []string{"rev-parse", "--abbrev-ref", "HEAD"}) } -func GetHeadCommitSHA(path string) (string, error) { - return runGitCommand(path, []string{"rev-parse", "HEAD"}) -} - -func GetHeadCommitAuthor(path string) (name, email string, err error) { - authorJSON, err := runGitCommand(path, []string{"log", "-1", `--pretty=format:{"name":"%an","email":"%ae"}`, "HEAD"}) +func GetHeadCommit(path string) (sha, message, name, email string, err error) { + commitJSON, err := runGitCommand(path, []string{"log", "-1", `--pretty=format:{"sha":"%H","name":"%an","email":"%ae"}`, "HEAD"}) if err != nil { - return "", "", err + return "", "", "", "", err } - // parse the author JSON - // e.g. {"name":"Jane Doe","email":"jane@doe.com"} - author := struct { + // parse the commit JSON + // e.g. {"sha":"c1b4c1b...","name":"author name","email":"author email"} + commit := struct { + Sha string `json:"sha"` Name string `json:"name"` Email string `json:"email"` }{} - err = json.Unmarshal([]byte(authorJSON), &author) + err = json.Unmarshal([]byte(commitJSON), &commit) if err != nil { - return "", "", err + return "", "", "", "", err + } + + // get the commit message, truncated to the first line with a max line length + message, err = runGitCommand(path, []string{"log", "-1", "--pretty=%B", "HEAD"}) + if err != nil { + return "", "", "", "", err + } + message = strings.Split(message, "\n")[0] + if len(message) > MaxCommitMessageLineLength { + message = message[:MaxCommitMessageLineLength] } - return author.Name, author.Email, nil + return commit.Sha, message, commit.Name, commit.Email, nil } func runGitCommand(path string, args []string) (string, error) {