Skip to content

Commit 3a8a30a

Browse files
author
Pete Wagner
authored
Merge pull request #53 from thepwagner/batching
update batching
2 parents 8008b03 + 1b0c893 commit 3a8a30a

19 files changed

+306
-276
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
This action checks for available dependency updates to a go project, and opens individual pull requests proposing each available update.
44

55
* Ignores dependencies not released with semver
6-
* Ignores dependencies if the initial PR is closed
76
* Go module major version updates (e.g. `github.com/foo/bar/v2`)
87
* Vendoring detection and support
98
* Can multiple multiple base branches
9+
* Update batching
1010

1111
Suggested triggers: `schedule`, `workflow_dispatch`.
1212

action.yml

+22-13
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,28 @@ inputs:
1818
log_level:
1919
description: 'Control debug/info/warn/error output'
2020
required: false
21+
batches:
22+
description: >
23+
Configuration for grouping updates together, newline separated following format:
24+
label:prefix1,prefix2
25+
e.g.
26+
internal:github.com/thepwagner/
27+
aws:github.com/aws
28+
required: false
2129
runs:
2230
using: "composite"
2331
steps:
24-
- name: Verify Go SDK
25-
run: which go || echo "Go required, please use actions/setup-go before me"
26-
shell: bash
27-
- name: Compile action-update-go
28-
run: cd "${{github.action_path}}" && go build -o ./action-update-go .
29-
shell: bash
30-
- name: Run action-update-go
31-
run: pwd && "${{github.action_path}}/action-update-go"
32-
shell: bash
33-
env:
34-
INPUT_BRANCHES: ${{ inputs.branches }}
35-
INPUT_TOKEN: ${{ inputs.token }}
36-
INPUT_LOG_LEVEL: ${{ inputs.log_level }}
32+
- name: Verify Go SDK
33+
run: which go || echo "Go required, please use actions/setup-go before me"
34+
shell: bash
35+
- name: Compile action-update-go
36+
run: cd "${{github.action_path}}" && go build -o ./action-update-go .
37+
shell: bash
38+
- name: Run action-update-go
39+
run: pwd && "${{github.action_path}}/action-update-go"
40+
shell: bash
41+
env:
42+
INPUT_BRANCHES: ${{ inputs.branches }}
43+
INPUT_BATCHES: ${{ inputs.batches }}
44+
INPUT_TOKEN: ${{ inputs.token }}
45+
INPUT_LOG_LEVEL: ${{ inputs.log_level }}

cmd/env.go

+24
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import (
88
"github.com/caarlos0/env/v5"
99
"github.com/google/go-github/v32/github"
1010
"github.com/sirupsen/logrus"
11+
"gopkg.in/yaml.v3"
1112
)
1213

1314
type Environment struct {
1415
GitHubEventName string `env:"GITHUB_EVENT_NAME"`
1516
GitHubEventPath string `env:"GITHUB_EVENT_PATH"`
1617
GitHubRepository string `env:"GITHUB_REPOSITORY"`
1718

19+
InputBatches string `env:"INPUT_BATCHES"`
1820
InputBranches string `env:"INPUT_BRANCHES"`
1921
GitHubToken string `env:"INPUT_TOKEN"`
2022
InputLogLevel string `env:"INPUT_LOG_LEVEL" envDefault:"debug"`
@@ -56,6 +58,28 @@ func (e *Environment) Branches() (branches []string) {
5658
return
5759
}
5860

61+
func (e *Environment) Batches() (map[string][]string, error) {
62+
raw := map[string]interface{}{}
63+
if err := yaml.Unmarshal([]byte(e.InputBatches), &raw); err != nil {
64+
return nil, fmt.Errorf("decoding batches yaml: %w", err)
65+
}
66+
67+
m := make(map[string][]string, len(raw))
68+
for key, value := range raw {
69+
var prefixes []string
70+
switch v := value.(type) {
71+
case []interface{}:
72+
for _, s := range v {
73+
prefixes = append(prefixes, fmt.Sprintf("%v", s))
74+
}
75+
case string:
76+
prefixes = append(prefixes, v)
77+
}
78+
m[key] = prefixes
79+
}
80+
return m, nil
81+
}
82+
5983
func (e *Environment) LogLevel() logrus.Level {
6084
if e.InputLogLevel == "" {
6185
return logrus.InfoLevel

cmd/env_test.go

+41
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/sirupsen/logrus"
88
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
910
)
1011

1112
func TestEnvironment_LogLevel(t *testing.T) {
@@ -22,3 +23,43 @@ func TestEnvironment_LogLevel(t *testing.T) {
2223
})
2324
}
2425
}
26+
27+
func TestEnvironment_Batches(t *testing.T) {
28+
cases := []struct {
29+
input string
30+
batches map[string][]string
31+
}{
32+
{
33+
input: `foo: [bar, baz]`,
34+
batches: map[string][]string{"foo": {"bar", "baz"}},
35+
},
36+
{
37+
input: `---
38+
foo: bar
39+
foz: baz`,
40+
batches: map[string][]string{
41+
"foo": {"bar"},
42+
"foz": {"baz"},
43+
},
44+
},
45+
{
46+
input: `foo:
47+
- bar
48+
- baz`,
49+
batches: map[string][]string{
50+
"foo": {"bar", "baz"},
51+
},
52+
},
53+
{
54+
input: "",
55+
batches: map[string][]string{},
56+
},
57+
}
58+
59+
for _, tc := range cases {
60+
e := Environment{InputBatches: tc.input}
61+
b, err := e.Batches()
62+
require.NoError(t, err)
63+
assert.Equal(t, tc.batches, b)
64+
}
65+
}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ require (
1414
github.com/stretchr/testify v1.6.0
1515
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
1616
gopkg.in/yaml.v2 v2.3.0 // indirect
17+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
1718
)
1819

1920
replace github.com/containerd/containerd => github.com/containerd/containerd v1.4.0

handler/pullrequest.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ func PullRequest(ctx context.Context, env *cmd.Environment, evt interface{}) err
2828
}
2929

3030
func prReopened(ctx context.Context, env *cmd.Environment, pr *github.PullRequestEvent) error {
31-
repo, updater, err := getRepoUpdater(env)
31+
_, updater, err := getRepoUpdater(env)
3232
if err != nil {
3333
return err
3434
}
3535

3636
prRef := pr.GetPullRequest().GetHead().GetRef()
3737
logrus.WithField("ref", prRef).Info("PR reopened, recreating update")
3838

39-
base, update := repo.Parse(prRef)
39+
base, update := updater.Parse(prRef)
4040
if update == nil {
4141
logrus.Info("not an update PR")
4242
return nil

handler/schedule.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package handler
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/go-git/go-git/v5"
78
"github.com/sirupsen/logrus"
@@ -62,6 +63,10 @@ func getRepoUpdater(env *cmd.Environment) (updater.Repo, *updater.RepoUpdater, e
6263
}
6364

6465
gomodUpdater := gomod.NewUpdater(modRepo.Root())
65-
repoUpdater := updater.NewRepoUpdater(modRepo, gomodUpdater)
66+
batches, err := env.Batches()
67+
if err != nil {
68+
return nil, nil, fmt.Errorf("parsing batches")
69+
}
70+
repoUpdater := updater.NewRepoUpdater(modRepo, gomodUpdater, updater.WithBatches(batches))
6671
return gitRepo, repoUpdater, nil
6772
}

repo/git.go

+9-37
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ type GitRepo struct {
2323
branch string
2424
author GitIdentity
2525
remotes bool
26-
27-
branchNamer UpdateBranchNamer
2826
}
2927

3028
var _ updater.Repo = (*GitRepo)(nil)
@@ -67,12 +65,11 @@ func NewGitRepo(repo *git.Repository) (*GitRepo, error) {
6765
branch = head.Name().Short()
6866
}
6967
return &GitRepo{
70-
repo: repo,
71-
wt: wt,
72-
branch: branch,
73-
remotes: len(remotes) > 0,
74-
author: DefaultGitIdentity,
75-
branchNamer: DefaultUpdateBranchNamer{},
68+
repo: repo,
69+
wt: wt,
70+
branch: branch,
71+
remotes: len(remotes) > 0,
72+
author: DefaultGitIdentity,
7673
}, nil
7774
}
7875

@@ -122,22 +119,21 @@ func (t *GitRepo) setBranch(refName plumbing.ReferenceName) error {
122119
return nil
123120
}
124121

125-
func (t *GitRepo) NewBranch(baseBranch string, update updater.Update) error {
126-
branch := t.branchNamer.Format(baseBranch, update)
122+
func (t *GitRepo) NewBranch(base, branch string) error {
127123
log := logrus.WithFields(logrus.Fields{
128-
"base": baseBranch,
124+
"base": base,
129125
"branch": branch,
130126
})
131127
log.Debug("creating branch")
132128

133129
// Map string to a ref:
134-
baseRef, err := t.repo.Reference(plumbing.NewBranchReferenceName(baseBranch), true)
130+
baseRef, err := t.repo.Reference(plumbing.NewBranchReferenceName(base), true)
135131
if err != nil {
136132
if err != plumbing.ErrReferenceNotFound {
137133
return fmt.Errorf("querying branch ref: %w", err)
138134
}
139135
log.Debug("not found locally, checking remote")
140-
remoteRef, err := t.repo.Reference(plumbing.NewRemoteReferenceName(RemoteName, baseBranch), true)
136+
remoteRef, err := t.repo.Reference(plumbing.NewRemoteReferenceName(RemoteName, base), true)
141137
if err != nil {
142138
return fmt.Errorf("querying remote branch ref: %w", err)
143139
}
@@ -238,27 +234,3 @@ func (t *GitRepo) push(ctx context.Context) error {
238234
logrus.Debug("pushed to remote")
239235
return nil
240236
}
241-
242-
func (t *GitRepo) Updates(_ context.Context) (updater.UpdatesByBranch, error) {
243-
branches, err := t.repo.Branches()
244-
if err != nil {
245-
return nil, fmt.Errorf("iterating branches: %w", err)
246-
}
247-
defer branches.Close()
248-
249-
ret := updater.UpdatesByBranch{}
250-
addToIndex := func(ref *plumbing.Reference) error {
251-
if base, update := t.branchNamer.Parse(ref.Name().Short()); update != nil {
252-
ret.AddOpen(base, *update)
253-
}
254-
return nil
255-
}
256-
if err := branches.ForEach(addToIndex); err != nil {
257-
return nil, fmt.Errorf("indexing branches: %w", err)
258-
}
259-
return ret, nil
260-
}
261-
262-
func (t *GitRepo) Parse(b string) (string, *updater.Update) {
263-
return t.branchNamer.Parse(b)
264-
}

repo/git_test.go

+5-11
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,7 @@ const (
2222
updateBranch = "action-update-go/main/github.com/foo/bar/v1.0.0"
2323
)
2424

25-
var (
26-
fileData = []byte{1, 2, 3, 4}
27-
fakeUpdate = updater.Update{
28-
Path: "github.com/foo/bar",
29-
Next: "v1.0.0",
30-
}
31-
)
25+
var fileData = []byte{1, 2, 3, 4}
3226

3327
func TestNewGitRepo(t *testing.T) {
3428
gr := initGitRepo(t, plumbing.NewBranchReferenceName(branchName))
@@ -79,21 +73,21 @@ func TestGitRepo_SetBranch_NotFound(t *testing.T) {
7973

8074
func TestGitRepo_NewBranch(t *testing.T) {
8175
gr := initGitRepo(t, plumbing.NewBranchReferenceName(branchName))
82-
err := gr.NewBranch(branchName, fakeUpdate)
76+
err := gr.NewBranch(branchName, updateBranch)
8377
assert.NoError(t, err)
8478
assert.Equal(t, updateBranch, gr.Branch())
8579
}
8680

8781
func TestGitRepo_NewBranch_FromRemote(t *testing.T) {
8882
gr := initGitRepo(t, plumbing.NewRemoteReferenceName(repo.RemoteName, branchName))
89-
err := gr.NewBranch(branchName, fakeUpdate)
83+
err := gr.NewBranch(branchName, updateBranch)
9084
assert.NoError(t, err)
9185
assert.Equal(t, updateBranch, gr.Branch())
9286
}
9387

9488
func TestGitRepo_Push(t *testing.T) {
9589
gr := initGitRepo(t, plumbing.NewRemoteReferenceName(repo.RemoteName, branchName))
96-
err := gr.NewBranch(branchName, fakeUpdate)
90+
err := gr.NewBranch(branchName, updateBranch)
9791
require.NoError(t, err)
9892
tmpFile := addTempFile(t, gr)
9993

@@ -144,7 +138,7 @@ func TestGitRepo_Push_WithRemote(t *testing.T) {
144138

145139
gr, err := repo.NewGitRepo(downstream)
146140
require.NoError(t, err)
147-
err = gr.NewBranch(branchName, fakeUpdate)
141+
err = gr.NewBranch(branchName, updateBranch)
148142
require.NoError(t, err)
149143
addTempFile(t, gr)
150144

0 commit comments

Comments
 (0)