Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ on:

permissions: {}

env:
# renovate: datasource=github-releases depName=goreleaser/goreleaser
GORELEASER_VERSION: v1.25.1

concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
Expand Down Expand Up @@ -55,6 +59,8 @@ jobs:
permissions:
contents: read
env:
# renovate: datasource=go depName=github.com/google/go-licenses
GO_LICENSES_VERSION: v1.6.0
REPORT_FILE: gl-license-scanning-report.json

steps:
Expand All @@ -67,7 +73,7 @@ jobs:
cache: false
- name: License scanning
run: |
go install github.com/google/go-licenses@v1.6.0
scripts/install-go-tool.sh "github.com/google/go-licenses@${GO_LICENSES_VERSION}"
go-licenses check . --disallowed_types=forbidden,restricted
- name: Generate license report
run: |
Expand Down Expand Up @@ -99,7 +105,7 @@ jobs:
# either 'goreleaser' (default) or 'goreleaser-pro'
distribution: goreleaser
# 'latest', 'nightly', or a semver
version: v1.25.1
version: ${{ env.GORELEASER_VERSION }}
args: check

test:
Expand All @@ -120,7 +126,9 @@ jobs:
go-version-file: go.mod
cache: false
- name: Run tests
run: go test -v ./...
run: |
scripts/install-go-tool-test.sh
go test -v ./...

security:
name: GoReleaser artifacts - govulncheck, Trivy secrets/vulns, Grype
Expand All @@ -129,6 +137,7 @@ jobs:
permissions:
contents: read
env:
# renovate: datasource=go depName=golang.org/x/vuln
GOVULNCHECK_VERSION: v1.6.0

steps:
Expand All @@ -142,7 +151,7 @@ jobs:
- name: Test govulncheck warning and error handling
run: scripts/govulncheck-inform-test.sh
- name: Install govulncheck
run: go install "golang.org/x/vuln/cmd/govulncheck@${GOVULNCHECK_VERSION}"
run: scripts/install-go-tool.sh "golang.org/x/vuln/cmd/govulncheck@${GOVULNCHECK_VERSION}"
- name: Report reachable Go vulnerabilities in the source
run: scripts/govulncheck-inform.sh ./...
- name: Test that the symbol-table guard rejects a stripped binary
Expand All @@ -151,7 +160,7 @@ jobs:
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
with:
distribution: goreleaser
version: v1.25.1
version: ${{ env.GORELEASER_VERSION }}
args: release --snapshot --clean --skip=publish
- name: Verify and prepare all release artifacts
run: scripts/prepare-artifact-scan-rootfs.sh
Expand Down Expand Up @@ -211,7 +220,7 @@ jobs:
# either 'goreleaser' (default) or 'goreleaser-pro'
distribution: goreleaser
# 'latest', 'nightly', or a semver
version: v1.25.1
version: ${{ env.GORELEASER_VERSION }}
args: release
- name: Write latest version to file
run: mkdir -p dist && echo "${TAG}" > dist/LATEST_VERSION
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/renovate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Renovate

on:
schedule:
- cron: "0 5 * * *"
- cron: "0 0 * * *"
workflow_dispatch:

permissions: {}
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -458,9 +458,16 @@ This project uses GitHub Actions and GoReleaser for automated releases:
### Dependency updates

Renovate runs daily and keeps compiler updates separate from library updates.
GitHub Actions patches, minors, and digest updates use a separate automerge PR.
Major action upgrades require manual review.
CI tools use a separate manual group; their major upgrades get individual PRs.
Module patches and `golang.org/x/*` module minors share one library PR.
Manual AWS SDK and Kubernetes client updates have separate groups.
Other manual module updates get individual PRs.
Compiler updates stay within the release line declared in `renovate.json`.
Module candidates that declare a newer required Go release line are filtered out.
CI rejects a module update that selects a compiler from another release line.
Manual groups rebase only when conflicting; automatic groups stay current with main.
The shared approval action approves verified Renovate commits with native automerge enabled.
GitHub requires the existing CI checks and an approving review before merging.
Compiler patches and the library group use native automerge after artifact validation and App approval.
Expand Down Expand Up @@ -491,7 +498,7 @@ go test ./...
Test the Renovate rules against an installed Renovate distribution:

```bash
mise exec -- node scripts/renovate-config-test.cjs /path/to/renovate/dist
mise exec -- node scripts/renovate-config-test.cjs /path/to/renovate/dist /path/to/renovate-config
```

### Linting
Expand Down
82 changes: 79 additions & 3 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,85 @@
"rebaseWhen": "behind-base-branch",
"packageRules": [
{
"description": "Track direct and indirect Go module updates",
"description": "Review major upgrades separately without rebasing for unrelated changes",
"matchUpdateTypes": ["major"],
"groupName": null,
"groupSlug": null,
"automerge": false,
"rebaseWhen": "conflicted"
},
{
"description": "Automerge compatible action updates after required CI and App approval",
"matchManagers": ["github-actions"],
"matchDepTypes": ["action"],
"matchUpdateTypes": ["patch", "minor", "digest", "pin", "pinDigest"],
"groupName": "GitHub Actions",
"groupSlug": "github-actions",
"automerge": true,
"automergeType": "pr",
"platformAutomerge": true
},
{
"description": "Review CI tool updates separately from action references",
"matchManagers": ["github-actions", "custom.regex"],
"matchPackageNames": [
"golangci/golangci-lint",
"goreleaser/goreleaser",
"github.com/google/go-licenses",
"golang.org/x/vuln"
],
"matchUpdateTypes": ["patch", "minor", "digest", "pin", "pinDigest"],
"groupName": "CI tools",
"groupSlug": "ci-tools",
"automerge": false,
"rebaseWhen": "conflicted"
},
{
"description": "Track Go modules compatible with the approved compiler release line",
"matchManagers": ["gomod"],
"matchDepTypes": ["require", "indirect", "replace"],
"enabled": true,
"constraintsFiltering": "strict",
"constraints": {
"%goMod": ">=1.0.0 <1.27.0"
},
"constraintsVersioning": {
"%goMod": "semver-coerced"
}
},
{
"description": "Review other module minors individually without rebasing for unrelated changes",
"matchManagers": ["gomod"],
"matchDepTypes": ["require", "indirect", "replace"],
"enabled": true
"matchUpdateTypes": ["minor"],
"groupName": null,
"groupSlug": null,
"automerge": false,
"rebaseWhen": "conflicted"
},
{
"description": "Review coupled AWS SDK updates together",
"matchManagers": ["gomod"],
"matchDepTypes": ["require", "indirect", "replace"],
"matchPackageNames": ["github.com/aws/aws-sdk-go-v2{,/**}", "github.com/aws/smithy-go"],
"matchUpdateTypes": ["minor", "major"],
"groupName": "AWS Go SDK",
"groupSlug": "go-aws-sdk",
"group": {
"branchTopic": "go-aws-sdk"
}
},
{
"description": "Review coupled Kubernetes clients and schema migrations together",
"matchManagers": ["gomod"],
"matchDepTypes": ["require", "indirect", "replace"],
"matchPackageNames": ["k8s.io/**", "sigs.k8s.io/**"],
"matchUpdateTypes": ["minor", "major"],
"groupName": "Kubernetes Go clients",
"groupSlug": "go-kubernetes",
"group": {
"branchTopic": "go-kubernetes"
}
},
{
"description": "Keep automerged patches available alongside manual module minors",
Expand Down Expand Up @@ -64,7 +139,8 @@
"groupSlug": "go-libraries",
"automerge": true,
"automergeType": "pr",
"platformAutomerge": true
"platformAutomerge": true,
"rebaseWhen": "behind-base-branch"
}
]
}
48 changes: 48 additions & 0 deletions scripts/install-go-tool-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bash

set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
test_dir="$(mktemp -d)"
trap 'rm -rf "${test_dir}"' EXIT
export test_dir

go() {
printf '%s\0' "$@" > "${test_dir}/args"
cmp "${test_dir}/expected-args" "${test_dir}/args" || return 99
local attempt
attempt="$(cat "${test_dir}/attempts")"
attempt=$((attempt + 1))
echo "${attempt}" > "${test_dir}/attempts"
if [[ "${attempt}" -le "${failures}" ]]; then
return "$((40 + attempt))"
fi
}

sleep() {
[[ "$#" -eq 1 && "$1" == 2 ]] || return 99
echo "$1" >> "${test_dir}/sleeps"
}
export -f go sleep

args=(-tags "tag with spaces" "" "example.com/tool*@\$version")
printf '%s\0' install "${args[@]}" > "${test_dir}/expected-args"

for failures in 0 1 2 3; do
export failures
echo 0 > "${test_dir}/attempts"
: > "${test_dir}/sleeps"
actual=0
"${script_dir}/install-go-tool.sh" "${args[@]}" || actual=$?
expected=0
attempts=$((failures + 1))
if [[ "${failures}" -eq 3 ]]; then
expected=43
attempts=3
fi
[[ "${actual}" -eq "${expected}" ]]
[[ "$(cat "${test_dir}/attempts")" -eq "${attempts}" ]]
[[ "$(wc -l < "${test_dir}/sleeps")" -eq $((attempts - 1)) ]]
done

echo "PASS: bounded retries, final failure status, delays, and arguments are preserved"
16 changes: 16 additions & 0 deletions scripts/install-go-tool.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash

set -euo pipefail

for attempt in 1 2 3; do
if go install "$@"; then
exit 0
else
status=$?
fi
if [[ "${attempt}" -eq 3 ]]; then
exit "${status}"
fi
echo "Go tool installation failed (attempt ${attempt}/3); retrying in 2 seconds" >&2
sleep 2
done
Loading
Loading