feat(scaffolder): Added the ability to create the repos with optional org in github

This commit is contained in:
blam
2020-02-05 21:20:42 +01:00
parent c112b57ed6
commit e75fae0377
7 changed files with 142 additions and 15 deletions
+38 -5
View File
@@ -2,20 +2,53 @@ package app
import (
"context"
"fmt"
identity "github.com/spotify/backstage/backend/proto/identity/v1"
pb "github.com/spotify/backstage/proto/scaffolder/v1"
"github.com/spotify/backstage/scaffolder/remote"
"github.com/spotify/backstage/scaffolder/repository"
)
// Server is the inventory Grpc server
type Server struct {
Repository *repository.Repository
repository *repository.Repository
github *remote.Github
}
// GetAllTemplates returns the local templatess
func (s *Server) GetAllTemplates(ctx context.Context, req *pb.Empty) (*pb.GetAllTemplatesReply, error) {
// NewServer creates a new server for with all the things
func NewServer() *Server {
return &Server{
github: remote.NewGithubClient(),
}
}
// Create scaffolds the repo in github and then will create push to the repository
func (s *Server) Create(ctx context.Context, req *pb.CreateRequest) (*pb.CreateReply, error) {
repo := remote.Repository{
Name: req.ComponentId,
Org: req.Org,
Private: req.Private,
}
err := s.github.CreateRepository(repo)
fmt.Println("Meta is")
fmt.Println(req.Metadata)
fmt.Println("error is")
fmt.Println(err)
return nil, nil
// first create the repository with github
// move the template into a temporary directory
// use git bindings to add the remote with access token and push to the directory
}
// ListTemplates returns the local templatess
func (s *Server) ListTemplates(ctx context.Context, req *pb.Empty) (*pb.ListTemplatesReply, error) {
// todo (blam): yes we currently read the disk on every load. but it's fine for now 🤷‍♂️
definitions, err := s.Repository.Load()
definitions, err := s.repository.Load()
var templates []*pb.Template
for _, definition := range definitions {
@@ -34,7 +67,7 @@ func (s *Server) GetAllTemplates(ctx context.Context, req *pb.Empty) (*pb.GetAll
templates = append(templates, template)
}
return &pb.GetAllTemplatesReply{
return &pb.ListTemplatesReply{
Templates: templates,
}, err
}
+2
View File
@@ -8,7 +8,9 @@ replace github.com/spotify/backstage/backend/proto => ../proto
require (
github.com/golang/protobuf v1.3.3
github.com/google/go-github/v29 v29.0.2
github.com/spotify/backstage/backend/proto v0.0.0-00010101000000-000000000000
github.com/spotify/backstage/proto v0.0.0-00010101000000-000000000000
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
google.golang.org/grpc v1.27.0
)
+7
View File
@@ -14,7 +14,13 @@ github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github/v29 v29.0.2 h1:opYN6Wc7DOz7Ku3Oh4l7prmkOMwEcQxpFtxdU8N8Pts=
github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -25,6 +31,7 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+3 -2
View File
@@ -6,7 +6,6 @@ import (
pb "github.com/spotify/backstage/proto/scaffolder/v1"
"github.com/spotify/backstage/scaffolder/app"
"google.golang.org/grpc"
)
@@ -21,7 +20,9 @@ func main() {
}
grpcServer := grpc.NewServer()
pb.RegisterScaffolderServer(grpcServer, &app.Server{})
serverHandler := app.NewServer()
pb.RegisterScaffolderServer(grpcServer, serverHandler)
log.Println("Serving Scaffolder Service")
grpcServer.Serve(lis)
}
+65
View File
@@ -0,0 +1,65 @@
package remote
import (
"context"
"fmt"
gh "github.com/google/go-github/v29/github"
"golang.org/x/oauth2"
"os"
)
// Github is the exported struct
type Github struct {
client *gh.Client
ctx *context.Context
}
// NewGithubClient returns a new client with the correct access token enabled
func NewGithubClient() *Github {
accessToken := os.Getenv("BOSS_GH_ACCESS_TOKEN")
if accessToken == "" {
fmt.Println("No BOSS_GH_ACCESS_TOKEN set. Cannot continue")
os.Exit(1)
}
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: accessToken},
)
tc := oauth2.NewClient(ctx, ts)
client := gh.NewClient(tc)
return &Github{
client: client,
ctx: &ctx,
}
}
// Repository holds the information of the created repo
type Repository struct {
Org string
Name string
Private bool
}
// CreateRepository will create the repository in Github ready for use by the scaffolder
func (g *Github) CreateRepository(repo Repository) error {
ghRepo := &gh.Repository{
Name: &repo.Name,
Private: &repo.Private,
}
var org string
if repo.Org != "" {
org = repo.Org
}
created, response, err := g.client.Repositories.Create(*g.ctx, org, ghRepo)
fmt.Println(created)
fmt.Println(response)
fmt.Println(err)
return nil
}
+1 -1
View File
@@ -45,5 +45,5 @@ func (s *Repository) Load() ([]*TemplateDefinition, error) {
templateDefinitions = append(templateDefinitions, &definition)
}
return templateDefinitions, err
return templateDefinitions, nil
}
+26 -7
View File
@@ -3,22 +3,41 @@ syntax = "proto3";
package spotify.backstage.scaffolder.v1;
import "identity/v1/identity.proto";
import "google/protobuf/struct.proto";
option go_package = "scaffolderv1";
service Scaffolder {
rpc GetAllTemplates(Empty) returns (GetAllTemplatesReply);
rpc ListTemplates(Empty) returns (ListTemplatesReply);
rpc Create(CreateRequest) returns (CreateReply);
}
message Empty {}
message GetAllTemplatesReply {
message ListTemplatesReply {
repeated Template templates = 1;
}
message Template {
string id = 1;
string name = 2;
string description = 3;
spotify.backstage.identity.v1.User user = 4;
message CreateReply {
string component_id = 1;
}
message CreateRequest {
string template_id = 1;
string org = 2;
string component_id = 3;
bool private = 4;
// here's the cookiecutter.json that is used for the request.
// make as a struct so that we can pass through the data in a nice way
// withouth having to mess around with stuff and special types.
google.protobuf.Struct metadata = 5;
}
message Template {
string id = 1;
string name = 2;
string description = 3;
spotify.backstage.identity.v1.User user = 4;
}