-
Notifications
You must be signed in to change notification settings - Fork 5
Add automated Go version update workflow and version schemas #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,179 @@ | ||||||||||||||||||||||||||||||||||||||
| name: Update Go Version | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||
| workflow_call: | ||||||||||||||||||||||||||||||||||||||
| inputs: | ||||||||||||||||||||||||||||||||||||||
| version-schema: | ||||||||||||||||||||||||||||||||||||||
| description: > | ||||||||||||||||||||||||||||||||||||||
| Version schema key matching a file in go-versions/ (e.g. "ocp-4.21"). | ||||||||||||||||||||||||||||||||||||||
| The workflow fetches go-versions/<version-schema>.yaml from medik8s/.github | ||||||||||||||||||||||||||||||||||||||
| to determine the Go version and CI operator image. | ||||||||||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||||||||
| dry-run: | ||||||||||||||||||||||||||||||||||||||
| description: "If true, only show what would change without creating a PR" | ||||||||||||||||||||||||||||||||||||||
| required: false | ||||||||||||||||||||||||||||||||||||||
| default: false | ||||||||||||||||||||||||||||||||||||||
| type: boolean | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||||||||||||||||||
| pull-requests: write | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||
| update-go: | ||||||||||||||||||||||||||||||||||||||
| name: Update Go version | ||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-24.04 | ||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||
| - name: Checkout operator repo | ||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v6 | ||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Fetch version config from medik8s/.github | ||||||||||||||||||||||||||||||||||||||
| id: config | ||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||
| VERSION_SCHEMA: ${{ inputs.version-schema }} | ||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||
| CONFIG_URL="https://raw.githubusercontent.com/medik8s/.github/main/go-versions/${VERSION_SCHEMA}.yaml" | ||||||||||||||||||||||||||||||||||||||
| HTTP_CODE=$(curl -sL -w "%{http_code}" -o /tmp/go-version.yaml "${CONFIG_URL}") | ||||||||||||||||||||||||||||||||||||||
| if [ "${HTTP_CODE}" != "200" ]; then | ||||||||||||||||||||||||||||||||||||||
| echo "::error::Version schema '${VERSION_SCHEMA}' not found at ${CONFIG_URL} (HTTP ${HTTP_CODE})" | ||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| # Parse simple key: "value" YAML without yq (not pre-installed on runners) | ||||||||||||||||||||||||||||||||||||||
| GO_VERSION=$(grep '^go:' /tmp/go-version.yaml | sed 's/^go: *"\?\([^"]*\)"\?/\1/') | ||||||||||||||||||||||||||||||||||||||
| CI_IMAGE=$(grep '^ci-operator-image:' /tmp/go-version.yaml | sed 's/^ci-operator-image: *"\?\([^"]*\)"\?/\1/') | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if [ -z "${GO_VERSION}" ] || [ -z "${CI_IMAGE}" ]; then | ||||||||||||||||||||||||||||||||||||||
| echo "::error::Failed to parse version config — go='${GO_VERSION}' ci-image='${CI_IMAGE}'" | ||||||||||||||||||||||||||||||||||||||
| cat /tmp/go-version.yaml | ||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| echo "go=${GO_VERSION}" >> "${GITHUB_OUTPUT}" | ||||||||||||||||||||||||||||||||||||||
| echo "ci-image=${CI_IMAGE}" >> "${GITHUB_OUTPUT}" | ||||||||||||||||||||||||||||||||||||||
| echo "Go version: ${GO_VERSION}" | ||||||||||||||||||||||||||||||||||||||
| echo "CI image: ${CI_IMAGE}" | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Check if update needed | ||||||||||||||||||||||||||||||||||||||
| id: check | ||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||
| TARGET_GO: ${{ steps.config.outputs.go }} | ||||||||||||||||||||||||||||||||||||||
| TARGET_CI_IMAGE: ${{ steps.config.outputs.ci-image }} | ||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||
| CURRENT_GO=$(grep '^go ' go.mod | awk '{print $2}') | ||||||||||||||||||||||||||||||||||||||
| HAS_TOOLCHAIN=$(grep -c '^toolchain ' go.mod || true) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| # Detect if go.mod needs changes: | ||||||||||||||||||||||||||||||||||||||
| # - Version mismatch (e.g. 1.24 -> 1.25) | ||||||||||||||||||||||||||||||||||||||
| # - Needs normalization (e.g. 1.25.0 -> 1.25) | ||||||||||||||||||||||||||||||||||||||
| # - Has toolchain directive that should be removed | ||||||||||||||||||||||||||||||||||||||
| if [ "${CURRENT_GO}" != "${TARGET_GO}" ] || [ "${HAS_TOOLCHAIN}" -gt 0 ]; then | ||||||||||||||||||||||||||||||||||||||
| echo "go-update=true" >> "${GITHUB_OUTPUT}" | ||||||||||||||||||||||||||||||||||||||
| echo "Go update needed: '${CURRENT_GO}' -> '${TARGET_GO}' (toolchain present: ${HAS_TOOLCHAIN})" | ||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||
| echo "go-update=false" >> "${GITHUB_OUTPUT}" | ||||||||||||||||||||||||||||||||||||||
| echo "Go version already at ${TARGET_GO}, no toolchain directive" | ||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if [ -f .ci-operator.yaml ]; then | ||||||||||||||||||||||||||||||||||||||
| CURRENT_IMAGE=$(grep '^ *tag:' .ci-operator.yaml | head -1 | sed 's/.*tag: *"\?\([^"]*\)"\?/\1/') | ||||||||||||||||||||||||||||||||||||||
| if [ "${CURRENT_IMAGE}" = "${TARGET_CI_IMAGE}" ]; then | ||||||||||||||||||||||||||||||||||||||
| echo "CI image already at ${TARGET_CI_IMAGE}" | ||||||||||||||||||||||||||||||||||||||
| echo "ci-update=false" >> "${GITHUB_OUTPUT}" | ||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||
| echo "CI image update needed: ${CURRENT_IMAGE} -> ${TARGET_CI_IMAGE}" | ||||||||||||||||||||||||||||||||||||||
| echo "ci-update=true" >> "${GITHUB_OUTPUT}" | ||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+81
to
+89
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win
Using Use the pre-installed 🐛 Proposed fix if [ -f .ci-operator.yaml ]; then
- CURRENT_IMAGE=$(grep 'tag:' .ci-operator.yaml | sed 's/.*tag: *"\?\([^"]*\)"\?/\1/')
+ CURRENT_IMAGE=$(yq '.build_root.image_stream_tag.tag' .ci-operator.yaml)
if [ "${CURRENT_IMAGE}" = "${TARGET_CI_IMAGE}" ]; then📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||
| echo "No .ci-operator.yaml found, skipping CI image update" | ||||||||||||||||||||||||||||||||||||||
| echo "ci-update=false" >> "${GITHUB_OUTPUT}" | ||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Set up Go | ||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-go@v6 | ||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||
| go-version: "${{ steps.config.outputs.go }}" | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Update go.mod | ||||||||||||||||||||||||||||||||||||||
| if: steps.check.outputs.go-update == 'true' | ||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||
| TARGET_GO: ${{ steps.config.outputs.go }} | ||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||
| # Set Go minor version only (e.g. "1.25", not "1.25.0") | ||||||||||||||||||||||||||||||||||||||
| go mod edit -go="${TARGET_GO}" | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| # Remove toolchain directive — patch versions are handled by the builder | ||||||||||||||||||||||||||||||||||||||
| sed -i '/^toolchain /d' go.mod | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+106
to
+109
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This contradicts how every operator actually manages Go versions. All 6 repos use patch versions with
The Recommendation: keep # go-versions/latest.yaml
go: "1.26.5" # full patch version
ci-operator-image: "rhel-9-release-golang-1.26-openshift-5.0"Then replace these lines with: go mod edit -go="${TARGET_GO}" -toolchain="go${TARGET_GO}"
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Acknowledged, will address in a follow-up — need to update the schema to include patch versions first. |
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Update dependencies | ||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||
| # Always run tidy + vendor to pick up dependency security patches, | ||||||||||||||||||||||||||||||||||||||
| # even when the Go version itself hasn't changed | ||||||||||||||||||||||||||||||||||||||
| go mod tidy | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if [ -d vendor ]; then | ||||||||||||||||||||||||||||||||||||||
| go mod vendor | ||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+113
to
+119
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two issues here: 1. It's fine to keep this PR focused on Go + go.sum only, but as a follow-up consider extending the version schema to cover packages, tools, and test framework alignment: # go-versions/latest.yaml
go: "1.26.5"
ci-operator-image: "rhel-9-release-golang-1.26-openshift-5.0"
packages:
- golang.org/x/net@latest
- golang.org/x/sys@latest
# K8s packages follow release branches matching OCP version
- k8s.io/api@release-0.32
- k8s.io/client-go@release-0.32
tools:
kustomize: latest # auto-resolve from GitHub releases
controller-gen: latest
ginkgo: "2.23.4" # must match go.mod
gomega: "1.37.1" # must match go.modKey design points:
2. All 6 operators (excluding CUR) have
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good suggestions for follow-up — keeping this PR focused on Go version + go.sum for now. |
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Update .ci-operator.yaml | ||||||||||||||||||||||||||||||||||||||
| if: steps.check.outputs.ci-update == 'true' | ||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||
| TARGET_CI_IMAGE: ${{ steps.config.outputs.ci-image }} | ||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||
| sed -i "s|^\( tag: \).*|\1${TARGET_CI_IMAGE}|" .ci-operator.yaml | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+125
to
+127
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Incorrect indentation assumption in The regex Use 🐛 Proposed fix env:
TARGET_CI_IMAGE: ${{ steps.config.outputs.ci-image }}
run: |
- sed -i "s|^\( tag: \).*|\1${TARGET_CI_IMAGE}|" .ci-operator.yaml
+ yq -i '.build_root.image_stream_tag.tag = env(TARGET_CI_IMAGE)' .ci-operator.yaml📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||
| - name: Check for changes | ||||||||||||||||||||||||||||||||||||||
| id: changes | ||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||
| if [ -z "$(git status --porcelain)" ]; then | ||||||||||||||||||||||||||||||||||||||
| echo "No file changes — everything is up to date" | ||||||||||||||||||||||||||||||||||||||
| echo "has-changes=false" >> "${GITHUB_OUTPUT}" | ||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||
| echo "has-changes=true" >> "${GITHUB_OUTPUT}" | ||||||||||||||||||||||||||||||||||||||
| git diff --stat | ||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Verify build | ||||||||||||||||||||||||||||||||||||||
| if: steps.changes.outputs.has-changes == 'true' | ||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||
| if grep -q '^build:' Makefile 2>/dev/null; then | ||||||||||||||||||||||||||||||||||||||
| make build | ||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||
| go build ./... | ||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Show changes (dry run) | ||||||||||||||||||||||||||||||||||||||
| if: inputs.dry-run && steps.changes.outputs.has-changes == 'true' | ||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||
| echo "=== Dry run — would create PR with these changes ===" | ||||||||||||||||||||||||||||||||||||||
| git diff --stat | ||||||||||||||||||||||||||||||||||||||
| echo "---" | ||||||||||||||||||||||||||||||||||||||
| git diff go.mod | ||||||||||||||||||||||||||||||||||||||
| echo "---" | ||||||||||||||||||||||||||||||||||||||
| git diff .ci-operator.yaml 2>/dev/null || true | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - name: Create Pull Request | ||||||||||||||||||||||||||||||||||||||
| if: "!inputs.dry-run && steps.changes.outputs.has-changes == 'true'" | ||||||||||||||||||||||||||||||||||||||
| uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 | ||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||
| token: ${{ github.token }} | ||||||||||||||||||||||||||||||||||||||
| commit-message: "chore: update Go to ${{ steps.config.outputs.go }} and dependencies (${{ inputs.version-schema }})" | ||||||||||||||||||||||||||||||||||||||
| title: "chore: update Go to ${{ steps.config.outputs.go }} and dependencies (${{ inputs.version-schema }})" | ||||||||||||||||||||||||||||||||||||||
| branch: automated/go-version-update-${{ inputs.version-schema }} | ||||||||||||||||||||||||||||||||||||||
| delete-branch: true | ||||||||||||||||||||||||||||||||||||||
| body: | | ||||||||||||||||||||||||||||||||||||||
| Automated Go version and dependency update based on schema `${{ inputs.version-schema }}`. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| **Changes:** | ||||||||||||||||||||||||||||||||||||||
| - Go version: `${{ steps.config.outputs.go }}` | ||||||||||||||||||||||||||||||||||||||
| - CI operator image: `${{ steps.config.outputs.ci-image }}` | ||||||||||||||||||||||||||||||||||||||
| - Toolchain directive removed (patch versions handled by builder image) | ||||||||||||||||||||||||||||||||||||||
| - Dependencies updated via `go mod tidy` + `go mod vendor` | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| This workflow runs weekly to pick up dependency security patches (CVE fixes) | ||||||||||||||||||||||||||||||||||||||
| even when the Go minor version hasn't changed. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| **Version schema:** [`go-versions/${{ inputs.version-schema }}.yaml`](https://github.com/medik8s/.github/blob/main/go-versions/${{ inputs.version-schema }}.yaml) | ||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| # Go Version Schemas | ||
|
|
||
| Each YAML file defines a Go version schema tied to an OCP release. Operator | ||
| repos reference a schema by name when calling the | ||
| [`update-go-version`](../.github/workflows/update-go-version.yaml) reusable | ||
| workflow. | ||
|
|
||
| ## Design principles | ||
|
|
||
| - **`go.mod` tracks the minor version only** (e.g. `go 1.25`, not `go 1.25.0`). | ||
| - **No `toolchain` directive** — patch-level updates (`1.25.x`) are handled by | ||
| updating the CI builder image, not `go.mod`. | ||
| - **Minor version bumps** (e.g. `1.25` → `1.26`) require an explicit `go.mod` | ||
| update, which is what this workflow automates. | ||
|
|
||
| ## Schema format | ||
|
|
||
| ```yaml | ||
| # go-versions/ocp-4.21.yaml | ||
| go: "1.25" # Go minor version | ||
| ci-operator-image: "rhel-9-release-golang-1.25-openshift-4.21" # CI image tag | ||
| ``` | ||
|
|
||
| ## Adding a new schema | ||
|
|
||
| When a new OCP version requires a Go bump: | ||
|
|
||
| 1. Create `go-versions/ocp-X.Y.yaml` with the new values | ||
| 2. Each operator repo updates its caller workflow to reference the new schema | ||
| 3. On the next scheduled run (or manual dispatch), the workflow creates a PR | ||
|
|
||
| ## Usage in operator repos | ||
|
|
||
| ```yaml | ||
| # .github/workflows/go-update.yaml | ||
| name: Go Version Update | ||
| on: | ||
| schedule: | ||
| - cron: '0 8 * * 1' | ||
| workflow_dispatch: | ||
|
|
||
| jobs: | ||
| update: | ||
| uses: medik8s/.github/.github/workflows/update-go-version.yaml@main | ||
| with: | ||
| version-schema: ocp-4.21 | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Go version schema for OCP 4.19 | ||
| # Used by: older release branches (e.g. FAR release-0.5, SNR release-0.10) | ||
| go: "1.23" | ||
| ci-operator-image: "rhel-9-release-golang-1.23-openshift-4.19" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Go version schema for OCP 4.20 | ||
| # Used by: older release branches (e.g. FAR release-0.6, release-0.7) | ||
| go: "1.24" | ||
| ci-operator-image: "rhel-9-release-golang-1.24-openshift-4.20" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Go version schema for OCP 4.21 (RHWA 25.9) | ||
| # Used by: release branches targeting OCP 4.21 | ||
| go: "1.25" | ||
| ci-operator-image: "rhel-9-release-golang-1.25-openshift-4.21" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Go version schema for OCP 4.22 / OCP 5.0 | ||
| # Used by: main branches targeting OCP 4.22+ | ||
| go: "1.26" | ||
| ci-operator-image: "rhel-9-release-golang-1.26-openshift-5.0" |
Uh oh!
There was an error while loading. Please reload this page.