Recipe: support digest pinning at upgrade-time #916

Open
sixsmith wants to merge 10 commits from sixsmith/abra:main into main
Member

This change adds a --pindigests flag to abra recipe upgrade. The recipe maintainer still chooses a tagged container version that is semver-like, but abra will write the tag+multiplatform digest to compose.yml.

TODO

  • add unit tests
This change adds a `--pindigests` flag to `abra recipe upgrade`. The recipe maintainer still chooses a tagged container version that is semver-like, but abra will write the tag+multiplatform digest to `compose.yml`. TODO - [ ] add unit tests
Author
Member

Fixes #892

Fixes #892
sixsmith added 5 commits 2026-09-10 04:14:19 +00:00
* also run `go mod vendor`
* handle digests for the recipe subcommand
* add make parameter to pass args
sixsmith force-pushed main from 1f8b51ab40 to 0f7d991709 2026-09-10 04:14:19 +00:00 Compare
sixsmith marked the pull request as ready for review 2026-09-10 04:16:27 +00:00
Owner

Just to get it into the issue also:

thanks! flying by review: can you add some integration tests also? i see you covered the upgrade path, but not the standard deploy and also rollback/downgrade? those should all have a working integration test imho

Just to get it into the issue also: > thanks! flying by review: can you add some integration tests also? i see you covered the upgrade path, but not the standard deploy and also rollback/downgrade? those should all have a working integration test imho
sixsmith added 1 commit 2026-10-10 01:52:02 +00:00
- formatter.RemoveSha
- make pindigests TRUE by default
- more strict matching of digests
- unit and integration tests
sixsmith added 1 commit 2026-10-10 01:56:13 +00:00
sixsmith added 1 commit 2026-10-10 01:59:09 +00:00
sixsmith added 1 commit 2026-10-10 05:23:58 +00:00
Owner

Will this still work with renovate? Also how will abra recipe upgrade behave with digests regarding versioning?

Will this still work with renovate? Also how will abra recipe upgrade behave with digests regarding versioning?
Author
Member

@p4u1 Yes, it should work with renovate. By default it'll attempt to add pins, the user can disable if they want with --pindigests=false. abra recipe upgrade/release should use the version before @, so semver basically. There isn't a test for releasing though, I'll add one.

@p4u1 Yes, it should work with renovate. By default it'll attempt to add pins, the user can disable if they want with `--pindigests=false`. `abra recipe upgrade/release` should use the version before `@`, so semver basically. There isn't a test for releasing though, I'll add one.
Author
Member

On second thought, recipe_release.bats should cover the release path since those tests run an upgrade first - and --pindigests is true by default on those upgrades.

On second thought, `recipe_release.bats` should cover the release path since those tests run an upgrade first - and `--pindigests` is true by default on those upgrades.
sixsmith added 1 commit 2026-10-17 01:29:15 +00:00
@@ -333,4 +336,3 @@
var tag string
switch img.(type) {
case reference.NamedTagged:
Member

remove the empty switch case

remove the empty switch case
@@ -295,2 +302,3 @@
if upgradeTag != "skip" {
ok, err := recipe.UpdateTag(image, upgradeTag)
var resolvedDigest string
if shouldPin(service.Image, internal.PinDigests) {
Member

the logs and function calls in the file diverge, the logs use the variable image in most cases and shouldPin checks service.Image, maybe you can generalize that. If that does not work it would be nice to document why service.Image is used.

the logs and function calls in the file diverge, the logs use the variable image in most cases and shouldPin checks service.Image, maybe you can generalize that. If that does not work it would be nice to document why service.Image is used.
@@ -9,6 +9,8 @@ import (
"github.com/containers/image/docker"
"github.com/containers/image/types"
"github.com/distribution/reference"
"github.com/regclient/regclient"
Member

Is there a way to have the same logic without a new dependency?

Is there a way to have the same logic without a new dependency?
@@ -40,2 +42,4 @@
}
// GetTagAndDigest returns the tag and any digest for comparison and display.
func GetTagAndDigest(image reference.Named) string {
Member

More of a nit pick, but I would rename it to GetTagWithDigest because it only returns only one variable

More of a nit pick, but I would rename it to GetTagWithDigest because it only returns only one variable
@@ -170,0 +190,4 @@
// Don't confuse digests if the image isn't an exact match. E.g. if old is postgres:13, don't
// match postgres:13-alpine
pattern := regexp.MustCompile(`(?m)(^\s*image:\s*["']?)` + regexp.QuoteMeta(old) + `(["']?\s*(?:#.*)?$)`)
Member

Can you explain the regex in detail? Is it copied from somewhere or is there a spec to extract the pattern like that?

Can you explain the regex in detail? Is it copied from somewhere or is there a spec to extract the pattern like that?
You are not authorized to merge this pull request.
This pull request can be merged automatically.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u https://git.coopcloud.tech/sixsmith/abra main:sixsmith-main
git checkout sixsmith-main
Sign in to join this conversation.
No Reviewers
4 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: toolshed/abra#916