Assign GitHub teams during bootstrap
This commit is contained in:
@@ -43,6 +43,9 @@ the bootstrap command will perform an upgrade if needed.`,
|
|||||||
# Run bootstrap for a private repo owned by a GitHub organization
|
# Run bootstrap for a private repo owned by a GitHub organization
|
||||||
bootstrap github --owner=<organization> --repository=<repo name>
|
bootstrap github --owner=<organization> --repository=<repo name>
|
||||||
|
|
||||||
|
# Run bootstrap for a private repo and assign organization teams to it
|
||||||
|
bootstrap github --owner=<organization> --repository=<repo name> --team=<team1 slug> --team=<team2 slug>
|
||||||
|
|
||||||
# Run bootstrap for a repository path
|
# Run bootstrap for a repository path
|
||||||
bootstrap github --owner=<organization> --repository=<repo name> --path=dev-cluster
|
bootstrap github --owner=<organization> --repository=<repo name> --path=dev-cluster
|
||||||
|
|
||||||
@@ -63,6 +66,7 @@ var (
|
|||||||
ghPrivate bool
|
ghPrivate bool
|
||||||
ghHostname string
|
ghHostname string
|
||||||
ghPath string
|
ghPath string
|
||||||
|
ghTeams []string
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -72,11 +76,13 @@ const (
|
|||||||
ghSourceManifest = "toolkit-source.yaml"
|
ghSourceManifest = "toolkit-source.yaml"
|
||||||
ghKustomizationManifest = "toolkit-kustomization.yaml"
|
ghKustomizationManifest = "toolkit-kustomization.yaml"
|
||||||
ghDefaultHostname = "github.com"
|
ghDefaultHostname = "github.com"
|
||||||
|
ghDefaultPermission = "maintain"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
bootstrapGitHubCmd.Flags().StringVar(&ghOwner, "owner", "", "GitHub user or organization name")
|
bootstrapGitHubCmd.Flags().StringVar(&ghOwner, "owner", "", "GitHub user or organization name")
|
||||||
bootstrapGitHubCmd.Flags().StringVar(&ghRepository, "repository", "", "GitHub repository name")
|
bootstrapGitHubCmd.Flags().StringVar(&ghRepository, "repository", "", "GitHub repository name")
|
||||||
|
bootstrapGitHubCmd.Flags().StringArrayVar(&ghTeams, "team", []string{}, "GitHub team to be given maintainer access")
|
||||||
bootstrapGitHubCmd.Flags().BoolVar(&ghPersonal, "personal", false, "is personal repository")
|
bootstrapGitHubCmd.Flags().BoolVar(&ghPersonal, "personal", false, "is personal repository")
|
||||||
bootstrapGitHubCmd.Flags().BoolVar(&ghPrivate, "private", true, "is private repository")
|
bootstrapGitHubCmd.Flags().BoolVar(&ghPrivate, "private", true, "is private repository")
|
||||||
bootstrapGitHubCmd.Flags().DurationVar(&ghInterval, "interval", time.Minute, "sync interval")
|
bootstrapGitHubCmd.Flags().DurationVar(&ghInterval, "interval", time.Minute, "sync interval")
|
||||||
@@ -118,6 +124,19 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
withErrors := false
|
||||||
|
// add teams to org repository
|
||||||
|
if !ghPersonal {
|
||||||
|
for _, team := range ghTeams {
|
||||||
|
if err := addGitHubTeam(ctx, ghHostname, ghOwner, ghRepository, ghToken, team, ghDefaultPermission); err != nil {
|
||||||
|
logFailure(err.Error())
|
||||||
|
withErrors = true
|
||||||
|
} else {
|
||||||
|
logSuccess("%s team access granted", team)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// clone repository and checkout the master branch
|
// clone repository and checkout the master branch
|
||||||
repo, err := checkoutGitHubRepository(ctx, ghURL, ghBranch, ghToken, tmpDir)
|
repo, err := checkoutGitHubRepository(ctx, ghURL, ghBranch, ghToken, tmpDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -221,6 +240,10 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if withErrors {
|
||||||
|
return fmt.Errorf("bootstrap completed with errors")
|
||||||
|
}
|
||||||
|
|
||||||
logSuccess("bootstrap finished")
|
logSuccess("bootstrap finished")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -275,6 +298,37 @@ func createGitHubRepository(ctx context.Context, hostname, owner, name, token st
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addGitHubTeam(ctx context.Context, hostname, owner, repository, token string, teamSlug, permission string) error {
|
||||||
|
gh, err := makeGitHubClient(hostname, token)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check team exists
|
||||||
|
_, _, err = gh.Teams.GetTeamBySlug(ctx, owner, teamSlug)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("github get team %s error: %w", teamSlug, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if team is assigned to the repo
|
||||||
|
_, resp, err := gh.Teams.IsTeamRepoBySlug(ctx, owner, teamSlug, owner, repository)
|
||||||
|
if resp == nil && err != nil {
|
||||||
|
return fmt.Errorf("github is team %s error: %w", teamSlug, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add team to the repo
|
||||||
|
if resp.StatusCode == 404 {
|
||||||
|
_, err = gh.Teams.AddTeamRepoBySlug(ctx, owner, teamSlug, owner, repository, &github.TeamAddTeamRepoOptions{
|
||||||
|
Permission: permission,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("github add team %s error: %w", teamSlug, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func checkoutGitHubRepository(ctx context.Context, url, branch, token, path string) (*git.Repository, error) {
|
func checkoutGitHubRepository(ctx context.Context, url, branch, token, path string) (*git.Repository, error) {
|
||||||
auth := &http.BasicAuth{
|
auth := &http.BasicAuth{
|
||||||
Username: "git",
|
Username: "git",
|
||||||
@@ -423,7 +477,7 @@ func generateGitHubKustomization(url, name, namespace, targetPath, tmpDir string
|
|||||||
Interval: metav1.Duration{
|
Interval: metav1.Duration{
|
||||||
Duration: 10 * time.Minute,
|
Duration: 10 * time.Minute,
|
||||||
},
|
},
|
||||||
Path: "./" + strings.TrimPrefix("./", targetPath),
|
Path: fmt.Sprintf("./%s", strings.TrimPrefix(targetPath, "./")),
|
||||||
Prune: true,
|
Prune: true,
|
||||||
SourceRef: corev1.TypedLocalObjectReference{
|
SourceRef: corev1.TypedLocalObjectReference{
|
||||||
APIGroup: &emptyAPIGroup,
|
APIGroup: &emptyAPIGroup,
|
||||||
|
|||||||
@@ -51,7 +51,11 @@ func getKsCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
for _, condition := range kustomization.Status.Conditions {
|
for _, condition := range kustomization.Status.Conditions {
|
||||||
if condition.Type == kustomizev1.ReadyCondition {
|
if condition.Type == kustomizev1.ReadyCondition {
|
||||||
if condition.Status != corev1.ConditionFalse {
|
if condition.Status != corev1.ConditionFalse {
|
||||||
logSuccess("%s last applied revision %s", kustomization.GetName(), kustomization.Status.LastAppliedRevision)
|
if kustomization.Status.LastAppliedRevision != "" {
|
||||||
|
logSuccess("%s last applied revision %s", kustomization.GetName(), kustomization.Status.LastAppliedRevision)
|
||||||
|
} else {
|
||||||
|
logSuccess("%s reconciling", kustomization.GetName())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logFailure("%s %s", kustomization.GetName(), condition.Message)
|
logFailure("%s %s", kustomization.GetName(), condition.Message)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user