From 73093b5e7f22d2a29cd166ecb420eb510d870144 Mon Sep 17 00:00:00 2001 From: Horst Gutmann Date: Tue, 3 Dec 2024 14:24:02 +0100 Subject: [PATCH] ci: add renovate We need a way to update the dependencies mentioned inside the Dockerfile definition. Dependabot does not support this but Renovate does, allowing to treat arbitrary strings as version identifiers. Additionally, we can use custom datasources to retrieve, for instance, the latest version of kubectl. --- .github/renovate-config.json5 | 77 ++++++++++++++++++++++++++++++++ .github/workflows/renovate.yml | 80 ++++++++++++++++++++++++++++++++++ Dockerfile | 9 ++-- 3 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 .github/renovate-config.json5 create mode 100644 .github/workflows/renovate.yml diff --git a/.github/renovate-config.json5 b/.github/renovate-config.json5 new file mode 100644 index 000000000..60aeef829 --- /dev/null +++ b/.github/renovate-config.json5 @@ -0,0 +1,77 @@ +{ + $schema: "https://docs.renovatebot.com/renovate-schema.json", + branchPrefix: "grafanarenovatebot/", + customDatasources: { + "kubectl": { + "defaultRegistryUrlTemplate": "https://cdn.dl.k8s.io/release/stable.txt", + "format": "plain" + }, + "helm": { + "defaultRegistryUrlTemplate": "https://api.github.com/repos/helm/helm/releases", + "format": "json", + "transformTemplates": [ + "{\"releases\": [{\"version\": $$.tag_name}]}", + ], + } + }, + + customManagers: [ + { + "customType": "regex", + "fileMatch": ["Dockerfile"], + "matchStrings": [ + "ARG KUBECTL_VERSION=(?\\S+)", + ], + "datasourceTemplate": "custom.kubectl", + "depNameTemplate": "kubectl", + }, + { + "customType": "regex", + "fileMatch": ["Dockerfile"], + "matchStrings": [ + "ARG HELM_VERSION=(?\\S+)", + ], + "datasourceTemplate": "custom.helm", + "depNameTemplate": "helm", + "versioningTemplate": "semver", + }, + ], + dependencyDashboard: false, + enabledManagers: ["custom.regex"], + forkProcessing: "enabled", + globalExtends: [":pinDependencies", "config:best-practices"], + onboarding: false, + osvVulnerabilityAlerts: true, + packageRules: [ + { + labels: ["update-major"], + matchUpdateTypes: ["major"], + }, + { + labels: ["update-minor"], + matchUpdateTypes: ["minor"], + }, + { + automerge: true, + labels: ["automerge-patch"], + matchUpdateTypes: ["patch"], + }, + { + labels: ["update-digest"], + matchUpdateTypes: ["digest"], + }, + { + // Run the custom matcher on early Monday mornings (UTC) + schedule: "* 0-4 * * 1", + matchPackageNames: ["ghcr.io/renovatebot/renovate"], + }, + ], + platformCommit: "enabled", + rebaseWhen: "behind-base-branch", + requireConfig: "optional", + vulnerabilityAlerts: { + automerge: true, + enabled: true, + labels: ["automerge-security-update"], + }, +} diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml new file mode 100644 index 000000000..debb8de59 --- /dev/null +++ b/.github/workflows/renovate.yml @@ -0,0 +1,80 @@ +name: Renovate +on: + schedule: + # Offset by 12 minutes to avoid busy times on the hour + - cron: 12 */4 * * * + + pull_request: + paths: + - .github/renovate-config.json5 + - .github/workflows/renovate.yml + types: + - edited + - opened + - ready_for_review + - synchronize + + push: + branches: + - main + paths: + - .github/renovate-config.json5 + - .github/workflows/renovate.yml + + workflow_dispatch: + inputs: + dry-run: + description: "Run Renovate in dry-run mode" + required: false + default: false + type: boolean + +jobs: + renovate: + permissions: + contents: read + id-token: write + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Checkout Code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + sparse-checkout: | + .github/renovate-config.json5 + + - name: Retrieve renovate secrets + id: get-secrets + # TODO: Pin version + uses: grafana/shared-workflows/actions/get-vault-secrets@get-vault-secrets-v1.0.1 + with: + common_secrets: | + GRAFANA_RENOVATE_APP_ID=grafana-renovate-app:app-id + GRAFANA_RENOVATE_PRIVATE_KEY=grafana-renovate-app:private-key + + - name: Generate token + id: generate-token + uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + with: + app-id: ${{ env.GRAFANA_RENOVATE_APP_ID }} + private-key: ${{ env.GRAFANA_RENOVATE_PRIVATE_KEY }} + + - name: Self-hosted Renovate + uses: renovatebot/github-action@936628dfbff213ab2eb95033c5e123cfcaf09ebb # v41.0.5 + with: + configurationFile: .github/renovate-config.json5 + # renovate: datasource=docker depName=ghcr.io/renovatebot/renovate + renovate-version: 39.42.4@sha256:c5d718e312cdacc0746e37f13c215ff498be28c51e50efd24c070ae29f5b636a + token: ${{ steps.generate-token.outputs.token }} + env: + LOG_LEVEL: ${{ github.event_name == 'pull_request' && 'debug' || 'info' }} + # For pull requests, this means we'll get the dependencies of the PR's + # branch, so you can fix/change things and see the results in the PR's + # run. By default, Renovate will clone the main/default branch. + RENOVATE_BASE_BRANCHES: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || null }} + # Dry run if the event is pull_request, or workflow_dispatch AND the dry-run input is true + RENOVATE_DRY_RUN: ${{ (github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.dry-run == 'true')) && 'full' || null }} + RENOVATE_PLATFORM: github + RENOVATE_REPOSITORIES: ${{ github.repository }} + RENOVATE_USERNAME: GrafanaRenovateBot diff --git a/Dockerfile b/Dockerfile index 5fa0db8a2..372275bb1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ # download kubectl FROM golang:1.23.3-alpine AS kubectl +ARG KUBECTL_VERSION=1.31.0 RUN apk add --no-cache curl -RUN export VERSION=$(curl -s https://cdn.dl.k8s.io/release/stable.txt) &&\ - export OS=$(go env GOOS) && \ +RUN export OS=$(go env GOOS) && \ export ARCH=$(go env GOARCH) &&\ - curl -o /usr/local/bin/kubectl -L https://cdn.dl.k8s.io/release/${VERSION}/bin/${OS}/${ARCH}/kubectl &&\ + curl -o /usr/local/bin/kubectl -L https://cdn.dl.k8s.io/release/${KUBECTL_VERSION}/bin/${OS}/${ARCH}/kubectl &&\ chmod +x /usr/local/bin/kubectl # build jsonnet-bundler @@ -19,11 +19,10 @@ RUN apk add --no-cache git make bash &&\ FROM golang:1.23.3-alpine AS helm WORKDIR /tmp/helm -ARG HELM_VERSION +ARG HELM_VERSION=v3.16.0 RUN apk add --no-cache jq curl RUN export OS=$(go env GOOS) && \ export ARCH=$(go env GOARCH) &&\ - if [[ -z ${HELM_VERSION} ]]; then export HELM_VERSION=$(curl --silent "https://api.github.com/repos/helm/helm/releases" | jq -r '.[0].tag_name'); fi && \ curl -SL "https://get.helm.sh/helm-${HELM_VERSION}-${OS}-${ARCH}.tar.gz" > helm.tgz && \ tar -xvf helm.tgz --strip-components=1