From d158ec0e69829cce61dc28d5ffc52b271df87b87 Mon Sep 17 00:00:00 2001 From: Robin Breathe Date: Mon, 13 Jul 2026 09:06:06 +0200 Subject: [PATCH 1/2] ci: publish Homebrew bottles with gobottle and attest all release artefacts Replace goreleaser's brews: formula publishing with gobottle: goreleaser keeps building the GitHub release archives, and gobottle bottles the exact binaries it built (--source local), pushes them to GHCR, and commits the formula to isometry/homebrew-tap. Attest provenance for every distribution surface: release archives, checksums, raw binaries, and bottle tarballs. Harden CI dependencies: - pin all workflow actions to commit SHAs - group all github-actions dependabot updates into a single PR - restrict gomod dependabot to security-only updates Document Homebrew installation (brew trust + install) and attestation verification in the README. Co-Authored-By: Claude Fable 5 --- .github/dependabot.yml | 11 ++++++----- .github/workflows/codecov.yml | 2 +- .github/workflows/codeql.yml | 8 ++++---- .github/workflows/release.yml | 31 +++++++++++++++++++++++++------ .gitignore | 1 + .gobottle.yaml | 11 +++++++++++ .goreleaser.yml | 12 ------------ README.md | 17 +++++++++++++++++ 8 files changed, 65 insertions(+), 28 deletions(-) create mode 100644 .gobottle.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 731f404..4931b1f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,12 +6,13 @@ updates: directory: "/" schedule: interval: "weekly" + groups: + github-actions: + patterns: + - "*" - package-ecosystem: "gomod" directory: "/" schedule: interval: "weekly" - groups: - "aws-sdk-go-v2": - patterns: - - "github.com/aws/aws-sdk-go-v2" - - "github.com/aws/aws-sdk-go-v2/*" + # Security-only: disables version updates while security updates continue + open-pull-requests-limit: 0 diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index c6aa1b5..b76d2ce 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -13,6 +13,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5c646f9..b21dadf 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -25,11 +25,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v7 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 with: languages: ${{ matrix.language }} @@ -40,9 +40,9 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v4 + uses: github/codeql-action/autobuild@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e9150cb..909f6de 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: goreleaser +name: release on: push: @@ -6,22 +6,41 @@ on: - "*" jobs: - goreleaser: + release: runs-on: ubuntu-latest + permissions: + contents: write + packages: write + id-token: write + attestations: write steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version-file: go.mod - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v7 + uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 with: version: latest args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }} + - name: Set up gobottle + uses: isometry/gobottle-setup@c7fe02d3fd382ccf59387747aaec4686c2281475 # v1.0.0 + - name: Publish bottles and update tap + run: gobottle release --source local + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GOBOTTLE_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }} + - name: Attest build provenance + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 + with: + subject-path: | + dist/*.zip + dist/*_SHA256SUMS + dist/*/docker-credential-env* + bottles/*.tar.gz diff --git a/.gitignore b/.gitignore index a34dbe9..73620b8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +bottles dist docker-credential-env diff --git a/.gobottle.yaml b/.gobottle.yaml new file mode 100644 index 0000000..b4d375a --- /dev/null +++ b/.gobottle.yaml @@ -0,0 +1,11 @@ +formula: + name: docker-credential-env + description: Environment-driven Docker credential helper + homepage: https://just.breathe.io/project/docker-credential-env/ + license: MIT + +source: + type: local + +tap: + owner: isometry diff --git a/.goreleaser.yml b/.goreleaser.yml index f236431..e2d01c2 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -39,15 +39,3 @@ changelog: exclude: - "^docs:" - "^test:" -brews: - - repository: - owner: isometry - name: homebrew-tap - token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" - directory: Formula - description: Environment-driven Docker credential helper - homepage: https://just.breathe.io/project/docker-credential-env/ - test: | - system "#{bin}/docker-credential-env --version" - install: | - bin.install "docker-credential-env" diff --git a/README.md b/README.md index fb30e2c..67fb821 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,23 @@ Hyphens within DNS labels are transformed to underscores (`s/-/_/g`) for credent Set the environment variable `DOCKER_CREDENTIAL_ENV_DEBUG=true` to enable diagnostic output. When enabled, the helper will print information about credential sources to stderr, which can help troubleshoot authentication issues, especially with AWS ECR repositories. +## Installation + +Install with [Homebrew](https://brew.sh) (bottles are published for all supported macOS and Linux platforms): + +```bash +brew trust isometry/tap # once, required on Homebrew ≥6 +brew install isometry/tap/docker-credential-env +``` + +Installed binaries carry build provenance and can be verified with: + +```bash +gh attestation verify "$(brew --prefix)/bin/docker-credential-env" --repo isometry/docker-credential-env +``` + +Alternatively, download a pre-built archive from the [releases page](https://github.com/isometry/docker-credential-env/releases) or `go install github.com/isometry/docker-credential-env@latest`. + ## Configuration The `docker-credential-env` binary must be installed to `$PATH`, and is enabled via `~/.docker/config.json` (or `$DOCKER_CONFIG/config.json` if the `DOCKER_CONFIG` environment variable is set): From de812a13b6e832cee110b40e682d8870b6d0f8cc Mon Sep 17 00:00:00 2001 From: Robin Breathe Date: Mon, 13 Jul 2026 09:06:45 +0200 Subject: [PATCH 2/2] chore(deps): bump go dependencies --- go.mod | 10 +++++----- go.sum | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index ba68372..6a95a85 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/isometry/docker-credential-env -go 1.26.1 +go 1.26.5 require ( github.com/aws/aws-sdk-go-v2 v1.42.1 - github.com/aws/aws-sdk-go-v2/config v1.32.28 - github.com/aws/aws-sdk-go-v2/credentials v1.19.27 + github.com/aws/aws-sdk-go-v2/config v1.32.29 + github.com/aws/aws-sdk-go-v2/credentials v1.19.28 github.com/aws/aws-sdk-go-v2/service/ecr v1.59.0 github.com/aws/aws-sdk-go-v2/service/sts v1.44.0 github.com/docker/cli v29.6.1+incompatible @@ -20,12 +20,12 @@ require ( github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.31 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30 // indirect - github.com/aws/aws-sdk-go-v2/service/signin v1.3.0 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.4.0 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.32.0 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.37.0 // indirect github.com/aws/smithy-go v1.27.3 // indirect github.com/sirupsen/logrus v1.9.4 // indirect - golang.org/x/sys v0.42.0 // indirect + golang.org/x/sys v0.47.0 // indirect gotest.tools/v3 v3.5.2 // indirect ) diff --git a/go.sum b/go.sum index 0c35797..f3ab291 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ github.com/aws/aws-sdk-go-v2 v1.42.1 h1:9eOTgu1z/dVtYpNZ3/8/XbbaX0x/BqE3HUzAzs6K0ek= github.com/aws/aws-sdk-go-v2 v1.42.1/go.mod h1:5pKeft2eJj+gElQ38Jqg4ibCqh+/AK33/0X3hip7IjM= -github.com/aws/aws-sdk-go-v2/config v1.32.28 h1:qY6afygxK5c2PPU3Sz8W6yB5W44RF1vnmPdBwViDN+Y= -github.com/aws/aws-sdk-go-v2/config v1.32.28/go.mod h1:WeS/wN1IDs8YC+BxTrFz9ZyJ1rufRBQfirOcDusEpmQ= -github.com/aws/aws-sdk-go-v2/credentials v1.19.27 h1:cFksKkdaBGGmpe6XJpvrxFNWkbXY5/gwFqZNB2O9WCM= -github.com/aws/aws-sdk-go-v2/credentials v1.19.27/go.mod h1:20CoObBgNhFfl8/ggDQu2IZmItxDhkLcWSy4C3alDPI= +github.com/aws/aws-sdk-go-v2/config v1.32.29 h1:BcMHHnpiWKogf+gGfpj3K1w+Sktz29XDo/cPSAPO3FU= +github.com/aws/aws-sdk-go-v2/config v1.32.29/go.mod h1:+Kbhn8Es4kPUph3F/0W7avykytc+Jh2Ld9/msv9ljV4= +github.com/aws/aws-sdk-go-v2/credentials v1.19.28 h1:zTXJSsNcoO91/mTXsZoYf0AK8dvNPiA58/VtyGXR+wM= +github.com/aws/aws-sdk-go-v2/credentials v1.19.28/go.mod h1:Kd9E0JzDBW/q1xbsHFrev/GnbAf5J0Ng8xoyc7HZ91Q= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.30 h1:/hi1JADLEW9YYryEz1w4GQu0EtP23pP553Cf9KgsDV4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.30/go.mod h1:/3AOgy4K17Dm4ucMZVC/MJkzy5kmfKUcINRHZyo0koQ= github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30 h1:xM/Is9cKMHa8Jj8zkvWhvrFkZsXJV9E+BB4g0HW0duQ= @@ -18,8 +18,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13 h1:mbRIur github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13/go.mod h1:ITg9em2KbJx1s0y4aqRX5OYWG6HBZ5TVR//OdpEZ2CQ= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30 h1:/Z5jmNrKsSD7EmDjzAPsm/3L9IuOkzaynklJZ1qX7S4= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30/go.mod h1:lEzEZnOosE7zi8Z6royW1cFJTD9fpab4Ul1SBrllewk= -github.com/aws/aws-sdk-go-v2/service/signin v1.3.0 h1:i0+tbB9QBnzL5NrF2WR/zk8q2s+1N+RaDYr2627E8UI= -github.com/aws/aws-sdk-go-v2/service/signin v1.3.0/go.mod h1:mxC0nT/C8wMMS97DemZPzvUZxvIt+2Iq+eS3JdFZGgg= +github.com/aws/aws-sdk-go-v2/service/signin v1.4.0 h1:sLzmJGCMv+C8KqiJgEqDLB6vxaJGmobRh4rr//ZpA3w= +github.com/aws/aws-sdk-go-v2/service/signin v1.4.0/go.mod h1:mxC0nT/C8wMMS97DemZPzvUZxvIt+2Iq+eS3JdFZGgg= github.com/aws/aws-sdk-go-v2/service/sso v1.32.0 h1:qjMmry/cBDee1E/2gyvel0uRYCi3mwRZ2hf6N+GAodo= github.com/aws/aws-sdk-go-v2/service/sso v1.32.0/go.mod h1:u8af9Nqkmqnr96f7v9nHqzZT9XBwbXEkTiqT4ROuJSE= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.37.0 h1:fpOlDPI55HdszaxapEGk6HsGosOUaM2YPWJpjMgp8UI= @@ -46,7 +46,7 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=