Skip to content

Commit 6ae5eaa

Browse files
committed
lint: version stream
Signed-off-by: Dentrax <furkan.turkal@chainguard.dev>
1 parent f10bd62 commit 6ae5eaa

5 files changed

Lines changed: 161 additions & 0 deletions

pkg/lint/rules.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,50 @@ var AllRules = func(l *Linter) Rules { //nolint:gocyclo
439439
return fmt.Errorf("no main package or subpackage test found")
440440
},
441441
},
442+
{
443+
Name: "valid-version-stream",
444+
Description: "check the provides and tag filter if version stream suffix is passed to package name",
445+
Severity: SeverityError,
446+
LintFunc: func(c config.Configuration) error {
447+
// This regex captures a string that ends with a semantic version (semver) suffix.
448+
// It returns two groups:
449+
// - Group 1: The prefix part of the string before the semver.
450+
// - Group 2: The semver (major.minor or major.minor.patch).
451+
// If there is no semver suffix, the string will not match.
452+
re := regexp.MustCompile(`^(.*?)-(\d+\.\d+(?:\.\d+)?)$`)
453+
454+
// It means that the package is not a version streamed, so early return.
455+
if !re.MatchString(c.Package.Name) {
456+
return nil
457+
}
458+
459+
matches := re.FindStringSubmatch(c.Package.Name)
460+
if len(matches) != 3 {
461+
return fmt.Errorf("invalid package name %s for version stream, regex matches %+v", c.Package.Name, matches)
462+
}
463+
464+
packageName := matches[1]
465+
versionStream := matches[2]
466+
467+
// package-name=${{package.full-version}}
468+
provides := fmt.Sprintf("%s=%s-r%d", packageName, c.Package.Version, c.Package.Epoch)
469+
// Some packages does not have ${{package.full-version}}, instead they have PACKAGE=VERSION.999. This is for backward compatibility.
470+
provides999 := fmt.Sprintf("%s=%s.999", packageName, versionStream)
471+
if !slices.Contains(c.Package.Dependencies.Provides, provides) && !slices.Contains(c.Package.Dependencies.Provides, provides999) {
472+
return fmt.Errorf("package is version streamed but %s=${{package.full-version}} is missing on dependencies.provides", packageName)
473+
}
474+
475+
if c.Update.Enabled && !c.Update.Manual && c.Update.GitHubMonitor != nil {
476+
// package-name-X.Y, package-name-X.Y., X.Y, vX.Y, X.Y., vX.Y., release-X.Y, release-X.Y.
477+
filtersToCheck := []string{c.Package.Name, c.Package.Name + ".", versionStream, "v" + versionStream, versionStream + ".", "v" + versionStream + ".", "release-" + versionStream, "release-" + versionStream + "."}
478+
479+
if !slices.Contains(filtersToCheck, c.Update.GitHubMonitor.TagFilter) && !slices.Contains(filtersToCheck, c.Update.GitHubMonitor.TagFilterPrefix) {
480+
return fmt.Errorf("package is version streamed but tag filter %s is missing on update.github", versionStream)
481+
}
482+
}
483+
return nil
484+
},
485+
},
442486
}
443487
}
444488

pkg/lint/rules_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,60 @@ func TestLinter_Rules(t *testing.T) {
397397
wantErr: false,
398398
matches: 0,
399399
},
400+
{
401+
file: "version-stream-missing-provides-1.2.yaml",
402+
minSeverity: SeverityError,
403+
want: EvalResult{
404+
File: "version-stream-missing-provides-1.2",
405+
Errors: EvalRuleErrors{
406+
{
407+
Rule: Rule{
408+
Name: "valid-version-stream",
409+
Severity: SeverityError,
410+
},
411+
Error: fmt.Errorf("[valid-version-stream]: package is version streamed but version-stream-missing-provides=${{package.full-version}} is missing on dependencies.provides (ERROR)"),
412+
},
413+
},
414+
},
415+
wantErr: false,
416+
matches: 1,
417+
},
418+
{
419+
file: "version-stream-missing-update-tagfilter-1.2.yaml",
420+
minSeverity: SeverityError,
421+
want: EvalResult{
422+
File: "version-stream-missing-update-tagfilter-1.2",
423+
Errors: EvalRuleErrors{
424+
{
425+
Rule: Rule{
426+
Name: "valid-version-stream",
427+
Severity: SeverityError,
428+
},
429+
Error: fmt.Errorf("[valid-version-stream]: package is version streamed but tag filter 1.2 is missing on update.github (ERROR)"),
430+
},
431+
},
432+
},
433+
wantErr: false,
434+
matches: 1,
435+
},
436+
{
437+
file: "version-stream-missing-update-tagfilter-1.2-999.yaml",
438+
minSeverity: SeverityError,
439+
want: EvalResult{
440+
File: "version-stream-missing-update-tagfilter-1.2",
441+
Errors: EvalRuleErrors{
442+
{
443+
Rule: Rule{
444+
Name: "valid-version-stream",
445+
Severity: SeverityError,
446+
},
447+
Error: fmt.Errorf("[valid-version-stream]: package is version streamed but tag filter 1.2 is missing on update.github (ERROR)"),
448+
},
449+
},
450+
},
451+
wantErr: false,
452+
matches: 1,
453+
},
400454
}
401455

402456
for _, tt := range tests {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package:
2+
name: version-stream-missing-provides-1.2
3+
version: 1.2.3
4+
epoch: 0
5+
description: "a version-streamed package with no dependencies.provides"
6+
7+
pipeline:
8+
- uses: fetch
9+
with:
10+
uri: https://test.com/version-stream-missing-provides/${{package.version}}.tar.gz
11+
expected-sha256: ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269
12+
13+
test:
14+
pipeline:
15+
- runs: "echo 'test'"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package:
2+
name: version-stream-missing-update-tagfilter-1.2
3+
version: 1.2.3
4+
epoch: 0
5+
description: "a version-streamed package with no dependencies.provides"
6+
dependencies:
7+
provides:
8+
- version-stream-missing-update-tagfilter=1.2.999
9+
10+
pipeline:
11+
- uses: fetch
12+
with:
13+
uri: https://test.com/version-stream-missing-update-tagfilter/${{package.version}}.tar.gz
14+
expected-sha256: ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269
15+
16+
test:
17+
pipeline:
18+
- runs: "echo 'test'"
19+
20+
update:
21+
enabled: true
22+
github:
23+
identifier: test/version-stream-missing-update-tagfilter
24+
use-tag: true
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package:
2+
name: version-stream-missing-update-tagfilter-1.2
3+
version: 1.2.3
4+
epoch: 0
5+
description: "a version-streamed package with no dependencies.provides"
6+
dependencies:
7+
provides:
8+
- version-stream-missing-update-tagfilter=${{package.full-version}}
9+
10+
pipeline:
11+
- uses: fetch
12+
with:
13+
uri: https://test.com/version-stream-missing-update-tagfilter/${{package.version}}.tar.gz
14+
expected-sha256: ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269
15+
16+
test:
17+
pipeline:
18+
- runs: "echo 'test'"
19+
20+
update:
21+
enabled: true
22+
github:
23+
identifier: test/version-stream-missing-update-tagfilter
24+
use-tag: true

0 commit comments

Comments
 (0)