Skip to content
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ mpd:
startercode:
url: git@gitlab.example.org:mpd/startercode/blatt-01.git
fromBranch: startercode
# tag: startercode # optional: sets this tag in generated repos at startercode commit
template: true
templateMessage: Initial Commit
```
Expand Down
6 changes: 6 additions & 0 deletions config/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ func startercode(assignmentKey string) *Startercode {
fromBranch = fB
}

tag := ""
if t := viper.GetString(assignmentKey + ".startercode.tag"); len(t) > 0 {
tag = t
}

template := viper.GetBool(assignmentKey + ".startercode.template")

templateMessage := "Initial"
Expand All @@ -44,6 +49,7 @@ func startercode(assignmentKey string) *Startercode {
return &Startercode{
URL: url,
FromBranch: fromBranch,
Tag: tag,
Template: template,
TemplateMessage: templateMessage,
ToBranch: toBranch,
Expand Down
7 changes: 7 additions & 0 deletions config/repo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,27 @@ func TestStartercodeDefaultsAndReplication(t *testing.T) {
if s.FromBranch != "main" || s.ToBranch != "main" {
t.Fatalf("unexpected startercode defaults: %#v", s)
}
if s.Tag != "" {
t.Fatalf("startercode tag = %q, want empty", s.Tag)
}
}

func TestStartercodeOverrides(t *testing.T) {
resetViper(t)
viper.Set("course.a1.startercode", map[string]string{"url": "git@example.org:starter.git"})
viper.Set("course.a1.startercode.url", "git@example.org:starter.git")
viper.Set("course.a1.startercode.fromBranch", "template")
viper.Set("course.a1.startercode.tag", "v1.2.3")
viper.Set("course.a1.startercode.toBranch", "submission")
viper.Set("course.a1.startercode.additionalBranches", []string{"release", "demo"})

s := startercode("course.a1")
if s.FromBranch != "template" || s.ToBranch != "submission" {
t.Fatalf("startercode branches = %#v", s)
}
if s.Tag != "v1.2.3" {
t.Fatalf("startercode tag = %q, want %q", s.Tag, "v1.2.3")
}
if !reflect.DeepEqual(s.AdditionalBranches, []string{"release", "demo"}) {
t.Fatalf("startercode additional branches = %#v", s.AdditionalBranches)
}
Expand Down
2 changes: 2 additions & 0 deletions config/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func (cfg *AssignmentConfig) Show() {
fieldCandidate(0, "Container-Registry"),
fieldCandidate(2, "URL"),
fieldCandidate(2, "FromBranch"),
fieldCandidate(2, "Tag"),
fieldCandidate(2, "ToBranch"),
fieldCandidate(2, "AdditionalBranches"),
fieldCandidate(2, "ReplicateFromStartercode"),
Expand Down Expand Up @@ -170,6 +171,7 @@ func (cfg *AssignmentConfig) Show() {
} else {
writeSectionField("URL", cfg.Startercode.URL)
writeSectionField("FromBranch", cfg.Startercode.FromBranch)
writeSectionField("Tag", cfg.Startercode.Tag)
writeSectionField("Template", cfg.Startercode.Template)
writeSectionField("TemplateMessage", cfg.Startercode.TemplateMessage)
writeSectionField("ToBranch", cfg.Startercode.ToBranch)
Expand Down
1 change: 1 addition & 0 deletions config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type Seeder struct {
type Startercode struct {
URL string
FromBranch string
Tag string
Template bool
TemplateMessage string
ToBranch string
Expand Down
16 changes: 16 additions & 0 deletions config/urls_show_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,22 @@ func TestShow_WithStartercode_WithIssues(t *testing.T) {
cfg.Show()
}

func TestStartercodeURL_UsesFromBranchEvenWhenTagConfigured(t *testing.T) {
cfg := &AssignmentConfig{
Startercode: &Startercode{
URL: "git@gitlab.example.org:mpd/starter/blatt-01.git",
FromBranch: "startercode",
Tag: "v1.0.0",
},
}

out := captureStdout(t, func() { cfg.StartercodeURL() })
want := "https://gitlab.example.org/mpd/starter/blatt-01/-/tree/startercode\n"
if out != want {
t.Fatalf("StartercodeURL() = %q, want %q", out, want)
}
}

func TestShow_WithBranches(t *testing.T) {
cfg := &AssignmentConfig{
Branches: []BranchRule{{Name: "main", Protect: true, Default: true, AllowForcePush: true}, {Name: "develop", MergeOnly: true, CodeOwnerApprovalRequired: true}},
Expand Down
2 changes: 2 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ Clone from a starter repository to each student repo:
startercode:
url: git@gitlab.example.org:mpd/startercode/blatt-01.git
fromBranch: template # Clone this branch
# tag: startercode # Optional: create this tag in generated repos at startercode commit
toBranch: main # Into this branch
additionalBranches: [] # Push starter/<branch> to repo/<branch>
```
Expand All @@ -193,6 +194,7 @@ startercode:
|---|---|---|---|
| `url` | SSH URL of starter repo | — | Required if startercode block exists |
| `fromBranch` | Source branch in starter | `main` | Must exist in starter repo |
| `tag` | Tag created in generated repos | empty | Marks the pushed startercode commit in each target repo |
| `toBranch` | Target branch in new repos | `main` | Usually production branch |
| `additionalBranches` | Additional branches mirrored from starter repo | `[]` | Each `x` maps `starter/x -> repo/x` |

Expand Down
3 changes: 2 additions & 1 deletion git/sourcerepo.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
)

func PrepareSourceRepo(url, fromBranch string, singleCommit bool, commitMessage string) (*SourceRepo, error) {

cfg := yacspin.Config{
Frequency: 100 * time.Millisecond,
CharSet: yacspin.CharSets[69],
Expand Down Expand Up @@ -125,7 +126,7 @@ func PrepareSourceRepo(url, fromBranch string, singleCommit bool, commitMessage
return nil, err
}

singleCommitBranchName := fmt.Sprintf("orphan-%s-%d", fromBranch, time.Now().UnixNano())
singleCommitBranchName := fmt.Sprintf("orphan-%s-%d", sourceRef.Short(), time.Now().UnixNano())
refName := plumbing.NewBranchReferenceName(singleCommitBranchName)

committerName := "glabs"
Expand Down
7 changes: 6 additions & 1 deletion gitlab/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ func (c *Client) Generate(assignmentCfg *config.AssignmentConfig) {
var starterrepo *git.SourceRepo

if assignmentCfg.Startercode != nil {
starterrepo, err = git.PrepareSourceRepo(assignmentCfg.Startercode.URL, assignmentCfg.Startercode.FromBranch, assignmentCfg.Startercode.Template, assignmentCfg.Startercode.TemplateMessage)
starterrepo, err = git.PrepareSourceRepo(
assignmentCfg.Startercode.URL,
assignmentCfg.Startercode.FromBranch,
assignmentCfg.Startercode.Template,
assignmentCfg.Startercode.TemplateMessage,
)

if err != nil {
fmt.Println(err)
Expand Down
32 changes: 32 additions & 0 deletions gitlab/starterrepo.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package gitlab

import (
"fmt"
"strings"

git "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
cfg "github.com/obcode/glabs/v2/config"
g "github.com/obcode/glabs/v2/git"
"github.com/rs/zerolog/log"
Expand Down Expand Up @@ -52,6 +54,36 @@ func (c *Client) pushStartercode(assignmentCfg *cfg.AssignmentConfig, from *g.So
return fmt.Errorf("cannot push to remote: %w", err)
}

tagName := strings.TrimSpace(assignmentCfg.Startercode.Tag)
if tagName != "" {
sourceRef, err := from.Repo.Reference(from.Ref, true)
if err != nil {
return fmt.Errorf("cannot resolve source reference for tag %q: %w", tagName, err)
}

tagRef := plumbing.NewTagReferenceName(tagName)
if err := from.Repo.Storer.SetReference(plumbing.NewHashReference(tagRef, sourceRef.Hash())); err != nil {
return fmt.Errorf("cannot set local tag %q: %w", tagName, err)
}

tagRefSpec := config.RefSpec(fmt.Sprintf("+%s:%s", tagRef.String(), tagRef.String()))
log.Debug().
Str("refSpec", string(tagRefSpec)).
Str("name", project.Name).
Str("toURL", project.SSHURLToRepo).
Str("tag", tagName).
Msg("pushing startercode tag")

err = from.Repo.Push(&git.PushOptions{
RemoteName: remote.Config().Name,
RefSpecs: []config.RefSpec{tagRefSpec},
Auth: from.Auth,
})
if err != nil {
return fmt.Errorf("cannot push startercode tag %q to remote: %w", tagName, err)
}
}

for _, additionalBranch := range assignmentCfg.Startercode.AdditionalBranches {
if additionalBranch == "" {
continue
Expand Down
7 changes: 6 additions & 1 deletion gitlab/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ func (c *Client) Update(assignmentCfg *config.AssignmentConfig) {
var starterrepo *git.SourceRepo

if assignmentCfg.Startercode != nil {
starterrepo, err = git.PrepareSourceRepo(assignmentCfg.Startercode.URL, assignmentCfg.Startercode.FromBranch, assignmentCfg.Startercode.Template, assignmentCfg.Startercode.TemplateMessage)
starterrepo, err = git.PrepareSourceRepo(
assignmentCfg.Startercode.URL,
assignmentCfg.Startercode.FromBranch,
assignmentCfg.Startercode.Template,
assignmentCfg.Startercode.TemplateMessage,
)

if err != nil {
fmt.Println(err)
Expand Down
Loading