Skip to content
Snippets Groups Projects
Commit 125ba11a authored by Shreyas Prabhu's avatar Shreyas Prabhu
Browse files

feat: add repository management functionality with link operation

parent f9835d90
Branches
No related tags found
No related merge requests found
package cloudbuild
import (
"fmt"
"google.golang.org/api/cloudbuild/v2"
)
// LinkRepository links a repository to Cloud Build
// It creates a repository resource in Cloud Build that points to the specified repository
// in the source provider (GitHub, GitLab, etc.)
func (c *Client) LinkRepository(projectID, location, connectionName, repoName, remoteURI string) error {
// Format the connection name as required by the API (this is the parent for repository creation)
connectionRef := fmt.Sprintf("projects/%s/locations/%s/connections/%s", projectID, location, connectionName)
// Create a repository object with the required remoteUri field
repository := &cloudbuild.Repository{
RemoteUri: remoteURI, // The API requires the remote URI to be specified
}
// Make the API call to create/link the repository
_, err := c.service.Projects.Locations.Connections.Repositories.Create(
connectionRef, // The parent (connection)
repository, // Repository object with required fields
).RepositoryId(repoName).Do() // Set the repository ID
if err != nil {
return fmt.Errorf("error linking repository: %w", err)
}
return nil
}
// GetRepository retrieves information about a specific repository
func (c *Client) GetRepository(projectID, location, connectionName, repoName string) (*cloudbuild.Repository, error) {
// Format the repository name as required by the API
repoFullName := fmt.Sprintf("projects/%s/locations/%s/connections/%s/repositories/%s",
projectID, location, connectionName, repoName)
// Make the API call to get the repository
repo, err := c.service.Projects.Locations.Connections.Repositories.Get(repoFullName).Do()
if err != nil {
return nil, fmt.Errorf("error getting repository: %w", err)
}
return repo, nil
}
......@@ -165,6 +165,123 @@ func main() {
}
}
case "link-repository":
// If connection name not provided via command line, get it from config
connNameToLink := *connectionName
if connNameToLink == "" {
// If there's only one connection in config, use that
if len(cfg.Connections) == 1 {
connNameToLink = cfg.Connections[0].Name
fmt.Printf("Using connection name from config: %s\n", connNameToLink)
} else if len(cfg.Connections) > 1 {
// If multiple connections, show the available options
fmt.Println("Multiple connections found in config. Please specify which one to use with --name flag:")
for i, conn := range cfg.Connections {
fmt.Printf("%d. %s\n", i+1, conn.Name)
}
os.Exit(1)
} else {
log.Fatalf("No connections found in config file")
}
}
// Get the linkable repositories for this connection
log.Printf("Finding linkable repositories for connection %s in project %s (location: %s)",
connNameToLink, projectIDValue, locationValue)
linkableRepos, err := client.ListLinkableRepositories(projectIDValue, locationValue, connNameToLink)
if err != nil {
log.Fatalf("Failed to list linkable repositories: %v", err)
}
if len(linkableRepos) == 0 {
log.Fatalf("No linkable repositories found for connection %s", connNameToLink)
}
// Use the first repository in the list
repoToLink := linkableRepos[0]
// Extract and use a valid repository name
// First check if the repository has a RemoteUri field which usually contains the repo info
var repoName string
if repoToLink.RemoteUri != "" {
// Extract name from the remote URI (e.g., https://gitlab.com/namespace/repo-name)
uriParts := strings.Split(repoToLink.RemoteUri, "/")
if len(uriParts) > 0 {
repoName = uriParts[len(uriParts)-1]
// Remove .git suffix if present
repoName = strings.TrimSuffix(repoName, ".git")
}
}
// If we still don't have a name, use attributes (which is a more reliable way)
if repoName == "" {
// For GitLab repositories, the name is in the attributes
printRepositoryInfo(repoToLink) // Print debug info
// Try common attribute keys that might contain the name
if repoToLink.Annotations != nil {
if name, ok := repoToLink.Annotations["name"]; ok && name != "" {
repoName = name
} else if name, ok := repoToLink.Annotations["repository_name"]; ok && name != "" {
repoName = name
}
}
}
// If we still don't have a name, ask the user to provide one manually
if repoName == "" {
fmt.Println("Unable to automatically determine repository name. Please provide one manually:")
fmt.Print("Repository name: ")
fmt.Scanln(&repoName)
}
// Make sure the repository name is valid
if repoName == "" {
log.Fatalf("Cannot link repository: No valid repository name provided")
}
fmt.Printf("Linking repository: %s\n", repoName)
// We need to get the remote URI for the repository
var remoteURI string
if repoToLink.RemoteUri != "" {
// Use the remote URI from the repository object if available
remoteURI = repoToLink.RemoteUri
fmt.Printf("Using remote URI from repository data: %s\n", remoteURI)
} else {
// Otherwise construct a likely URI based on the connection and repository name
// This is a best guess and may need adjustment for different Git providers
for _, conn := range cfg.Connections {
if conn.Name == connNameToLink && conn.GitlabConfig != nil {
// If we have GitLab config, use the host URI to construct a repo URL
remoteURI = fmt.Sprintf("%s/%s.git", strings.TrimSuffix(conn.GitlabConfig.HostURI, "/"), repoName)
break
}
}
// If we still don't have a remote URI, prompt the user
if remoteURI == "" {
fmt.Println("Please enter the remote URI for the repository (e.g., https://gitlab.com/namespace/repo.git):")
fmt.Print("Remote URI: ")
fmt.Scanln(&remoteURI)
if remoteURI == "" {
log.Fatalf("Remote URI is required to link a repository")
}
} else {
fmt.Printf("Constructed remote URI: %s\n", remoteURI)
}
}
// Link the repository with the remote URI
err = client.LinkRepository(projectIDValue, locationValue, connNameToLink, repoName, remoteURI)
if err != nil {
log.Fatalf("Failed to link repository: %v", err)
}
fmt.Printf("Successfully linked repository %s to connection %s\n", repoName, connNameToLink)
case "delete-connection":
// If connection name not provided via command line, get it from config
connNameToDelete := *connectionName
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment