Skip to content

Commit 1bd4bce

Browse files
author
tazhate
committed
feat(versioncheck): add stable-tag filter and CI auto-merge
Skip pre-release tags (alpha, beta, rc, dev, pre, snapshot, experimental) and floating tags (latest, nightly, canary, edge) when selecting the latest image version. Fetch up to 25 tags and pick the first stable one. Add build, lint, and test steps to the version-update workflow before creating the PR. Enable auto-merge via gh pr merge --auto --squash so the PR lands automatically when all required checks pass. Context: reviewed tag patterns across registries to identify common pre-release naming conventions. Verified isStableTag handles TRON's GreatVoyage- prefix correctly (prefix is stripped before the check).
1 parent d601515 commit 1bd4bce

2 files changed

Lines changed: 55 additions & 8 deletions

File tree

.github/workflows/version-update.yml

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ jobs:
1111
permissions:
1212
contents: write
1313
pull-requests: write
14+
1415
steps:
1516
- uses: actions/checkout@v4
1617

@@ -25,7 +26,19 @@ jobs:
2526
# Optional: set to avoid Docker Hub anonymous rate limits (600 req/h)
2627
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
2728

28-
- name: Create PR if versions changed
29+
- name: Verify build after update
30+
run: go build ./...
31+
32+
- name: Run linter
33+
uses: golangci/golangci-lint-action@v7
34+
with:
35+
version: v2.11.4
36+
37+
- name: Run tests
38+
run: go test ./internal/... ./api/...
39+
40+
- name: Create PR
41+
id: cpr
2942
uses: peter-evans/create-pull-request@v7
3043
with:
3144
commit-message: |
@@ -37,11 +50,19 @@ jobs:
3750
body: |
3851
## Automated image version update
3952
40-
`cmd/versioncheck` found newer tags in upstream registries and updated
53+
`cmd/versioncheck` found newer stable tags in upstream registries and updated
4154
`internal/adapters/versions_gen.go`.
4255
43-
**Review the diff before merging** — verify each updated image is a
44-
stable release (not a pre-release or breaking change).
56+
Pre-releases (alpha/beta/rc), nightly and floating tags (latest, canary)
57+
are automatically skipped.
58+
59+
Build, lint and tests passed. Safe to auto-merge.
4560
branch: chore/update-node-images
4661
delete-branch: true
4762
labels: dependencies
63+
64+
- name: Enable auto-merge
65+
if: steps.cpr.outputs.pull-request-number
66+
run: gh pr merge --auto --squash "${{ steps.cpr.outputs.pull-request-number }}"
67+
env:
68+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

cmd/versioncheck/main.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func checkVersions(ctx context.Context, filterChain string, concurrency int, tim
119119
return
120120
}
121121

122-
tags, err := client.LatestTags(reqCtx, it.policy, 5)
122+
tags, err := client.LatestTags(reqCtx, it.policy, 25)
123123
if err != nil {
124124
res.Err = err
125125
mu.Lock()
@@ -128,9 +128,13 @@ func checkVersions(ctx context.Context, filterChain string, concurrency int, tim
128128
return
129129
}
130130

131-
if len(tags) > 0 {
132-
res.LatestTag = tags[0].Tag
133-
res.IsNewer = registry.IsNewer(res.LatestTag, res.CurrentTag, it.policy.TagPrefix)
131+
// Pick the latest stable tag (skip pre-releases, nightly, latest, etc.)
132+
for _, t := range tags {
133+
if isStableTag(t.Tag, it.policy.TagPrefix) {
134+
res.LatestTag = t.Tag
135+
res.IsNewer = registry.IsNewer(res.LatestTag, res.CurrentTag, it.policy.TagPrefix)
136+
break
137+
}
134138
}
135139

136140
mu.Lock()
@@ -193,6 +197,28 @@ func applyUpdates(updates []versionResult) error {
193197
return writeVersionsGen(genPath, images)
194198
}
195199

200+
// isStableTag reports whether tag is a stable release — not a pre-release, nightly, or floating tag.
201+
// prefix is stripped before the check (e.g. "GreatVoyage-" for TRON).
202+
func isStableTag(tag, prefix string) bool {
203+
stripped := strings.TrimPrefix(tag, prefix)
204+
lower := strings.ToLower(stripped)
205+
// Reject floating / non-versioned tags
206+
floating := []string{"latest", "nightly", "canary", "edge", "develop", "main", "master", "unstable"}
207+
for _, f := range floating {
208+
if lower == f {
209+
return false
210+
}
211+
}
212+
// Reject pre-release suffix keywords that appear after a "-"
213+
preRelease := []string{"-alpha", "-beta", "-rc", "-dev", "-pre", "-snapshot", "-test", "-experimental"}
214+
for _, p := range preRelease {
215+
if strings.Contains(lower, p) {
216+
return false
217+
}
218+
}
219+
return true
220+
}
221+
196222
// parseTag extracts the tag from an image reference (everything after the last ":").
197223
func parseTag(imageRef string) string {
198224
if i := strings.LastIndex(imageRef, ":"); i >= 0 {

0 commit comments

Comments
 (0)