Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package frizbee for openSUSE:Factory checked 
in at 2024-09-10 21:14:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/frizbee (Old)
 and      /work/SRC/openSUSE:Factory/.frizbee.new.17570 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "frizbee"

Tue Sep 10 21:14:09 2024 rev:2 rq:1199834 version:0.1.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/frizbee/frizbee.changes  2024-07-19 
15:27:24.459355406 +0200
+++ /work/SRC/openSUSE:Factory/.frizbee.new.17570/frizbee.changes       
2024-09-10 21:15:33.827863349 +0200
@@ -1,0 +2,79 @@
+Tue Sep 10 08:37:57 UTC 2024 - opensuse_buildserv...@ojkastl.de
+
+- Update to version 0.1.2:
+  * Add cert string to goreleaser configuration (#198)
+  * Bump anchore/sbom-action from 0.17.1 to 0.17.2 (#197)
+  * Output certificate as part of frizbee release
+
+-------------------------------------------------------------------
+Tue Sep 10 08:31:09 UTC 2024 - opensuse_buildserv...@ojkastl.de
+
+- Update to version 0.1.1:
+  * Bump github.com/moby/buildkit from 0.15.1 to 0.15.2
+  * Bump anchore/sbom-action from 0.17.0 to 0.17.1
+  * Bump sigstore/cosign-installer from 3.5.0 to 3.6.0
+  * Bump actions/upload-artifact from 4.3.5 to 4.3.6
+  * Bump github.com/google/go-containerregistry from 0.20.1 to
+    0.20.2
+  * Bump golang.org/x/sync from 0.7.0 to 0.8.0
+  * Bump actions/upload-artifact from 4.3.4 to 4.3.5
+  * Bump github.com/moby/buildkit from 0.15.0 to 0.15.1
+  * Bump golangci/golangci-lint-action from 6.0.1 to 6.1.0
+  * Use unmaintained version tag in tests
+
+-------------------------------------------------------------------
+Tue Sep 10 08:30:08 UTC 2024 - opensuse_buildserv...@ojkastl.de
+
+- Update to version 0.1.0:
+  * Fix the default configuration note in README
+  * Only ignore main and master, not all branches when pinning
+    actions
+  * Bump github.com/google/go-containerregistry from 0.20.0 to
+    0.20.1
+  * Bump slsa-framework/slsa-verifier from 2.5.1 to 2.6.0
+  * Bump anchore/sbom-action from 0.16.1 to 0.17.0
+  * chore: improve release binary
+  * docs: update to use core tap
+  * Bump github.com/moby/buildkit from 0.14.1 to 0.15.0 (#174)
+  * Bump actions/setup-go from 5.0.1 to 5.0.2
+  * Bump aquasecurity/trivy-action from 0.23.0 to 0.24.0
+  * Bump anchore/sbom-action from 0.16.0 to 0.16.1
+  * Bump github.com/google/go-containerregistry from 0.19.2 to
+    0.20.0 (#170)
+  * Bump actions/upload-artifact from 4.3.3 to 4.3.4
+  * Bump actions/download-artifact from 4.1.7 to 4.1.8
+  * Update Contributing & Community section in README.md
+  * Update Contributor License Agreement link in CONTRIBUTING.md
+  * Bump buf hashes again
+  * Add readme entry pointing to the github action
+  * Bump github.com/moby/buildkit from 0.14.0 to 0.14.1
+
+-------------------------------------------------------------------
+Tue Sep 10 08:26:05 UTC 2024 - opensuse_buildserv...@ojkastl.de
+
+- Update to version 0.0.20:
+  * Always ignore scratch even with an empty config
+  * Bump aquasecurity/trivy-action from 0.22.0 to 0.23.0
+  * Make DefaultConfig public
+  * Update documentation
+  * Default to skipping actions referenced by a tag
+  * Handle images with AS and platform, use excludes
+  * Add a configuration to exclude images
+  * Fix unit test hash reference and bump cobra and
+    go-containerregistry
+  * Bump actions/checkout from 4.1.6 to 4.1.7
+
+-------------------------------------------------------------------
+Tue Sep 10 08:23:53 UTC 2024 - opensuse_buildserv...@ojkastl.de
+
+- Update to version 0.0.19 (no releases between 0.0.16 and this
+  one):
+  * Fix missing ldflags while releasing
+  * Rename folder to directory field
+  * Update goreleaser config to v2
+  * Update releaser.yml to use v2
+  * Fix version variable path in goreleaser config
+  * Bump aquasecurity/trivy-action from 0.21.0 to 0.22.0
+  * Bump goreleaser/goreleaser-action from 5.1.0 to 6.0.0
+
+-------------------------------------------------------------------

Old:
----
  frizbee-0.0.16.obscpio

New:
----
  frizbee-0.1.2.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ frizbee.spec ++++++
--- /var/tmp/diff_new_pack.D58Xb0/_old  2024-09-10 21:15:34.403887349 +0200
+++ /var/tmp/diff_new_pack.D58Xb0/_new  2024-09-10 21:15:34.407887516 +0200
@@ -19,7 +19,7 @@
 %define __arch_install_post export NO_BRP_STRIP_DEBUG=true
 
 Name:           frizbee
-Version:        0.0.16
+Version:        0.1.2
 Release:        0
 Summary:        Throw a tag at and it comes back with a checksum
 License:        Apache-2.0
@@ -76,7 +76,6 @@
 DATE_FMT="+%%Y-%%m-%%dT%%H:%%M:%%SZ"
 BUILD_DATE=$(date -u -d "@${SOURCE_DATE_EPOCH}" "${DATE_FMT}" 2>/dev/null || 
date -u -r "${SOURCE_DATE_EPOCH}" "${DATE_FMT}" 2>/dev/null || date -u 
"${DATE_FMT}")
 
-
 # output of 'frizbee version' still partially broken/missing
 # https://github.com/stacklok/frizbee/issues/148
 go build \

++++++ _service ++++++
--- /var/tmp/diff_new_pack.D58Xb0/_old  2024-09-10 21:15:34.439888849 +0200
+++ /var/tmp/diff_new_pack.D58Xb0/_new  2024-09-10 21:15:34.443889015 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/stacklok/frizbee</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v0.0.16</param>
+    <param name="revision">v0.1.2</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
     <param name="versionrewrite-pattern">v(.*)</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.D58Xb0/_old  2024-09-10 21:15:34.463889849 +0200
+++ /var/tmp/diff_new_pack.D58Xb0/_new  2024-09-10 21:15:34.467890015 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/stacklok/frizbee</param>
-              <param 
name="changesrevision">181f1567cfeaf5998c4922deb3b73cbcb06af694</param></service></servicedata>
+              <param 
name="changesrevision">227081dd83c913a7aae818196a5124bd2c01eb62</param></service></servicedata>
 (No newline at EOF)
 

++++++ frizbee-0.0.16.obscpio -> frizbee-0.1.2.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/.github/workflows/codeql.yml 
new/frizbee-0.1.2/.github/workflows/codeql.yml
--- old/frizbee-0.0.16/.github/workflows/codeql.yml     2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/.github/workflows/codeql.yml      2024-08-27 
10:24:18.000000000 +0200
@@ -45,10 +45,10 @@
 
     steps:
     - name: Checkout repository
-      uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v3
+      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v3
 
     - name: Setup Go
-      uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v4
+      uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v4
       with:
         go-version-file: ./go.mod
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/.github/workflows/releaser.yml 
new/frizbee-0.1.2/.github/workflows/releaser.yml
--- old/frizbee-0.0.16/.github/workflows/releaser.yml   2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/.github/workflows/releaser.yml    2024-08-27 
10:24:18.000000000 +0200
@@ -39,7 +39,7 @@
       tree-state: ${{ steps.ldflags.outputs.tree-state }}
     steps:
       - id: checkout
-        uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4
+        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
         with:
           fetch-depth: 0
       - id: ldflags
@@ -49,6 +49,8 @@
           echo "version=$(git describe --tags --always --dirty | cut -c2-)" >> 
$GITHUB_OUTPUT
           echo "tree-state=$(if git diff --quiet; then echo "clean"; else echo 
"dirty"; fi)" >> $GITHUB_OUTPUT
   release:
+    needs:
+      - ldflags_args
     name: Build and release
     outputs:
       hashes: ${{ steps.hash.outputs.hashes }}
@@ -58,28 +60,28 @@
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
-        uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4
+        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
         with:
           fetch-depth: 0
 
       - name: Setup Go
-        uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v4
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v4
         with:
           go-version-file: 'go.mod'
           cache: true
 
       - name: Install Syft
-        uses: 
anchore/sbom-action/download-syft@e8d2a6937ecead383dfe75190d104edd1f9c5751 # 
v0.16.0
+        uses: 
anchore/sbom-action/download-syft@61119d458adab75f756bc0b9e4bde25725f86a7a # 
v0.17.2
 
       - name: Install Cosign
-        uses: 
sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0
+        uses: 
sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0
 
       - name: Run GoReleaser
         id: run-goreleaser
-        uses: 
goreleaser/goreleaser-action@5742e2a039330cbb23ebf35f046f814d4c6ff811 # v5
+        uses: 
goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v5
         with:
           distribution: goreleaser
-          version: latest
+          version: "~> v2"
           args: release --clean
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -125,7 +127,7 @@
     permissions: read-all
     steps:
       - name: Install the SLSA verifier
-        uses: 
slsa-framework/slsa-verifier/actions/installer@eb7007070baa04976cb9e25a0d8034f8db030a86
 # v2.5.1
+        uses: 
slsa-framework/slsa-verifier/actions/installer@3714a2a4684014deb874a0e737dffa0ee02dd647
 # v2.6.0
       - name: Download assets
         env:
           GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/.github/workflows/test.yml 
new/frizbee-0.1.2/.github/workflows/test.yml
--- old/frizbee-0.0.16/.github/workflows/test.yml       2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/.github/workflows/test.yml        2024-08-27 
10:24:18.000000000 +0200
@@ -12,10 +12,10 @@
     runs-on: ubuntu-latest
     steps:
       - name: checkout
-        uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4
+        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
 
       - name: setup go
-        uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v4
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v4
         with:
           go-version-file: ./go.mod
 
@@ -30,7 +30,7 @@
           task build
 
       - name: upload artifact
-        uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 
# v4.3.3
+        uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a 
# v4.3.6
         with:
           name: frizbee
           path: bin/frizbee
@@ -42,10 +42,10 @@
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
-        uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4
+        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
 
       - name: Set up Go
-        uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v4
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v4
         with:
           go-version-file: 'go.mod'
 
@@ -68,24 +68,24 @@
     runs-on: ubuntu-latest
     steps:
       - name: checkout
-        uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4
+        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
 
       - name: setup go
-        uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v4
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v4
         with:
           go-version-file: ./go.mod
 
       - name: golangci-lint
-        uses: 
golangci/golangci-lint-action@a4f60bb28d35aeee14e6880718e0c85ff1882e64 # v3
+        uses: 
golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v3
 
   test:
     runs-on: ubuntu-latest
     steps:
       - name: checkout
-        uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4
+        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
 
       - name: setup go
-        uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v4
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v4
         with:
           go-version-file: ./go.mod
 
@@ -107,10 +107,10 @@
       - build
     steps:
       - name: checkout
-        uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4
+        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
 
       - name: download artifact
-        uses: 
actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e #v4.1.7
+        uses: 
actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 #v4.1.8
         with:
           name: frizbee
           path: bin/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/.github/workflows/trivy.yml 
new/frizbee-0.1.2/.github/workflows/trivy.yml
--- old/frizbee-0.0.16/.github/workflows/trivy.yml      2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/.github/workflows/trivy.yml       2024-08-27 
10:24:18.000000000 +0200
@@ -9,9 +9,9 @@
     name: Trivy 
     steps:
       - name: Checkout
-        uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4
+        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
       - name: Security Scan
-        uses: 
aquasecurity/trivy-action@fd25fed6972e341ff0007ddb61f77e88103953c2 # 0.21.0
+        uses: 
aquasecurity/trivy-action@6e7b7d1fd3e4fef0c5fa8cce1229c54b2c9bd0d8 # 0.24.0
         with:
           scan-type: 'fs'
           scanners: vuln,secret
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/.goreleaser.yaml 
new/frizbee-0.1.2/.goreleaser.yaml
--- old/frizbee-0.0.16/.goreleaser.yaml 2024-06-04 09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/.goreleaser.yaml  2024-08-27 10:24:18.000000000 +0200
@@ -1,6 +1,7 @@
 # yaml-language-server: $schema=https://goreleaser.com/static/schema.json
 # vim: set ts=2 sw=2 tw=0 fo=cnqoj
 project_name: frizbee
+version: 2
 # This section defines the build matrix.
 builds:
   - env:
@@ -10,11 +11,12 @@
       - -trimpath
       - -tags=netgo
     ldflags:
+      - "-s -w"
       - "-X main.Version={{ .Env.VERSION }}"
       - "-X main.Commit={{ .Env.COMMIT }}"
       - "-X main.CommitDate={{ .Env.COMMIT_DATE }}"
       - "-X main.TreeState={{ .Env.TREE_STATE }}"
-      - "-X github.com/stacklok/frizbee/pkg/constants.CLIVersion={{ 
.Env.VERSION }}"
+      - "-X github.com/stacklok/frizbee/internal/cli.CLIVersion={{ 
.Env.VERSION }}"
     goos:
       - linux
       - windows
@@ -34,7 +36,7 @@
 brews:
   - homepage: 'https://github.com/stacklok/frizbee'
     description: 'frizbee is a tool you may throw a tag at and it comes back 
with a checksum.'
-    folder: Formula
+    directory: Formula
     commit_author:
       name: stacklokbot
       email: i...@stacklok.com
@@ -98,7 +100,9 @@
     args:
       - "sign-blob"
       - "--output-signature=${signature}"
+      - "--output-certificate=${certificate}"
       - "${artifact}"
       - "--yes" # needed on cosign 2.0.0+
     artifacts: archive
     output: true
+    certificate: '{{ trimsuffix (trimsuffix .Env.artifact ".zip") ".tar.gz" 
}}.pem'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/CONTRIBUTING.md 
new/frizbee-0.1.2/CONTRIBUTING.md
--- old/frizbee-0.0.16/CONTRIBUTING.md  2024-06-04 09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/CONTRIBUTING.md   2024-08-27 10:24:18.000000000 +0200
@@ -29,7 +29,7 @@
 If you are reporting a bug, please help to speed up problem diagnosis by 
providing as much information as possible. Ideally, that would include a small 
sample project that reproduces the problem.
 
 ### Sign the Contributor License Agreement
-Before we accept a non-trivial patch or pull request, we will need you to sign 
the [Contributor License Agreement](https://github.com/stacklok/frizbee). 
Signing the contributor’s agreement does not grant anyone commit rights to 
the main repository, but it does mean that we can accept your contributions, 
and you will get an author credit if we do. Active contributors might be asked 
to join the core team and given the ability to merge pull requests.
+Before we accept a non-trivial patch or pull request, we will need you to sign 
the [Contributor License Agreement](https://cla-assistant.io/stacklok/frizbee). 
Signing the contributor’s agreement does not grant anyone commit rights to 
the main repository, but it does mean that we can accept your contributions, 
and you will get an author credit if we do. Active contributors might be asked 
to join the core team and given the ability to merge pull requests.
 
 ### Not sure how to start contributing...
 PRs to resolve existing issues are greatly appreciated and issues labeled as 
["good first 
issue"](https://github.com/stacklok/frizbee/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
 are a great place to start!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/README.md new/frizbee-0.1.2/README.md
--- old/frizbee-0.0.16/README.md        2024-06-04 09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/README.md 2024-08-27 10:24:18.000000000 +0200
@@ -13,6 +13,8 @@
 
 It also includes a set of libraries for working with tags and checksums.
 
+Frizbee is available as a GitHub Action: 
[frizbee-action](https://github.com/marketplace/actions/frizbee-action)
+
 ## Table of Contents
 
 - [Installation](#installation)
@@ -36,7 +38,7 @@
 go install github.com/stacklok/frizbee
 
 # Using Homebrew
-brew install stacklok/tap/frizbee
+brew install frizbee
 
 # Using winget
 winget install stacklok.frizbee
@@ -107,7 +109,7 @@
 
 ```go
 // Create a new replacer
-r := replacer.NewGitHubActionsReplacer(cfg)
+r := replacer.NewGitHubActionsReplacer(config.DefaultConfig())
 ...
 // Parse a single GitHub Action reference
 ret, err := r.ParseString(ctx, ghActionRef)
@@ -135,7 +137,7 @@
 
 ```go
 // Create a new replacer
-r := replacer.NewContainerImagesReplacer(cfg)
+r := replacer.NewContainerImagesReplacer(config.DefaultConfig())
 ...
 // Parse a single container image reference
 ret, err := r.ParseString(ctx, ghActionRef)
@@ -173,9 +175,30 @@
 
 ```
 
-## Contributing
+Similarly, you can exclude actions that are referenced using a particular 
branch:
+```yml
+ghactions:
+  exclude_branches:
+     - main
+     - master
+```
+By default, Frizbee will exclude all actions that are referencing `main` or 
`master`.
+
+You can also configure Frizbee to skip processing certain container images or 
certain tags:
+```yml
+images:
+  exclude_images:
+    - busybox
+  exclude_tags:
+    - devel
+```
+By default, Frizbee will exclude the image named `scratch` and the tag 
`latest`.
+
+## Contributing & Community
+
+Frizbee is maintained by a dedicated community of developers that want this 
open souce project to benefit others and thrive. The main development of 
Frizbee is done in [Go](https://go.dev/). We welcome contributions of all 
types! Please see our [Contributing](./CONTRIBUTING.md) guide for more 
information on how you can help!
 
-We welcome contributions to Frizbee. Please see our 
[Contributing](./CONTRIBUTING.md) guide for more information.
+If you have questions, or just want to chat with us - please use the #frizbee 
channel on our [Discord Server](https://discord.gg/stacklok).
 
 ## License
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/go.mod new/frizbee-0.1.2/go.mod
--- old/frizbee-0.0.16/go.mod   2024-06-04 09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/go.mod    2024-08-27 10:24:18.000000000 +0200
@@ -1,41 +1,44 @@
 module github.com/stacklok/frizbee
 
-go 1.21
+go 1.22.5
 
 require (
        github.com/deckarep/golang-set/v2 v2.6.0
        github.com/go-git/go-billy/v5 v5.5.0
-       github.com/google/go-containerregistry v0.19.1
+       github.com/google/go-containerregistry v0.20.2
        github.com/google/go-github/v61 v61.0.0
+       github.com/moby/buildkit v0.15.2
        github.com/olekukonko/tablewriter v0.0.5
        github.com/puzpuzpuz/xsync v1.5.2
-       github.com/spf13/cobra v1.8.0
+       github.com/spf13/cobra v1.8.1
        github.com/stretchr/testify v1.9.0
-       golang.org/x/sync v0.7.0
+       golang.org/x/sync v0.8.0
+       gopkg.in/h2non/gock.v1 v1.1.2
        gopkg.in/yaml.v3 v3.0.1
 )
 
 require (
-       github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
+       github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
+       github.com/containerd/typeurl/v2 v2.1.1 // indirect
        github.com/cyphar/filepath-securejoin v0.2.4 // indirect
        github.com/davecgh/go-spew v1.1.1 // indirect
-       github.com/docker/cli v24.0.0+incompatible // indirect
+       github.com/docker/cli v27.1.1+incompatible // indirect
        github.com/docker/distribution v2.8.2+incompatible // indirect
-       github.com/docker/docker v24.0.9+incompatible // indirect
-       github.com/docker/docker-credential-helpers v0.7.0 // indirect
+       github.com/docker/docker-credential-helpers v0.8.2 // indirect
+       github.com/gogo/protobuf v1.3.2 // indirect
        github.com/google/go-querystring v1.1.0 // indirect
        github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
        github.com/inconshreveable/mousetrap v1.1.0 // indirect
-       github.com/klauspost/compress v1.16.5 // indirect
+       github.com/klauspost/compress v1.17.9 // indirect
        github.com/mattn/go-runewidth v0.0.9 // indirect
        github.com/mitchellh/go-homedir v1.1.0 // indirect
        github.com/opencontainers/go-digest v1.0.0 // indirect
-       github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
+       github.com/opencontainers/image-spec v1.1.0 // indirect
        github.com/pkg/errors v0.9.1 // indirect
        github.com/pmezard/go-difflib v1.0.0 // indirect
-       github.com/sirupsen/logrus v1.9.1 // indirect
+       github.com/sirupsen/logrus v1.9.3 // indirect
        github.com/spf13/pflag v1.0.5 // indirect
-       github.com/vbatts/tar-split v0.11.3 // indirect
-       golang.org/x/sys v0.15.0 // indirect
-       gopkg.in/h2non/gock.v1 v1.1.2 // indirect
+       github.com/vbatts/tar-split v0.11.5 // indirect
+       golang.org/x/sys v0.22.0 // indirect
+       google.golang.org/protobuf v1.33.0 // indirect
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/go.sum new/frizbee-0.1.2/go.sum
--- old/frizbee-0.0.16/go.sum   2024-06-04 09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/go.sum    2024-08-27 10:24:18.000000000 +0200
@@ -1,8 +1,8 @@
-github.com/BurntSushi/toml v1.2.1/go.mod 
h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/containerd/stargz-snapshotter/estargz v0.14.3 
h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
-github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod 
h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
-github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod 
h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
-github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod 
h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/containerd/stargz-snapshotter/estargz v0.15.1 
h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
+github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod 
h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
+github.com/containerd/typeurl/v2 v2.1.1 
h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4=
+github.com/containerd/typeurl/v2 v2.1.1/go.mod 
h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
+github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod 
h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 github.com/cyphar/filepath-securejoin v0.2.4 
h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
 github.com/cyphar/filepath-securejoin v0.2.4/go.mod 
h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
 github.com/davecgh/go-spew v1.1.0/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -10,21 +10,23 @@
 github.com/davecgh/go-spew v1.1.1/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/deckarep/golang-set/v2 v2.6.0 
h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM=
 github.com/deckarep/golang-set/v2 v2.6.0/go.mod 
h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
-github.com/docker/cli v24.0.0+incompatible 
h1:0+1VshNwBQzQAx9lOl+OYCTCEAD8fKs/qeXMx3O0wqM=
-github.com/docker/cli v24.0.0+incompatible/go.mod 
h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/cli v27.1.1+incompatible 
h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE=
+github.com/docker/cli v27.1.1+incompatible/go.mod 
h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 github.com/docker/distribution v2.8.2+incompatible 
h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
 github.com/docker/distribution v2.8.2+incompatible/go.mod 
h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v24.0.9+incompatible 
h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0=
-github.com/docker/docker v24.0.9+incompatible/go.mod 
h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker-credential-helpers v0.7.0 
h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
-github.com/docker/docker-credential-helpers v0.7.0/go.mod 
h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
+github.com/docker/docker-credential-helpers v0.8.2 
h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
+github.com/docker/docker-credential-helpers v0.8.2/go.mod 
h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
 github.com/go-git/go-billy/v5 v5.5.0 
h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
 github.com/go-git/go-billy/v5 v5.5.0/go.mod 
h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod 
h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang/protobuf v1.5.0/go.mod 
h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/google/go-cmp v0.5.2/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod 
h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-containerregistry v0.19.1 
h1:yMQ62Al6/V0Z7CqIrrS1iYoA5/oQCm88DeNujc7C1KY=
-github.com/google/go-containerregistry v0.19.1/go.mod 
h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
+github.com/google/go-containerregistry v0.20.2 
h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo=
+github.com/google/go-containerregistry v0.20.2/go.mod 
h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8=
 github.com/google/go-github/v61 v61.0.0 
h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go=
 github.com/google/go-github/v61 v61.0.0/go.mod 
h1:0WR+KmsWX75G2EbpyGsGmradjo3IiciuI4BmdVCobQY=
 github.com/google/go-querystring v1.1.0 
h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
@@ -33,8 +35,10 @@
 github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod 
h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
 github.com/inconshreveable/mousetrap v1.1.0 
h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod 
h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/klauspost/compress v1.16.5 
h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
-github.com/klauspost/compress v1.16.5/go.mod 
h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/kisielk/errcheck v1.5.0/go.mod 
h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod 
h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.17.9 
h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
+github.com/klauspost/compress v1.17.9/go.mod 
h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod 
h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -43,6 +47,9 @@
 github.com/mattn/go-runewidth v0.0.9/go.mod 
h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 github.com/mitchellh/go-homedir v1.1.0 
h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
 github.com/mitchellh/go-homedir v1.1.0/go.mod 
h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/moby/buildkit v0.15.2 
h1:DnONr0AoceTWyv+plsQ7IhkSaj+6o0WyoaxYPyTFIxs=
+github.com/moby/buildkit v0.15.2/go.mod 
h1:Yis8ZMUJTHX9XhH9zVyK2igqSHV3sxi3UN0uztZocZk=
+github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 
h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
 github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod 
h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
 github.com/olekukonko/tablewriter v0.0.5 
h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
 github.com/olekukonko/tablewriter v0.0.5/go.mod 
h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
@@ -50,8 +57,8 @@
 github.com/onsi/gomega v1.27.10/go.mod 
h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
 github.com/opencontainers/go-digest v1.0.0 
h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
 github.com/opencontainers/go-digest v1.0.0/go.mod 
h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
-github.com/opencontainers/image-spec v1.1.0-rc3 
h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8=
-github.com/opencontainers/image-spec v1.1.0-rc3/go.mod 
h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
+github.com/opencontainers/image-spec v1.1.0 
h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
+github.com/opencontainers/image-spec v1.1.0/go.mod 
h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod 
h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 
h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -61,42 +68,63 @@
 github.com/rogpeppe/go-internal v1.11.0 
h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
 github.com/rogpeppe/go-internal v1.11.0/go.mod 
h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod 
h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sirupsen/logrus v1.9.0/go.mod 
h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/sirupsen/logrus v1.9.1 
h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ=
-github.com/sirupsen/logrus v1.9.1/go.mod 
h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
-github.com/spf13/cobra v1.8.0/go.mod 
h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
+github.com/sirupsen/logrus v1.9.3 
h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod 
h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
+github.com/spf13/cobra v1.8.1/go.mod 
h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod 
h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod 
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0/go.mod 
h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0/go.mod 
h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/testify v1.7.0/go.mod 
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1/go.mod 
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0/go.mod 
h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1/go.mod 
h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.9.0 
h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 github.com/stretchr/testify v1.9.0/go.mod 
h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/urfave/cli v1.22.12/go.mod 
h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
-github.com/vbatts/tar-split v0.11.3 
h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
-github.com/vbatts/tar-split v0.11.3/go.mod 
h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
-golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
-golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+github.com/vbatts/tar-split v0.11.5 
h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
+github.com/vbatts/tar-split v0.11.5/go.mod 
h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
+github.com/yuin/goldmark v1.1.27/go.mod 
h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod 
h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod 
h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod 
h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod 
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod 
h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod 
h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod 
h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod 
h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod 
h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
-golang.org/x/text v0.13.0/go.mod 
h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
+golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
+golang.org/x/text v0.15.0/go.mod 
h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod 
h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod 
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod 
h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod 
h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod 
h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.27.1/go.mod 
h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.33.0 
h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod 
h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c 
h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod 
h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
 gopkg.in/h2non/gock.v1 v1.1.2/go.mod 
h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod 
h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/pkg/replacer/actions/actions.go 
new/frizbee-0.1.2/pkg/replacer/actions/actions.go
--- old/frizbee-0.0.16/pkg/replacer/actions/actions.go  2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/pkg/replacer/actions/actions.go   2024-08-27 
10:24:18.000000000 +0200
@@ -23,6 +23,7 @@
        "fmt"
        "net/http"
        "net/url"
+       "slices"
        "strings"
 
        "github.com/google/go-github/v61/github"
@@ -144,7 +145,7 @@
                        sum = val
                } else {
                        // Get the checksum for the action reference
-                       sum, err = GetChecksum(ctx, restIf, act, ref)
+                       sum, err = GetChecksum(ctx, cfg.GHActions, restIf, act, 
ref)
                        if err != nil {
                                return nil, fmt.Errorf("failed to get checksum 
for action '%s': %w", matchedLine, err)
                        }
@@ -153,7 +154,7 @@
                }
        } else {
                // Get the checksum for the action reference
-               sum, err = GetChecksum(ctx, restIf, act, ref)
+               sum, err = GetChecksum(ctx, cfg.GHActions, restIf, act, ref)
                if err != nil {
                        return nil, fmt.Errorf("failed to get checksum for 
action '%s': %w", matchedLine, err)
                }
@@ -255,7 +256,7 @@
 }
 
 // GetChecksum returns the checksum for a given action and tag.
-func GetChecksum(ctx context.Context, restIf interfaces.REST, action, ref 
string) (string, error) {
+func GetChecksum(ctx context.Context, cfg config.GHActions, restIf 
interfaces.REST, action, ref string) (string, error) {
        owner, repo, err := parseActionFragments(action)
        if err != nil {
                return "", err
@@ -274,6 +275,12 @@
        }
 
        // check branch
+       if excludeBranch(cfg.Filter.ExcludeBranches, ref) {
+               // if a branch is excluded, we won't know if it's a valid 
reference
+               // but that's OK - we just won't touch that reference
+               return "", fmt.Errorf("%w: %s", interfaces.ErrReferenceSkipped, 
ref)
+       }
+
        res, err = getCheckSumForBranch(ctx, restIf, owner, repo, ref)
        if err != nil {
                return "", fmt.Errorf("failed to get checksum for branch: %w", 
err)
@@ -319,6 +326,17 @@
        return doGetReference(ctx, restIf, path)
 }
 
+func excludeBranch(excludes []string, branch string) bool {
+       if len(excludes) == 0 {
+               return false
+       }
+       if slices.Contains(excludes, "*") {
+               return true
+       }
+
+       return slices.Contains(excludes, branch)
+}
+
 func doGetReference(ctx context.Context, restIf interfaces.REST, path string) 
(string, error) {
        req, err := restIf.NewRequest(http.MethodGet, path, nil)
        if err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/pkg/replacer/actions/actions_test.go 
new/frizbee-0.1.2/pkg/replacer/actions/actions_test.go
--- old/frizbee-0.0.16/pkg/replacer/actions/actions_test.go     2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/pkg/replacer/actions/actions_test.go      2024-08-27 
10:24:18.000000000 +0200
@@ -292,9 +292,9 @@
                        wantErr: true,
                },
                {
-                       name:    "bufbuild/buf-setup-action with v1 is an 
array",
-                       args:    struct{ action, ref string }{action: 
"bufbuild/buf-setup-action", ref: "v1"},
-                       want:    "dde0b9351db90fbf78e345f41a57de8514bf1091",
+                       name:    "actions/setup-node with v1 is an array",
+                       args:    struct{ action, ref string }{action: 
"actions/setup-node", ref: "v1"},
+                       want:    "f1f314fca9dfce2769ece7d933488f076716723e",
                        wantErr: false,
                },
                {
@@ -310,7 +310,7 @@
                t.Run(tt.name, func(t *testing.T) {
                        t.Parallel()
 
-                       got, err := GetChecksum(ctx, ghcli, tt.args.action, 
tt.args.ref)
+                       got, err := GetChecksum(ctx, config.GHActions{}, ghcli, 
tt.args.action, tt.args.ref)
                        if tt.wantErr {
                                require.Error(t, err, "Wanted error, got none")
                                require.Empty(t, got, "Wanted empty string, got 
%v", got)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/pkg/replacer/image/image.go 
new/frizbee-0.1.2/pkg/replacer/image/image.go
--- old/frizbee-0.0.16/pkg/replacer/image/image.go      2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/pkg/replacer/image/image.go       2024-08-27 
10:24:18.000000000 +0200
@@ -20,12 +20,14 @@
        "context"
        "errors"
        "fmt"
+       "slices"
        "strings"
 
        "github.com/google/go-containerregistry/pkg/authn"
        "github.com/google/go-containerregistry/pkg/name"
        v1 "github.com/google/go-containerregistry/pkg/v1"
        "github.com/google/go-containerregistry/pkg/v1/remote"
+       dockerparser "github.com/moby/buildkit/frontend/dockerfile/parser"
 
        "github.com/stacklok/frizbee/internal/cli"
        "github.com/stacklok/frizbee/pkg/interfaces"
@@ -36,7 +38,7 @@
 const (
        // ContainerImageRegex is regular expression pattern to match container 
image usage in YAML
        // nolint:lll
-       ContainerImageRegex = 
`image\s*:\s*["']?([^\s"']+/[^\s"']+|[^\s"']+)(:[^\s"']+)?(@[^\s"']+)?["']?|FROM\s+([^\s]+(/[^\s]+)?(:[^\s]+)?(@[^\s]+)?)`
+       ContainerImageRegex = 
`image\s*:\s*["']?([^\s"']+/[^\s"']+|[^\s"']+)(:[^\s"']+)?(@[^\s"']+)?["']?|FROM\s+(--platform=[^\s]+[^\s]*\s+)?([^\s]+(/[^\s]+)?(:[^\s]+)?(@[^\s]+)?)`
        prefixFROM          = "FROM "
        prefixImage         = "image: "
        // ReferenceType is the type of the reference
@@ -49,6 +51,11 @@
        cache store.RefCacher
 }
 
+type unresolvedImage struct {
+       imageRef string
+       flags    []string
+}
+
 // New creates a new Parser
 func New() *Parser {
        return &Parser{
@@ -79,32 +86,52 @@
        _ interfaces.REST,
        cfg config.Config,
 ) (*interfaces.EntityRef, error) {
+       var imageRef string
+       var extraArgs string
+
        // Trim the prefix
        hasFROMPrefix := false
        hasImagePrefix := false
        // Check if the image reference has the FROM prefix, i.e. Dockerfile
        if strings.HasPrefix(matchedLine, prefixFROM) {
-               matchedLine = strings.TrimPrefix(matchedLine, prefixFROM)
+               parsedFrom, err := getRefFromDockerfileFROM(matchedLine)
+               if err != nil {
+                       return nil, err
+               }
+
                // Check if the image reference should be excluded, i.e. scratch
-               if shouldExclude(matchedLine) {
+               if shouldSkipImageRef(&cfg, parsedFrom.imageRef) {
                        return nil, fmt.Errorf("image reference %s should be 
excluded - %w", matchedLine, interfaces.ErrReferenceSkipped)
                }
+
+               imageRef = parsedFrom.imageRef
+               extraArgs = strings.Join(parsedFrom.flags, " ")
+               if extraArgs != "" {
+                       extraArgs += " "
+               }
+
                hasFROMPrefix = true
        } else if strings.HasPrefix(matchedLine, prefixImage) {
                // Check if the image reference has the image prefix, i.e. 
Kubernetes or Docker Compose YAML
-               matchedLine = strings.TrimPrefix(matchedLine, prefixImage)
+               imageRef = strings.TrimPrefix(matchedLine, prefixImage)
+               // Check if the image reference should be excluded, i.e. scratch
+               if shouldSkipImageRef(&cfg, imageRef) {
+                       return nil, fmt.Errorf("image reference %s should be 
excluded - %w", matchedLine, interfaces.ErrReferenceSkipped)
+               }
                hasImagePrefix = true
+       } else {
+               imageRef = matchedLine
        }
 
        // Get the digest of the image reference
-       imageRefWithDigest, err := GetImageDigestFromRef(ctx, matchedLine, 
cfg.Platform, p.cache)
+       imageRefWithDigest, err := GetImageDigestFromRef(ctx, imageRef, 
cfg.Platform, p.cache)
        if err != nil {
                return nil, err
        }
 
        // Add the prefix back
        if hasFROMPrefix {
-               imageRefWithDigest.Prefix = fmt.Sprintf("%s%s", prefixFROM, 
imageRefWithDigest.Prefix)
+               imageRefWithDigest.Prefix = fmt.Sprintf("%s%s%s", prefixFROM, 
extraArgs, imageRefWithDigest.Prefix)
        } else if hasImagePrefix {
                imageRefWithDigest.Prefix = fmt.Sprintf("%s%s", prefixImage, 
imageRefWithDigest.Prefix)
        }
@@ -202,6 +229,54 @@
        }, nil
 }
 
-func shouldExclude(ref string) bool {
-       return ref == "scratch"
+func shouldSkipImageRef(cfg *config.Config, ref string) bool {
+       // Parse the image reference
+       nameRef, err := name.ParseReference(ref)
+       if err != nil {
+               // we wouldn't know how to resolve this reference, so let's skip
+               return true
+       }
+
+       imageName := getImageNameFromRef(nameRef)
+       if slices.Contains(cfg.Images.ImageFilter.ExcludeImages, imageName) {
+               return true
+       }
+
+       tag := nameRef.Identifier()
+       return slices.Contains(cfg.Images.ImageFilter.ExcludeTags, tag)
+}
+
+// TODO(jakub): this is a bit of a hack, but I didn't find a better way to get 
just the name
+func getImageNameFromRef(nameRef name.Reference) string {
+       fullRepositoryName := nameRef.Context().Name()
+       parts := strings.Split(fullRepositoryName, "/")
+       if len(parts) > 1 {
+               return parts[len(parts)-1]
+       }
+
+       return ""
+}
+func getRefFromDockerfileFROM(line string) (unresolvedImage, error) {
+       parseResult, err := dockerparser.Parse(strings.NewReader(line))
+       if err != nil {
+               return unresolvedImage{}, fmt.Errorf("failed to parse 
Dockerfile line: %w", err)
+       }
+
+       if len(parseResult.AST.Children) == 0 ||
+               parseResult.AST.Children[0] == nil ||
+               strings.ToUpper(parseResult.AST.Children[0].Value) != "FROM" {
+               return unresolvedImage{}, errors.New("invalid Dockerfile line: 
the first parsed node is not FROM")
+       }
+
+       fromNode := parseResult.AST.Children[0]
+
+       imgNode := parseResult.AST.Children[0].Next
+       if imgNode == nil {
+               return unresolvedImage{}, errors.New("invalid Dockerfile line: 
no image node found")
+       }
+
+       return unresolvedImage{
+               imageRef: imgNode.Value,
+               flags:    fromNode.Flags,
+       }, nil
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/pkg/replacer/image/image_test.go 
new/frizbee-0.1.2/pkg/replacer/image/image_test.go
--- old/frizbee-0.0.16/pkg/replacer/image/image_test.go 2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/pkg/replacer/image/image_test.go  2024-08-27 
10:24:18.000000000 +0200
@@ -6,6 +6,7 @@
 
        "github.com/stretchr/testify/require"
 
+       "github.com/stacklok/frizbee/pkg/interfaces"
        "github.com/stacklok/frizbee/pkg/utils/config"
        "github.com/stacklok/frizbee/pkg/utils/store"
 )
@@ -78,13 +79,65 @@
 
        parser := New()
        ctx := context.Background()
-       cfg := config.Config{GHActions: config.GHActions{Filter: 
config.Filter{Exclude: []string{"scratch"}}}}
+       cfg := config.Config{
+               Images: config.Images{
+                       ImageFilter: config.ImageFilter{
+                               ExcludeImages: []string{"scratch"},
+                               ExcludeTags:   []string{"latest"},
+                       },
+               },
+       }
 
        tests := []struct {
                name        string
                matchedLine string
+               expected    error
        }{
-               {"Replace excluded path", "FROM scratch"},
+               {
+                       "Do not replace scratch FROM image",
+                       "FROM scratch",
+                       interfaces.ErrReferenceSkipped,
+               },
+               {
+                       "Do not replace ubuntu:latest",
+                       "FROM ubuntu:latest",
+                       interfaces.ErrReferenceSkipped,
+               },
+               {
+                       "Do not replace ubuntu:latest with AS",
+                       "FROM ubuntu:latest AS builder",
+                       interfaces.ErrReferenceSkipped,
+               },
+               {
+                       "Do not replace ubuntu without a tag",
+                       "FROM ubuntu",
+                       interfaces.ErrReferenceSkipped,
+               },
+               {
+                       "Do not replace ubuntu without a tag with a stage",
+                       "FROM ubuntu AS builder",
+                       interfaces.ErrReferenceSkipped,
+               },
+               {
+                       "Replace ubuntu:22.04",
+                       "FROM ubuntu:22.04",
+                       nil,
+               },
+               {
+                       "Replace ubuntu:22.04 with AS",
+                       "FROM ubuntu:22.04 AS builder",
+                       nil,
+               },
+               {
+                       "Replace ubuntu:22.04 with AS",
+                       "FROM --platform=linux/amd64 ubuntu:22.04 AS builder",
+                       nil,
+               },
+               {
+                       "Replace with repo reference and tag",
+                       "FROM 
ghcr.io/stacklok/minder/helm/minder:0.20231123.829_ref.26ca90b",
+                       nil,
+               },
        }
 
        for _, tt := range tests {
@@ -92,8 +145,12 @@
                t.Run(tt.name, func(t *testing.T) {
                        t.Parallel()
                        _, err := parser.Replace(ctx, tt.matchedLine, nil, cfg)
-                       require.Error(t, err, "Should return error for excluded 
path")
-                       require.Contains(t, err.Error(), "reference skipped", 
"Error should indicate reference skipped")
+                       if tt.expected == nil {
+                               require.NoError(t, err, "Should not return 
error for excluded path")
+                       } else {
+                               require.Error(t, err, "Should return error for 
excluded path")
+                               require.ErrorIs(t, err, tt.expected, 
"Unexpected error")
+                       }
                })
        }
 }
@@ -178,24 +235,39 @@
        }
 }
 
-func TestShouldExclude(t *testing.T) {
+func TestShouldSkipImage(t *testing.T) {
        t.Parallel()
 
        tests := []struct {
                name string
                ref  string
-               want bool
+               skip bool
        }{
-               {"Exclude scratch", "scratch", true},
-               {"Do not exclude ubuntu", "ubuntu", false},
+               // skip cases
+               {"Skip scratch", "scratch", true},
+               {"Skip ubuntu without a tag", "ubuntu", true},
+               {"Skip ubuntu:latest", "ubuntu:latest", true},
+               // keep cases
+               {"Do not skip ubuntu:22.04", "ubuntu:22.04", false},
+               {"Do not skip with repo reference and tag", 
"myrepo/myimage:1.2.3", false},
        }
 
        for _, tt := range tests {
                tt := tt
                t.Run(tt.name, func(t *testing.T) {
                        t.Parallel()
-                       got := shouldExclude(tt.ref)
-                       require.Equal(t, tt.want, got, "shouldExclude should 
return the correct exclusion status")
+
+                       config := &config.Config{
+                               Images: config.Images{
+                                       ImageFilter: config.ImageFilter{
+                                               ExcludeImages: 
[]string{"scratch"},
+                                               ExcludeTags:   
[]string{"latest"},
+                                       },
+                               },
+                       }
+
+                       got := shouldSkipImageRef(config, tt.ref)
+                       require.Equal(t, tt.skip, got, "shouldSkipImageRef 
should return the correct exclusion status")
                })
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/pkg/replacer/replacer.go 
new/frizbee-0.1.2/pkg/replacer/replacer.go
--- old/frizbee-0.0.16/pkg/replacer/replacer.go 2024-06-04 09:27:11.000000000 
+0200
+++ new/frizbee-0.1.2/pkg/replacer/replacer.go  2024-08-27 10:24:18.000000000 
+0200
@@ -61,6 +61,8 @@
 
 // NewGitHubActionsReplacer creates a new replacer for GitHub actions
 func NewGitHubActionsReplacer(cfg *config.Config) *Replacer {
+       cfg = config.MergeUserConfig(cfg)
+
        return &Replacer{
                cfg:    *cfg,
                parser: actions.New(),
@@ -70,6 +72,8 @@
 
 // NewContainerImagesReplacer creates a new replacer for container images
 func NewContainerImagesReplacer(cfg *config.Config) *Replacer {
+       cfg = config.MergeUserConfig(cfg)
+
        return &Replacer{
                cfg:    *cfg,
                parser: image.New(),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/pkg/replacer/replacer_test.go 
new/frizbee-0.1.2/pkg/replacer/replacer_test.go
--- old/frizbee-0.0.16/pkg/replacer/replacer_test.go    2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/pkg/replacer/replacer_test.go     2024-08-27 
10:24:18.000000000 +0200
@@ -59,6 +59,36 @@
                        wantErr: false,
                },
                {
+                       name: "dockerfile - tag, stage and platform",
+                       args: args{
+                               refstr: "FROM --platform=linux/s390x 
golang:1.22.2 AS build",
+                       },
+                       want: &interfaces.EntityRef{
+                               Name:   "index.docker.io/library/golang",
+                               Ref:    
"sha256:d5302d40dc5fbbf38ec472d1848a9d2391a13f93293a6a5b0b87c99dc0eaa6ae",
+                               Type:   image.ReferenceType,
+                               Tag:    "1.22.2",
+                               Prefix: "FROM --platform=linux/s390x ",
+                       },
+                       wantErr: false,
+               },
+               {
+                       name: "dockerfile - no tag",
+                       args: args{
+                               refstr: "FROM golang",
+                       },
+                       want:    nil,
+                       wantErr: true,
+               },
+               {
+                       name: "dockerfile - latest",
+                       args: args{
+                               refstr: "FROM golang:latest",
+                       },
+                       want:    nil,
+                       wantErr: true,
+               },
+               {
                        name: "dockerfile - already by digest",
                        args: args{
                                refstr: "FROM 
golang:1.22.2@sha256:aca60c1f21de99aa3a34e653f0cdc8c8ea8fe6480359229809d5bcb974f599ec",
@@ -103,6 +133,22 @@
                        wantErr: false,
                },
                {
+                       name: "image with no tag is skipped",
+                       args: args{
+                               refstr: "image: nginx",
+                       },
+                       want:    nil,
+                       wantErr: true,
+               },
+               {
+                       name: "image with latest tag is skipped",
+                       args: args{
+                               refstr: "image: nginx:latest",
+                       },
+                       want:    nil,
+                       wantErr: true,
+               },
+               {
                        name: "invalid ref string",
                        args: args{
                                refstr: "ghcr.io/stacklok/minder/helm/minder!",
@@ -147,7 +193,14 @@
                t.Run(tt.name, func(t *testing.T) {
                        t.Parallel()
                        ctx := context.Background()
-                       r := NewContainerImagesReplacer(&config.Config{})
+                       config := &config.Config{
+                               Images: config.Images{
+                                       ImageFilter: config.ImageFilter{
+                                               ExcludeTags: []string{"latest"},
+                                       },
+                               },
+                       }
+                       r := NewContainerImagesReplacer(config)
                        got, err := r.ParseString(ctx, tt.args.refstr)
                        if tt.wantErr {
                                require.Error(t, err)
@@ -251,6 +304,13 @@
                        wantErr: false,
                },
                {
+                       name: "aquasecurity/trivy-action with ignored branch 
returns error",
+                       args: args{
+                               action: "aquasecurity/trivy-action@main",
+                       },
+                       wantErr: true,
+               },
+               {
                        name: "actions/checkout with invalid tag returns error",
                        args: args{
                                action: "actions/checkout@v4.1.1.1",
@@ -283,13 +343,13 @@
                        wantErr: true,
                },
                {
-                       name: "bufbuild/buf-setup-action with v1 is an array",
+                       name: "actions/setup-node with v1 is an array",
                        args: args{
-                               action: "bufbuild/buf-setup-action@v1",
+                               action: "actions/setup-node@v1",
                        },
                        want: &interfaces.EntityRef{
-                               Name:   "bufbuild/buf-setup-action",
-                               Ref:    
"dde0b9351db90fbf78e345f41a57de8514bf1091",
+                               Name:   "actions/setup-node",
+                               Ref:    
"f1f314fca9dfce2769ece7d933488f076716723e",
                                Type:   actions.ReferenceType,
                                Tag:    "v1",
                                Prefix: "",
@@ -338,7 +398,19 @@
                t.Run(tt.name, func(t *testing.T) {
                        t.Parallel()
                        ctx := context.Background()
-                       r := 
NewGitHubActionsReplacer(&config.Config{}).WithGitHubClientFromToken(os.Getenv("GITHUB_TOKEN"))
+                       conf := &config.Config{
+                               GHActions: config.GHActions{
+                                       Filter: config.Filter{
+                                               ExcludeBranches: 
[]string{"main"},
+                                       },
+                               },
+                               Images: config.Images{
+                                       ImageFilter: config.ImageFilter{
+                                               ExcludeTags: []string{"latest"},
+                                       },
+                               },
+                       }
+                       r := 
NewGitHubActionsReplacer(conf).WithGitHubClientFromToken(os.Getenv("GITHUB_TOKEN"))
                        got, err := r.ParseString(ctx, tt.args.action)
                        if tt.wantErr {
                                require.Error(t, err)
@@ -470,16 +542,194 @@
       path: /
       type: Directory
 `,
-                       expected: "",
+                       modified: false,
+               },
+               {
+                       name: "A complex dockerfile",
+                       before: `
+ARG BASE_IMAGE=alpine
+
+FROM --platform=$BUILDPLATFORM 
tonistiigi/xx:1.2.1@sha256:8879a398dedf0aadaacfbd332b29ff2f84bc39ae6d4e9c0a1109db27ac5ba012
 AS xx
+
+FROM --platform=$BUILDPLATFORM golang:1.20.4-alpine3.16 AS builder
+
+COPY --from=xx / /
+
+RUN apk add --update alpine-sdk ca-certificates openssl clang lld
+
+ARG TARGETPLATFORM
+
+RUN xx-apk --update add musl-dev gcc
+
+# lld has issues building static binaries for ppc so prefer ld for it
+RUN [ "$(xx-info arch)" != "ppc64le" ] || XX_CC_PREFER_LINKER=ld xx-clang 
--setup-target-triple
+
+RUN xx-go --wrap
+
+WORKDIR /usr/local/src/dex
+
+ARG GOPROXY
+
+ENV CGO_ENABLED=1
+
+COPY go.mod go.sum ./
+COPY api/v2/go.mod api/v2/go.sum ./api/v2/
+RUN go mod download
+
+COPY . .
+
+RUN make release-binary
+RUN xx-verify /go/bin/dex && xx-verify /go/bin/docker-entrypoint
+
+FROM alpine:3.18.2 AS stager
+
+RUN mkdir -p /var/dex
+RUN mkdir -p /etc/dex
+COPY config.docker.yaml /etc/dex/
+
+FROM alpine:3.18.2 AS gomplate
+
+ARG TARGETOS
+ARG TARGETARCH
+ARG TARGETVARIANT
+
+ENV GOMPLATE_VERSION=v3.11.4
+
+RUN wget -O /usr/local/bin/gomplate \
+  
"https://github.com/hairyhenderson/gomplate/releases/download/${GOMPLATE_VERSION}/gomplate_${TARGETOS:-linux}-${TARGETARCH:-amd64}${TARGETVARIANT}";
 \
+  && chmod +x /usr/local/bin/gomplate
+
+# For Dependabot to detect base image versions
+FROM alpine:3.18.2 AS alpine
+FROM gcr.io/distroless/static:latest AS distroless
+
+FROM $BASE_IMAGE
+
+# Dex connectors, such as GitHub and Google logins require root certificates.
+# Proper installations should manage those certificates, but it's a bad user
+# experience when this doesn't work out of the box.
+#
+# See https://go.dev/src/crypto/x509/root_linux.go for Go root CA bundle 
locations.
+COPY --from=builder /etc/ssl/certs/ca-certificates.crt 
/etc/ssl/certs/ca-certificates.crt
+
+COPY --from=stager --chown=1001:1001 /var/dex /var/dex
+COPY --from=stager --chown=1001:1001 /etc/dex /etc/dex
+
+# Copy module files for CVE scanning / dependency analysis.
+COPY --from=builder /usr/local/src/dex/go.mod /usr/local/src/dex/go.sum 
/usr/local/src/dex/
+COPY --from=builder /usr/local/src/dex/api/v2/go.mod 
/usr/local/src/dex/api/v2/go.sum /usr/local/src/dex/api/v2/
+
+COPY --from=builder /go/bin/dex /usr/local/bin/dex
+COPY --from=builder /go/bin/docker-entrypoint /usr/local/bin/docker-entrypoint
+COPY --from=builder /usr/local/src/dex/web /srv/dex/web
+
+COPY --from=gomplate /usr/local/bin/gomplate /usr/local/bin/gomplate
+
+USER 1001:1001
+
+ENTRYPOINT ["/usr/local/bin/docker-entrypoint"]
+CMD ["dex", "serve", "/etc/dex/config.docker.yaml"]
+`,
+                       expected: `
+ARG BASE_IMAGE=alpine
+
+FROM --platform=$BUILDPLATFORM 
tonistiigi/xx:1.2.1@sha256:8879a398dedf0aadaacfbd332b29ff2f84bc39ae6d4e9c0a1109db27ac5ba012
 AS xx
+
+FROM --platform=$BUILDPLATFORM 
index.docker.io/library/golang:1.20.4-alpine3.16@sha256:6469405d7297f82d56195c90a3270b0806ef4bd897aa0628477d9959ab97a577
 AS builder
+
+COPY --from=xx / /
+
+RUN apk add --update alpine-sdk ca-certificates openssl clang lld
+
+ARG TARGETPLATFORM
+
+RUN xx-apk --update add musl-dev gcc
+
+# lld has issues building static binaries for ppc so prefer ld for it
+RUN [ "$(xx-info arch)" != "ppc64le" ] || XX_CC_PREFER_LINKER=ld xx-clang 
--setup-target-triple
+
+RUN xx-go --wrap
+
+WORKDIR /usr/local/src/dex
+
+ARG GOPROXY
+
+ENV CGO_ENABLED=1
+
+COPY go.mod go.sum ./
+COPY api/v2/go.mod api/v2/go.sum ./api/v2/
+RUN go mod download
+
+COPY . .
+
+RUN make release-binary
+RUN xx-verify /go/bin/dex && xx-verify /go/bin/docker-entrypoint
+
+FROM 
index.docker.io/library/alpine:3.18.2@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1
 AS stager
+
+RUN mkdir -p /var/dex
+RUN mkdir -p /etc/dex
+COPY config.docker.yaml /etc/dex/
+
+FROM 
index.docker.io/library/alpine:3.18.2@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1
 AS gomplate
+
+ARG TARGETOS
+ARG TARGETARCH
+ARG TARGETVARIANT
+
+ENV GOMPLATE_VERSION=v3.11.4
+
+RUN wget -O /usr/local/bin/gomplate \
+  
"https://github.com/hairyhenderson/gomplate/releases/download/${GOMPLATE_VERSION}/gomplate_${TARGETOS:-linux}-${TARGETARCH:-amd64}${TARGETVARIANT}";
 \
+  && chmod +x /usr/local/bin/gomplate
+
+# For Dependabot to detect base image versions
+FROM 
index.docker.io/library/alpine:3.18.2@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1
 AS alpine
+FROM gcr.io/distroless/static:latest AS distroless
+
+FROM $BASE_IMAGE
+
+# Dex connectors, such as GitHub and Google logins require root certificates.
+# Proper installations should manage those certificates, but it's a bad user
+# experience when this doesn't work out of the box.
+#
+# See https://go.dev/src/crypto/x509/root_linux.go for Go root CA bundle 
locations.
+COPY --from=builder /etc/ssl/certs/ca-certificates.crt 
/etc/ssl/certs/ca-certificates.crt
+
+COPY --from=stager --chown=1001:1001 /var/dex /var/dex
+COPY --from=stager --chown=1001:1001 /etc/dex /etc/dex
+
+# Copy module files for CVE scanning / dependency analysis.
+COPY --from=builder /usr/local/src/dex/go.mod /usr/local/src/dex/go.sum 
/usr/local/src/dex/
+COPY --from=builder /usr/local/src/dex/api/v2/go.mod 
/usr/local/src/dex/api/v2/go.sum /usr/local/src/dex/api/v2/
+
+COPY --from=builder /go/bin/dex /usr/local/bin/dex
+COPY --from=builder /go/bin/docker-entrypoint /usr/local/bin/docker-entrypoint
+COPY --from=builder /usr/local/src/dex/web /srv/dex/web
+
+COPY --from=gomplate /usr/local/bin/gomplate /usr/local/bin/gomplate
+
+USER 1001:1001
+
+ENTRYPOINT ["/usr/local/bin/docker-entrypoint"]
+CMD ["dex", "serve", "/etc/dex/config.docker.yaml"]
+`,
                        modified: true,
                },
        }
+
        for _, tt := range testCases {
                tt := tt
                t.Run(tt.name, func(t *testing.T) {
                        t.Parallel()
                        ctx := context.Background()
-                       r := NewContainerImagesReplacer(&config.Config{})
+                       r := NewContainerImagesReplacer(&config.Config{
+                               Images: config.Images{
+                                       ImageFilter: config.ImageFilter{
+                                               ExcludeTags: []string{"latest"},
+                                       },
+                               },
+                       })
                        modified, newContent, err := r.ParseFile(ctx, 
strings.NewReader(tt.before))
                        if tt.wantErr {
                                require.False(t, modified)
@@ -552,6 +802,41 @@
                        wantErr:  false,
                },
                {
+                       name: "Replace actions with tags, not with branches",
+                       before: `
+name: Linter
+on: pull_request
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: ./minder/server.yml # this should not be replaced
+      - uses: actions/checkout@v2
+      - uses: aquasecurity/trivy-action@main
+      - name: "Run Markdown linter"
+        uses: docker://avtodev/markdown-lint:v1
+        with:
+          args: src/*.md
+`,
+                       expected: `
+name: Linter
+on: pull_request
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: ./minder/server.yml # this should not be replaced
+      - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2
+      - uses: aquasecurity/trivy-action@main
+      - name: "Run Markdown linter"
+        uses: 
docker://index.docker.io/avtodev/markdown-lint@sha256:6aeedc2f49138ce7a1cd0adffc1b1c0321b841dc2102408967d9301c031949ee
 # v1
+        with:
+          args: src/*.md
+`,
+                       modified: true,
+                       wantErr:  false,
+               },
+               {
                        name: "No action reference modification",
                        before: `
 name: Linter
@@ -667,7 +952,13 @@
                t.Run(tt.name, func(t *testing.T) {
                        t.Parallel()
                        ctx := context.Background()
-                       r := 
NewGitHubActionsReplacer(&config.Config{}).WithGitHubClientFromToken(os.Getenv(cli.GitHubTokenEnvKey))
+                       r := NewGitHubActionsReplacer(&config.Config{
+                               GHActions: config.GHActions{
+                                       Filter: config.Filter{
+                                               ExcludeBranches: []string{"*"},
+                                       },
+                               },
+                       
}).WithGitHubClientFromToken(os.Getenv(cli.GitHubTokenEnvKey))
                        if tt.useCustomRegex {
                                r = r.WithUserRegex(tt.regex)
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/pkg/utils/config/config.go 
new/frizbee-0.1.2/pkg/utils/config/config.go
--- old/frizbee-0.0.16/pkg/utils/config/config.go       2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/pkg/utils/config/config.go        2024-08-27 
10:24:18.000000000 +0200
@@ -22,6 +22,7 @@
        "io"
        "os"
        "path/filepath"
+       "slices"
 
        "github.com/go-git/go-billy/v5"
        "github.com/go-git/go-billy/v5/osfs"
@@ -59,6 +60,7 @@
 type Config struct {
        Platform  string    `yaml:"platform" mapstructure:"platform"`
        GHActions GHActions `yaml:"ghactions" mapstructure:"ghactions"`
+       Images    Images    `yaml:"images" mapstructure:"images"`
 }
 
 // GHActions is the GitHub Actions configuration.
@@ -69,7 +71,20 @@
 // Filter is a common configuration for filtering out patterns.
 type Filter struct {
        // Exclude is a list of patterns to exclude.
-       Exclude []string `yaml:"exclude" mapstructure:"exclude"`
+       Exclude         []string `yaml:"exclude" mapstructure:"exclude"`
+       ExcludeBranches []string `yaml:"exclude_branches" 
mapstructure:"exclude_branches"`
+}
+
+// Images is the image configuration.
+type Images struct {
+       ImageFilter `yaml:",inline" mapstructure:",inline"`
+}
+
+// ImageFilter is the image filter configuration.
+type ImageFilter struct {
+       // ExcludeImages is a regex that must match in order for an image to be 
excluded and not pinned
+       ExcludeImages []string `yaml:"exclude_images" 
mapstructure:"exclude_images"`
+       ExcludeTags   []string `yaml:"exclude_tags" mapstructure:"exclude_tags"`
 }
 
 // ParseConfigFile parses a configuration file.
@@ -78,9 +93,44 @@
        return ParseConfigFileFromFS(bfs, configfile)
 }
 
+// DefaultConfig returns the default configuration.
+func DefaultConfig() *Config {
+       return &Config{
+               GHActions: GHActions{
+                       Filter: Filter{
+                               ExcludeBranches: []string{"main", "master"},
+                       },
+               },
+               Images: Images{
+                       ImageFilter: ImageFilter{
+                               ExcludeImages: []string{"scratch"},
+                               ExcludeTags:   []string{"latest"},
+                       },
+               },
+       }
+}
+
+// MergeUserConfig merges the user configuration with the default 
configuration.
+// mostly making sure that we don't try to pin the scratch image
+func MergeUserConfig(userConfig *Config) *Config {
+       if userConfig == nil {
+               return DefaultConfig()
+       }
+
+       if userConfig.Images.ExcludeImages == nil {
+               userConfig.Images.ExcludeImages = []string{"scratch"}
+       }
+
+       if !slices.Contains(userConfig.Images.ExcludeImages, "scratch") {
+               userConfig.Images.ExcludeImages = 
append(userConfig.Images.ExcludeImages, "scratch")
+       }
+
+       return userConfig
+}
+
 // ParseConfigFileFromFS parses a configuration file from a filesystem.
 func ParseConfigFileFromFS(fs billy.Filesystem, configfile string) (*Config, 
error) {
-       cfg := &Config{}
+       cfg := DefaultConfig()
        cleancfgfile := filepath.Clean(configfile)
        cfgF, err := fs.Open(cleancfgfile)
        if err != nil {
@@ -94,10 +144,9 @@
 
        dec := yaml.NewDecoder(cfgF)
        if err := dec.Decode(cfg); err != nil {
-               if err == io.EOF {
-                       return cfg, nil
+               if err != io.EOF {
+                       return nil, fmt.Errorf("failed to decode config file: 
%w", err)
                }
-               return nil, fmt.Errorf("failed to decode config file: %w", err)
        }
 
        return cfg, nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/frizbee-0.0.16/pkg/utils/config/config_test.go 
new/frizbee-0.1.2/pkg/utils/config/config_test.go
--- old/frizbee-0.0.16/pkg/utils/config/config_test.go  2024-06-04 
09:27:11.000000000 +0200
+++ new/frizbee-0.1.2/pkg/utils/config/config_test.go   2024-08-27 
10:24:18.000000000 +0200
@@ -82,7 +82,7 @@
                {
                        name:           "FileNotFound",
                        fileName:       "nonexistent.yaml",
-                       expectedResult: &Config{},
+                       expectedResult: DefaultConfig(),
                },
                {
                        name:        "InvalidYaml",
@@ -91,6 +91,31 @@
                        expectError: true,
                },
                {
+                       name:     "DontIngoreBranches",
+                       fileName: "dont_ignore_branches.yaml",
+                       fsContent: map[string]string{
+                               "dont_ignore_branches.yaml": `
+platform: linux/amd64
+ghactions:
+  exclude_branches:
+`,
+                       },
+                       expectedResult: &Config{
+                               Platform: "linux/amd64",
+                               GHActions: GHActions{
+                                       Filter: Filter{
+                                               ExcludeBranches: []string{},
+                                       },
+                               },
+                               Images: Images{
+                                       ImageFilter: ImageFilter{
+                                               ExcludeImages: 
[]string{"scratch"},
+                                               ExcludeTags:   
[]string{"latest"},
+                                       },
+                               },
+                       },
+               },
+               {
                        name:     "ValidYaml",
                        fileName: "valid.yaml",
                        fsContent: map[string]string{
@@ -100,13 +125,25 @@
   exclude:
     - pattern1
     - pattern2
+images:
+  exclude_images:
+    - notthisone
+  exclude_tags:
+    - notthistag       
 `,
                        },
                        expectedResult: &Config{
                                Platform: "linux/amd64",
                                GHActions: GHActions{
                                        Filter: Filter{
-                                               Exclude: []string{"pattern1", 
"pattern2"},
+                                               Exclude:         
[]string{"pattern1", "pattern2"},
+                                               ExcludeBranches: 
[]string{"main", "master"},
+                                       },
+                               },
+                               Images: Images{
+                                       ImageFilter: ImageFilter{
+                                               ExcludeImages: 
[]string{"notthisone"},
+                                               ExcludeTags:   
[]string{"notthistag"},
                                        },
                                },
                        },
@@ -115,7 +152,7 @@
                        name:           "EmptyFile",
                        fileName:       "empty.yaml",
                        fsContent:      map[string]string{"empty.yaml": ""},
-                       expectedResult: &Config{},
+                       expectedResult: DefaultConfig(),
                },
        }
 
@@ -141,6 +178,15 @@
                                if cfg.GHActions.Exclude != nil {
                                        require.Equal(t, 
tt.expectedResult.GHActions.Exclude, cfg.GHActions.Exclude)
                                }
+                               if cfg.Images.ExcludeImages != nil {
+                                       require.Equal(t, 
tt.expectedResult.Images.ExcludeImages, cfg.Images.ExcludeImages)
+                               }
+                               if cfg.Images.ExcludeTags != nil {
+                                       require.Equal(t, 
tt.expectedResult.Images.ExcludeTags, cfg.Images.ExcludeTags)
+                               }
+                               if cfg.GHActions.ExcludeBranches != nil {
+                                       require.Equal(t, 
tt.expectedResult.GHActions.ExcludeBranches, cfg.GHActions.ExcludeBranches)
+                               }
                        }
                })
        }

++++++ frizbee.obsinfo ++++++
--- /var/tmp/diff_new_pack.D58Xb0/_old  2024-09-10 21:15:34.591895182 +0200
+++ /var/tmp/diff_new_pack.D58Xb0/_new  2024-09-10 21:15:34.599895516 +0200
@@ -1,5 +1,5 @@
 name: frizbee
-version: 0.0.16
-mtime: 1717486031
-commit: 181f1567cfeaf5998c4922deb3b73cbcb06af694
+version: 0.1.2
+mtime: 1724747058
+commit: 227081dd83c913a7aae818196a5124bd2c01eb62
 

++++++ vendor.tar.gz ++++++
++++ 77907 lines of diff (skipped)

Reply via email to