Skip to content

Commit 92879c2

Browse files
committed
Filter refs by default and add corresponding command line flags
1 parent 304d301 commit 92879c2

File tree

4 files changed

+134
-9
lines changed

4 files changed

+134
-9
lines changed

cmd/push.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ var pushCmd = &cobra.Command{
1616
RunE: func(cmd *cobra.Command, args []string) error {
1717
version.LogVersion()
1818
cacheDirectory := cachedirectory.NewCacheDirectory(rootFlags.cacheDir)
19-
return push.Push(cmd.Context(), cacheDirectory, pushFlags.destinationURL, pushFlags.destinationToken, pushFlags.destinationRepository, pushFlags.actionsAdminUser, pushFlags.force, pushFlags.pushSSH, pushFlags.gitURL)
19+
return push.Push(cmd.Context(), cacheDirectory, pushFlags.destinationURL, pushFlags.destinationToken, pushFlags.destinationRepository, pushFlags.actionsAdminUser, pushFlags.force, pushFlags.pushSSH, pushFlags.gitURL, pushFlags.maxTags, pushFlags.includeBranches)
2020
},
2121
}
2222

@@ -28,6 +28,8 @@ type pushFlagFields struct {
2828
force bool
2929
pushSSH bool
3030
gitURL string
31+
maxTags int
32+
includeBranches bool
3133
}
3234

3335
var pushFlags = pushFlagFields{}
@@ -48,4 +50,6 @@ func (f *pushFlagFields) Init(cmd *cobra.Command) {
4850
cmd.Flags().BoolVar(&f.pushSSH, "push-ssh", false, "Push Git contents over SSH rather than HTTPS. To use this option you must have SSH access to your GitHub Enterprise instance configured.")
4951
cmd.Flags().StringVar(&f.gitURL, "git-url", "", "Use a custom Git URL for pushing the Action repository contents to.")
5052
cmd.Flags().MarkHidden("git-url")
53+
cmd.Flags().IntVar(&f.maxTags, "max-tags", 50, "Maximum number of most recent tags to synchronize. Set to 0 to sync all tags.")
54+
cmd.Flags().BoolVar(&f.includeBranches, "include-branches", false, "Include all branches in synchronization. By default, only the main branch and tags are synchronized.")
5155
}

cmd/sync.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ var syncCmd = &cobra.Command{
1818
if err != nil {
1919
return err
2020
}
21-
err = push.Push(cmd.Context(), cacheDirectory, pushFlags.destinationURL, pushFlags.destinationToken, pushFlags.destinationRepository, pushFlags.actionsAdminUser, pushFlags.force, pushFlags.pushSSH, pushFlags.gitURL)
21+
err = push.Push(cmd.Context(), cacheDirectory, pushFlags.destinationURL, pushFlags.destinationToken, pushFlags.destinationRepository, pushFlags.actionsAdminUser, pushFlags.force, pushFlags.pushSSH, pushFlags.gitURL, pushFlags.maxTags, pushFlags.includeBranches)
2222
if err != nil {
2323
return err
2424
}

internal/push/push.go

Lines changed: 126 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import (
1212
"net/url"
1313
"os"
1414
"path/filepath"
15+
"sort"
1516
"strings"
17+
"time"
1618

1719
"github.com/go-git/go-git/v5/plumbing"
1820

@@ -54,6 +56,8 @@ type pushService struct {
5456
force bool
5557
pushSSH bool
5658
gitURL string
59+
maxTags int
60+
includeBranches bool
5761
}
5862

5963
func (pushService *pushService) createRepository() (*github.Repository, error) {
@@ -175,6 +179,103 @@ func splitLargeRefSpecs(refSpecs []config.RefSpec) [][]config.RefSpec {
175179
return splitRefSpecs
176180
}
177181

182+
// Returns the most recent tags up to maxTags limit. If maxTags is 0, returns all tags.
183+
func (pushService *pushService) getAllowedTagsMap(gitRepository *git.Repository) (map[string]bool, error) {
184+
allowedTags := make(map[string]bool)
185+
if pushService.maxTags == 0 {
186+
tags, err := gitRepository.Tags()
187+
if err != nil {
188+
return nil, errors.Wrap(err, "Error listing tags.")
189+
}
190+
191+
err = tags.ForEach(func(ref *plumbing.Reference) error {
192+
allowedTags[ref.Name().Short()] = true
193+
return nil
194+
})
195+
return allowedTags, err
196+
}
197+
198+
type tagInfo struct {
199+
name string
200+
time time.Time
201+
}
202+
203+
var tagInfos []tagInfo
204+
tags, err := gitRepository.Tags()
205+
if err != nil {
206+
return nil, errors.Wrap(err, "Error listing tags.")
207+
}
208+
209+
err = tags.ForEach(func(ref *plumbing.Reference) error {
210+
var tagTime time.Time
211+
212+
// First try to get it as an annotated tag
213+
tagObj, err := gitRepository.TagObject(ref.Hash())
214+
if err == nil {
215+
// It's an annotated tag, use the tag date
216+
tagTime = tagObj.Tagger.When
217+
} else {
218+
// It's a lightweight tag, get the commit it points to
219+
commit, err := gitRepository.CommitObject(ref.Hash())
220+
if err != nil {
221+
// If we can't get the commit, use zero time (will be filtered out)
222+
tagTime = time.Time{}
223+
} else {
224+
tagTime = commit.Committer.When
225+
}
226+
}
227+
228+
tagInfos = append(tagInfos, tagInfo{
229+
name: ref.Name().Short(),
230+
time: tagTime,
231+
})
232+
return nil
233+
})
234+
235+
if err != nil {
236+
return nil, err
237+
}
238+
239+
sort.Slice(tagInfos, func(i, j int) bool {
240+
return tagInfos[i].time.After(tagInfos[j].time) // most recent first
241+
})
242+
243+
limit := pushService.maxTags
244+
if limit > len(tagInfos) {
245+
limit = len(tagInfos)
246+
}
247+
248+
for i := 0; i < limit; i++ {
249+
allowedTags[tagInfos[i].name] = true
250+
}
251+
252+
return allowedTags, nil
253+
}
254+
255+
// Determines if a reference should be included based on filtering rules:
256+
// - For tags, only includes those in the allowedTags set.
257+
// - Always includes the main branch.
258+
// - For other branches, includes them only if includeBranches is enabled.
259+
func (pushService *pushService) shouldIncludeReference(ref *plumbing.Reference, allowedTags map[string]bool) bool {
260+
refName := ref.Name().String()
261+
262+
if refName == "refs/heads/main" {
263+
return true
264+
}
265+
266+
if strings.HasPrefix(refName, "refs/tags/") {
267+
tagName := ref.Name().Short()
268+
return allowedTags[tagName]
269+
}
270+
271+
if strings.HasPrefix(refName, "refs/heads/") {
272+
return pushService.includeBranches
273+
}
274+
275+
// No other refs are currently pulled, but include any that might in the future to be safe.
276+
return true
277+
}
278+
178279
func (pushService *pushService) pushGit(repository *github.Repository, initialPush bool) error {
179280
remoteURL := pushService.gitURL
180281
if remoteURL == "" {
@@ -231,14 +332,22 @@ func (pushService *pushService) pushGit(repository *github.Repository, initialPu
231332
if err != nil {
232333
return errors.Wrap(err, "Error reading releases.")
233334
}
335+
336+
allowedTags, err := pushService.getAllowedTagsMap(gitRepository)
337+
if err != nil {
338+
return err
339+
}
340+
234341
initialRefSpecs := []config.RefSpec{}
235342
for _, releasePathStat := range releasePathStats {
236-
tagReferenceName := plumbing.NewTagReferenceName(releasePathStat.Name())
237-
_, err := gitRepository.Reference(tagReferenceName, true)
238-
if err != nil {
239-
return errors.Wrapf(err, "Error finding local tag reference %s.", tagReferenceName)
343+
if allowedTags[releasePathStat.Name()] {
344+
tagReferenceName := plumbing.NewTagReferenceName(releasePathStat.Name())
345+
_, err := gitRepository.Reference(tagReferenceName, true)
346+
if err != nil {
347+
return errors.Wrapf(err, "Error finding local tag reference %s.", tagReferenceName)
348+
}
349+
initialRefSpecs = append(initialRefSpecs, config.RefSpec("+"+tagReferenceName.String()+":"+tagReferenceName.String()))
240350
}
241-
initialRefSpecs = append(initialRefSpecs, config.RefSpec("+"+tagReferenceName.String()+":"+tagReferenceName.String()))
242351
}
243352
refSpecBatches = append(refSpecBatches, splitLargeRefSpecs(initialRefSpecs)...)
244353
} else {
@@ -248,14 +357,22 @@ func (pushService *pushService) pushGit(repository *github.Repository, initialPu
248357
config.RefSpec(defaultBranchRefSpec),
249358
},
250359
)
360+
361+
allowedTags, err := pushService.getAllowedTagsMap(gitRepository)
362+
if err != nil {
363+
return err
364+
}
365+
251366
nonDefaultRefSpecs := []config.RefSpec{}
252367
localReferences, err := gitRepository.References()
253368
if err != nil {
254369
return errors.Wrap(err, "Error listing local references.")
255370
}
256371
localReferences.ForEach(func(ref *plumbing.Reference) error {
257372
if ref.Name().String() != defaultBranchRef && strings.HasPrefix(ref.Name().String(), "refs/") {
258-
nonDefaultRefSpecs = append(nonDefaultRefSpecs, config.RefSpec("+"+ref.Name().String()+":"+ref.Name().String()))
373+
if pushService.shouldIncludeReference(ref, allowedTags) {
374+
nonDefaultRefSpecs = append(nonDefaultRefSpecs, config.RefSpec("+"+ref.Name().String()+":"+ref.Name().String()))
375+
}
259376
}
260377
return nil
261378
})
@@ -432,7 +549,7 @@ func (pushService *pushService) pushReleases() error {
432549
return nil
433550
}
434551

435-
func Push(ctx context.Context, cacheDirectory cachedirectory.CacheDirectory, destinationURL string, destinationToken string, destinationRepository string, actionsAdminUser string, force bool, pushSSH bool, gitURL string) error {
552+
func Push(ctx context.Context, cacheDirectory cachedirectory.CacheDirectory, destinationURL string, destinationToken string, destinationRepository string, actionsAdminUser string, force bool, pushSSH bool, gitURL string, maxTags int, includeBranches bool) error {
436553
err := cacheDirectory.CheckOrCreateVersionFile(false, version.Version())
437554
if err != nil {
438555
return err
@@ -491,6 +608,8 @@ func Push(ctx context.Context, cacheDirectory cachedirectory.CacheDirectory, des
491608
force: force,
492609
pushSSH: pushSSH,
493610
gitURL: gitURL,
611+
maxTags: maxTags,
612+
includeBranches: includeBranches,
494613
}
495614

496615
repository, err := pushService.createRepository()

internal/push/push_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ func getTestPushService(t *testing.T, cacheDirectoryString string, githubEnterpr
4141
destinationRepositoryOwner: "destination-repository-owner",
4242
destinationRepositoryName: "destination-repository-name",
4343
destinationToken: &token,
44+
maxTags: 0, // no tag limit
45+
includeBranches: true,
4446
}
4547
}
4648

0 commit comments

Comments
 (0)