Skip to content

Commit 8cdc12a

Browse files
WIP
1 parent 1c5d49c commit 8cdc12a

File tree

3 files changed

+63
-27
lines changed

3 files changed

+63
-27
lines changed

attest/manifest/manifest.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ var (
1616
)
1717

1818
type DirContents struct {
19-
types.GenericStatement[SourceDirectory]
19+
types.GenericStatement[SourceDirectoryContents]
2020
}
2121

2222
type SourceDirectory struct {
@@ -25,14 +25,16 @@ type SourceDirectory struct {
2525
VCSEntries *types.PathCheckSummaryCollection `json:"vcsEntries"`
2626
}
2727

28+
type SourceDirectoryContents struct {
29+
SourceDirectory `json:"containedInDirectory"`
30+
}
31+
2832
func MakeDirContentsStatement(dir string, entries *types.PathCheckSummaryCollection) types.Statement {
2933
return &DirContents{
30-
types.MakeStatement[SourceDirectory](
34+
types.MakeStatement[SourceDirectoryContents](
3135
ManifestDirPredicateType,
32-
struct {
33-
SourceDirectory `json:"containedInDirectory"`
34-
}{
35-
SourceDirectory{
36+
SourceDirectoryContents{
37+
SourceDirectory: SourceDirectory{
3638
Path: dir,
3739
VCSEntries: entries,
3840
},
@@ -44,7 +46,7 @@ func MakeDirContentsStatement(dir string, entries *types.PathCheckSummaryCollect
4446

4547
func MakeDirContentsStatementFrom(statement types.Statement) DirContents {
4648
dirContents := DirContents{
47-
GenericStatement: attestTypes.GenericStatement[SourceDirectory]{},
49+
GenericStatement: attestTypes.GenericStatement[SourceDirectoryContents]{},
4850
}
4951
dirContents.ConvertFrom(statement)
5052
return dirContents
@@ -63,3 +65,7 @@ func (a SourceDirectory) Compare(b SourceDirectory) types.Cmp {
6365
cmp := a.VCSEntries.Compare(*b.VCSEntries)
6466
return &cmp
6567
}
68+
69+
func (a SourceDirectoryContents) Compare(b SourceDirectoryContents) types.Cmp {
70+
return a.SourceDirectory.Compare(b.SourceDirectory)
71+
}

attest/types/types.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,12 @@ type StamentConverter[T any] struct {
134134
}
135135

136136
func (s *GenericStatement[T]) ConvertFrom(statement Statement) error {
137-
predicate, ok := s.GetPredicate().(ComparablePredicate[T])
137+
predicate, ok := statement.GetPredicate().(ComparablePredicate[T])
138138
if !ok {
139-
return fmt.Errorf("cannot convert statement with predicte of type %T into %T", s.GetPredicate(), GenericStatement[T]{})
139+
return fmt.Errorf("cannot convert statement with predicte of type %T into %T", statement.GetPredicate(), GenericStatement[T]{})
140140
}
141141

142-
*s = MakeStatement[T](s.GetType(), predicate, s.GetSubject()...)
142+
*s = MakeStatement[T](statement.GetType(), predicate, statement.GetSubject()...)
143143
return nil
144144
}
145145

@@ -392,8 +392,9 @@ func comparePathCheckSummaries(a, b PathCheckSummary) int {
392392
return cmp.Compare(a.Common().Path, b.Common().Path)
393393
}
394394

395-
func (p Predicate[T]) GetType() string { return p.Type }
396-
func (p Predicate[T]) GetPredicate() any { return p.ComparablePredicate }
395+
func (p Predicate[T]) GetType() string { return p.Type }
396+
func (p Predicate[T]) GetPredicate() any { return p.ComparablePredicate }
397+
func (p Predicate[T]) GetUnderlyingPredicate() T { return p.ComparablePredicate.(T) }
397398

398399
func (p Predicate[T]) Compare(b any) Cmp {
399400
if b, ok := b.(Predicate[T]); ok {

oci/artefact.go

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import (
1313
"path/filepath"
1414
"time"
1515

16+
"golang.org/x/mod/semver"
17+
1618
ociclient "github.com/fluxcd/pkg/oci"
1719
"github.com/go-git/go-git/v5/utils/ioutil"
1820
"github.com/google/go-containerregistry/pkg/compression"
@@ -25,6 +27,7 @@ import (
2527

2628
"github.com/errordeveloper/tape/attest/manifest"
2729
attestTypes "github.com/errordeveloper/tape/attest/types"
30+
"github.com/errordeveloper/tape/attest/vcs/git"
2831
manifestTypes "github.com/errordeveloper/tape/manifest/types"
2932
)
3033

@@ -224,10 +227,6 @@ func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir str
224227
}
225228
defer os.RemoveAll(tmpDir)
226229

227-
_, err = SemVerFromAttestations(ctx, sourceAttestations...)
228-
if err != nil {
229-
return "", err
230-
}
231230
tmpFile := filepath.Join(tmpDir, "artefact.tgz")
232231

233232
outputFile, err := os.OpenFile(tmpFile, os.O_RDWR|os.O_CREATE|os.O_EXCL, regularFileMode)
@@ -255,7 +254,11 @@ func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir str
255254
}
256255
hash := hex.EncodeToString(c.hash.Sum(nil))
257256
tag := repo.Tag(manifestTypes.ConfigImageTagPrefix + hash)
258-
tagAlias := tag.Context().Tag(manifestTypes.ConfigImageTagPrefix + hash[:7])
257+
258+
tagAliases := append(
259+
SemVerTagsFromAttestations(ctx, tag, sourceAttestations...),
260+
tag.Context().Tag(manifestTypes.ConfigImageTagPrefix+hash[:7]),
261+
)
259262

260263
if timestamp == nil {
261264
timestamp = new(time.Time)
@@ -346,25 +349,51 @@ func (c *Client) PushArtefact(ctx context.Context, destinationRef, sourceDir str
346349
return "", fmt.Errorf("pushing index failed: %w", err)
347350
}
348351

349-
if err := remote.Tag(tagAlias, index, c.remoteWithContext(ctx)...); err != nil {
350-
return "", fmt.Errorf("adding alias tagging failed: %w", err)
352+
for i := range tagAliases {
353+
if err := remote.Tag(tagAliases[i], index, c.remoteWithContext(ctx)...); err != nil {
354+
return "", fmt.Errorf("adding alias tagging failed: %w", err)
355+
}
351356
}
352357

353-
return tagAlias.String() + "@" + digest.String(), err
358+
return tagAliases[0].String() + "@" + digest.String(), err
354359
}
355360

356-
func SemVerFromAttestations(ctx context.Context, sourceAttestations ...attestTypes.Statement) (string, error) {
361+
func SemVerTagsFromAttestations(ctx context.Context, tag name.Tag, sourceAttestations ...attestTypes.Statement) []name.Tag {
357362
statements := attestTypes.FilterByPredicateType(manifest.ManifestDirPredicateType, sourceAttestations)
358-
if len(statements) == 0 {
359-
return "", fmt.Errorf("VCS provinance attestion (%q) not found", manifest.ManifestDirPredicateType)
363+
if len(statements) != 1 {
364+
return []name.Tag{}
360365
}
361-
if len(statements) > 1 {
362-
return "", fmt.Errorf("too many attestations of type %q found, expected 1", manifest.ManifestDirPredicateType)
366+
367+
entries := manifest.MakeDirContentsStatementFrom(statements[0]).GetUnderlyingPredicate().VCSEntries
368+
if len(entries.EntryGroups) != 1 && len(entries.Providers) != 1 ||
369+
entries.Providers[0] != git.ProviderName {
370+
return []name.Tag{}
371+
}
372+
if len(entries.EntryGroups[0]) == 0 {
373+
return []name.Tag{}
374+
}
375+
groupSummary, ok := entries.EntryGroups[0][0].Full().(*git.GitSummary)
376+
if !ok {
377+
return []name.Tag{}
378+
}
379+
if len(groupSummary.Reference.Tags) == 0 {
380+
return []name.Tag{}
363381
}
364382

365-
_ = manifest.MakeDirContentsStatementFrom(statements[0])
383+
tags := make([]name.Tag, 0, len(groupSummary.Reference.Tags))
366384

367-
return "", nil
385+
// TODO: detect tags with groupSummary.Path+"/" as prefix and priorities them
386+
for i := range groupSummary.Reference.Tags {
387+
t := groupSummary.Reference.Tags[i].Name
388+
fmt.Println(t)
389+
if semver.IsValid(t) {
390+
tags = append(tags, tag.Context().Tag(t))
391+
}
392+
}
393+
if len(tags) == 0 {
394+
return []name.Tag{}
395+
}
396+
return tags
368397
}
369398

370399
func makeDescriptorWithPlatform() Descriptor {

0 commit comments

Comments
 (0)