Add initial Updatecli ADR automation (#6583)

* Add initial Updatecli ADR automation

Signed-off-by: Guilherme Macedo <guilherme.macedo@suse.com>
This commit is contained in:
Guilherme Macedo 2023-01-03 14:56:08 -03:00 committed by GitHub
parent 9e97a3b4aa
commit 8f28de259c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 516 additions and 0 deletions

36
.github/workflows/updatecli.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: "Updatecli: Dependency Management"
on:
schedule:
# Runs at 06 PM UTC
- cron: '0 18 * * *'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
permissions:
contents: write
issues: write
pull-requests: write
jobs:
updatecli:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: '1.19.4'
- name: Install Updatecli
uses: updatecli/updatecli-action@v2
- name: Apply Updatecli
# Never use '--debug' option, because it might leak the access tokens.
run: "updatecli apply --clean --config ./updatecli/updatecli.d/ --values ./updatecli/values.yaml"
env:
UPDATECLI_GITHUB_ACTOR: ${{ github.actor }}
UPDATECLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

61
updatecli/README.md Normal file
View File

@ -0,0 +1,61 @@
# Updatecli automation
*Note:* This automation is still work in progress and subject to change. For more information, please consult [PR #6559](https://github.com/k3s-io/k3s/pull/6559).
This project uses [Updatecli](https://github.com/updatecli/updatecli) to automate and orchestrate security related updates and versions bumps in K3s.
## Tool
We use Updatecli for this automation, instead of Dependabot or Renovate, because of its extensibility and multiple [plugins resources](https://www.updatecli.io/docs/prologue/introduction/) that allow greater flexibility when automating sequences of conditional update steps across multiple repos.
For detailed information on how to use Updatecli, please consult its [documentation](https://www.updatecli.io/docs/prologue/introduction/) page.
## Scope
The main usage of Updatecli is for:
* Bumping versions in unstructured formats, e.g., environment variables in Dockerfiles and by matching regular expressions.
* Scripting the automation process, e.g., update package A in repo B after package X in repo Y matches a pre-defined version criteria.
### Not in scope
* Updatecli will only open a pull request in the targeted repo. It's not responsible for approving and merging the PR.
* The resulting PR must still follow the rules of the targeted repo, e.g., passing checks, QA testing, review process etc.
## Project organization
A manifest or pipeline consists of three stages - source, condition and target - that define how to apply the update strategy.
When adding a new manifest, please follow the example structure defined below.
```
.
└── updatecli
├── scripts # Contains the auxiliary scripts used in the manifests
├── updatecli.d
│   ├── golang-alpine.yaml # Ideally each pipeline file corresponds to a dependency update
│   ├── helm-controller.yaml
│   ├── klipper.yaml
└── values.yaml # Configuration values
```
## Local testing
Local testing of manifests require:
1. Updatecli binary that can be download from [updatecli/updatecli#releases](https://github.com/updatecli/updatecli/releases). Test only with the latest stable version.
1. Always run locally with the command `diff`, that will show the changes without actually applying them.
2. A GitHub [PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) (personal access token). The only required permission scope for Updatecli to work, when targeting only public repos, is `public_repo`.
1. For obvious security reasons and to avoid leaking your GH PAT, export it as a local environment variable.
```shell
export UPDATECLI_GITHUB_TOKEN="your GH PAT"
updatecli diff --clean --config updatecli/updatecli.d/ --values updatecli/values.yaml
```
## Contributing
Everyone is free to contribute with new manifests and pipelines for security version bumps targeting Rancher owned repos.
Before contributing, please follow the guidelines provided in this readme and make sure to test locally your changes before opening a PR.

View File

@ -0,0 +1,10 @@
#!/bin/bash
set -eux
go get "${1}" >&2
go mod tidy >&2
git diff
exit 0

View File

@ -0,0 +1,77 @@
---
name: "Bump Golang Alpine version"
scms:
k3s:
kind: "github"
spec:
user: "{{ .github.user }}"
email: "{{ .github.email }}"
username: "{{ .github.username }}"
token: "{{ requiredEnv .github.token }}"
owner: "{{ .k3s.org }}"
repository: "{{ .k3s.repo }}"
branch: "{{ .k3s.branch }}"
commitmessage:
title: "Bump golang:alpine version"
actions:
github:
title: "Bump golang:alpine image version"
kind: "github/pullrequest"
scmid: "k3s"
spec:
automerge: false
sources:
# Find Alpine latest semver version in DockerHub
alpine-docker-image:
name: "Check Alpine image version in DockerHub"
kind: "dockerimage"
spec:
image: "alpine"
versionfilter:
kind: "semver"
strict: true
# We want only the major and minor version, because it's the format
# used in golang:alpine version.
# Example: Alpine latest version is alpine:3.17.0, so we want only
# 3.17 to then check for golang:X.Y-alpine3.17 .
transformers:
- find: '\d+\.\d+'
# Dockerfile.dapper is considered the base for the Golang version that we
# must use.
dockerfile-dapper:
name: "Retrieve golang image version used in Dockerfile.dapper"
kind: "file"
scmid: "k3s"
disablesourceinput: true
spec:
file: "Dockerfile.dapper"
matchpattern: 'golang:\S+-alpine(\S+)?'
# Example: if the version found is golang:1.19.3-alpine3.16, then
# we extract only 1.19.3-alpine .
transformers:
- find: 'v?\d+\.\d+\.\d+-alpine'
conditions:
docker-image:
name: "Check golang:alpine latest image version in DockerHub"
kind: "dockerimage"
disablesourceinput: true
spec:
image: "golang"
tag: '{{ source "dockerfile-dapper" }}{{ source "alpine-docker-image" }}'
targets:
dockerfiles:
name: "Bump golang:alpine image version in Dockerfiles"
kind: "file"
scmid: "k3s"
disablesourceinput: true
spec:
files:
- "Dockerfile.dapper"
- "Dockerfile.test"
- "Dockerfile.manifest"
matchpattern: 'golang:\S+-alpine(\S+)?'
replacepattern: 'golang:{{ source "dockerfile-dapper" }}{{ source "alpine-docker-image" }}'

View File

@ -0,0 +1,68 @@
---
name: "Bump Helm Controller version"
scms:
k3s:
kind: "github"
spec:
user: "{{ .github.user }}"
email: "{{ .github.email }}"
username: "{{ .github.username }}"
token: "{{ requiredEnv .github.token }}"
owner: "{{ .k3s.org }}"
repository: "{{ .k3s.repo }}"
branch: "{{ .k3s.branch }}"
commitmessage:
title: "Bump Helm Controller version"
actions:
github:
title: "Bump Helm Controller version"
kind: "github/pullrequest"
scmid: "k3s"
spec:
automerge: false
mergemethod: "squash"
usetitleforautomerge: true
sources:
helm-controller:
name: "Get Helm Controller latest release version"
kind: "githubrelease"
spec:
owner: "{{ .helm_controller.org }}"
repository: "{{ .helm_controller.repo }}"
branch: "{{ .helm_controller.branch }}"
token: "{{ requiredEnv .github.token }}"
versionfilter:
kind: "latest"
get-pwd:
name: "Run Updatecli execution directory"
kind: "shell"
disablesourceinput: true
spec:
command: 'pwd'
environments:
- name: PATH
conditions:
helm-controller:
name: "Check Helm Controller usage in go.mod"
kind: "file"
scmid: "k3s"
disablesourceinput: true
spec:
file: "go.mod"
matchpattern: 'github.com/k3s-io/helm-controller'
targets:
go-mod:
name: "Run go mod update"
kind: "shell"
scmid: "k3s"
disablesourceinput: true
spec:
command: '{{ source "get-pwd" }}/updatecli/scripts/run-go-mod-update.sh github.com/k3s-io/helm-controller@{{ source "helm-controller" }}'
environments:
- name: PATH
- name: HOME

View File

@ -0,0 +1,103 @@
---
name: "Bump Klipper Helm and LB versions"
scms:
k3s:
kind: "github"
spec:
user: "{{ .github.user }}"
email: "{{ .github.email }}"
username: "{{ .github.username }}"
token: "{{ requiredEnv .github.token }}"
owner: "{{ .k3s.org }}"
repository: "{{ .k3s.repo }}"
branch: "{{ .k3s.branch }}"
commitmessage:
title: "Bump Klipper version"
klipper-helm:
kind: "github"
spec:
user: "{{ .github.user }}"
email: "{{ .github.email }}"
username: "{{ .github.username }}"
token: "{{ requiredEnv .github.token }}"
owner: "{{ .k3s.org }}"
repository: "{{ .klipper_helm.repo }}"
branch: "{{ .klipper_helm.branch }}"
klipper-lb:
kind: "github"
spec:
user: "{{ .github.user }}"
email: "{{ .github.email }}"
username: "{{ .github.username }}"
token: "{{ requiredEnv .github.token }}"
owner: "{{ .k3s.org }}"
repository: "{{ .klipper_lb.repo }}"
branch: "{{ .klipper_lb.branch }}"
actions:
github:
title: "Bump Klipper Helm and LB versions"
kind: "github/pullrequest"
scmid: "k3s"
spec:
automerge: false
mergemethod: "squash"
usetitleforautomerge: true
sources:
klipper-helm:
name: "Get Klipper Helm latest release version"
kind: "githubrelease"
spec:
owner: "{{ .klipper_helm.org }}"
repository: "{{ .klipper_helm.repo }}"
branch: "{{ .klipper_helm.branch }}"
token: "{{ requiredEnv .github.token }}"
versionfilter:
kind: "latest"
klipper-lb:
name: "Get Klipper LB latest release version"
kind: "githubrelease"
spec:
owner: "{{ .klipper_helm.org }}"
repository: "{{ .klipper_lb.repo }}"
branch: "{{ .klipper_lb.branch }}"
token: "{{ requiredEnv .github.token }}"
versionfilter:
kind: "latest"
conditions:
klipper-helm:
name: "Check rancher/klipper-helm image version in DockerHub"
kind: "dockerimage"
sourceid: "klipper-helm"
spec:
image: "rancher/klipper-helm"
klipper-lb:
name: "Check rancher/klipper-lb image version in DockerHub"
kind: "dockerimage"
sourceid: "klipper-lb"
spec:
image: "rancher/klipper-lb"
targets:
klipper-lb:
name: "Update rancher/klipper-lb image versions"
kind: "file"
scmid: "k3s"
sourceid: "klipper-lb"
spec:
files:
- "pkg/cloudprovider/servicelb.go"
- "scripts/airgap/image-list.txt"
matchpattern: 'rancher/klipper-lb:v\d+\.\d+\.\d+(-\w+)?'
replacepattern: 'rancher/klipper-lb:{{ source "klipper-lb" }}'
klipper-helm:
name: "Update rancher/klipper-helm image versions"
kind: "file"
scmid: "k3s"
sourceid: "klipper-helm"
spec:
file: "scripts/airgap/image-list.txt"
matchpattern: 'rancher/klipper-helm:v\d+\.\d+\.\d+(-\w+)?'
replacepattern: 'rancher/klipper-helm:{{ source "klipper-helm" }}'

View File

@ -0,0 +1,68 @@
---
name: "Bump Local Path Provisioner version"
scms:
k3s:
kind: "github"
spec:
user: "{{ .github.user }}"
email: "{{ .github.email }}"
username: "{{ .github.username }}"
token: "{{ requiredEnv .github.token }}"
owner: "{{ .k3s.org }}"
repository: "{{ .k3s.repo }}"
branch: "{{ .k3s.branch }}"
commitmessage:
title: "Bump Local Path Provisioner version"
local-path-provisioner:
kind: "github"
spec:
user: "{{ .github.user }}"
email: "{{ .github.email }}"
username: "{{ .github.username }}"
token: "{{ requiredEnv .github.token }}"
owner: "{{ .local_path_provisioner.org }}"
repository: "{{ .local_path_provisioner.repo }}"
branch: "{{ .local_path_provisioner.branch }}"
actions:
github:
title: "Bump Local Path Provisioner version"
kind: "github/pullrequest"
scmid: "k3s"
spec:
automerge: false
mergemethod: "squash"
usetitleforautomerge: true
sources:
local-path-provisioner:
name: "Get Local Path Provisioner latest release version"
kind: "githubrelease"
spec:
owner: "{{ .local_path_provisioner.org }}"
repository: "{{ .local_path_provisioner.repo }}"
branch: "{{ .local_path_provisioner.branch }}"
token: "{{ requiredEnv .github.token }}"
versionfilter:
kind: "latest"
conditions:
local-path-provisioner:
name: "Check rancher/local-path-provisioner image version in DockerHub"
kind: "dockerimage"
sourceid: "local-path-provisioner"
spec:
image: "rancher/local-path-provisioner"
targets:
local-path-provisioner:
name: "Update rancher/local-path-provisioner image version"
kind: "file"
scmid: "k3s"
sourceid: "local-path-provisioner"
spec:
files:
- "manifests/local-storage.yaml"
- "scripts/airgap/image-list.txt"
matchpattern: 'rancher/local-path-provisioner:v\d+\.\d+\.\d+(-\w+)?'
replacepattern: 'rancher/local-path-provisioner:{{ source `local-path-provisioner` }}'

View File

@ -0,0 +1,68 @@
---
name: "Bump Sonobuoy version"
scms:
k3s:
kind: "github"
spec:
user: "{{ .github.user }}"
email: "{{ .github.email }}"
username: "{{ .github.username }}"
token: "{{ requiredEnv .github.token }}"
owner: "{{ .k3s.org }}"
repository: "{{ .k3s.repo }}"
branch: "{{ .k3s.branch }}"
actions:
github:
title: "Bump Sonobuoy version"
kind: "github/pullrequest"
scmid: "k3s"
spec:
automerge: false
sources:
sonobuoy:
name: "Get Sonobuoy latest release version"
kind: "githubrelease"
spec:
owner: "vmware-tanzu"
repository: "sonobuoy"
token: "{{ requiredEnv .github.token }}"
branch: "main"
versionfilter:
kind: "latest"
transformers:
- trimprefix: "v"
conditions:
docker-image:
name: "Check sonobuoy/sonobuoy image version in DockerHub"
kind: "dockerimage"
sourceid: "sonobuoy"
spec:
image: "sonobuoy/sonobuoy"
transformers:
- addprefix: "v"
dockerfiles:
name: "Check if 'ENV SONOBUOY_VERSION' is set in Dockerfiles"
kind: "file"
scmid: "k3s"
disablesourceinput: true
spec:
files:
- "Dockerfile.test"
- "conformance/Dockerfile"
matchpattern: 'ENV SONOBUOY_VERSION \d+\.\d+\.\d+(-\w+)?'
targets:
sonobuoy:
name: "Update sonobuoy image versions"
kind: "file"
scmid: "k3s"
sourceid: "sonobuoy"
spec:
files:
- "Dockerfile.test"
- "conformance/Dockerfile"
matchpattern: 'ENV SONOBUOY_VERSION \d+\.\d+\.\d+(-\w+)?'
replacepattern: 'ENV SONOBUOY_VERSION {{ source "sonobuoy" }}'

25
updatecli/values.yaml Normal file
View File

@ -0,0 +1,25 @@
github:
user: "github-actions[bot]"
email: "41898282+github-actions[bot]@users.noreply.github.com"
username: "UPDATECLI_GITHUB_ACTOR"
token: "UPDATECLI_GITHUB_TOKEN"
k3s:
org: "k3s-io"
repo: "k3s"
branch: "master"
klipper_helm:
org: "k3s-io"
repo: "klipper-helm"
branch: "master"
klipper_lb:
org: "k3s-io"
repo: "klipper-lb"
branch: "master"
local_path_provisioner:
org: "rancher"
repo: "local-path-provisioner"
branch: "master"
helm_controller:
org: "k3s-io"
repo: "helm-controller"
branch: "master"