diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..57b486fb0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,43 @@ +version: 2 +updates: + # Go modules dependencies + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "weekly" + + # GitHub Actions dependencies + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + + # Docker base images + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "weekly" + + # OpenTofu/Terraform providers - AWS + - package-ecosystem: "terraform" + directory: "/tofu/main/aws" + schedule: + interval: "weekly" + + # OpenTofu/Terraform providers - Azure + - package-ecosystem: "terraform" + directory: "/tofu/main/azure" + schedule: + interval: "weekly" + + # OpenTofu/Terraform providers - K3D + - package-ecosystem: "terraform" + directory: "/tofu/main/k3d" + schedule: + interval: "weekly" + + # OpenTofu/Terraform providers - Harvester + - package-ecosystem: "terraform" + directory: "/tofu/main/harvester" + schedule: + interval: "weekly" diff --git a/.github/workflows/updatecli.yml b/.github/workflows/updatecli.yml new file mode 100644 index 000000000..538cfd47c --- /dev/null +++ b/.github/workflows/updatecli.yml @@ -0,0 +1,70 @@ +name: "updatecli" + +on: + schedule: + # Runs weekly on Mondays at 12:00 UTC + - cron: '0 12 * * 1' + workflow_dispatch: + inputs: + target: + description: 'Select which updatecli workflow to run or `all` to run all updates.' + required: true + default: 'all' + type: choice + options: + - 'all' + - 'vendored-binaries' + +permissions: + contents: write + pull-requests: write + +jobs: + updatecli: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install updatecli + uses: updatecli/updatecli-action@e63dd5570becd9cc73bbba5c7c2f6ffc0e07e047 # v2.82.0 + + - name: Delete leftover updatecli branches + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh pr list \ + --search "is:closed is:pr head:updatecli_" \ + --json headRefName \ + --jq ".[].headRefName" | sort -u > closed_prs_branches.txt + gh pr list \ + --search "is:open is:pr head:updatecli_" \ + --json headRefName \ + --jq ".[].headRefName" | sort -u > open_prs_branches.txt + for branch in $(comm -23 closed_prs_branches.txt open_prs_branches.txt); do + if (git ls-remote --exit-code --heads origin "${branch}"); then + echo "Deleting leftover updatecli branch - ${branch}"; + git push origin --delete "${branch}"; + fi + done + + - name: Apply updatecli + env: + UPDATECLI_GITHUB_ACTOR: ${{ github.actor }} + UPDATECLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + if [[ "${GITHUB_EVENT_NAME}" = "schedule" ]] || + ([[ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]] && [[ "${{ inputs.target }}" = "all" ]]); + then + echo "Running updatecli on all targets" + updatecli apply --clean --values updatecli/values.d/values.yaml \ + --config updatecli/updatecli.d/ + elif [[ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]]; + then + echo "Running updatecli on ${{ inputs.target }} target" + updatecli apply --clean --values updatecli/values.d/values.yaml \ + --config "updatecli/updatecli.d/update-${{ inputs.target }}/" + else + echo "Invalid event name or target" + fi diff --git a/updatecli/README.md b/updatecli/README.md new file mode 100644 index 000000000..456873393 --- /dev/null +++ b/updatecli/README.md @@ -0,0 +1,63 @@ +# updatecli automation + +The dartboard project uses [updatecli] to automate version updates for +dependencies that are not covered by Dependabot. + +## Tool + +We use updatecli for this automation because of its extensibility and multiple +plugins that allow greater flexibility when automating sequences of conditional +update steps. + +For detailed information on how to use updatecli, please consult its +[documentation]. + +## Scheduled workflow + +The automation runs as a GitHub Actions scheduled workflow once per week. +Manual execution of the pipelines can be [triggered] when needed. + +## Covered dependencies + +The following dependencies are managed by updatecli: + +- **Vendored binaries** (`download-vendored-bin.sh`): + - OpenTofu + - kubectl + - Helm + - k3d + +## Project organization + +``` +updatecli/ +├── README.md +├── updatecli.d # Update workflows +│ └── update-vendored-binaries # Vendored binaries update workflow +└── values.d # Configuration files + └── values.yaml # Configuration values +``` + +## Local testing + +Local testing of manifests requires: + +1. The updatecli binary that can be downloaded from + [updatecli/updatecli#releases]. Test only with the latest stable version. +2. A GitHub personal fine-grained token. + +```shell +export UPDATECLI_GITHUB_TOKEN="your GH token" +updatecli diff --clean --values updatecli/values.d/values.yaml --config updatecli/updatecli.d/update-vendored-binaries/ +``` + +## Contributing + +Before contributing, please follow the guidelines provided in this README and +make sure to test locally your changes before opening a PR. + + +[updatecli]: https://github.com/updatecli/updatecli +[documentation]: https://www.updatecli.io/docs/prologue/introduction/ +[triggered]: ../../actions/workflows/updatecli.yml +[updatecli/updatecli#releases]: https://github.com/updatecli/updatecli/releases diff --git a/updatecli/updatecli.d/update-vendored-binaries/update-vendored-binaries.yaml b/updatecli/updatecli.d/update-vendored-binaries/update-vendored-binaries.yaml new file mode 100644 index 000000000..4aa2d4277 --- /dev/null +++ b/updatecli/updatecli.d/update-vendored-binaries/update-vendored-binaries.yaml @@ -0,0 +1,186 @@ +name: '{{ .vendored_binaries.manifest }}' +pipelineid: '{{ .vendored_binaries.pipelineid }}' + +scms: + default: + kind: github + spec: + owner: '{{ .scm.owner }}' + repository: '{{ .scm.repo }}' + branch: '{{ .scm.branch }}' + user: '{{ .scm.user }}' + email: '{{ .scm.email }}' + username: '{{ .scm.username }}' + token: '{{ requiredEnv .scm.token }}' + commitusingapi: {{ .scm.commitusingapi }} + commitmessage: + squash: {{ .scm.commitmessage.squash }} + type: '{{ .vendored_binaries.commitmessage.type }}' + scope: '{{ .vendored_binaries.commitmessage.scope }}' + title: 'Bump vendored binaries versions' + +actions: + vendored-binaries-pr: + kind: github/pullrequest + scmid: 'default' + spec: + labels: + - 'dependencies' + mergemethod: '{{ .scm.mergemethod }}' + title: 'Bump vendored binaries versions' + description: | + Automated update of vendored binary versions in `download-vendored-bin.sh`. + + Updates: + - OpenTofu: `{{ source "opentofu-current" }}` → `{{ source "opentofu-latest" }}` + - kubectl: `{{ source "kubectl-current" }}` → `{{ source "kubectl-latest" }}` + - Helm: `{{ source "helm-current" }}` → `{{ source "helm-latest" }}` + - k3d: `{{ source "k3d-current" }}` → `{{ source "k3d-latest" }}` + +sources: + # Current versions from download-vendored-bin.sh + opentofu-current: + name: 'Get current OpenTofu version' + kind: file + scmid: 'default' + spec: + file: 'download-vendored-bin.sh' + matchpattern: 'OPENTOFU_VERSION=\d+\.\d+\.\d+' + transformers: + - find: '\d+\.\d+\.\d+' + + kubectl-current: + name: 'Get current kubectl version' + kind: file + scmid: 'default' + spec: + file: 'download-vendored-bin.sh' + matchpattern: 'KUBECTL_VERSION=\d+\.\d+\.\d+' + transformers: + - find: '\d+\.\d+\.\d+' + + helm-current: + name: 'Get current Helm version' + kind: file + scmid: 'default' + spec: + file: 'download-vendored-bin.sh' + matchpattern: 'HELM_VERSION=\d+\.\d+\.\d+' + transformers: + - find: '\d+\.\d+\.\d+' + + k3d-current: + name: 'Get current k3d version' + kind: file + scmid: 'default' + spec: + file: 'download-vendored-bin.sh' + matchpattern: 'K3D_VERSION=\d+\.\d+\.\d+' + transformers: + - find: '\d+\.\d+\.\d+' + + # Latest versions from GitHub releases + opentofu-latest: + name: 'Get latest OpenTofu version' + kind: githubrelease + spec: + owner: '{{ .repos.opentofu.owner }}' + repository: '{{ .repos.opentofu.repo }}' + key: tagname + typefilter: + release: true + username: '{{ .scm.username }}' + token: '{{ requiredEnv .scm.token }}' + versionfilter: + kind: semver + transformers: + - trimprefix: 'v' + + kubectl-latest: + name: 'Get latest kubectl version' + kind: githubrelease + spec: + owner: '{{ .repos.kubectl.owner }}' + repository: '{{ .repos.kubectl.repo }}' + key: tagname + typefilter: + release: true + username: '{{ .scm.username }}' + token: '{{ requiredEnv .scm.token }}' + versionfilter: + kind: semver + transformers: + - trimprefix: 'v' + + helm-latest: + name: 'Get latest Helm version' + kind: githubrelease + spec: + owner: '{{ .repos.helm.owner }}' + repository: '{{ .repos.helm.repo }}' + key: tagname + typefilter: + release: true + username: '{{ .scm.username }}' + token: '{{ requiredEnv .scm.token }}' + versionfilter: + kind: semver + transformers: + - trimprefix: 'v' + + k3d-latest: + name: 'Get latest k3d version' + kind: githubrelease + spec: + owner: '{{ .repos.k3d.owner }}' + repository: '{{ .repos.k3d.repo }}' + key: tagname + typefilter: + release: true + username: '{{ .scm.username }}' + token: '{{ requiredEnv .scm.token }}' + versionfilter: + kind: semver + transformers: + - trimprefix: 'v' + +targets: + update-opentofu-version: + name: 'Update OpenTofu version to {{ source "opentofu-latest" }}' + kind: file + scmid: 'default' + sourceid: 'opentofu-latest' + spec: + file: 'download-vendored-bin.sh' + matchpattern: 'OPENTOFU_VERSION=\d+\.\d+\.\d+' + replacepattern: 'OPENTOFU_VERSION={{ source "opentofu-latest" }}' + + update-kubectl-version: + name: 'Update kubectl version to {{ source "kubectl-latest" }}' + kind: file + scmid: 'default' + sourceid: 'kubectl-latest' + spec: + file: 'download-vendored-bin.sh' + matchpattern: 'KUBECTL_VERSION=\d+\.\d+\.\d+' + replacepattern: 'KUBECTL_VERSION={{ source "kubectl-latest" }}' + + update-helm-version: + name: 'Update Helm version to {{ source "helm-latest" }}' + kind: file + scmid: 'default' + sourceid: 'helm-latest' + spec: + file: 'download-vendored-bin.sh' + matchpattern: 'HELM_VERSION=\d+\.\d+\.\d+' + replacepattern: 'HELM_VERSION={{ source "helm-latest" }}' + + update-k3d-version: + name: 'Update k3d version to {{ source "k3d-latest" }}' + kind: file + scmid: 'default' + sourceid: 'k3d-latest' + spec: + file: 'download-vendored-bin.sh' + matchpattern: 'K3D_VERSION=\d+\.\d+\.\d+' + replacepattern: 'K3D_VERSION={{ source "k3d-latest" }}' diff --git a/updatecli/values.d/values.yaml b/updatecli/values.d/values.yaml new file mode 100644 index 000000000..4be02f67b --- /dev/null +++ b/updatecli/values.d/values.yaml @@ -0,0 +1,33 @@ +scm: + user: 'github-actions[bot]' + email: '41898282+github-actions[bot]@users.noreply.github.com' + username: 'UPDATECLI_GITHUB_ACTOR' + token: 'UPDATECLI_GITHUB_TOKEN' + owner: 'rancher' + repo: 'dartboard' + branch: 'main' + commitusingapi: false + commitmessage: + squash: true + mergemethod: 'squash' + +repos: + opentofu: + owner: 'opentofu' + repo: 'opentofu' + kubectl: + owner: 'kubernetes' + repo: 'kubernetes' + helm: + owner: 'helm' + repo: 'helm' + k3d: + owner: 'k3d-io' + repo: 'k3d' + +vendored_binaries: + manifest: 'Update vendored binaries versions' + pipelineid: 'update-vendored-binaries' + commitmessage: + type: 'deps' + scope: 'vendored-binaries'