42 Commits

Author SHA1 Message Date
7dac56f404 chore(deps): update ghcr.io/linuxserver/qbittorrent:5.1.4 docker digest to 855e5f4 (#4753)
All checks were successful
render-manifests / render-manifests (push) Has been skipped
lint-test-helm / lint-helm (push) Successful in 21s
lint-test-helm / validate-kubeconform (push) Has been skipped
renovate / renovate (push) Successful in 2m56s
2026-03-15 08:03:46 +00:00
649b9f4bbe chore(config): migrate Renovate config (#4752)
All checks were successful
renovate / renovate (push) Successful in 3m8s
The Renovate config in this repository needs migrating. Typically this is because one or more configuration options you are using have been renamed.

  You don't need to merge this PR right away, because Renovate will continue to migrate these fields internally each time it runs. But later some of these fields may be fully deprecated and the migrations removed. So it's a good idea to merge this migration PR soon.

🔕 **Ignore**: Close this PR and you won't be reminded about config migration again, but one day your current config may no longer be valid.

 Got questions? Does something look wrong to you? Please don't hesitate to [request help here](https://github.com/renovatebot/renovate/discussions).

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Reviewed-on: #4752
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
2026-03-15 06:08:46 +00:00
27151632c0 feat: add description
All checks were successful
lint-test-helm / lint-helm (push) Successful in 50s
render-manifests / render-manifests (push) Successful in 49s
lint-test-helm / validate-kubeconform (push) Has been skipped
renovate / renovate (push) Successful in 1m48s
2026-03-15 01:00:58 -05:00
04ff752696 feat: add renovate tags for specific images 2026-03-15 01:00:28 -05:00
d373ba5ae9 feat: renovate for kubeconform 2026-03-15 00:54:33 -05:00
e00b12f619 feat: update helm and use renovate to keep it updated 2026-03-15 00:52:57 -05:00
6cb0c2e987 feat: remove if
All checks were successful
renovate / renovate (push) Successful in 1m27s
2026-03-15 00:44:06 -05:00
088c4ae827 feat: remove link to wiki
All checks were successful
lint-test-helm / lint-helm (push) Successful in 14s
lint-test-helm / validate-kubeconform (push) Has been skipped
render-manifests / render-manifests (push) Successful in 33s
renovate / renovate (push) Successful in 2m46s
2026-03-15 00:39:46 -05:00
e00766e4b0 feat: add cache
Some checks failed
renovate / renovate (push) Has been cancelled
2026-03-15 00:39:04 -05:00
79b301e4ef feat: add helm repos
All checks were successful
renovate / renovate (push) Successful in 1m26s
2026-03-15 00:34:47 -05:00
e1bf47f045 feat: improve linking 2026-03-15 00:33:28 -05:00
0315445a50 feat: add kubeconform job
All checks were successful
renovate / renovate (push) Successful in 1m40s
2026-03-15 00:25:35 -05:00
6450588d17 feat: refactor and improve steps
All checks were successful
renovate / renovate (push) Successful in 1m40s
2026-03-15 00:10:28 -05:00
4dd98f9581 feat: refactor and improve steps
All checks were successful
renovate / renovate (push) Successful in 3m34s
2026-03-15 00:05:19 -05:00
702ffc65da feat: use hyphen for consistency
All checks were successful
renovate / renovate (push) Successful in 1m27s
2026-03-14 23:38:35 -05:00
2372ab4b69 feat: add dir output to render
All checks were successful
renovate / renovate (push) Successful in 1m43s
2026-03-14 23:33:15 -05:00
ed57ae842b feat: ignore oci repo
All checks were successful
renovate / renovate (push) Successful in 1m33s
2026-03-14 23:26:46 -05:00
9099d66bd8 feat: group output
All checks were successful
renovate / renovate (push) Successful in 1m35s
2026-03-14 23:22:46 -05:00
b8447dd0ed feat: add update pr step 2026-03-14 23:22:03 -05:00
c373ee4844 feat: improve formatting, revert yq strip command
All checks were successful
renovate / renovate (push) Successful in 1m26s
2026-03-14 23:19:31 -05:00
da8ba776e8 feat: consolidate render workflows to 1
All checks were successful
renovate / renovate (push) Successful in 1m55s
2026-03-14 23:07:57 -05:00
b4afd2ab46 feat: upgrade chart to v1
All checks were successful
lint-test-helm / lint-helm (push) Successful in 11s
render-manifests-push / render-manifests-push (push) Successful in 2m10s
renovate / renovate (push) Successful in 1m18s
2026-03-14 21:08:24 -05:00
d0d9380b93 chore(deps): update booklore-app/booklore to v2.2.1 (#4747)
Some checks failed
render-manifests-push / render-manifests-push (push) Has been skipped
lint-test-helm / lint-helm (push) Successful in 14s
renovate / renovate (push) Has been cancelled
2026-03-15 02:06:18 +00:00
c435ba993e feat: refactor and improve steps
Some checks failed
renovate / renovate (push) Has been cancelled
2026-03-14 21:04:35 -05:00
85aa62b529 feat: remove link to wiki
All checks were successful
lint-test-helm / lint-helm (push) Successful in 31s
render-manifests-push / render-manifests-push (push) Successful in 31s
renovate / renovate (push) Successful in 2m8s
2026-03-14 21:02:19 -05:00
74af45cb57 fix: missing closing quote
Some checks failed
renovate / renovate (push) Has been cancelled
2026-03-14 21:00:35 -05:00
849fdb432d chore(deps): update registry.k8s.io/coredns/coredns docker tag to v1.14.2 (#4745)
All checks were successful
render-manifests-push / render-manifests-push (push) Has been skipped
lint-test-helm / lint-helm (push) Successful in 31s
renovate / renovate (push) Successful in 1m36s
2026-03-15 01:58:17 +00:00
78d15dccad feat: refactor and improve steps
All checks were successful
renovate / renovate (push) Successful in 1m57s
2026-03-14 20:56:01 -05:00
8bfb5aeea3 feat: add api version and dry-run=server options to render
Some checks failed
renovate / renovate (push) Has been cancelled
2026-03-14 20:54:57 -05:00
5baa34db7e feat: change schedule to morning 2026-03-14 20:49:05 -05:00
d05381f6d2 fix: missing slash to place into folder
All checks were successful
renovate / renovate (push) Successful in 3m17s
2026-03-14 20:45:48 -05:00
b2cf5c094c feat: revert clean comments
All checks were successful
renovate / renovate (push) Successful in 2m4s
2026-03-14 20:31:20 -05:00
20d80826cb fix: missing apostrophe
All checks were successful
renovate / renovate (push) Successful in 3m59s
2026-03-14 20:15:06 -05:00
efe27b9307 chore(deps): update actions/cache action to v5 (#4741)
All checks were successful
renovate / renovate (push) Successful in 3m2s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/cache](https://github.com/actions/cache) | action | major | `v4` → `v5` |

---

### Release Notes

<details>
<summary>actions/cache (actions/cache)</summary>

### [`v5`](https://github.com/actions/cache/compare/v4...v5)

[Compare Source](https://github.com/actions/cache/compare/v4...v5)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Reviewed-on: #4741
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
2026-03-15 01:06:15 +00:00
13f4726021 fix: remove local variable assignment
Some checks failed
renovate / renovate (push) Has been cancelled
2026-03-14 20:05:46 -05:00
2785f337cf feat: refactor and improve steps
All checks were successful
renovate / renovate (push) Successful in 3m1s
2026-03-14 19:59:30 -05:00
67163611af chore(deps): update dependency mariadb-operator/mariadb-operator to v26 (#4704)
All checks were successful
render-manifests-push / render-manifests-push (push) Has been skipped
lint-test-helm / lint-helm (push) Successful in 1m0s
renovate / renovate (push) Successful in 2m58s
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [mariadb-operator/mariadb-operator](https://github.com/mariadb-operator/mariadb-operator) | major | `25.10.4` → `26.3.0` |

---

### Release Notes

<details>
<summary>mariadb-operator/mariadb-operator (mariadb-operator/mariadb-operator)</summary>

### [`v26.3.0`](https://github.com/mariadb-operator/mariadb-operator/releases/tag/26.3.0)

[Compare Source](https://github.com/mariadb-operator/mariadb-operator/compare/25.10.4...26.3.0)

**`mariadb-operator` [26.03](https://github.com/mariadb-operator/mariadb-operator/releases/tag/26.3.0) is here!** 🦭

Welcome to another release of `mariadb-operator`! In this version, we have significantly enhanced our disaster recovery capabilities by adding support for **on-demand physical backups**, **Azure Blob Storage** and... (🥁)... **Point-In-Time-Recovery** .

Additionally, we've received a bunch of contributions by our amazing community during this release, including bug fixes and new features. We feel very grateful for your efforts and support, thank you! 🙇‍♂️ Refer to the PRs in the changelog below for further details.

If you're upgrading from previous versions, **do not miss the [UPGRADE GUIDE](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/releases/UPGRADE_26.3.0.md)** for a smooth transition.

#### Point-In-Time-Recovery

Point-in-time recovery (PITR) is a feature that allows you to restore a `MariaDB` instance to a specific point in time. For achieving this, it combines a full base backup and the binary logs that record all changes made to the database after the backup. This is something fully automated by operator, covering archival and restoration up to a specific time, ensuring business continuity and reduced RTO and RPO.

In order to configure PITR, you need to create a `PhysicalBackup` object to be used as full base backup. For example, you can configure a nightly backup:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
  name: physicalbackup-daily
spec:
  mariaDbRef:
    name: mariadb-repl
  schedule:
    cron: "0 0 * * *"
    suspend: false
    immediate: true
  compression: bzip2
  maxRetention: 720h
  storage:
    s3:
      bucket: physicalbackups
      prefix: mariadb
      endpoint: minio.minio.svc.cluster.local:9000
      region: us-east-1
      accessKeyIdSecretKeyRef:
        name: minio
        key: access-key-id
      secretAccessKeySecretKeyRef:
        name: minio
        key: secret-access-key
      tls:
        enabled: true
        caSecretKeyRef:
          name: minio-ca
          key: ca.crt
```

Next step is configuring common aspects of both binary log archiving and point-in-time restoration by defining a `PointInTimeRecovery` object:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
  name: pitr
spec:
  physicalBackupRef:
    name: physicalbackup-daily
  storage:
    s3:
      bucket: binlogs
      prefix: mariadb
      endpoint: minio.minio.svc.cluster.local:9000
      region: us-east-1
      accessKeyIdSecretKeyRef:
        name: minio
        key: access-key-id
      secretAccessKeySecretKeyRef:
        name: minio
        key: secret-access-key
      tls:
        enabled: true
        caSecretKeyRef:
          name: minio-ca
          key: ca.crt
  compression: gzip
  archiveTimeout: 1h
  strictMode: false
```

The new `PointInTimeRecovery` CR is just a configuration object that contains shared settings for both binary log archiving and point-in-time recovery. It has also a reference to a `PhysicalBackup` CR, used as full base backup.

In order to configure binary log archiving, you need to set a reference to the `PointInTimeRecovery` CR in the `MariaDB` object:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: MariaDB
metadata:
  name: mariadb-repl
spec:
  pointInTimeRecoveryRef:
    name: pitr
```

This will enable the binary log archival in the sidecar agent, which will eventually report the last recoverable time via the `PointInTimeRecovery` status:

```bash
kubectl get pitr
NAME   PHYSICAL BACKUP        LAST RECOVERABLE TIME   STRICT MODE   AGE
pitr   physicalbackup-daily   2026-02-27T20:10:42Z    false         43h
```

In order to perform a point-in-time restoration, you can create a new `MariaDB` instance with a reference to the `PointInTimeRecovery` object in the `bootstrapFrom` field, along with the `targetRecoveryTime`, which should be before or at the last recoverable time:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: MariaDB
metadata:
  name: mariadb-repl
spec:
  bootstrapFrom:
    pointInTimeRecoveryRef:
      name: pitr
    targetRecoveryTime: 2026-02-27T20:10:42Z
```

The restoration process will match the closest physical backup before or at the `targetRecoveryTime`, and then it will replay the archived binary logs from the backup GTID position up until the `targetRecoveryTime`.

Refer to the [PITR docs](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/pitr.md) for additional details.

#### Azure Blob Storage

So far, we have only supported S3-compatible storage as object storage for keeping the backups. We are now introducing native support for Azure Blob Storage in the `PhysicalBackup` and `PointInTimeRecovery` CRs. You can configure it under the `storage` field, similarly to S3:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
  name: pitr
spec:
  storage:
    azureBlob:
      containerName: binlogs
      serviceURL: https://azurite.default.svc.cluster.local:10000/devstoreaccount1
      prefix: mariadb
      storageAccountName: devstoreaccount1
      storageAccountKey:
        name: azurite-key
        key: storageAccountKey
      tls:
        enabled: true
        caSecretKeyRef:
          name: azurite-certs
          key: cert.pem
```

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
  name: physicalbackup-daily
spec:
  storage:
    azureBlob:
      containerName: physicalbackup
      serviceURL: https://azurite.default.svc.cluster.local:10000/devstoreaccount1
      prefix: mariadb
      storageAccountName: devstoreaccount1
      storageAccountKey:
        name: azurite-key
        key: storageAccountKey
      tls:
        enabled: true
        caSecretKeyRef:
          name: azurite-certs
          key: cert.pem
```

Refer to the [physical backup storage](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/physical_backup.md#azure-blob-storage-credentials) docs for additional details.

It is important to note that we couldn't find the bandwidth to support it for `Backup` resource (logical backup) in this release, [contributions are welcomed](https://github.com/mariadb-operator/mariadb-operator/issues/1653)!

Kudos to our co-maintainer [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) for smoothly driving this feature end-to-end!

#### On-demand `PhysicalBackup`

We have introduced the ability to trigger on-demand physical backup manually. For doing so, you need to provide an identifier in the `schedule.onDemand` field of the `PhysicalBackup` resource:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
  name: physicalbackup
spec:
  schedule:
    onDemand: "1"
```

Once scheduled, the operator tracks the identifier under the status subresource. If the identifier in the status differs from `schedule.onDemand`, the operator will trigger a new physical backup.

Refer to the [physical backup scheduling](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/physical_backup.md#scheduling) docs for additional details.

##### Behaviour change in `targetRecoveryTime`

To satisfy requirements of point-in-time recovery, we have unified the behaviour of the `bootstrapFrom.targetRecoveryTime` field in the `MariaDB` object: Logical and physical backup files whose timestamp is closest to `targetRecoveryTime`, **but not after**, will be matched.

Please take this into account when upgrading to this version.

##### Change in Helm `values.yaml`

`config` has been split into `repository` and `tag` to facilitate overriding the image registry (see [#&#8203;1632](https://github.com/mariadb-operator/mariadb-operator/pull/1632)). Please update your `values.yaml` from:

```yaml
config:
  mariadbImageName: docker-registry1.mariadb.com/library/mariadb
  maxscaleImage: docker-registry2.mariadb.com/mariadb/maxscale:23.08.5
  exporterImage: prom/mysqld-exporter:v0.15.1
  exporterMaxscaleImage: docker-registry2.mariadb.com/mariadb/maxscale-prometheus-exporter-ubi:v0.0.1
```

to the following format:

```yaml
config:
  mariadbImage:
    repository: docker-registry1.mariadb.com/library/mariadb
    tag: 11.8.5
  maxscaleImage:
    repository: docker-registry2.mariadb.com/mariadb/maxscale
    tag: 23.08.5
  exporterImage:
    repository: prom/mysqld-exporter
    tag: v0.15.1
  exporterMaxscaleImage:
    repository: docker-registry2.mariadb.com/mariadb/maxscale-prometheus-exporter-ubi
    tag: v0.0.1
```

##### Updated dependencies

| Platform/Component | Version |
| ------------------ | ------- |
| Kubernetes         | 1.35    |
| Go                 | 1.26.1  |
| controller-runtime | 0.23.3  |

#### Updated roadmap

The next feature to be supported is the new multi-cluster topology. Stay tuned!

- [x] ~~[Point In Time Recovery (PITR)](https://github.com/mariadb-operator/mariadb-operator/issues/507)~~
- [ ] [Multi-cluster topology](https://github.com/mariadb-operator/mariadb-operator/issues/1543)

***

#### Community

Contributions of any kind are always welcome: adding yourself to the [list of adopters](https://github.com/mariadb-operator/mariadb-operator/blob/main/ADOPTERS.md), reporting issues, submitting pull requests, or simply starring the project! 🌟

#### Enterprise

For enterprise users, see the **[MariaDB Enterprise Operator](https://mariadb.com/products/enterprise/kubernetes-operator/)**, a commercially supported Kubernetes operator from MariaDB with additional enterprise-grade features.

#### What's Changed

- feat: Use primary Service by default for HA mariaDB connections by [@&#8203;softho0n](https://github.com/softho0n) in [#&#8203;1575](https://github.com/mariadb-operator/mariadb-operator/pull/1575)
- feat: add loadBalancerClass field to ServiceTemplate by [@&#8203;yangminglintw](https://github.com/yangminglintw) in [#&#8203;1589](https://github.com/mariadb-operator/mariadb-operator/pull/1589)
- fix: use standard compression extensions and add magic bytes validation by [@&#8203;yangminglintw](https://github.com/yangminglintw) in [#&#8203;1588](https://github.com/mariadb-operator/mariadb-operator/pull/1588)
- Make volumes and volumeMounts mutable by [@&#8203;hedgieinsocks](https://github.com/hedgieinsocks) in [#&#8203;1601](https://github.com/mariadb-operator/mariadb-operator/pull/1601)
- chore: Bump to latest go by [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) in [#&#8203;1630](https://github.com/mariadb-operator/mariadb-operator/pull/1630)
- make imagePullSecrets mutable by [@&#8203;dmaes](https://github.com/dmaes) in [#&#8203;1614](https://github.com/mariadb-operator/mariadb-operator/pull/1614)
- split config images in repository and tag by [@&#8203;dmaes](https://github.com/dmaes) in [#&#8203;1632](https://github.com/mariadb-operator/mariadb-operator/pull/1632)
- Galera recovery: disable bootstrap on other pods before bootstrapping by [@&#8203;infocusmodereal](https://github.com/infocusmodereal) in [#&#8203;1631](https://github.com/mariadb-operator/mariadb-operator/pull/1631)
- Bump github.com/minio/minio-go/v7 from 7.0.97 to 7.0.98 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1585](https://github.com/mariadb-operator/mariadb-operator/pull/1585)
- Bump ghcr.io/devcontainers/features/docker-in-docker from 2.13.0 to 2.16.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1624](https://github.com/mariadb-operator/mariadb-operator/pull/1624)
- Bump ghcr.io/devcontainers/features/kubectl-helm-minikube from 1.2.2 to 1.3.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1623](https://github.com/mariadb-operator/mariadb-operator/pull/1623)
- Bump goreleaser/goreleaser-action from 6 to 7 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1620](https://github.com/mariadb-operator/mariadb-operator/pull/1620)
- Bump github.com/onsi/gomega from 1.38.3 to 1.39.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1581](https://github.com/mariadb-operator/mariadb-operator/pull/1581)
- Bump crate-ci/typos from 1.41.0 to 1.44.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1625](https://github.com/mariadb-operator/mariadb-operator/pull/1625)
- Bump github.com/onsi/ginkgo/v2 from 2.27.3 to 2.27.5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1586](https://github.com/mariadb-operator/mariadb-operator/pull/1586)
- Bump github.com/cert-manager/cert-manager from 1.18.2 to 1.19.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1580](https://github.com/mariadb-operator/mariadb-operator/pull/1580)
- Bump github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring from 0.87.1 to 0.88.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1579](https://github.com/mariadb-operator/mariadb-operator/pull/1579)
- Disable service links in MariaDB and MaxScale pod specs by [@&#8203;usiegj00](https://github.com/usiegj00) in [#&#8203;1635](https://github.com/mariadb-operator/mariadb-operator/pull/1635)
- Fix finalizer for ExternalMariDB by [@&#8203;snaax](https://github.com/snaax) in [#&#8203;1606](https://github.com/mariadb-operator/mariadb-operator/pull/1606)
- test: Added int tests for sql resources with external mariadb deletion by [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) in [#&#8203;1649](https://github.com/mariadb-operator/mariadb-operator/pull/1649)
- Bump github.com/minio/minio-go/v7 from 7.0.98 to 7.0.99 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1648](https://github.com/mariadb-operator/mariadb-operator/pull/1648)
- Bump golang.org/x/sync from 0.19.0 to 0.20.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1645](https://github.com/mariadb-operator/mariadb-operator/pull/1645)
- Bump docker/build-push-action from 6 to 7 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1644](https://github.com/mariadb-operator/mariadb-operator/pull/1644)
- Bump docker/setup-qemu-action from 3 to 4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1642](https://github.com/mariadb-operator/mariadb-operator/pull/1642)
- Bump github.com/go-chi/chi/v5 from 5.2.3 to 5.2.5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1641](https://github.com/mariadb-operator/mariadb-operator/pull/1641)
- Bump docker/login-action from 3 to 4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1646](https://github.com/mariadb-operator/mariadb-operator/pull/1646)
- Bump ghcr.io/devcontainers/features/docker-in-docker from 2.16.0 to 2.16.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1640](https://github.com/mariadb-operator/mariadb-operator/pull/1640)
- Bump docker/setup-buildx-action from 3 to 4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1638](https://github.com/mariadb-operator/mariadb-operator/pull/1638)
- Bump github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring from 0.88.0 to 0.89.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1643](https://github.com/mariadb-operator/mariadb-operator/pull/1643)
- Bump golang from 1.25.7-alpine3.23 to 1.26.1-alpine3.23 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1639](https://github.com/mariadb-operator/mariadb-operator/pull/1639)
- feat: Latest controller-runtime. Webhook changes, New Events API by [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) in [#&#8203;1651](https://github.com/mariadb-operator/mariadb-operator/pull/1651)
- Support for ephemeral volumes in `MariaDB` by [@&#8203;mmontes11](https://github.com/mmontes11) in [#&#8203;1650](https://github.com/mariadb-operator/mariadb-operator/pull/1650)
- fix: accept compressed backup files in logical restore by [@&#8203;voron](https://github.com/voron) in [#&#8203;1655](https://github.com/mariadb-operator/mariadb-operator/pull/1655)
- Fix typo: syncrhonous -> synchronous by [@&#8203;sjmudd](https://github.com/sjmudd) in [#&#8203;1657](https://github.com/mariadb-operator/mariadb-operator/pull/1657)
- Release 26.03: `PointInTimeRecovery`, Azure Blob Storage & on-demand `PhysicalBackups` by [@&#8203;mmontes11](https://github.com/mmontes11) in [#&#8203;1517](https://github.com/mariadb-operator/mariadb-operator/pull/1517)

#### New Contributors

- [@&#8203;softho0n](https://github.com/softho0n) made their first contribution in [#&#8203;1575](https://github.com/mariadb-operator/mariadb-operator/pull/1575)
- [@&#8203;yangminglintw](https://github.com/yangminglintw) made their first contribution in [#&#8203;1589](https://github.com/mariadb-operator/mariadb-operator/pull/1589)
- [@&#8203;dmaes](https://github.com/dmaes) made their first contribution in [#&#8203;1614](https://github.com/mariadb-operator/mariadb-operator/pull/1614)
- [@&#8203;infocusmodereal](https://github.com/infocusmodereal) made their first contribution in [#&#8203;1631](https://github.com/mariadb-operator/mariadb-operator/pull/1631)
- [@&#8203;usiegj00](https://github.com/usiegj00) made their first contribution in [#&#8203;1635](https://github.com/mariadb-operator/mariadb-operator/pull/1635)
- [@&#8203;voron](https://github.com/voron) made their first contribution in [#&#8203;1655](https://github.com/mariadb-operator/mariadb-operator/pull/1655)
- [@&#8203;sjmudd](https://github.com/sjmudd) made their first contribution in [#&#8203;1657](https://github.com/mariadb-operator/mariadb-operator/pull/1657)

**Full Changelog**: <https://github.com/mariadb-operator/mariadb-operator/compare/25.10.4...26.3.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4704
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
2026-03-15 00:04:42 +00:00
15f4df3ec4 chore(deps): update helm release mariadb-cluster to v26 (#4705)
All checks were successful
render-manifests-push / render-manifests-push (push) Has been skipped
lint-test-helm / lint-helm (push) Successful in 11s
renovate / renovate (push) Successful in 2m31s
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [mariadb-cluster](https://github.com/mariadb-operator/mariadb-operator) | major | `25.10.4` → `26.3.0` |

---

### Release Notes

<details>
<summary>mariadb-operator/mariadb-operator (mariadb-cluster)</summary>

### [`v26.3.0`](https://github.com/mariadb-operator/mariadb-operator/releases/tag/26.3.0)

[Compare Source](https://github.com/mariadb-operator/mariadb-operator/compare/mariadb-cluster-25.10.4...mariadb-cluster-26.3.0)

**`mariadb-operator` [26.03](https://github.com/mariadb-operator/mariadb-operator/releases/tag/26.3.0) is here!** 🦭

Welcome to another release of `mariadb-operator`! In this version, we have significantly enhanced our disaster recovery capabilities by adding support for **on-demand physical backups**, **Azure Blob Storage** and... (🥁)... **Point-In-Time-Recovery** .

Additionally, we've received a bunch of contributions by our amazing community during this release, including bug fixes and new features. We feel very grateful for your efforts and support, thank you! 🙇‍♂️ Refer to the PRs in the changelog below for further details.

If you're upgrading from previous versions, **do not miss the [UPGRADE GUIDE](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/releases/UPGRADE_26.3.0.md)** for a smooth transition.

#### Point-In-Time-Recovery

Point-in-time recovery (PITR) is a feature that allows you to restore a `MariaDB` instance to a specific point in time. For achieving this, it combines a full base backup and the binary logs that record all changes made to the database after the backup. This is something fully automated by operator, covering archival and restoration up to a specific time, ensuring business continuity and reduced RTO and RPO.

In order to configure PITR, you need to create a `PhysicalBackup` object to be used as full base backup. For example, you can configure a nightly backup:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
  name: physicalbackup-daily
spec:
  mariaDbRef:
    name: mariadb-repl
  schedule:
    cron: "0 0 * * *"
    suspend: false
    immediate: true
  compression: bzip2
  maxRetention: 720h
  storage:
    s3:
      bucket: physicalbackups
      prefix: mariadb
      endpoint: minio.minio.svc.cluster.local:9000
      region: us-east-1
      accessKeyIdSecretKeyRef:
        name: minio
        key: access-key-id
      secretAccessKeySecretKeyRef:
        name: minio
        key: secret-access-key
      tls:
        enabled: true
        caSecretKeyRef:
          name: minio-ca
          key: ca.crt
```

Next step is configuring common aspects of both binary log archiving and point-in-time restoration by defining a `PointInTimeRecovery` object:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
  name: pitr
spec:
  physicalBackupRef:
    name: physicalbackup-daily
  storage:
    s3:
      bucket: binlogs
      prefix: mariadb
      endpoint: minio.minio.svc.cluster.local:9000
      region: us-east-1
      accessKeyIdSecretKeyRef:
        name: minio
        key: access-key-id
      secretAccessKeySecretKeyRef:
        name: minio
        key: secret-access-key
      tls:
        enabled: true
        caSecretKeyRef:
          name: minio-ca
          key: ca.crt
  compression: gzip
  archiveTimeout: 1h
  strictMode: false
```

The new `PointInTimeRecovery` CR is just a configuration object that contains shared settings for both binary log archiving and point-in-time recovery. It has also a reference to a `PhysicalBackup` CR, used as full base backup.

In order to configure binary log archiving, you need to set a reference to the `PointInTimeRecovery` CR in the `MariaDB` object:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: MariaDB
metadata:
  name: mariadb-repl
spec:
  pointInTimeRecoveryRef:
    name: pitr
```

This will enable the binary log archival in the sidecar agent, which will eventually report the last recoverable time via the `PointInTimeRecovery` status:

```bash
kubectl get pitr
NAME   PHYSICAL BACKUP        LAST RECOVERABLE TIME   STRICT MODE   AGE
pitr   physicalbackup-daily   2026-02-27T20:10:42Z    false         43h
```

In order to perform a point-in-time restoration, you can create a new `MariaDB` instance with a reference to the `PointInTimeRecovery` object in the `bootstrapFrom` field, along with the `targetRecoveryTime`, which should be before or at the last recoverable time:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: MariaDB
metadata:
  name: mariadb-repl
spec:
  bootstrapFrom:
    pointInTimeRecoveryRef:
      name: pitr
    targetRecoveryTime: 2026-02-27T20:10:42Z
```

The restoration process will match the closest physical backup before or at the `targetRecoveryTime`, and then it will replay the archived binary logs from the backup GTID position up until the `targetRecoveryTime`.

Refer to the [PITR docs](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/pitr.md) for additional details.

#### Azure Blob Storage

So far, we have only supported S3-compatible storage as object storage for keeping the backups. We are now introducing native support for Azure Blob Storage in the `PhysicalBackup` and `PointInTimeRecovery` CRs. You can configure it under the `storage` field, similarly to S3:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
  name: pitr
spec:
  storage:
    azureBlob:
      containerName: binlogs
      serviceURL: https://azurite.default.svc.cluster.local:10000/devstoreaccount1
      prefix: mariadb
      storageAccountName: devstoreaccount1
      storageAccountKey:
        name: azurite-key
        key: storageAccountKey
      tls:
        enabled: true
        caSecretKeyRef:
          name: azurite-certs
          key: cert.pem
```

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
  name: physicalbackup-daily
spec:
  storage:
    azureBlob:
      containerName: physicalbackup
      serviceURL: https://azurite.default.svc.cluster.local:10000/devstoreaccount1
      prefix: mariadb
      storageAccountName: devstoreaccount1
      storageAccountKey:
        name: azurite-key
        key: storageAccountKey
      tls:
        enabled: true
        caSecretKeyRef:
          name: azurite-certs
          key: cert.pem
```

Refer to the [physical backup storage](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/physical_backup.md#azure-blob-storage-credentials) docs for additional details.

It is important to note that we couldn't find the bandwidth to support it for `Backup` resource (logical backup) in this release, [contributions are welcomed](https://github.com/mariadb-operator/mariadb-operator/issues/1653)!

Kudos to our co-maintainer [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) for smoothly driving this feature end-to-end!

#### On-demand `PhysicalBackup`

We have introduced the ability to trigger on-demand physical backup manually. For doing so, you need to provide an identifier in the `schedule.onDemand` field of the `PhysicalBackup` resource:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
  name: physicalbackup
spec:
  schedule:
    onDemand: "1"
```

Once scheduled, the operator tracks the identifier under the status subresource. If the identifier in the status differs from `schedule.onDemand`, the operator will trigger a new physical backup.

Refer to the [physical backup scheduling](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/physical_backup.md#scheduling) docs for additional details.

##### Behaviour change in `targetRecoveryTime`

To satisfy requirements of point-in-time recovery, we have unified the behaviour of the `bootstrapFrom.targetRecoveryTime` field in the `MariaDB` object: Logical and physical backup files whose timestamp is closest to `targetRecoveryTime`, **but not after**, will be matched.

Please take this into account when upgrading to this version.

##### Change in Helm `values.yaml`

`config` has been split into `repository` and `tag` to facilitate overriding the image registry (see [#&#8203;1632](https://github.com/mariadb-operator/mariadb-operator/pull/1632)). Please update your `values.yaml` from:

```yaml
config:
  mariadbImageName: docker-registry1.mariadb.com/library/mariadb
  maxscaleImage: docker-registry2.mariadb.com/mariadb/maxscale:23.08.5
  exporterImage: prom/mysqld-exporter:v0.15.1
  exporterMaxscaleImage: docker-registry2.mariadb.com/mariadb/maxscale-prometheus-exporter-ubi:v0.0.1
```

to the following format:

```yaml
config:
  mariadbImage:
    repository: docker-registry1.mariadb.com/library/mariadb
    tag: 11.8.5
  maxscaleImage:
    repository: docker-registry2.mariadb.com/mariadb/maxscale
    tag: 23.08.5
  exporterImage:
    repository: prom/mysqld-exporter
    tag: v0.15.1
  exporterMaxscaleImage:
    repository: docker-registry2.mariadb.com/mariadb/maxscale-prometheus-exporter-ubi
    tag: v0.0.1
```

##### Updated dependencies

| Platform/Component | Version |
| ------------------ | ------- |
| Kubernetes         | 1.35    |
| Go                 | 1.26.1  |
| controller-runtime | 0.23.3  |

#### Updated roadmap

The next feature to be supported is the new multi-cluster topology. Stay tuned!

- [x] ~~[Point In Time Recovery (PITR)](https://github.com/mariadb-operator/mariadb-operator/issues/507)~~
- [ ] [Multi-cluster topology](https://github.com/mariadb-operator/mariadb-operator/issues/1543)

***

#### Community

Contributions of any kind are always welcome: adding yourself to the [list of adopters](https://github.com/mariadb-operator/mariadb-operator/blob/main/ADOPTERS.md), reporting issues, submitting pull requests, or simply starring the project! 🌟

#### Enterprise

For enterprise users, see the **[MariaDB Enterprise Operator](https://mariadb.com/products/enterprise/kubernetes-operator/)**, a commercially supported Kubernetes operator from MariaDB with additional enterprise-grade features.

#### What's Changed

- feat: Use primary Service by default for HA mariaDB connections by [@&#8203;softho0n](https://github.com/softho0n) in [#&#8203;1575](https://github.com/mariadb-operator/mariadb-operator/pull/1575)
- feat: add loadBalancerClass field to ServiceTemplate by [@&#8203;yangminglintw](https://github.com/yangminglintw) in [#&#8203;1589](https://github.com/mariadb-operator/mariadb-operator/pull/1589)
- fix: use standard compression extensions and add magic bytes validation by [@&#8203;yangminglintw](https://github.com/yangminglintw) in [#&#8203;1588](https://github.com/mariadb-operator/mariadb-operator/pull/1588)
- Make volumes and volumeMounts mutable by [@&#8203;hedgieinsocks](https://github.com/hedgieinsocks) in [#&#8203;1601](https://github.com/mariadb-operator/mariadb-operator/pull/1601)
- chore: Bump to latest go by [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) in [#&#8203;1630](https://github.com/mariadb-operator/mariadb-operator/pull/1630)
- make imagePullSecrets mutable by [@&#8203;dmaes](https://github.com/dmaes) in [#&#8203;1614](https://github.com/mariadb-operator/mariadb-operator/pull/1614)
- split config images in repository and tag by [@&#8203;dmaes](https://github.com/dmaes) in [#&#8203;1632](https://github.com/mariadb-operator/mariadb-operator/pull/1632)
- Galera recovery: disable bootstrap on other pods before bootstrapping by [@&#8203;infocusmodereal](https://github.com/infocusmodereal) in [#&#8203;1631](https://github.com/mariadb-operator/mariadb-operator/pull/1631)
- Bump github.com/minio/minio-go/v7 from 7.0.97 to 7.0.98 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1585](https://github.com/mariadb-operator/mariadb-operator/pull/1585)
- Bump ghcr.io/devcontainers/features/docker-in-docker from 2.13.0 to 2.16.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1624](https://github.com/mariadb-operator/mariadb-operator/pull/1624)
- Bump ghcr.io/devcontainers/features/kubectl-helm-minikube from 1.2.2 to 1.3.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1623](https://github.com/mariadb-operator/mariadb-operator/pull/1623)
- Bump goreleaser/goreleaser-action from 6 to 7 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1620](https://github.com/mariadb-operator/mariadb-operator/pull/1620)
- Bump github.com/onsi/gomega from 1.38.3 to 1.39.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1581](https://github.com/mariadb-operator/mariadb-operator/pull/1581)
- Bump crate-ci/typos from 1.41.0 to 1.44.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1625](https://github.com/mariadb-operator/mariadb-operator/pull/1625)
- Bump github.com/onsi/ginkgo/v2 from 2.27.3 to 2.27.5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1586](https://github.com/mariadb-operator/mariadb-operator/pull/1586)
- Bump github.com/cert-manager/cert-manager from 1.18.2 to 1.19.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1580](https://github.com/mariadb-operator/mariadb-operator/pull/1580)
- Bump github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring from 0.87.1 to 0.88.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1579](https://github.com/mariadb-operator/mariadb-operator/pull/1579)
- Disable service links in MariaDB and MaxScale pod specs by [@&#8203;usiegj00](https://github.com/usiegj00) in [#&#8203;1635](https://github.com/mariadb-operator/mariadb-operator/pull/1635)
- Fix finalizer for ExternalMariDB by [@&#8203;snaax](https://github.com/snaax) in [#&#8203;1606](https://github.com/mariadb-operator/mariadb-operator/pull/1606)
- test: Added int tests for sql resources with external mariadb deletion by [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) in [#&#8203;1649](https://github.com/mariadb-operator/mariadb-operator/pull/1649)
- Bump github.com/minio/minio-go/v7 from 7.0.98 to 7.0.99 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1648](https://github.com/mariadb-operator/mariadb-operator/pull/1648)
- Bump golang.org/x/sync from 0.19.0 to 0.20.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1645](https://github.com/mariadb-operator/mariadb-operator/pull/1645)
- Bump docker/build-push-action from 6 to 7 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1644](https://github.com/mariadb-operator/mariadb-operator/pull/1644)
- Bump docker/setup-qemu-action from 3 to 4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1642](https://github.com/mariadb-operator/mariadb-operator/pull/1642)
- Bump github.com/go-chi/chi/v5 from 5.2.3 to 5.2.5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1641](https://github.com/mariadb-operator/mariadb-operator/pull/1641)
- Bump docker/login-action from 3 to 4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1646](https://github.com/mariadb-operator/mariadb-operator/pull/1646)
- Bump ghcr.io/devcontainers/features/docker-in-docker from 2.16.0 to 2.16.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1640](https://github.com/mariadb-operator/mariadb-operator/pull/1640)
- Bump docker/setup-buildx-action from 3 to 4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1638](https://github.com/mariadb-operator/mariadb-operator/pull/1638)
- Bump github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring from 0.88.0 to 0.89.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1643](https://github.com/mariadb-operator/mariadb-operator/pull/1643)
- Bump golang from 1.25.7-alpine3.23 to 1.26.1-alpine3.23 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1639](https://github.com/mariadb-operator/mariadb-operator/pull/1639)
- feat: Latest controller-runtime. Webhook changes, New Events API by [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) in [#&#8203;1651](https://github.com/mariadb-operator/mariadb-operator/pull/1651)
- Support for ephemeral volumes in `MariaDB` by [@&#8203;mmontes11](https://github.com/mmontes11) in [#&#8203;1650](https://github.com/mariadb-operator/mariadb-operator/pull/1650)
- fix: accept compressed backup files in logical restore by [@&#8203;voron](https://github.com/voron) in [#&#8203;1655](https://github.com/mariadb-operator/mariadb-operator/pull/1655)
- Fix typo: syncrhonous -> synchronous by [@&#8203;sjmudd](https://github.com/sjmudd) in [#&#8203;1657](https://github.com/mariadb-operator/mariadb-operator/pull/1657)
- Release 26.03: `PointInTimeRecovery`, Azure Blob Storage & on-demand `PhysicalBackups` by [@&#8203;mmontes11](https://github.com/mmontes11) in [#&#8203;1517](https://github.com/mariadb-operator/mariadb-operator/pull/1517)

#### New Contributors

- [@&#8203;softho0n](https://github.com/softho0n) made their first contribution in [#&#8203;1575](https://github.com/mariadb-operator/mariadb-operator/pull/1575)
- [@&#8203;yangminglintw](https://github.com/yangminglintw) made their first contribution in [#&#8203;1589](https://github.com/mariadb-operator/mariadb-operator/pull/1589)
- [@&#8203;dmaes](https://github.com/dmaes) made their first contribution in [#&#8203;1614](https://github.com/mariadb-operator/mariadb-operator/pull/1614)
- [@&#8203;infocusmodereal](https://github.com/infocusmodereal) made their first contribution in [#&#8203;1631](https://github.com/mariadb-operator/mariadb-operator/pull/1631)
- [@&#8203;usiegj00](https://github.com/usiegj00) made their first contribution in [#&#8203;1635](https://github.com/mariadb-operator/mariadb-operator/pull/1635)
- [@&#8203;voron](https://github.com/voron) made their first contribution in [#&#8203;1655](https://github.com/mariadb-operator/mariadb-operator/pull/1655)
- [@&#8203;sjmudd](https://github.com/sjmudd) made their first contribution in [#&#8203;1657](https://github.com/mariadb-operator/mariadb-operator/pull/1657)

**Full Changelog**: <https://github.com/mariadb-operator/mariadb-operator/compare/25.10.4...26.3.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiY2hhcnQiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4705
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
2026-03-14 23:58:42 +00:00
215f7edc86 chore(deps): update helm release mariadb-operator to v26 (#4706)
All checks were successful
render-manifests-push / render-manifests-push (push) Has been skipped
lint-test-helm / lint-helm (push) Successful in 12s
renovate / renovate (push) Successful in 3m2s
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [mariadb-operator](https://github.com/mariadb-operator/mariadb-operator) | major | `25.10.4` → `26.3.0` |

---

### Release Notes

<details>
<summary>mariadb-operator/mariadb-operator (mariadb-operator)</summary>

### [`v26.3.0`](https://github.com/mariadb-operator/mariadb-operator/releases/tag/26.3.0)

[Compare Source](https://github.com/mariadb-operator/mariadb-operator/compare/mariadb-operator-25.10.4...mariadb-operator-26.3.0)

**`mariadb-operator` [26.03](https://github.com/mariadb-operator/mariadb-operator/releases/tag/26.3.0) is here!** 🦭

Welcome to another release of `mariadb-operator`! In this version, we have significantly enhanced our disaster recovery capabilities by adding support for **on-demand physical backups**, **Azure Blob Storage** and... (🥁)... **Point-In-Time-Recovery** .

Additionally, we've received a bunch of contributions by our amazing community during this release, including bug fixes and new features. We feel very grateful for your efforts and support, thank you! 🙇‍♂️ Refer to the PRs in the changelog below for further details.

If you're upgrading from previous versions, **do not miss the [UPGRADE GUIDE](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/releases/UPGRADE_26.3.0.md)** for a smooth transition.

#### Point-In-Time-Recovery

Point-in-time recovery (PITR) is a feature that allows you to restore a `MariaDB` instance to a specific point in time. For achieving this, it combines a full base backup and the binary logs that record all changes made to the database after the backup. This is something fully automated by operator, covering archival and restoration up to a specific time, ensuring business continuity and reduced RTO and RPO.

In order to configure PITR, you need to create a `PhysicalBackup` object to be used as full base backup. For example, you can configure a nightly backup:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
  name: physicalbackup-daily
spec:
  mariaDbRef:
    name: mariadb-repl
  schedule:
    cron: "0 0 * * *"
    suspend: false
    immediate: true
  compression: bzip2
  maxRetention: 720h
  storage:
    s3:
      bucket: physicalbackups
      prefix: mariadb
      endpoint: minio.minio.svc.cluster.local:9000
      region: us-east-1
      accessKeyIdSecretKeyRef:
        name: minio
        key: access-key-id
      secretAccessKeySecretKeyRef:
        name: minio
        key: secret-access-key
      tls:
        enabled: true
        caSecretKeyRef:
          name: minio-ca
          key: ca.crt
```

Next step is configuring common aspects of both binary log archiving and point-in-time restoration by defining a `PointInTimeRecovery` object:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
  name: pitr
spec:
  physicalBackupRef:
    name: physicalbackup-daily
  storage:
    s3:
      bucket: binlogs
      prefix: mariadb
      endpoint: minio.minio.svc.cluster.local:9000
      region: us-east-1
      accessKeyIdSecretKeyRef:
        name: minio
        key: access-key-id
      secretAccessKeySecretKeyRef:
        name: minio
        key: secret-access-key
      tls:
        enabled: true
        caSecretKeyRef:
          name: minio-ca
          key: ca.crt
  compression: gzip
  archiveTimeout: 1h
  strictMode: false
```

The new `PointInTimeRecovery` CR is just a configuration object that contains shared settings for both binary log archiving and point-in-time recovery. It has also a reference to a `PhysicalBackup` CR, used as full base backup.

In order to configure binary log archiving, you need to set a reference to the `PointInTimeRecovery` CR in the `MariaDB` object:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: MariaDB
metadata:
  name: mariadb-repl
spec:
  pointInTimeRecoveryRef:
    name: pitr
```

This will enable the binary log archival in the sidecar agent, which will eventually report the last recoverable time via the `PointInTimeRecovery` status:

```bash
kubectl get pitr
NAME   PHYSICAL BACKUP        LAST RECOVERABLE TIME   STRICT MODE   AGE
pitr   physicalbackup-daily   2026-02-27T20:10:42Z    false         43h
```

In order to perform a point-in-time restoration, you can create a new `MariaDB` instance with a reference to the `PointInTimeRecovery` object in the `bootstrapFrom` field, along with the `targetRecoveryTime`, which should be before or at the last recoverable time:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: MariaDB
metadata:
  name: mariadb-repl
spec:
  bootstrapFrom:
    pointInTimeRecoveryRef:
      name: pitr
    targetRecoveryTime: 2026-02-27T20:10:42Z
```

The restoration process will match the closest physical backup before or at the `targetRecoveryTime`, and then it will replay the archived binary logs from the backup GTID position up until the `targetRecoveryTime`.

Refer to the [PITR docs](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/pitr.md) for additional details.

#### Azure Blob Storage

So far, we have only supported S3-compatible storage as object storage for keeping the backups. We are now introducing native support for Azure Blob Storage in the `PhysicalBackup` and `PointInTimeRecovery` CRs. You can configure it under the `storage` field, similarly to S3:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PointInTimeRecovery
metadata:
  name: pitr
spec:
  storage:
    azureBlob:
      containerName: binlogs
      serviceURL: https://azurite.default.svc.cluster.local:10000/devstoreaccount1
      prefix: mariadb
      storageAccountName: devstoreaccount1
      storageAccountKey:
        name: azurite-key
        key: storageAccountKey
      tls:
        enabled: true
        caSecretKeyRef:
          name: azurite-certs
          key: cert.pem
```

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
  name: physicalbackup-daily
spec:
  storage:
    azureBlob:
      containerName: physicalbackup
      serviceURL: https://azurite.default.svc.cluster.local:10000/devstoreaccount1
      prefix: mariadb
      storageAccountName: devstoreaccount1
      storageAccountKey:
        name: azurite-key
        key: storageAccountKey
      tls:
        enabled: true
        caSecretKeyRef:
          name: azurite-certs
          key: cert.pem
```

Refer to the [physical backup storage](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/physical_backup.md#azure-blob-storage-credentials) docs for additional details.

It is important to note that we couldn't find the bandwidth to support it for `Backup` resource (logical backup) in this release, [contributions are welcomed](https://github.com/mariadb-operator/mariadb-operator/issues/1653)!

Kudos to our co-maintainer [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) for smoothly driving this feature end-to-end!

#### On-demand `PhysicalBackup`

We have introduced the ability to trigger on-demand physical backup manually. For doing so, you need to provide an identifier in the `schedule.onDemand` field of the `PhysicalBackup` resource:

```yaml
apiVersion: k8s.mariadb.com/v1alpha1
kind: PhysicalBackup
metadata:
  name: physicalbackup
spec:
  schedule:
    onDemand: "1"
```

Once scheduled, the operator tracks the identifier under the status subresource. If the identifier in the status differs from `schedule.onDemand`, the operator will trigger a new physical backup.

Refer to the [physical backup scheduling](https://github.com/mariadb-operator/mariadb-operator/blob/main/docs/physical_backup.md#scheduling) docs for additional details.

##### Behaviour change in `targetRecoveryTime`

To satisfy requirements of point-in-time recovery, we have unified the behaviour of the `bootstrapFrom.targetRecoveryTime` field in the `MariaDB` object: Logical and physical backup files whose timestamp is closest to `targetRecoveryTime`, **but not after**, will be matched.

Please take this into account when upgrading to this version.

##### Change in Helm `values.yaml`

`config` has been split into `repository` and `tag` to facilitate overriding the image registry (see [#&#8203;1632](https://github.com/mariadb-operator/mariadb-operator/pull/1632)). Please update your `values.yaml` from:

```yaml
config:
  mariadbImageName: docker-registry1.mariadb.com/library/mariadb
  maxscaleImage: docker-registry2.mariadb.com/mariadb/maxscale:23.08.5
  exporterImage: prom/mysqld-exporter:v0.15.1
  exporterMaxscaleImage: docker-registry2.mariadb.com/mariadb/maxscale-prometheus-exporter-ubi:v0.0.1
```

to the following format:

```yaml
config:
  mariadbImage:
    repository: docker-registry1.mariadb.com/library/mariadb
    tag: 11.8.5
  maxscaleImage:
    repository: docker-registry2.mariadb.com/mariadb/maxscale
    tag: 23.08.5
  exporterImage:
    repository: prom/mysqld-exporter
    tag: v0.15.1
  exporterMaxscaleImage:
    repository: docker-registry2.mariadb.com/mariadb/maxscale-prometheus-exporter-ubi
    tag: v0.0.1
```

##### Updated dependencies

| Platform/Component | Version |
| ------------------ | ------- |
| Kubernetes         | 1.35    |
| Go                 | 1.26.1  |
| controller-runtime | 0.23.3  |

#### Updated roadmap

The next feature to be supported is the new multi-cluster topology. Stay tuned!

- [x] ~~[Point In Time Recovery (PITR)](https://github.com/mariadb-operator/mariadb-operator/issues/507)~~
- [ ] [Multi-cluster topology](https://github.com/mariadb-operator/mariadb-operator/issues/1543)

***

#### Community

Contributions of any kind are always welcome: adding yourself to the [list of adopters](https://github.com/mariadb-operator/mariadb-operator/blob/main/ADOPTERS.md), reporting issues, submitting pull requests, or simply starring the project! 🌟

#### Enterprise

For enterprise users, see the **[MariaDB Enterprise Operator](https://mariadb.com/products/enterprise/kubernetes-operator/)**, a commercially supported Kubernetes operator from MariaDB with additional enterprise-grade features.

#### What's Changed

- feat: Use primary Service by default for HA mariaDB connections by [@&#8203;softho0n](https://github.com/softho0n) in [#&#8203;1575](https://github.com/mariadb-operator/mariadb-operator/pull/1575)
- feat: add loadBalancerClass field to ServiceTemplate by [@&#8203;yangminglintw](https://github.com/yangminglintw) in [#&#8203;1589](https://github.com/mariadb-operator/mariadb-operator/pull/1589)
- fix: use standard compression extensions and add magic bytes validation by [@&#8203;yangminglintw](https://github.com/yangminglintw) in [#&#8203;1588](https://github.com/mariadb-operator/mariadb-operator/pull/1588)
- Make volumes and volumeMounts mutable by [@&#8203;hedgieinsocks](https://github.com/hedgieinsocks) in [#&#8203;1601](https://github.com/mariadb-operator/mariadb-operator/pull/1601)
- chore: Bump to latest go by [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) in [#&#8203;1630](https://github.com/mariadb-operator/mariadb-operator/pull/1630)
- make imagePullSecrets mutable by [@&#8203;dmaes](https://github.com/dmaes) in [#&#8203;1614](https://github.com/mariadb-operator/mariadb-operator/pull/1614)
- split config images in repository and tag by [@&#8203;dmaes](https://github.com/dmaes) in [#&#8203;1632](https://github.com/mariadb-operator/mariadb-operator/pull/1632)
- Galera recovery: disable bootstrap on other pods before bootstrapping by [@&#8203;infocusmodereal](https://github.com/infocusmodereal) in [#&#8203;1631](https://github.com/mariadb-operator/mariadb-operator/pull/1631)
- Bump github.com/minio/minio-go/v7 from 7.0.97 to 7.0.98 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1585](https://github.com/mariadb-operator/mariadb-operator/pull/1585)
- Bump ghcr.io/devcontainers/features/docker-in-docker from 2.13.0 to 2.16.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1624](https://github.com/mariadb-operator/mariadb-operator/pull/1624)
- Bump ghcr.io/devcontainers/features/kubectl-helm-minikube from 1.2.2 to 1.3.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1623](https://github.com/mariadb-operator/mariadb-operator/pull/1623)
- Bump goreleaser/goreleaser-action from 6 to 7 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1620](https://github.com/mariadb-operator/mariadb-operator/pull/1620)
- Bump github.com/onsi/gomega from 1.38.3 to 1.39.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1581](https://github.com/mariadb-operator/mariadb-operator/pull/1581)
- Bump crate-ci/typos from 1.41.0 to 1.44.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1625](https://github.com/mariadb-operator/mariadb-operator/pull/1625)
- Bump github.com/onsi/ginkgo/v2 from 2.27.3 to 2.27.5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1586](https://github.com/mariadb-operator/mariadb-operator/pull/1586)
- Bump github.com/cert-manager/cert-manager from 1.18.2 to 1.19.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1580](https://github.com/mariadb-operator/mariadb-operator/pull/1580)
- Bump github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring from 0.87.1 to 0.88.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1579](https://github.com/mariadb-operator/mariadb-operator/pull/1579)
- Disable service links in MariaDB and MaxScale pod specs by [@&#8203;usiegj00](https://github.com/usiegj00) in [#&#8203;1635](https://github.com/mariadb-operator/mariadb-operator/pull/1635)
- Fix finalizer for ExternalMariDB by [@&#8203;snaax](https://github.com/snaax) in [#&#8203;1606](https://github.com/mariadb-operator/mariadb-operator/pull/1606)
- test: Added int tests for sql resources with external mariadb deletion by [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) in [#&#8203;1649](https://github.com/mariadb-operator/mariadb-operator/pull/1649)
- Bump github.com/minio/minio-go/v7 from 7.0.98 to 7.0.99 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1648](https://github.com/mariadb-operator/mariadb-operator/pull/1648)
- Bump golang.org/x/sync from 0.19.0 to 0.20.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1645](https://github.com/mariadb-operator/mariadb-operator/pull/1645)
- Bump docker/build-push-action from 6 to 7 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1644](https://github.com/mariadb-operator/mariadb-operator/pull/1644)
- Bump docker/setup-qemu-action from 3 to 4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1642](https://github.com/mariadb-operator/mariadb-operator/pull/1642)
- Bump github.com/go-chi/chi/v5 from 5.2.3 to 5.2.5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1641](https://github.com/mariadb-operator/mariadb-operator/pull/1641)
- Bump docker/login-action from 3 to 4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1646](https://github.com/mariadb-operator/mariadb-operator/pull/1646)
- Bump ghcr.io/devcontainers/features/docker-in-docker from 2.16.0 to 2.16.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1640](https://github.com/mariadb-operator/mariadb-operator/pull/1640)
- Bump docker/setup-buildx-action from 3 to 4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1638](https://github.com/mariadb-operator/mariadb-operator/pull/1638)
- Bump github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring from 0.88.0 to 0.89.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1643](https://github.com/mariadb-operator/mariadb-operator/pull/1643)
- Bump golang from 1.25.7-alpine3.23 to 1.26.1-alpine3.23 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1639](https://github.com/mariadb-operator/mariadb-operator/pull/1639)
- feat: Latest controller-runtime. Webhook changes, New Events API by [@&#8203;Michaelpalacce](https://github.com/Michaelpalacce) in [#&#8203;1651](https://github.com/mariadb-operator/mariadb-operator/pull/1651)
- Support for ephemeral volumes in `MariaDB` by [@&#8203;mmontes11](https://github.com/mmontes11) in [#&#8203;1650](https://github.com/mariadb-operator/mariadb-operator/pull/1650)
- fix: accept compressed backup files in logical restore by [@&#8203;voron](https://github.com/voron) in [#&#8203;1655](https://github.com/mariadb-operator/mariadb-operator/pull/1655)
- Fix typo: syncrhonous -> synchronous by [@&#8203;sjmudd](https://github.com/sjmudd) in [#&#8203;1657](https://github.com/mariadb-operator/mariadb-operator/pull/1657)
- Release 26.03: `PointInTimeRecovery`, Azure Blob Storage & on-demand `PhysicalBackups` by [@&#8203;mmontes11](https://github.com/mmontes11) in [#&#8203;1517](https://github.com/mariadb-operator/mariadb-operator/pull/1517)

#### New Contributors

- [@&#8203;softho0n](https://github.com/softho0n) made their first contribution in [#&#8203;1575](https://github.com/mariadb-operator/mariadb-operator/pull/1575)
- [@&#8203;yangminglintw](https://github.com/yangminglintw) made their first contribution in [#&#8203;1589](https://github.com/mariadb-operator/mariadb-operator/pull/1589)
- [@&#8203;dmaes](https://github.com/dmaes) made their first contribution in [#&#8203;1614](https://github.com/mariadb-operator/mariadb-operator/pull/1614)
- [@&#8203;infocusmodereal](https://github.com/infocusmodereal) made their first contribution in [#&#8203;1631](https://github.com/mariadb-operator/mariadb-operator/pull/1631)
- [@&#8203;usiegj00](https://github.com/usiegj00) made their first contribution in [#&#8203;1635](https://github.com/mariadb-operator/mariadb-operator/pull/1635)
- [@&#8203;voron](https://github.com/voron) made their first contribution in [#&#8203;1655](https://github.com/mariadb-operator/mariadb-operator/pull/1655)
- [@&#8203;sjmudd](https://github.com/sjmudd) made their first contribution in [#&#8203;1657](https://github.com/mariadb-operator/mariadb-operator/pull/1657)

**Full Changelog**: <https://github.com/mariadb-operator/mariadb-operator/compare/25.10.4...26.3.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiY2hhcnQiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4706
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
2026-03-14 23:54:24 +00:00
510f059037 chore(deps): update ghcr.io/haveagitgat/tdarr_node docker tag to v2.63.01 (#4737)
Some checks failed
render-manifests-push / render-manifests-push (push) Has been skipped
lint-test-helm / lint-helm (push) Successful in 11s
renovate / renovate (push) Has been cancelled
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/haveagitgat/tdarr_node](https://github.com/HaveAGitGat/tdarr_express_be) | minor | `2.62.01` → `2.63.01` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: #4737
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
2026-03-14 23:51:38 +00:00
9fce102ad0 chore(deps): update ghcr.io/haveagitgat/tdarr docker tag to v2.63.01 (#4736)
All checks were successful
render-manifests-push / render-manifests-push (push) Has been skipped
lint-test-helm / lint-helm (push) Successful in 19s
renovate / renovate (push) Successful in 3m29s
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/haveagitgat/tdarr](https://github.com/HaveAGitGat/tdarr_express_be) | minor | `2.62.01` → `2.63.01` |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: #4736
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
2026-03-14 23:19:45 +00:00
56f7191743 chore(deps): update harbor.alexlebens.net/images/site-profile docker tag to v3.12.1 (#4738)
All checks were successful
render-manifests-push / render-manifests-push (push) Has been skipped
lint-test-helm / lint-helm (push) Successful in 48s
renovate / renovate (push) Successful in 5m47s
2026-03-14 23:02:43 +00:00
23 changed files with 1451 additions and 464 deletions

View File

@@ -14,7 +14,7 @@ on:
- 'hosts/**'
env:
BASE_BRANCH: "origin/${{ gitea.base_ref }}"
BASE_BRANCH: "origin/${{ github.base_ref }}"
jobs:
lint-docker-compose:
@@ -36,19 +36,20 @@ jobs:
id: branch-exists
if: github.event_name == 'push' || steps.check-branch-exists.outputs.exists == 'true' && github.event_name == 'pull_request'
run: |
if [ ${{ github.event_name == 'push' }} ]; then
if [ "${{ github.event_name }}" == "push" ]; then
echo ">> Action is from a push event, will continue with linting"
else
echo ">> Branch ${{ gitea.base_ref }} exists, will continue with linting"
echo ">> Branch ${{ github.base_ref }} exists, will continue with linting"
fi
echo ""
echo "----"
echo "exists=true" >> $GITEA_OUTPUT
echo "exists=true" >> $GITHUB_OUTPUT
- name: Set up Node.js
- name: Set Up Node.js
if: steps.branch-exists.outputs.exists == 'true'
uses: actions/setup-node@v6
with:
@@ -58,58 +59,48 @@ jobs:
id: check-dir-changes
if: steps.branch-exists.outputs.exists == 'true'
run: |
CHANGED_COMPOSE=()
echo ">> Target branch for diff is: ${BASE_BRANCH}"
if [ "${{ github.event_name }}" == "pull_request" ]; then
DIFF_TARGET="${BASE_BRANCH}"
echo ""
echo ">> Checking for changes in a pull request ..."
GIT_DIFF=$(git diff --name-only "${BASE_BRANCH}" | xargs -I {} dirname {} | sort -u)
else
DIFF_TARGET="${{ github.event.before }}..HEAD"
echo ""
echo ">> Checking for changes from a push ..."
GIT_DIFF=$(git diff --name-only ${{ gitea.event.before }}..HEAD | xargs -I {} dirname {} | sort -u)
fi
if [ -n "${GIT_DIFF}" ]; then
echo ""
echo ">> Changes detected:"
echo "$GIT_DIFF"
for path in $GIT_DIFF; do
if echo "$path" | grep -q -E "hosts/[^/]+/[^/]+"; then
echo ""
echo ">> Adding path: $path"
CHANGED_COMPOSE+=$(echo "$path")
CHANGED_COMPOSE+=$(echo " ")
fi
done
else
echo ""
echo ">> No changes detected"
fi
CHANGED_COMPOSE=$(git diff --name-only "${DIFF_TARGET}" | grep -E "^hosts/[^/]+/[^/]+/" | cut -d/ -f1,2,3 | sort -u || true)
if [ -n "${CHANGED_COMPOSE}" ]; then
echo ""
echo ">> Compose to Lint:"
echo "$(echo "${CHANGED_COMPOSE}" | sort -u)"
echo ""
echo "${CHANGED_COMPOSE}"
CHANGED_COMPOSE_CSV=$(echo "$CHANGED_COMPOSE" | paste -sd ',' -)
echo ""
echo "----"
echo "changes-detected=true" >> $GITEA_OUTPUT
echo "compose-dir<<EOF" >> $GITEA_OUTPUT
echo "$(echo "${CHANGED_COMPOSE}" | sort -u)" >> $GITEA_OUTPUT
echo "EOF" >> $GITEA_OUTPUT
echo "changes-detected=true" >> $GITHUB_OUTPUT
echo "compose-dir-csv=${CHANGED_COMPOSE_CSV}" >> $GITHUB_OUTPUT
echo "compose-dir<<EOF" >> $GITHUB_OUTPUT
echo "${CHANGED_COMPOSE}" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
else
echo ""
echo ">> Did not find any docker compose files to lint"
echo ""
echo "----"
echo "changes-detected=false" >> $GITEA_OUTPUT
echo "changes-detected=false" >> $GITHUB_OUTPUT
fi
- name: Lint Docker Compose
@@ -117,25 +108,27 @@ jobs:
env:
CHANGED_COMPOSE: ${{ steps.check-dir-changes.outputs.compose-dir }}
run: |
echo ">> Running dclint on changed compose files:"
echo "$CHANGED_COMPOSE"
echo ">> Running dclint on changed compose files ..."
for COMPOSE in $CHANGED_COMPOSE; do
echo ">> Linting ${COMPOSE} ..."
npx dclint ${COMPOSE}
for compose in $CHANGED_COMPOSE; do
echo ">> Linting $compose ..."
npx dclint $compose
done
echo ""
echo "----"
- name: ntfy Failed
uses: niniyas/ntfy-action@master
if: failure()
with:
url: '${{ secrets.NTFY_URL }}'
topic: '${{ secrets.NTFY_TOPIC }}'
title: 'Test Failure - Infrastructure'
title: 'Docker Compose Test Failure'
priority: 3
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
tags: action,failed
details: 'Docker linting on Pull Request for Infrastructure has failed!'
details: "Docker linting for compose dirs: ${{ steps.check-dir-changes.outputs.compose-dir-csv }}"
icon: 'https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png'
actions: '[{"action": "view", "label": "Open Gitea", "url": "https://gitea.alexlebens.dev/alexlebens/infrastructure/actions?workflow=lint-test-docker-pull.yaml", "clear": true}]'
image: true
actions: '[{"action": "view", "label": "View Logs", "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", "clear": true}]'

View File

@@ -15,11 +15,17 @@ on:
env:
CLUSTER: cl01tl
BASE_BRANCH: "origin/${{ gitea.base_ref }}"
BASE_BRANCH: "origin/${{ github.base_ref }}"
# renovate: datasource=github-releases depName=yannh/kubeconform
KUBECONFORM_VERSION: "v0.6.7"
jobs:
lint-helm:
runs-on: ubuntu-js
outputs:
chart-dir: ${{ steps.check-dir-changes.outputs.chart-dir }}
chart-dir-csv: ${{ steps.check-dir-changes.outputs.chart-dir-csv }}
changes-detected: ${{ steps.check-dir-changes.outputs.changes-detected }}
steps:
- name: Checkout
uses: actions/checkout@v6
@@ -31,88 +37,91 @@ jobs:
if: github.event_name == 'pull_request'
uses: GuillaumeFalourd/branch-exists@v1.1
with:
branch: ${{ gitea.base_ref }}
branch: ${{ github.base_ref }}
- name: Report Branch Exists
id: branch-exists
if: github.event_name == 'push' || steps.check-branch-exists.outputs.exists == 'true' && github.event_name == 'pull_request'
run: |
if [ ${{ github.event_name == 'push' }} ]; then
if [ "${{ github.event_name }}" == "push" ]; then
echo ">> Action is from a push event, will continue with linting"
else
echo ">> Branch ${{ gitea.base_ref }} exists, will continue with linting"
echo ">> Branch ${{ github.base_ref }} exists, will continue with linting"
fi
echo ""
echo "----"
echo "exists=true" >> $GITEA_OUTPUT
echo "exists=true" >> $GITHUB_OUTPUT
- name: Set up Helm
- name: Set Up Helm
if: steps.branch-exists.outputs.exists == 'true'
uses: azure/setup-helm@v4
with:
token: ${{ secrets.GITEA_TOKEN }}
version: v3.19.2
# renovate: datasource=github-releases depName=helm/helm
version: v4.1.3
cache: true
- name: Cache Helm Dependencies
if: steps.branch-exists.outputs.exists == 'true'
uses: actions/cache@v5
with:
path: |
~/.cache/helm
~/.config/helm
key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }}
restore-keys: |
helm-cache-${{ runner.os }}-
- name: Check Directories for Changes
id: check-dir-changes
if: steps.branch-exists.outputs.exists == 'true'
run: |
CHANGED_CHARTS=()
echo ">> Target branch for diff is: ${BASE_BRANCH}"
if [ "${{ github.event_name }}" == "pull_request" ]; then
DIFF_TARGET="${BASE_BRANCH}"
echo ""
echo ">> Checking for changes in a pull request ..."
GIT_DIFF=$(git diff --name-only "${BASE_BRANCH}" | xargs -I {} dirname {} | sort -u)
else
DIFF_TARGET="${{ github.event.before }}..HEAD"
echo ""
echo ">> Checking for changes from a push ..."
GIT_DIFF=$(git diff --name-only ${{ gitea.event.before }}..HEAD | xargs -I {} dirname {} | sort -u)
fi
if [ -n "${GIT_DIFF}" ]; then
echo ""
echo ">> Changes detected:"
echo "$GIT_DIFF"
for path in $GIT_DIFF; do
if echo "$path" | grep -q -E "clusters/[^/]+/helm/[^/]+"; then
echo ""
echo ">> Adding path: $path"
CHANGED_CHARTS+=$(echo "$path" | awk -F '/' '{print $4}')
CHANGED_CHARTS+=$(echo "\n")
fi
done
else
echo ""
echo ">> No changes detected"
fi
CHANGED_CHARTS=$(git diff --name-only "${DIFF_TARGET}" | grep -E "^clusters/${CLUSTER}/helm/" | awk -F '/' '{print $4}' | sort -u || true)
if [ -n "${CHANGED_CHARTS}" ]; then
echo ""
echo ">> Chart to Lint:"
echo "$(echo "${CHANGED_CHARTS}" | sort -u)"
echo ""
echo "${CHANGED_CHARTS}"
CHANGED_CHARTS_CSV=$(echo "$CHANGED_CHARTS" | paste -sd ',' -)
echo ""
echo "----"
echo "changes-detected=true" >> $GITEA_OUTPUT
echo "chart-dir<<EOF" >> $GITEA_OUTPUT
echo "$(echo "${CHANGED_CHARTS}" | sort -u)" >> $GITEA_OUTPUT
echo "EOF" >> $GITEA_OUTPUT
echo "changes-detected=true" >> $GITHUB_OUTPUT
echo "chart-dir-csv=${CHANGED_CHARTS_CSV}" >> $GITHUB_OUTPUT
echo "chart-dir<<EOF" >> $GITHUB_OUTPUT
echo "${CHANGED_CHARTS}" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
else
echo ""
echo ">> Did not find any helm charts files to lint"
echo ""
echo "----"
echo "changes-detected=false" >> $GITEA_OUTPUT
echo "changes-detected=false" >> $GITHUB_OUTPUT
fi
- name: Add Repositories
@@ -121,68 +130,238 @@ jobs:
CHANGED_CHARTS: ${{ steps.check-dir-changes.outputs.chart-dir }}
run: |
echo ">> Adding repositories for chart dependencies ..."
for dir in ${CHANGED_CHARTS}; do
helm dependency list --max-col-width 120 clusters/${CLUSTER}/helm/$dir 2> /dev/null \
| tail +2 | head -n -1 \
| awk '{ print "helm repo add " $1 " " $3 }' \
| while read cmd; do
if [[ "$cmd" == "*oci://*" ]]; then
echo ">> Ignoring OCI repo"
else
echo ">> Command: $cmd"
echo "$cmd" | sh;
echo ""
for DIR in ${CHANGED_CHARTS}; do
helm dependency list --max-col-width 120 clusters/${CLUSTER}/helm/${DIR} 2> /dev/null \
| tail -n +2 \
| awk 'NF > 0 { print $1, $3 }' \
| while read -r REPO_NAME REPO_URL; do
if [[ "${REPO_URL}" == oci://* ]]; then
echo ">> Ignoring OCI repo: ${REPO_URL}"
elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then
helm repo add "${REPO_NAME}" "${REPO_URL}"
fi
done || true
done
if helm repo list | tail +2 | read -r; then
if helm repo list > /dev/null 2>&1; then
echo ""
echo ">> Update repository cache ..."
helm repo update
fi
echo ""
echo "----"
- name: Lint Helm Chart
id: lint
if: steps.check-dir-changes.outputs.changes-detected == 'true'
env:
CHANGED_CHARTS: ${{ steps.check-dir-changes.outputs.chart-dir }}
run: |
EXIT_CODE=0
FAILED_CHARTS=""
echo ">> Running linting on changed charts ..."
for dir in ${CHANGED_CHARTS}; do
chart_path=clusters/${CLUSTER}/helm/$dir
chart_name=$(basename "$chart_path")
for DIR in ${CHANGED_CHARTS}; do
CHART_PATH="clusters/${CLUSTER}/helm/${DIR}"
CHART_NAME=$(basename "${CHART_PATH}")
if [ -f "$chart_path/Chart.yaml" ]; then
cd $chart_path
if [ -f "${CHART_PATH}/Chart.yaml" ]; then
echo ""
echo ">> Building helm dependency for ${CHART_NAME} ..."
helm dependency build "${CHART_PATH}" --skip-refresh
echo ""
echo ">> Building helm dependency ..."
helm dependency build --skip-refresh
echo ">> Linting helm chart ${CHART_NAME} ..."
echo ""
echo ">> Linting helm ..."
helm lint --namespace "$chart_name"
if ! helm lint "${CHART_PATH}" --namespace "default"; then
EXIT_CODE=1
if [ -z "${FAILED_CHARTS}" ]; then
FAILED_CHARTS="${DIR}"
else
FAILED_CHARTS="${FAILED_CHARTS}, ${DIR}"
fi
fi
else
echo ""
echo ">> Directory $chart_path does not contain a Chart.yaml. Skipping ..."
echo ""
echo ">> Directory ${CHART_PATH} does not contain a Chart.yaml. Skipping ..."
fi
done
echo ""
echo "----"
echo "failed-charts=${FAILED_CHARTS}" >> "$GITHUB_OUTPUT"
exit $EXIT_CODE
- name: ntfy Failed
uses: niniyas/ntfy-action@master
if: failure()
with:
url: '${{ secrets.NTFY_URL }}'
topic: '${{ secrets.NTFY_TOPIC }}'
title: 'Test Failure - Infrastructure'
title: 'Helm Test Failure'
priority: 3
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
tags: action,failed
details: 'Helm linting on Pull Request for Infrastructure has failed!'
details: "Helm linting for cluster '${CLUSTER}' failed on charts: ${{ steps.lint.outputs.failed-charts }}"
icon: 'https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png'
actions: '[{"action": "view", "label": "Open Gitea", "url": "https://gitea.alexlebens.dev/alexlebens/infrastructure/actions?workflow=lint-test-helm-pull.yaml", "clear": true}]'
actions: '[{"action": "view", "label": "View Run", "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", "clear": true}]'
image: true
validate-kubeconform:
needs: lint-helm
runs-on: ubuntu-js
if: |
needs.lint-helm.result == 'success' &&
needs.lint-helm.outputs.changes-detected == 'true' &&
github.event_name == 'pull_request'
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install Kubeconform
run: |
echo ">> Downloading Kubeconform ${{ env.KUBECONFORM_VERSION }} ..."
wget -q https://github.com/yannh/kubeconform/releases/download/${{ env.KUBECONFORM_VERSION }}/kubeconform-linux-amd64.tar.gz
echo ""
echo ">> Extracting Kubeconform ..."
tar xf kubeconform-linux-amd64.tar.gz
echo ""
echo ">> Installing Kubeconform ..."
sudo mv kubeconform /usr/local/bin/
echo ""
echo ">> Verifying installation ..."
kubeconform -v
echo ""
echo "----"
- name: Set Up Helm
uses: azure/setup-helm@v4
with:
token: ${{ secrets.GITEA_TOKEN }}
# renovate: datasource=github-releases depName=helm/helm
version: v4.1.3
cache: true
- name: Cache Helm Dependencies
uses: actions/cache@v5
with:
path: |
~/.cache/helm
~/.config/helm
key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }}
restore-keys: |
helm-cache-${{ runner.os }}-
- name: Add Repositories
env:
CHANGED_CHARTS: ${{ needs.lint-helm.outputs.chart-dir }}
run: |
echo ">> Adding repositories for chart dependencies ..."
echo ""
for DIR in ${CHANGED_CHARTS}; do
helm dependency list --max-col-width 120 clusters/${CLUSTER}/helm/${DIR} 2> /dev/null \
| tail -n +2 \
| awk 'NF > 0 { print $1, $3 }' \
| while read -r REPO_NAME REPO_URL; do
if [[ "${REPO_URL}" == oci://* ]]; then
echo ">> Ignoring OCI repo: ${REPO_URL}"
elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then
helm repo add "${REPO_NAME}" "${REPO_URL}"
fi
done || true
done
if helm repo list > /dev/null 2>&1; then
echo ""
echo ">> Update repository cache ..."
helm repo update
fi
echo ""
echo "----"
- name: Validate Rendered Templates
id: validate
env:
CHANGED_CHARTS: ${{ needs.lint-helm.outputs.chart-dir }}
run: |
SCHEMA_LOCATIONS="-schema-location default -schema-location https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json"
EXIT_CODE=0
FAILED_CHARTS=""
for DIR in ${CHANGED_CHARTS}; do
CHART_PATH="clusters/${CLUSTER}/helm/${DIR}"
echo ""
echo ">> Validating: ${DIR}"
helm dependency build "${CHART_PATH}" --skip-refresh
if ! helm template "${DIR}" "${CHART_PATH}" --include-crds --namespace default --api-versions "gateway.networking.k8s.io/v1/HTTPRoute" | \
kubeconform \
${SCHEMA_LOCATIONS} \
-ignore-missing-schemas \
-strict \
-summary; then
EXIT_CODE=1
if [ -z "${FAILED_CHARTS}" ]; then
FAILED_CHARTS="${DIR}"
else
FAILED_CHARTS="${FAILED_CHARTS}, ${DIR}"
fi
fi
done
echo ""
echo "----"
echo "failed-charts=${FAILED_CHARTS}" >> "$GITHUB_OUTPUT"
exit $EXIT_CODE
- name: ntfy Failed
uses: niniyas/ntfy-action@master
if: failure()
with:
url: '${{ secrets.NTFY_URL }}'
topic: '${{ secrets.NTFY_TOPIC }}'
title: 'Kubeconform Test Failure'
priority: 3
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
tags: action,failed
details: "Kubeconform for cluster '${CLUSTER}' failed on charts: ${{ steps.validate.outputs.failed-charts }}"
icon: 'https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png'
actions: '[{"action": "view", "label": "View Run", "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", "clear": true}]'
image: true

View File

@@ -1,13 +1,14 @@
name: render-manifests-automerge
on:
pull_request:
branches:
- main
paths:
- 'clusters/cl01tl/helm/**'
types:
- closed
workflow_dispatch:
# pull_request:
# branches:
# - main
# paths:
# - 'clusters/cl01tl/helm/**'
# types:
# - closed
env:
CLUSTER: cl01tl
@@ -46,6 +47,16 @@ jobs:
method: kubeconfig
kubeconfig: ${{ secrets.KUBECONFIG }}
- name: Cache Helm Dependencies
uses: actions/cache@v5
with:
path: |
~/.cache/helm
~/.config/helm
key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }}
restore-keys: |
helm-cache-${{ runner.os }}-
- name: Prepare Manifest Branch
id: prepare-manifest-branch
run: |
@@ -53,10 +64,12 @@ jobs:
BRANCH_NAME="${BRANCH_NAME_BASE}-$(date +%Y%m%d%H%M%S)"
echo ""
echo ">> Configure git to use gitea-bot as user ..."
git config user.name "gitea-bot"
git config user.email "gitea-bot@alexlebens.net"
echo ""
echo ">> Creating branch ..."
git checkout -b $BRANCH_NAME
@@ -67,38 +80,31 @@ jobs:
- name: Check which Directories have Changes
id: check-dir-changes
run: |
cd ${MAIN_DIR}
RENDER_DIR=()
cd "${MAIN_DIR}"
echo ""
echo ">> Checking for changes from HEAD^..HEAD ..."
GIT_DIFF=$(git diff --name-only HEAD^..HEAD | xargs -I {} dirname {} | sort -u | grep -E "clusters/[^/]+/helm/[^/]+")
if [ -n "${GIT_DIFF}" ]; then
echo ">> Changes detected:"
echo "$GIT_DIFF"
for path in $GIT_DIFF; do
RENDER_DIR+=$(echo "$path" | awk -F '/' '{print $4}')
RENDER_DIR+=$(echo " ")
done
else
echo ">> No changes detected"
fi
# Extract the chart names from the git diff
RENDER_DIR=$(git diff --name-only HEAD^..HEAD | grep -E "^clusters/${CLUSTER}/helm/" | awk -F '/' '{print $4}' | sort -u || true)
if [ -n "${RENDER_DIR}" ]; then
echo ""
echo ">> Directories to Render:"
echo "$(echo "${RENDER_DIR}" | sort -u)"
echo "${RENDER_DIR}"
echo "----"
echo "changes-detected=true" >> $GITEA_OUTPUT
echo "render-dir<<EOF" >> $GITEA_OUTPUT
echo "$(echo "${RENDER_DIR}" | sort -u)" >> $GITEA_OUTPUT
echo "EOF" >> $GITEA_OUTPUT
echo "changes-detected=true" >> "$GITEA_OUTPUT"
echo "render-dir<<EOF" >> "$GITEA_OUTPUT"
echo "${RENDER_DIR}" >> "$GITEA_OUTPUT"
echo "EOF" >> "$GITEA_OUTPUT"
else
echo "changes-detected=false" >> $GITEA_OUTPUT
echo ""
echo ">> No chart changes detected"
echo "changes-detected=false" >> "$GITEA_OUTPUT"
fi
- name: Add Repositories
@@ -106,25 +112,31 @@ jobs:
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd ${MAIN_DIR}
cd "${MAIN_DIR}"
echo ""
echo ">> Adding repositories for chart dependencies ..."
for dir in ${RENDER_DIR}; do
helm dependency list --max-col-width 120 ${MAIN_DIR}/clusters/${CLUSTER}/helm/$dir 2> /dev/null \
| tail +2 | head -n -1 \
| awk '{ print "helm repo add " $1 " " $3 }' \
| while read cmd; do
if [[ "$cmd" == "*oci://*" ]]; then
echo ">> Ignoring OCI repo"
else
echo "$cmd" | sh;
for DIR in ${RENDER_DIR}; do
helm dependency list --max-col-width 120 "${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" 2> /dev/null \
| tail -n +2 \
| awk 'NF > 0 { print $1, $3 }' \
| while read -r REPO_NAME REPO_URL; do
if [[ "${REPO_URL}" == oci://* ]]; then
echo ""
echo ">> Ignoring OCI repo: ${REPO_URL}"
elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then
helm repo add "${REPO_NAME}" "${REPO_URL}"
fi
done || true
done
if helm repo list | tail +2 | read -r; then
if helm repo list > /dev/null 2>&1; then
echo ""
echo ">> Update repository cache ..."
helm repo update
fi
echo "----"
@@ -134,15 +146,16 @@ jobs:
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
echo ""
echo ">> Remove manfiest files and rebuild from source ..."
for dir in ${RENDER_DIR}; do
chart_path=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$dir
for DIR in ${RENDER_DIR}; do
CHART_PATH=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${DIR}
echo "$chart_path"
rm -rf $chart_path/*
echo "${CHART_PATH}"
rm -rf ${CHART_PATH}/*
done
echo "----"
@@ -155,60 +168,57 @@ jobs:
run: |
cd ${MAIN_DIR}
echo ""
echo ">> Rendering Manifests ..."
for dir in ${RENDER_DIR}; do
chart_path=${MAIN_DIR}/clusters/${CLUSTER}/helm/$dir
chart_name=$(basename "$chart_path")
render_chart() {
local DIR="$1"
local CHART_PATH="${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}"
local CHART_NAME=$(basename "${CHART_PATH}")
echo ""
echo ""
echo ">> Rendering chart: $chart_name"
echo ">> Chart path $chart_path"
echo ">> Rendering ..."
echo ">> Chart: ${CHART_NAME}"
echo ">> Path: ${CHART_PATH}"
if [ -f "$chart_path/Chart.yaml" ]; then
OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$chart_name/"
TEMPLATE=""
if [ -f "${CHART_PATH}/Chart.yaml" ]; then
local OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${CHART_NAME}/"
mkdir -p ${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$chart_name
cd $chart_path
mkdir -p "${OUTPUT_FOLDER}"
cd "${CHART_PATH}"
echo ""
echo ">> Updating helm dependency ..."
helm dependency update --skip-refresh
echo ">> Updating helm dependencies ..."
helm dependency update --skip-refresh > /dev/null
echo ""
echo ">> Building helm dependency ..."
helm dependency build --skip-refresh
echo ">> Linting helm chart ..."
helm lint --namespace "${CHART_NAME}" --quiet
echo ""
echo ">> Linting helm ..."
helm lint --namespace "$chart_name"
echo ""
echo ">> Rendering templates ..."
case "$chart_name" in
local NAMESPACE="${CHART_NAME}"
case "${CHART_NAME}" in
"stack")
NAMESPACE="argocd"
echo ""
echo ">> Special Rendering for stack into argocd namespace ..."
TEMPLATE=$(helm template $chart_name ./ --namespace argocd --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
echo ">> Special Rendering into 'argocd' namespace ..."
;;
"cilium" | "coredns" | "metrics-server" |"prometheus-operator-crds")
"cilium" | "coredns" | "metrics-server" | "prometheus-operator-crds")
NAMESPACE="kube-system"
echo ""
echo ">> Special Rendering for $chart_name into kube-system namespace ..."
TEMPLATE=$(helm template $chart_name ./ --namespace kube-system --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
echo ">> Special Rendering for ${CHART_NAME} into 'kube-system' namespace ..."
;;
*)
echo ""
echo ">> Standard Rendering for $chart_name ..."
TEMPLATE=$(helm template "$chart_name" ./ --namespace "$chart_name" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
;;
echo ">> Standard Rendering for ${CHART_NAME} ..."
esac
echo ""
echo ">> Formating rendered template ..."
echo "$TEMPLATE" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"$OUTPUT_FOLDER"'" + .kind + "-" + .metadata.name + ".yaml"'
local TEMPLATE
TEMPLATE=$(helm template "${CHART_NAME}" ./ --namespace "${NAMESPACE}" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
# Format and split rendered template
echo "${TEMPLATE}" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"${OUTPUT_FOLDER}"'" + .kind + "-" + .metadata.name + ".yaml"'
# Strip comments again to ensure formatting correctness
for file in "$OUTPUT_FOLDER"/*; do
@@ -216,15 +226,23 @@ jobs:
done
echo ""
echo ">> Manifests for $chart_name rendered to $OUTPUT_FOLDER"
echo ">> Manifests for ${CHART_NAME} rendered to ${OUTPUT_FOLDER}:"
ls $OUTPUT_FOLDER
echo ""
else
echo ""
echo ">> Directory $chart_path does not contain a Chart.yaml. Skipping ..."
echo ">> Directory ${CHART_PATH} does not contain a Chart.yaml. Skipping ..."
echo ""
fi
done
}
export -f render_chart
export MAIN_DIR CLUSTER MANIFEST_DIR
# Run rendering in parallel
for DIR in ${RENDER_DIR}; do
echo "${DIR}"
done | xargs -n 1 -P 4 -I {} bash -c 'render_chart "$@"' _ {}
echo "----"
@@ -232,16 +250,18 @@ jobs:
id: check-changes
if: steps.check-dir-changes.outputs.changes-detected == 'true'
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
GIT_CHANGES=$(git status --porcelain)
if [ -n "$GIT_CHANGES" ]; then
if [ -n "${GIT_CHANGES}" ]; then
echo ""
echo ">> Changes detected"
git status --porcelain
echo "changes-detected=true" >> $GITEA_OUTPUT
else
echo ""
echo ">> No changes detected, skipping PR creation"
fi
@@ -254,19 +274,22 @@ jobs:
env:
BRANCH_NAME: ${{ steps.prepare-manifest-branch.outputs.BRANCH_NAME }}
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
echo ""
echo ">> Commiting changes to ${BRANCH_NAME} ..."
git add .
git commit -m "chore: Update manifests after automerge"
REPO_URL="${{ secrets.REPO_URL }}/${{ gitea.repository }}"
echo ">> Pushing changes to $REPO_URL ..."
git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@$(echo $REPO_URL | sed -e 's|https://||')" ${BRANCH_NAME}
echo ""
echo ">> Pushing changes to ${REPO_URL} ..."
git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@${REPO_URL#*://}" "${BRANCH_NAME}"
echo "----"
echo "push=true" >> $GITEA_OUTPUT
echo "push=true" >> "$GITEA_OUTPUT"
- name: Create Pull Request
id: create-pull-request

View File

@@ -1,10 +1,11 @@
name: render-manifests-dispatch
on:
schedule:
- cron: '0 3 * * *'
workflow_dispatch:
# schedule:
# - cron: '0 15 * * *'
# workflow_dispatch:
env:
CLUSTER: cl01tl
@@ -43,24 +44,39 @@ jobs:
method: kubeconfig
kubeconfig: ${{ secrets.KUBECONFIG }}
- name: Cache Helm Dependencies
uses: actions/cache@v5
with:
path: |
~/.cache/helm
~/.config/helm
key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }}
restore-keys: |
helm-cache-${{ runner.os }}-
- name: Prepare Manifest Branch
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
echo ""
echo ">> Configure git to use gitea-bot as user ..."
git config user.name "gitea-bot"
git config user.email "gitea-bot@alexlebens.net"
echo ""
echo ">> Checking if PR branch exists ..."
if [[ $(git ls-remote --heads origin "${BRANCH_NAME}" | wc -l) -gt 0 ]]; then
if git ls-remote --exit-code --heads origin "${BRANCH_NAME}" > /dev/null 2>&1; then
echo ""
echo ">> Branch '${BRANCH_NAME}' exists, pulling changes ..."
git fetch origin "${BRANCH_NAME}"
git checkout "${BRANCH_NAME}"
git pull --rebase
else
echo ""
echo ">> Branch '${BRANCH_NAME}' does not exist, creating ..."
git checkout -b $BRANCH_NAME
git checkout -b "${BRANCH_NAME}"
fi
echo "----"
@@ -68,25 +84,29 @@ jobs:
- name: Check which Directories have Changes
id: check-dir-changes
run: |
cd ${MAIN_DIR}
RENDER_DIR=()
cd "${MAIN_DIR}"
echo ""
echo ">> Triggered on dispatch, will check all paths ..."
RENDER_DIR+=$(ls clusters/cl01tl/helm/)
# Extract names of charts
RENDER_DIR=$(find "clusters/${CLUSTER}/helm" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort -u)
if [ -n "${RENDER_DIR}" ]; then
echo ""
echo ">> Directories to Render:"
echo "$(echo "${RENDER_DIR}" | sort -u)"
echo "${RENDER_DIR}"
echo "----"
echo "changes-detected=true" >> $GITEA_OUTPUT
echo "render-dir<<EOF" >> $GITEA_OUTPUT
echo "$(echo "${RENDER_DIR}" | sort -u)" >> $GITEA_OUTPUT
echo "EOF" >> $GITEA_OUTPUT
echo "changes-detected=true" >> "$GITEA_OUTPUT"
echo "render-dir<<EOF" >> "$GITEA_OUTPUT"
echo "${RENDER_DIR}" >> "$GITEA_OUTPUT"
echo "EOF" >> "$GITEA_OUTPUT"
else
echo "changes-detected=false" >> $GITEA_OUTPUT
echo ">> No directories found"
echo "changes-detected=false" >> "$GITEA_OUTPUT"
fi
- name: Add Repositories
@@ -94,29 +114,54 @@ jobs:
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd ${MAIN_DIR}
cd "${MAIN_DIR}"
echo ""
echo ">> Adding repositories for chart dependencies ..."
for dir in ${RENDER_DIR}; do
helm dependency list --max-col-width 120 ${MAIN_DIR}/clusters/${CLUSTER}/helm/$dir 2> /dev/null \
| tail +2 | head -n -1 \
| awk '{ print "helm repo add " $1 " " $3 }' \
| while read cmd; do
if [[ "$cmd" == "*oci://*" ]]; then
echo ">> Ignoring OCI repo"
else
echo "$cmd" | sh;
for DIR in ${RENDER_DIR}; do
helm dependency list --max-col-width 120 "${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" 2> /dev/null \
| tail -n +2 \
| awk 'NF > 0 { print $1, $3 }' \
| while read -r REPO_NAME REPO_URL; do
if [[ "${REPO_URL}" == oci://* ]]; then
echo ""
echo ">> Ignoring OCI repo: ${REPO_URL}"
elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then
helm repo add "${REPO_NAME}" "${REPO_URL}"
fi
done || true
done
if helm repo list | tail +2 | read -r; then
if helm repo list > /dev/null 2>&1; then
echo ""
echo ">> Update repository cache ..."
helm repo update
fi
echo "----"
- name: Remove Changed Manifest Files
if: steps.check-dir-changes.outputs.changes-detected == 'true'
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd "${MANIFEST_DIR}"
echo ""
echo ">> Remove manfiest files and rebuild from source ..."
for DIR in ${RENDER_DIR}; do
CHART_PATH=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${DIR}
echo "${CHART_PATH}"
rm -rf ${CHART_PATH}/*
done
echo "----"
- name: Render Helm Manifests
id: render-manifests
if: steps.check-dir-changes.outputs.changes-detected == 'true'
@@ -125,60 +170,57 @@ jobs:
run: |
cd ${MAIN_DIR}
echo ""
echo ">> Rendering Manifests ..."
for dir in ${RENDER_DIR}; do
chart_path=${MAIN_DIR}/clusters/${CLUSTER}/helm/$dir
chart_name=$(basename "$chart_path")
render_chart() {
local DIR="$1"
local CHART_PATH="${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}"
local CHART_NAME=$(basename "${CHART_PATH}")
echo ""
echo ""
echo ">> Rendering chart: $chart_name"
echo ">> Chart path $chart_path"
echo ">> Rendering ..."
echo ">> Chart: ${CHART_NAME}"
echo ">> Path: ${CHART_PATH}"
if [ -f "$chart_path/Chart.yaml" ]; then
OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$chart_name/"
TEMPLATE=""
if [ -f "${CHART_PATH}/Chart.yaml" ]; then
local OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${CHART_NAME}/"
mkdir -p ${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$chart_name
cd $chart_path
mkdir -p "${OUTPUT_FOLDER}"
cd "${CHART_PATH}"
echo ""
echo ">> Updating helm dependency ..."
helm dependency update --skip-refresh
echo ">> Updating helm dependencies ..."
helm dependency update --skip-refresh > /dev/null
echo ""
echo ">> Building helm dependency ..."
helm dependency build --skip-refresh
echo ">> Linting helm chart ..."
helm lint --namespace "${CHART_NAME}" --quiet
echo ""
echo ">> Linting helm ..."
helm lint --namespace "$chart_name"
echo ""
echo ">> Rendering templates ..."
case "$chart_name" in
local NAMESPACE="${CHART_NAME}"
case "${CHART_NAME}" in
"stack")
NAMESPACE="argocd"
echo ""
echo ">> Special Rendering for stack into argocd namespace ..."
TEMPLATE=$(helm template $chart_name ./ --namespace argocd --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
echo ">> Special Rendering into 'argocd' namespace ..."
;;
"cilium" | "coredns" | "metrics-server" |"prometheus-operator-crds")
"cilium" | "coredns" | "metrics-server" | "prometheus-operator-crds")
NAMESPACE="kube-system"
echo ""
echo ">> Special Rendering for $chart_name into kube-system namespace ..."
TEMPLATE=$(helm template $chart_name ./ --namespace kube-system --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
echo ">> Special Rendering for ${CHART_NAME} into 'kube-system' namespace ..."
;;
*)
echo ""
echo ">> Standard Rendering for $chart_name ..."
TEMPLATE=$(helm template "$chart_name" ./ --namespace "$chart_name" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
;;
echo ">> Standard Rendering for ${CHART_NAME} ..."
esac
echo ""
echo ">> Formating rendered template ..."
echo "$TEMPLATE" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"$OUTPUT_FOLDER"'" + .kind + "-" + .metadata.name + ".yaml"'
local TEMPLATE
TEMPLATE=$(helm template "${CHART_NAME}" ./ --namespace "${NAMESPACE}" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
# Format and split rendered template
echo "${TEMPLATE}" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"${OUTPUT_FOLDER}"'" + .kind + "-" + .metadata.name + ".yaml"'
# Strip comments again to ensure formatting correctness
for file in "$OUTPUT_FOLDER"/*; do
@@ -186,15 +228,23 @@ jobs:
done
echo ""
echo ">> Manifests for $chart_name rendered to $OUTPUT_FOLDER"
echo ">> Manifests for ${CHART_NAME} rendered to ${OUTPUT_FOLDER}:"
ls $OUTPUT_FOLDER
echo ""
else
echo ""
echo ">> Directory $chart_path does not contain a Chart.yaml. Skipping ..."
echo ">> Directory ${CHART_PATH} does not contain a Chart.yaml. Skipping ..."
echo ""
fi
done
}
export -f render_chart
export MAIN_DIR CLUSTER MANIFEST_DIR
# Run rendering in parallel
for DIR in ${RENDER_DIR}; do
echo "${DIR}"
done | xargs -n 1 -P 4 -I {} bash -c 'render_chart "$@"' _ {}
echo "----"
@@ -202,16 +252,18 @@ jobs:
id: check-changes
if: steps.check-dir-changes.outputs.changes-detected == 'true'
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
GIT_CHANGES=$(git status --porcelain)
if [ -n "$GIT_CHANGES" ]; then
if [ -n "${GIT_CHANGES}" ]; then
echo ""
echo ">> Changes detected"
git status --porcelain
echo "changes-detected=true" >> $GITEA_OUTPUT
else
echo ""
echo ">> No changes detected, skipping PR creation"
fi
@@ -222,20 +274,23 @@ jobs:
id: commit-push
if: steps.check-changes.outputs.changes-detected == 'true'
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
echo ""
echo ">> Commiting changes to ${BRANCH_NAME} ..."
git add .
git commit -m "chore: Update manifests after change"
REPO_URL="${{ secrets.REPO_URL }}/${{ gitea.repository }}"
echo ">> Pushing changes to $REPO_URL ..."
git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@$(echo $REPO_URL | sed -e 's|https://||')" ${BRANCH_NAME}
echo ""
echo ">> Pushing changes to ${REPO_URL} ..."
git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@${REPO_URL#*://}" "${BRANCH_NAME}"
echo "----"
echo "HEAD_BRANCH=${BRANCH_NAME}" >> $GITEA_OUTPUT
echo "push=true" >> $GITEA_OUTPUT
echo "HEAD_BRANCH=${BRANCH_NAME}" >> "$GITEA_OUTPUT"
echo "push=true" >> "$GITEA_OUTPUT"
- name: Check for Pull Request
id: check-for-pull-requst

View File

@@ -1,13 +1,14 @@
name: render-manifests-merge
on:
pull_request:
branches:
- main
paths:
- 'clusters/cl01tl/helm/**'
types:
- closed
workflow_dispatch:
# pull_request:
# branches:
# - main
# paths:
# - 'clusters/cl01tl/helm/**'
# types:
# - closed
env:
CLUSTER: cl01tl
@@ -47,24 +48,39 @@ jobs:
method: kubeconfig
kubeconfig: ${{ secrets.KUBECONFIG }}
- name: Cache Helm Dependencies
uses: actions/cache@v5
with:
path: |
~/.cache/helm
~/.config/helm
key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }}
restore-keys: |
helm-cache-${{ runner.os }}-
- name: Prepare Manifest Branch
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
echo ""
echo ">> Configure git to use gitea-bot as user ..."
git config user.name "gitea-bot"
git config user.email "gitea-bot@alexlebens.net"
echo ""
echo ">> Checking if PR branch exists ..."
if [[ $(git ls-remote --heads origin "${BRANCH_NAME}" | wc -l) -gt 0 ]]; then
if git ls-remote --exit-code --heads origin "${BRANCH_NAME}" > /dev/null 2>&1; then
echo ""
echo ">> Branch '${BRANCH_NAME}' exists, pulling changes ..."
git fetch origin "${BRANCH_NAME}"
git checkout "${BRANCH_NAME}"
git pull --rebase
else
echo ""
echo ">> Branch '${BRANCH_NAME}' does not exist, creating ..."
git checkout -b $BRANCH_NAME
git checkout -b "${BRANCH_NAME}"
fi
echo "----"
@@ -72,38 +88,31 @@ jobs:
- name: Check which Directories have Changes
id: check-dir-changes
run: |
cd ${MAIN_DIR}
RENDER_DIR=()
cd "${MAIN_DIR}"
echo ""
echo ">> Checking for changes from HEAD^..HEAD ..."
GIT_DIFF=$(git diff --name-only HEAD^..HEAD | xargs -I {} dirname {} | sort -u | grep -E "clusters/[^/]+/helm/[^/]+")
if [ -n "${GIT_DIFF}" ]; then
echo ">> Changes detected:"
echo "$GIT_DIFF"
for path in $GIT_DIFF; do
RENDER_DIR+=$(echo "$path" | awk -F '/' '{print $4}')
RENDER_DIR+=$(echo " ")
done
else
echo ">> No changes detected"
fi
# Extract the chart names from the git diff
RENDER_DIR=$(git diff --name-only HEAD^..HEAD | grep -E "^clusters/${CLUSTER}/helm/" | awk -F '/' '{print $4}' | sort -u || true)
if [ -n "${RENDER_DIR}" ]; then
echo ""
echo ">> Directories to Render:"
echo "$(echo "${RENDER_DIR}" | sort -u)"
echo "${RENDER_DIR}"
echo "----"
echo "changes-detected=true" >> $GITEA_OUTPUT
echo "render-dir<<EOF" >> $GITEA_OUTPUT
echo "$(echo "${RENDER_DIR}" | sort -u)" >> $GITEA_OUTPUT
echo "EOF" >> $GITEA_OUTPUT
echo "changes-detected=true" >> "$GITEA_OUTPUT"
echo "render-dir<<EOF" >> "$GITEA_OUTPUT"
echo "${RENDER_DIR}" >> "$GITEA_OUTPUT"
echo "EOF" >> "$GITEA_OUTPUT"
else
echo "changes-detected=false" >> $GITEA_OUTPUT
echo ""
echo ">> No chart changes detected"
echo "changes-detected=false" >> "$GITEA_OUTPUT"
fi
- name: Add Repositories
@@ -111,25 +120,31 @@ jobs:
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd ${MAIN_DIR}
cd "${MAIN_DIR}"
echo ""
echo ">> Adding repositories for chart dependencies ..."
for dir in ${RENDER_DIR}; do
helm dependency list --max-col-width 120 ${MAIN_DIR}/clusters/${CLUSTER}/helm/$dir 2> /dev/null \
| tail +2 | head -n -1 \
| awk '{ print "helm repo add " $1 " " $3 }' \
| while read cmd; do
if [[ "$cmd" == "*oci://*" ]]; then
echo ">> Ignoring OCI repo"
else
echo "$cmd" | sh;
for DIR in ${RENDER_DIR}; do
helm dependency list --max-col-width 120 "${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" 2> /dev/null \
| tail -n +2 \
| awk 'NF > 0 { print $1, $3 }' \
| while read -r REPO_NAME REPO_URL; do
if [[ "${REPO_URL}" == oci://* ]]; then
echo ""
echo ">> Ignoring OCI repo: ${REPO_URL}"
elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then
helm repo add "${REPO_NAME}" "${REPO_URL}"
fi
done || true
done
if helm repo list | tail +2 | read -r; then
if helm repo list > /dev/null 2>&1; then
echo ""
echo ">> Update repository cache ..."
helm repo update
fi
echo "----"
@@ -139,15 +154,16 @@ jobs:
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
echo ""
echo ">> Remove manfiest files and rebuild from source ..."
for dir in ${RENDER_DIR}; do
chart_path=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$dir
for DIR in ${RENDER_DIR}; do
CHART_PATH=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${DIR}
echo "$chart_path"
rm -rf $chart_path/*
echo "${CHART_PATH}"
rm -rf ${CHART_PATH}/*
done
echo "----"
@@ -160,60 +176,57 @@ jobs:
run: |
cd ${MAIN_DIR}
echo ""
echo ">> Rendering Manifests ..."
for dir in ${RENDER_DIR}; do
chart_path=${MAIN_DIR}/clusters/${CLUSTER}/helm/$dir
chart_name=$(basename "$chart_path")
render_chart() {
local DIR="$1"
local CHART_PATH="${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}"
local CHART_NAME=$(basename "${CHART_PATH}")
echo ""
echo ""
echo ">> Rendering chart: $chart_name"
echo ">> Chart path $chart_path"
echo ">> Rendering ..."
echo ">> Chart: ${CHART_NAME}"
echo ">> Path: ${CHART_PATH}"
if [ -f "$chart_path/Chart.yaml" ]; then
OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$chart_name/"
TEMPLATE=""
if [ -f "${CHART_PATH}/Chart.yaml" ]; then
local OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${CHART_NAME}/"
mkdir -p ${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$chart_name
cd $chart_path
mkdir -p "${OUTPUT_FOLDER}"
cd "${CHART_PATH}"
echo ""
echo ">> Updating helm dependency ..."
helm dependency update --skip-refresh
echo ">> Updating helm dependencies ..."
helm dependency update --skip-refresh > /dev/null
echo ""
echo ">> Building helm dependency ..."
helm dependency build --skip-refresh
echo ">> Linting helm chart ..."
helm lint --namespace "${CHART_NAME}" --quiet
echo ""
echo ">> Linting helm ..."
helm lint --namespace "$chart_name"
echo ""
echo ">> Rendering templates ..."
case "$chart_name" in
local NAMESPACE="${CHART_NAME}"
case "${CHART_NAME}" in
"stack")
NAMESPACE="argocd"
echo ""
echo ">> Special Rendering for stack into argocd namespace ..."
TEMPLATE=$(helm template $chart_name ./ --namespace argocd --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
echo ">> Special Rendering into 'argocd' namespace ..."
;;
"cilium" | "coredns" | "metrics-server" |"prometheus-operator-crds")
"cilium" | "coredns" | "metrics-server" | "prometheus-operator-crds")
NAMESPACE="kube-system"
echo ""
echo ">> Special Rendering for $chart_name into kube-system namespace ..."
TEMPLATE=$(helm template $chart_name ./ --namespace kube-system --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
echo ">> Special Rendering for ${CHART_NAME} into 'kube-system' namespace ..."
;;
*)
echo ""
echo ">> Standard Rendering for $chart_name ..."
TEMPLATE=$(helm template "$chart_name" ./ --namespace "$chart_name" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
;;
echo ">> Standard Rendering for ${CHART_NAME} ..."
esac
echo ""
echo ">> Formating rendered template ..."
echo "$TEMPLATE" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"$OUTPUT_FOLDER"'" + .kind + "-" + .metadata.name + ".yaml"'
local TEMPLATE
TEMPLATE=$(helm template "${CHART_NAME}" ./ --namespace "${NAMESPACE}" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
# Format and split rendered template
echo "${TEMPLATE}" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"${OUTPUT_FOLDER}"'" + .kind + "-" + .metadata.name + ".yaml"'
# Strip comments again to ensure formatting correctness
for file in "$OUTPUT_FOLDER"/*; do
@@ -221,15 +234,23 @@ jobs:
done
echo ""
echo ">> Manifests for $chart_name rendered to $OUTPUT_FOLDER"
echo ">> Manifests for ${CHART_NAME} rendered to ${OUTPUT_FOLDER}:"
ls $OUTPUT_FOLDER
echo ""
else
echo ""
echo ">> Directory $chart_path does not contain a Chart.yaml. Skipping ..."
echo ">> Directory ${CHART_PATH} does not contain a Chart.yaml. Skipping ..."
echo ""
fi
done
}
export -f render_chart
export MAIN_DIR CLUSTER MANIFEST_DIR
# Run rendering in parallel
for DIR in ${RENDER_DIR}; do
echo "${DIR}"
done | xargs -n 1 -P 4 -I {} bash -c 'render_chart "$@"' _ {}
echo "----"
@@ -237,16 +258,18 @@ jobs:
id: check-changes
if: steps.check-dir-changes.outputs.changes-detected == 'true'
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
GIT_CHANGES=$(git status --porcelain)
if [ -n "$GIT_CHANGES" ]; then
if [ -n "${GIT_CHANGES}" ]; then
echo ""
echo ">> Changes detected"
git status --porcelain
echo "changes-detected=true" >> $GITEA_OUTPUT
else
echo ""
echo ">> No changes detected, skipping PR creation"
fi
@@ -257,20 +280,23 @@ jobs:
id: commit-push
if: steps.check-changes.outputs.changes-detected == 'true'
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
echo ""
echo ">> Commiting changes to ${BRANCH_NAME} ..."
git add .
git commit -m "chore: Update manifests after change"
REPO_URL="${{ secrets.REPO_URL }}/${{ gitea.repository }}"
echo ">> Pushing changes to $REPO_URL ..."
git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@$(echo $REPO_URL | sed -e 's|https://||')" ${BRANCH_NAME}
echo ""
echo ">> Pushing changes to ${REPO_URL} ..."
git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@${REPO_URL#*://}" "${BRANCH_NAME}"
echo "----"
echo "HEAD_BRANCH=${BRANCH_NAME}" >> $GITEA_OUTPUT
echo "push=true" >> $GITEA_OUTPUT
echo "HEAD_BRANCH=${BRANCH_NAME}" >> "$GITEA_OUTPUT"
echo "push=true" >> "$GITEA_OUTPUT"
- name: Check for Pull Request
id: check-for-pull-requst

View File

@@ -1,11 +1,12 @@
name: render-manifests-push
on:
push:
branches:
- main
paths:
- 'clusters/cl01tl/helm/**'
workflow_dispatch:
# push:
# branches:
# - main
# paths:
# - 'clusters/cl01tl/helm/**'
env:
CLUSTER: cl01tl
@@ -45,24 +46,38 @@ jobs:
method: kubeconfig
kubeconfig: ${{ secrets.KUBECONFIG }}
- name: Cache Helm Dependencies
uses: actions/cache@v5
with:
path: |
~/.cache/helm
~/.config/helm
key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }}
restore-keys: |
helm-cache-${{ runner.os }}-
- name: Prepare Manifest Branch
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
echo ""
echo ">> Configure git to use gitea-bot as user ..."
git config user.name "gitea-bot"
git config user.email "gitea-bot@alexlebens.net"
echo ">> Checking if PR branch exists ..."
if [[ $(git ls-remote --heads origin "${BRANCH_NAME}" | wc -l) -gt 0 ]]; then
if git ls-remote --exit-code --heads origin "${BRANCH_NAME}" > /dev/null 2>&1; then
echo ""
echo ">> Branch '${BRANCH_NAME}' exists, pulling changes ..."
git fetch origin "${BRANCH_NAME}"
git checkout "${BRANCH_NAME}"
git pull --rebase
else
echo ""
echo ">> Branch '${BRANCH_NAME}' does not exist, creating ..."
git checkout -b $BRANCH_NAME
git checkout -b "${BRANCH_NAME}"
fi
echo "----"
@@ -70,38 +85,31 @@ jobs:
- name: Check which Directories have Changes
id: check-dir-changes
run: |
cd ${MAIN_DIR}
RENDER_DIR=()
cd "${MAIN_DIR}"
echo ""
echo ">> Checking for changes ..."
GIT_DIFF=$(git diff --name-only ${{ gitea.event.before }}..HEAD | xargs -I {} dirname {} | sort -u | grep -E "clusters/[^/]+/helm/[^/]+")
if [ -n "${GIT_DIFF}" ]; then
echo ">> Changes detected:"
echo "$GIT_DIFF"
for path in $GIT_DIFF; do
RENDER_DIR+=$(echo "$path" | awk -F '/' '{print $4}')
RENDER_DIR+=$(echo " ")
done
else
echo ">> No changes detected"
fi
# Extract the chart names from the git diff
RENDER_DIR=$(git diff --name-only ${{ gitea.event.before }}..HEAD | grep -E "^clusters/${CLUSTER}/helm/" | awk -F '/' '{print $4}' | sort -u || true)
if [ -n "${RENDER_DIR}" ]; then
echo ""
echo ">> Directories to Render:"
echo "$(echo "${RENDER_DIR}" | sort -u)"
echo "${RENDER_DIR}"
echo "----"
echo "changes-detected=true" >> $GITEA_OUTPUT
echo "render-dir<<EOF" >> $GITEA_OUTPUT
echo "$(echo "${RENDER_DIR}" | sort -u)" >> $GITEA_OUTPUT
echo "EOF" >> $GITEA_OUTPUT
echo "changes-detected=true" >> "$GITEA_OUTPUT"
echo "render-dir<<EOF" >> "$GITEA_OUTPUT"
echo "${RENDER_DIR}" >> "$GITEA_OUTPUT"
echo "EOF" >> "$GITEA_OUTPUT"
else
echo "changes-detected=false" >> $GITEA_OUTPUT
echo ""
echo ">> No chart changes detected"
echo "changes-detected=false" >> "$GITEA_OUTPUT"
fi
- name: Add Repositories
@@ -109,25 +117,31 @@ jobs:
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd ${MAIN_DIR}
cd "${MAIN_DIR}"
echo ""
echo ">> Adding repositories for chart dependencies ..."
for dir in ${RENDER_DIR}; do
helm dependency list --max-col-width 120 ${MAIN_DIR}/clusters/${CLUSTER}/helm/$dir 2> /dev/null \
| tail +2 | head -n -1 \
| awk '{ print "helm repo add " $1 " " $3 }' \
| while read cmd; do
if [[ "$cmd" == "*oci://*" ]]; then
echo ">> Ignoring OCI repo"
else
echo "$cmd" | sh;
for DIR in ${RENDER_DIR}; do
helm dependency list --max-col-width 120 "${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" 2> /dev/null \
| tail -n +2 \
| awk 'NF > 0 { print $1, $3 }' \
| while read -r REPO_NAME REPO_URL; do
if [[ "${REPO_URL}" == oci://* ]]; then
echo ""
echo ">> Ignoring OCI repo: ${REPO_URL}"
elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then
helm repo add "${REPO_NAME}" "${REPO_URL}"
fi
done || true
done
if helm repo list | tail +2 | read -r; then
if helm repo list > /dev/null 2>&1; then
echo ""
echo ">> Update repository cache ..."
helm repo update
fi
echo "----"
@@ -137,15 +151,17 @@ jobs:
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
echo ""
echo ">> Remove manfiest files and rebuild from source ..."
for dir in ${RENDER_DIR}; do
chart_path=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$dir
for DIR in ${RENDER_DIR}; do
CHART_PATH=${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${DIR}
echo "$chart_path"
rm -rf $chart_path/*
echo ""
echo "${CHART_PATH}"
rm -rf ${CHART_PATH}/*
done
echo "----"
@@ -158,60 +174,57 @@ jobs:
run: |
cd ${MAIN_DIR}
echo ""
echo ">> Rendering Manifests ..."
for dir in ${RENDER_DIR}; do
chart_path=${MAIN_DIR}/clusters/${CLUSTER}/helm/$dir
chart_name=$(basename "$chart_path")
render_chart() {
local DIR="$1"
local CHART_PATH="${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}"
local CHART_NAME=$(basename "${CHART_PATH}")
echo ""
echo ""
echo ">> Rendering chart: $chart_name"
echo ">> Chart path $chart_path"
echo ">> Rendering ..."
echo ">> Chart: ${CHART_NAME}"
echo ">> Path: ${CHART_PATH}"
if [ -f "$chart_path/Chart.yaml" ]; then
OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$chart_name/"
TEMPLATE=""
if [ -f "${CHART_PATH}/Chart.yaml" ]; then
local OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${CHART_NAME}/"
mkdir -p ${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/$chart_name
cd $chart_path
mkdir -p "${OUTPUT_FOLDER}"
cd "${CHART_PATH}"
echo ""
echo ">> Updating helm dependency ..."
helm dependency update --skip-refresh
echo ">> Updating helm dependencies ..."
helm dependency update --skip-refresh > /dev/null
echo ""
echo ">> Building helm dependency ..."
helm dependency build --skip-refresh
echo ">> Linting helm chart ..."
helm lint --namespace "${CHART_NAME}" --quiet
echo ""
echo ">> Linting helm ..."
helm lint --namespace "$chart_name"
echo ""
echo ">> Rendering templates ..."
case "$chart_name" in
local NAMESPACE="${CHART_NAME}"
case "${CHART_NAME}" in
"stack")
NAMESPACE="argocd"
echo ""
echo ">> Special Rendering for stack into argocd namespace ..."
TEMPLATE=$(helm template $chart_name ./ --namespace argocd --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
echo ">> Special Rendering into 'argocd' namespace ..."
;;
"cilium" | "coredns" | "metrics-server" |"prometheus-operator-crds")
"cilium" | "coredns" | "metrics-server" | "prometheus-operator-crds")
NAMESPACE="kube-system"
echo ""
echo ">> Special Rendering for $chart_name into kube-system namespace ..."
TEMPLATE=$(helm template $chart_name ./ --namespace kube-system --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
echo ">> Special Rendering for ${CHART_NAME} into 'kube-system' namespace ..."
;;
*)
echo ""
echo ">> Standard Rendering for $chart_name ..."
TEMPLATE=$(helm template "$chart_name" ./ --namespace "$chart_name" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
;;
echo ">> Standard Rendering for ${CHART_NAME} ..."
esac
echo ""
echo ">> Formating rendered template ..."
echo "$TEMPLATE" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"$OUTPUT_FOLDER"'" + .kind + "-" + .metadata.name + ".yaml"'
local TEMPLATE
TEMPLATE=$(helm template "${CHART_NAME}" ./ --namespace "${NAMESPACE}" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
# Format and split rendered template
echo "${TEMPLATE}" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"${OUTPUT_FOLDER}"'" + .kind + "-" + .metadata.name + ".yaml"'
# Strip comments again to ensure formatting correctness
for file in "$OUTPUT_FOLDER"/*; do
@@ -219,15 +232,23 @@ jobs:
done
echo ""
echo ">> Manifests for $chart_name rendered to $OUTPUT_FOLDER"
echo ">> Manifests for ${CHART_NAME} rendered to ${OUTPUT_FOLDER}:"
ls $OUTPUT_FOLDER
echo ""
else
echo ""
echo ">> Directory $chart_path does not contain a Chart.yaml. Skipping ..."
echo ">> Directory ${CHART_PATH} does not contain a Chart.yaml. Skipping ..."
echo ""
fi
done
}
export -f render_chart
export MAIN_DIR CLUSTER MANIFEST_DIR
# Run rendering in parallel
for DIR in ${RENDER_DIR}; do
echo "${DIR}"
done | xargs -n 1 -P 4 -I {} bash -c 'render_chart "$@"' _ {}
echo "----"
@@ -235,16 +256,18 @@ jobs:
id: check-changes
if: steps.check-dir-changes.outputs.changes-detected == 'true'
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
GIT_CHANGES=$(git status --porcelain)
if [ -n "$GIT_CHANGES" ]; then
if [ -n "${GIT_CHANGES}" ]; then
echo ""
echo ">> Changes detected"
git status --porcelain
echo "changes-detected=true" >> $GITEA_OUTPUT
else
echo ""
echo ">> No changes detected, skipping PR creation"
fi
@@ -255,20 +278,23 @@ jobs:
id: commit-push
if: steps.check-changes.outputs.changes-detected == 'true'
run: |
cd ${MANIFEST_DIR}
cd "${MANIFEST_DIR}"
echo ""
echo ">> Commiting changes to ${BRANCH_NAME} ..."
git add .
git commit -m "chore: Update manifests after change"
REPO_URL="${{ secrets.REPO_URL }}/${{ gitea.repository }}"
echo ">> Pushing changes to $REPO_URL ..."
git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@$(echo $REPO_URL | sed -e 's|https://||')" ${BRANCH_NAME}
echo ""
echo ">> Pushing changes to ${REPO_URL} ..."
git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@${REPO_URL#*://}" "${BRANCH_NAME}"
echo "----"
echo "HEAD_BRANCH=${BRANCH_NAME}" >> $GITEA_OUTPUT
echo "push=true" >> $GITEA_OUTPUT
echo "HEAD_BRANCH=${BRANCH_NAME}" >> "$GITEA_OUTPUT"
echo "push=true" >> "$GITEA_OUTPUT"
- name: Check for Pull Request
id: check-for-pull-requst

View File

@@ -0,0 +1,636 @@
name: render-manifests
on:
schedule:
- cron: '0 15 * * *'
workflow_dispatch:
push:
branches:
- main
paths:
- 'clusters/cl01tl/helm/**'
pull_request:
branches:
- main
paths:
- 'clusters/cl01tl/helm/**'
types:
- closed
env:
CLUSTER: cl01tl
BASE_BRANCH: manifests
BRANCH_NAME_BASE: auto/update-manifests
ASSIGNEE: alexlebens
MAIN_DIR: /workspace/alexlebens/infrastructure/infrastructure
MANIFEST_DIR: /workspace/alexlebens/infrastructure/infrastructure-manifests
jobs:
render-manifests:
runs-on: ubuntu-js
if: >-
github.event_name == 'schedule' ||
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'push' && github.actor != 'renovate-bot') ||
(github.event_name == 'pull_request' && github.event.pull_request.merged == true)
steps:
- name: Checkout Main
uses: actions/checkout@v6
with:
path: infrastructure
fetch-depth: 0
- name: Checkout Manifests
uses: actions/checkout@v6
with:
ref: manifests
path: infrastructure-manifests
- name: Set Up Helm
uses: azure/setup-helm@v4
with:
token: ${{ secrets.GITEA_TOKEN }}
version: v3.17.2 # Pending https://github.com/helm/helm/pull/30743
cache: true
- name: Configure Kubeconfig
uses: azure/k8s-set-context@v4
with:
method: kubeconfig
kubeconfig: ${{ secrets.KUBECONFIG }}
- name: Cache Helm Dependencies
uses: actions/cache@v5
with:
path: |
~/.cache/helm
~/.config/helm
key: helm-cache-${{ runner.os }}-${{ hashFiles('infrastructure/clusters/cl01tl/helm/**/Chart.yaml', 'infrastructure/clusters/cl01tl/helm/**/Chart.lock') }}
restore-keys: |
helm-cache-${{ runner.os }}-
- name: Determine Workflow Mode
id: mode
run: |
IS_AUTOMERGE="false"
RENDER_ALL="false"
DIFF_TARGET=""
if [[ "${{ github.event_name }}" == "schedule" || "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo ">> Mode: Dispatch/Schedule (Render All)"
RENDER_ALL="true"
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'automerge') }}" == "true" ]]; then
echo ">> Mode: PR Merged (Automerge)"
IS_AUTOMERGE="true"
else
echo ">> Mode: PR Merged (Standard)"
fi
DIFF_TARGET="HEAD^..HEAD"
elif [[ "${{ github.event_name }}" == "push" ]]; then
echo ">> Mode: Push (Standard)"
DIFF_TARGET="${{ github.event.before }}..HEAD"
fi
echo ""
echo "----"
echo "is-automerge=${IS_AUTOMERGE}" >> "$GITHUB_OUTPUT"
echo "render-all=${RENDER_ALL}" >> "$GITHUB_OUTPUT"
echo "diff-target=${DIFF_TARGET}" >> "$GITHUB_OUTPUT"
- name: Prepare Manifest Branch
id: prepare-manifest-branch
env:
IS_AUTOMERGE: ${{ steps.mode.outputs.is-automerge }}
run: |
cd "${MANIFEST_DIR}"
echo ">> Configure git to use gitea-bot as user ..."
git config user.name "gitea-bot"
git config user.email "gitea-bot@alexlebens.net"
if [[ "$IS_AUTOMERGE" == "true" ]]; then
echo ""
echo ">> Creating branch ${BRANCH_NAME} ..."
BRANCH_NAME="${BRANCH_NAME_BASE}-automerge-$(date +%Y%m%d%H%M%S)"
git checkout -b "$BRANCH_NAME"
else
echo ""
echo ">> Checking if PR branch exists ..."
BRANCH_NAME="${BRANCH_NAME_BASE}"
if git ls-remote --exit-code --heads origin "${BRANCH_NAME}" > /dev/null 2>&1; then
echo ""
echo ">> Branch '${BRANCH_NAME}' exists, pulling changes ..."
git fetch origin "${BRANCH_NAME}"
git checkout "${BRANCH_NAME}"
git pull --rebase
else
echo ""
echo ">> Branch '${BRANCH_NAME}' does not exist, creating ..."
git checkout -b "${BRANCH_NAME}"
fi
fi
echo ""
echo "----"
echo "branch-name=${BRANCH_NAME}" >> "$GITHUB_OUTPUT"
- name: Check Which Directories Have Changes
id: check-dir-changes
env:
RENDER_ALL: ${{ steps.mode.outputs.render-all }}
DIFF_TARGET: ${{ steps.mode.outputs.diff-target }}
run: |
cd "${MAIN_DIR}"
if [[ "$RENDER_ALL" == "true" ]]; then
echo ">> Triggered on dispatch, will check all paths ..."
RENDER_DIR=$(find "clusters/${CLUSTER}/helm" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort -u)
else
echo ">> Checking for changes from ${DIFF_TARGET} ..."
RENDER_DIR=$(git diff --name-only "${DIFF_TARGET}" | grep -E "^clusters/${CLUSTER}/helm/" | awk -F '/' '{print $4}' | sort -u || true)
fi
if [ -n "${RENDER_DIR}" ]; then
echo ""
echo ">> Directories to Render:"
echo ""
echo "${RENDER_DIR}"
echo ""
echo "----"
echo "changes-detected=true" >> "$GITHUB_OUTPUT"
echo "render-dir<<EOF" >> "$GITHUB_OUTPUT"
echo "${RENDER_DIR}" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
else
echo ""
echo ">> No chart changes detected"
echo ""
echo "----"
echo "changes-detected=false" >> "$GITHUB_OUTPUT"
fi
- name: Add Repositories
if: steps.check-dir-changes.outputs.changes-detected == 'true'
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd "${MAIN_DIR}"
echo ">> Adding repositories for chart dependencies ..."
echo ""
for DIR in ${RENDER_DIR}; do
helm dependency list --max-col-width 120 "${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}" 2> /dev/null \
| tail -n +2 \
| awk 'NF > 0 { print $1, $3 }' \
| while read -r REPO_NAME REPO_URL; do
if [[ "${REPO_URL}" == oci://* ]]; then
echo ">> Ignoring OCI repo: ${REPO_URL}"
elif [[ -n "${REPO_NAME}" && -n "${REPO_URL}" ]]; then
helm repo add "${REPO_NAME}" "${REPO_URL}"
fi
done || true
done
if helm repo list > /dev/null 2>&1; then
echo ""
echo ">> Update repository cache ..."
helm repo update
fi
echo ""
echo "----"
- name: Remove Changed Manifest Files
if: steps.check-dir-changes.outputs.changes-detected == 'true'
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd "${MANIFEST_DIR}"
echo ">> Remove manifest files and rebuild from source ..."
echo ""
for DIR in ${RENDER_DIR}; do
CHART_PATH="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${DIR}"
echo "${CHART_PATH}"
rm -rf "${CHART_PATH}"/*
done
echo ""
echo "----"
- name: Render Helm Manifests
id: render-manifests
if: steps.check-dir-changes.outputs.changes-detected == 'true'
env:
RENDER_DIR: ${{ steps.check-dir-changes.outputs.render-dir }}
run: |
cd "${MAIN_DIR}"
echo ">> Rendering Manifests ..."
render_chart() {
local DIR="$1"
local CHART_PATH="${MAIN_DIR}/clusters/${CLUSTER}/helm/${DIR}"
local CHART_NAME=$(basename "${CHART_PATH}")
echo ""
echo ">> Rendering chart: ${CHART_NAME}"
if [ -f "${CHART_PATH}/Chart.yaml" ]; then
local OUTPUT_FOLDER="${MANIFEST_DIR}/clusters/${CLUSTER}/manifests/${CHART_NAME}/"
mkdir -p "${OUTPUT_FOLDER}"
cd "${CHART_PATH}"
helm dependency update --skip-refresh > /dev/null
helm lint --namespace "${CHART_NAME}" --quiet
local NAMESPACE="${CHART_NAME}"
case "${CHART_NAME}" in
"stack")
NAMESPACE="argocd"
echo ">> Special Rendering into 'argocd' namespace ..."
;;
"cilium" | "coredns" | "metrics-server" | "prometheus-operator-crds")
NAMESPACE="kube-system"
echo ">> Special Rendering for ${CHART_NAME} into 'kube-system' namespace ..."
;;
*)
echo ">> Standard Rendering ..."
esac
echo ">> Formating rendered template ..."
local TEMPLATE
TEMPLATE=$(helm template "${CHART_NAME}" ./ --namespace "${NAMESPACE}" --include-crds --dry-run=server --api-versions "gateway.networking.k8s.io/v1/HTTPRoute")
# Format and split rendered template
echo "${TEMPLATE}" | yq '... comments=""' | yq 'select(. != null)' | yq -s '"'"${OUTPUT_FOLDER}"'" + .kind + "-" + .metadata.name + ".yaml"'
# Strip comments again to ensure formatting correctness
for file in "$OUTPUT_FOLDER"/*; do
yq -i '... comments=""' $file
done
echo ">> Manifests for ${CHART_NAME} rendered successfully to $OUTPUT_FOLDER:"
echo ""
ls $OUTPUT_FOLDER
echo ""
else
echo ""
echo ">> Directory ${CHART_PATH} does not contain a Chart.yaml. Skipping ..."
fi
}
export -f render_chart
export MAIN_DIR CLUSTER MANIFEST_DIR
# Run rendering in parallel
for DIR in ${RENDER_DIR}; do
echo "${DIR}"
done | xargs -P 4 -I {} bash -c 'OUT=$(render_chart "$@" 2>&1); printf "%s\n" "$OUT"' _ {}
echo ""
echo "----"
- name: Check for Changes
id: check-changes
if: steps.check-dir-changes.outputs.changes-detected == 'true'
run: |
cd "${MANIFEST_DIR}"
GIT_CHANGES=$(git status --porcelain)
if [ -n "${GIT_CHANGES}" ]; then
echo ">> Changes detected"
git status --porcelain
CHANGED_CHARTS=$(echo "$GIT_CHANGES" | grep -oE "clusters/${CLUSTER}/manifests/[^/]+" | awk -F '/' '{print $4}' | sort -u | paste -sd ',' -)
echo ""
echo "----"
echo "changes-detected=true" >> "$GITHUB_OUTPUT"
echo "changed-charts-csv=${CHANGED_CHARTS}" >> "$GITHUB_OUTPUT"
else
echo ">> No changes detected, skipping PR creation"
echo ""
echo "----"
fi
- name: Commit and Push Changes
id: commit-push
if: steps.check-changes.outputs.changes-detected == 'true'
env:
BRANCH_NAME: ${{ steps.prepare-manifest-branch.outputs.branch-name }}
IS_AUTOMERGE: ${{ steps.mode.outputs.is-automerge }}
run: |
cd "${MANIFEST_DIR}"
MSG="chore: Update manifests after change"
if [[ "$IS_AUTOMERGE" == "true" ]]; then
MSG="chore: Update manifests after automerge"
fi
echo ">> Commiting changes to ${BRANCH_NAME} ..."
git add .
git commit -m "${MSG}"
REPO_URL="${{ secrets.REPO_URL }}/${{ gitea.repository }}"
echo ""
echo ">> Pushing changes to ${REPO_URL} ..."
git push -u "https://oauth2:${{ secrets.BOT_TOKEN }}@${REPO_URL#*://}" "${BRANCH_NAME}"
echo ""
echo "----"
echo "push=true" >> "$GITHUB_OUTPUT"
echo "head-branch=${BRANCH_NAME}" >> "$GITHUB_OUTPUT"
- name: Check for Pull Request
id: check-for-pull-request
if: steps.commit-push.outputs.push == 'true' && steps.mode.outputs.is-automerge == 'false'
env:
GITEA_TOKEN: ${{ secrets.BOT_TOKEN }}
GITEA_URL: ${{ secrets.REPO_URL }}
HEAD_BRANCH: ${{ steps.commit-push.outputs.head-branch }}
run: |
cd "${MANIFEST_DIR}"
API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls?base_branch=${BASE_BRANCH}&state=open&page=1"
echo ">> Checking if PR from branch ${HEAD_BRANCH} into ${BASE_BRANCH}"
echo ">> With Endpoint of:"
echo "$API_ENDPOINT"
HTTP_STATUS=$(curl -X GET -s -w '%{http_code}' -o response_body.json -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" "$API_ENDPOINT")
if [ "$HTTP_STATUS" == "200" ] && [ "$(cat response_body.json | jq -r .[0].state)" == "open" ]; then
echo ""
echo ">> Pull Request has been found open, will update"
echo ""
echo "----"
echo "pull-request-exists=$(cat response_body.json | jq -r .[0].number)" >> "$GITHUB_OUTPUT"
echo "pull-request-url=$(cat response_body.json | jq -r .[0].html_url)" >> "$GITHUB_OUTPUT"
else
echo ""
echo ">> Pull Request not found"
echo ""
echo "----"
echo "pull-request-exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Create Pull Request
id: create-pull-request
if: steps.commit-push.outputs.push == 'true' && (steps.mode.outputs.is-automerge == 'true' || steps.check-for-pull-request.outputs.pull-request-exists == 'false')
env:
IS_AUTOMERGE: ${{ steps.mode.outputs.is-automerge }}
GITEA_TOKEN: ${{ secrets.BOT_TOKEN }}
GITEA_URL: ${{ secrets.REPO_URL }}
HEAD_BRANCH: ${{ steps.commit-push.outputs.head-branch }}
CHARTS: ${{ steps.check-changes.outputs.changed-charts-csv }}
EVENT_NAME: ${{ github.event_name }}
ACTOR: ${{ github.actor }}
SHA: ${{ github.sha }}
REF: ${{ github.ref_name }}
run: |
cd "${MANIFEST_DIR}"
API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls"
BODY=$(printf "This PR contains newly rendered Kubernetes manifests automatically generated by the CI workflow.\n\n### Details\n- **Trigger**: \`%s\` by \`@%s\`\n- **Commit**: \`%s\` (on \`%s\`)\n- **Charts Updated**: \`%s\`" "${EVENT_NAME}" "${ACTOR}" "${SHA:0:7}" "${REF}" "${CHARTS}")
if [[ "$IS_AUTOMERGE" == "true" ]]; then
TITLE="Automated Manifest Update - Automerge"
BODY=$(printf "%s\n\n_This PR is expected to be automerged._" "${BODY}")
else
TITLE="Automated Manifest Update"
fi
PAYLOAD=$(jq -n --arg head "${HEAD_BRANCH}" --arg base "${BASE_BRANCH}" --arg assignee "${ASSIGNEE}" --arg title "${TITLE}" --arg body "${BODY}" '{head: $head, base: $base, assignee: $assignee, title: $title, body: $body}')
HTTP_STATUS=$(curl -X POST -s -w '%{http_code}' -o response_body.json --data "$PAYLOAD" -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" "$API_ENDPOINT")
if [ "$HTTP_STATUS" == "201" ]; then
echo ">> Pull Request created successfully!"
echo ""
echo "----"
echo "pull-request-url=$(jq -r .html_url response_body.json)" >> "$GITHUB_OUTPUT"
echo "pull-request-id=$(jq -r .id response_body.json)" >> "$GITHUB_OUTPUT"
echo "pull-request-number=$(jq -r .number response_body.json)" >> "$GITHUB_OUTPUT"
echo "pull-request-operation=created" >> "$GITHUB_OUTPUT"
elif [[ "$HTTP_STATUS" == "422" || "$HTTP_STATUS" == "409" ]]; then
echo ""
echo ">> Failed to create PR (Already exists)"
echo ""
echo "----"
else
echo ""
echo ">> Failed to create PR, HTTP status code: $HTTP_STATUS"
echo ""
echo "----"
exit 1
fi
- name: Update Pull Request
id: update-pull-request
if: steps.commit-push.outputs.push == 'true' && steps.check-for-pull-request.outputs.pull-request-exists != 'false' && steps.mode.outputs.is-automerge == 'false'
env:
GITEA_TOKEN: ${{ secrets.BOT_TOKEN }}
GITEA_URL: ${{ secrets.REPO_URL }}
PR_NUMBER: ${{ steps.check-for-pull-request.outputs.pull-request-exists }}
CHARTS: ${{ steps.check-changes.outputs.changed-charts-csv }}
EVENT_NAME: ${{ github.event_name }}
ACTOR: ${{ github.actor }}
SHA: ${{ github.sha }}
REF: ${{ github.ref_name }}
run: |
cd "${MANIFEST_DIR}"
API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls/${PR_NUMBER}"
EXISTING_BODY=$(jq -r '.[0].body' response_body.json)
NEW_DETAILS=$(printf "### Update Details (%s)\n- **Trigger**: \`%s\` by \`@%s\`\n- **Commit**: \`%s\` (on \`%s\`)\n- **Charts Updated**: \`%s\`" "$(date -u +'%Y-%m-%d %H:%M UTC')" "${EVENT_NAME}" "${ACTOR}" "${SHA:0:7}" "${REF}" "${CHARTS}")
UPDATED_BODY=$(printf "%s\n\n%s" "${EXISTING_BODY}" "${NEW_DETAILS}")
PAYLOAD=$(jq -n --arg body "${UPDATED_BODY}" '{body: $body}')
HTTP_STATUS=$(curl -X PATCH -s -w '%{http_code}' -o update_response.json --data "$PAYLOAD" -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" "$API_ENDPOINT")
if [ "$HTTP_STATUS" == "201" ] || [ "$HTTP_STATUS" == "200" ]; then
echo ">> Pull Request updated successfully!"
echo ""
echo "----"
echo "pull-request-operation=updated" >> "$GITHUB_OUTPUT"
else
echo ">> Failed to update PR, HTTP status code: $HTTP_STATUS"; exit 1
echo ""
echo "----"
fi
- name: Merge Changes
id: merge-changes
if: steps.commit-push.outputs.push == 'true' && steps.mode.outputs.is-automerge == 'true'
env:
GITEA_TOKEN: ${{ secrets.BOT_TOKEN }}
GITEA_URL: ${{ secrets.REPO_URL }}
PR_NUMBER: ${{ steps.create-pull-request.outputs.pull-request-number }}
run: |
cd "${MANIFEST_DIR}"
API_ENDPOINT="${GITEA_URL}/api/v1/repos/${{ gitea.repository }}/pulls/${PR_NUMBER}/merge"
PAYLOAD=$(jq -n --arg Do "merge" '{Do: $Do}')
HTTP_STATUS=$(curl -X POST -s -w '%{http_code}' -o response_body.json --data "$PAYLOAD" -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" "$API_ENDPOINT")
if [ "$HTTP_STATUS" == "200" ]; then
echo ">> Pull Request merged successfully!"
echo ""
echo "----"
echo "pull-request-operation=merged" >> "$GITHUB_OUTPUT"
else
echo ">> Failed to merge PR, HTTP status code: $HTTP_STATUS"; exit 1
echo ""
echo "----"
fi
- name: Cleanup Branch
if: failure() && steps.mode.outputs.is-automerge == 'true'
env:
BRANCH_NAME: ${{ steps.prepare-manifest-branch.outputs.branch-name }}
run: |
cd "${MANIFEST_DIR}"
echo ">> Removing branch: ${BRANCH_NAME}"
git push origin --delete "${BRANCH_NAME}" || true
echo ""
echo "----"
- name: ntfy Created
uses: niniyas/ntfy-action@master
if: steps.create-pull-request.outputs.pull-request-operation == 'created' && steps.mode.outputs.is-automerge == 'false'
with:
url: "${{ secrets.NTFY_URL }}"
topic: "${{ secrets.NTFY_TOPIC }}"
title: "Manifest Render - Open PR"
priority: 3
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
tags: action,successfully,completed
details: "Created renderd manifests for cluster '${CLUSTER}' with charts: ${{ steps.check-changes.outputs.changed-charts-csv }}"
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png"
actions: '[{"action": "view", "label": "View PR", "url": "${{ steps.create-pull-request.outputs.pull-request-url }}", "clear": true}]'
- name: ntfy Updated
uses: niniyas/ntfy-action@master
if: steps.commit-push.outputs.push == 'true' && steps.check-for-pull-request.outputs.pull-request-exists != 'false' && steps.mode.outputs.is-automerge == 'false'
with:
url: "${{ secrets.NTFY_URL }}"
topic: "${{ secrets.NTFY_TOPIC }}"
title: "Manifest Render - PR Updated"
priority: 3
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
tags: action,successfully,completed
details: "Updated rendered manifests PR for cluster '${CLUSTER}' with charts: ${{ steps.check-changes.outputs.changed-charts-csv }}"
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png"
actions: '[{"action": "view", "label": "View PR", "url": "${{ steps.check-for-pull-request.outputs.pull-request-url }}", "clear": true}]'
- name: ntfy Merged
uses: niniyas/ntfy-action@master
if: steps.merge-changes.outputs.pull-request-operation == 'merged'
with:
url: "${{ secrets.NTFY_URL }}"
topic: "${{ secrets.NTFY_TOPIC }}"
title: "Manifest Render - Automerged"
priority: 3
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
tags: action,successfully,completed
details: "Automerged manifest rendering for cluster '${CLUSTER}' with charts: ${{ steps.check-changes.outputs.changed-charts-csv }}"
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png"
actions: '[{"action": "view", "label": "View PR", "url": "${{ steps.create-pull-request.outputs.pull-request-url }}", "clear": true}]'
- name: ntfy Failed
uses: niniyas/ntfy-action@master
if: failure()
with:
url: "${{ secrets.NTFY_URL }}"
topic: "${{ secrets.NTFY_TOPIC }}"
title: "Manifest Render Failure"
priority: 4
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
tags: action,failed
details: "Manifest rendering for Infrastructure has failed!"
icon: "https://cdn.jsdelivr.net/gh/selfhst/icons/png/gitea.png"
actions: '[{"action": "view", "label": "View Logs", "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", "clear": true}]'

View File

@@ -1,12 +1,12 @@
dependencies:
- name: argo-workflows
repository: https://argoproj.github.io/argo-helm
version: 0.47.5
version: 1.0.2
- name: argo-events
repository: https://argoproj.github.io/argo-helm
version: 2.4.20
- name: postgres-cluster
repository: oci://harbor.alexlebens.net/helm-charts
version: 7.9.1
digest: sha256:5b7f498040dd93f99a00c708c80fcefdb64dcdf473cfd3edcf8a94255b80b3b4
generated: "2026-03-12T13:02:52.109982708Z"
digest: sha256:31596af063744c13afac459184cd027d922d927f4191446eef63646bada28f8f
generated: "2026-03-14T21:07:58.491981-05:00"

View File

@@ -18,7 +18,7 @@ maintainers:
- name: alexlebens
dependencies:
- name: argo-workflows
version: 0.47.5
version: 1.0.2
repository: https://argoproj.github.io/argo-helm
- name: argo-events
version: 2.4.20

View File

@@ -1,4 +1,14 @@
argo-workflows:
crds:
install: true
keep: true
# -- Use full CRDs with complete OpenAPI schemas. When false, uses minified CRDs with x-kubernetes-preserve-unknown-fields.
# Full CRDs are very large and are installed via a pre-install/pre-upgrade hook Job that uses server-side apply.
full: true
upgradeJob:
image:
repository: registry.k8s.io/kubectl
tag: v1.35.2
controller:
metricsConfig:
enabled: true

View File

@@ -6,7 +6,7 @@ keywords:
- bazarr
- servarr
- subtitles
home: https://wiki.alexlebens.dev/s/92784d53-1d43-42fd-b509-f42c73454226
home: https://wiki.alexlebens.dev/s/
sources:
- https://github.com/morpheus65535/bazarr
- https://github.com/linuxserver/docker-bazarr

View File

@@ -4,12 +4,12 @@ dependencies:
version: 4.6.2
- name: mariadb-cluster
repository: https://helm.mariadb.com/mariadb-operator
version: 25.10.4
version: 26.3.0
- name: volsync-target
repository: oci://harbor.alexlebens.net/helm-charts
version: 0.8.0
- name: volsync-target
repository: oci://harbor.alexlebens.net/helm-charts
version: 0.8.0
digest: sha256:d4c7bf75f72f7eab4ad968bf9f55daac9392c9b2df08f8a27c5dc4f8fffb5f57
generated: "2026-03-06T01:06:05.696573273Z"
digest: sha256:e65fa008c652092da5431e9780eb2a87c944298a12e58e432efad61c9e826da5
generated: "2026-03-14T23:57:22.721295098Z"

View File

@@ -18,7 +18,7 @@ dependencies:
repository: https://bjw-s-labs.github.io/helm-charts/
version: 4.6.2
- name: mariadb-cluster
version: 25.10.4
version: 26.3.0
repository: https://helm.mariadb.com/mariadb-operator
- name: volsync-target
alias: volsync-target-config
@@ -30,4 +30,4 @@ dependencies:
repository: oci://harbor.alexlebens.net/helm-charts
icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/booklore.png
# renovate: datasource=github-releases depName=booklore-app/BookLore
appVersion: v2.2.0
appVersion: v2.2.1

View File

@@ -9,7 +9,7 @@ booklore:
main:
image:
repository: ghcr.io/booklore-app/booklore
tag: v2.2.0
tag: v2.2.1
pullPolicy: IfNotPresent
env:
- name: TZ

View File

@@ -7,7 +7,7 @@ keywords:
- dns
- network
- kubernetes
home: https://wiki.alexlebens.dev/s/43947ec6-a034-449f-8c76-982ac493b072
home: https://wiki.alexlebens.dev/s/
sources:
- https://github.com/coredns/coredns
- https://github.com/coredns/helm

View File

@@ -1,7 +1,7 @@
coredns:
image:
repository: registry.k8s.io/coredns/coredns
tag: v1.14.1
tag: v1.14.2
replicaCount: 3
resources:
requests:

View File

@@ -1,9 +1,9 @@
dependencies:
- name: mariadb-operator
repository: https://helm.mariadb.com/mariadb-operator
version: 25.10.4
version: 26.3.0
- name: mariadb-operator-crds
repository: https://helm.mariadb.com/mariadb-operator
version: 26.3.0
digest: sha256:a159f646b8f7501cc5285a508e21dcc96ced71722a3c911b1ee0c73ef7fc0e3a
generated: "2026-03-14T18:39:29.639188669Z"
digest: sha256:95f9484c385d08f9b15f55cbb0f8d82c55b8c1a055a4c7697335d4ca51c35d7e
generated: "2026-03-14T23:23:02.743862932Z"

View File

@@ -15,11 +15,11 @@ maintainers:
- name: alexlebens
dependencies:
- name: mariadb-operator
version: 25.10.4
version: 26.3.0
repository: https://helm.mariadb.com/mariadb-operator
- name: mariadb-operator-crds
version: 26.3.0
repository: https://helm.mariadb.com/mariadb-operator
icon: https://mariadb-operator.github.io/mariadb-operator/assets/mariadb_profile.svg
# renovate: datasource=github-releases depName=mariadb-operator/mariadb-operator
appVersion: 25.10.4
appVersion: 26.3.0

View File

@@ -28,7 +28,7 @@ qbittorrent:
qbittorrent:
image:
repository: ghcr.io/linuxserver/qbittorrent
tag: 5.1.4@sha256:6a7ffbfff04dd109bff37c474bfee00aa08dea5edb78c670439be3ed242b70fa
tag: 5.1.4@sha256:855e5f4805ac218f406a5ae989a62a77e03f7e5f70128335b7970550a58c96e1
pullPolicy: IfNotPresent
env:
- name: TZ

View File

@@ -11,7 +11,7 @@ site-profile:
main:
image:
repository: harbor.alexlebens.net/images/site-profile
tag: 3.12.0
tag: 3.12.1
pullPolicy: IfNotPresent
resources:
requests:

View File

@@ -11,4 +11,5 @@ spec:
nameserver:
image:
repo: tailscale/k8s-nameserver
tag: unstable-v1.93.44
# renovate: datasource=docker depName=tailscale/k8s-nameserver
tag: v1.94.2

View File

@@ -48,7 +48,7 @@ tdarr:
main:
image:
repository: ghcr.io/haveagitgat/tdarr_node
tag: 2.62.01
tag: 2.63.01
pullPolicy: IfNotPresent
env:
- name: TZ

View File

@@ -7,14 +7,50 @@
],
"customManagers": [
{
"description": "Update appVersion in Chart.yaml",
"customType": "regex",
"managerFilePatterns": [
"/(^|/)Chart\\.yaml$/"
],
"matchStrings": [
"#\\s*renovate:\\s*datasource=(?<datasource>.*?) depName=(?<depName>.*?)\\s+appVersion:\\s*[\"']?(?<currentValue>[^\"'\\s]+)[\"']?"
]
},
{
"description": "Update images in templates",
"customType": "regex",
"managerFilePatterns": [
"/(^|/)templates/.*\\.yaml$/"
],
"datasourceTemplate": "github-releases"
"matchStrings": [
"# renovate: datasource=(?<datasource>.*?) depName=(?<depName>.*?)\\s+tag: (?<currentValue>.*)"
]
},
{
"description": "Update Helm CLI version in GitHub Actions",
"customType": "regex",
"managerFilePatterns": [
"/^\\.github/workflows/.*\\.ya?ml$/"
],
"matchStrings": [
"uses: azure/setup-helm@v4[\\s\\S]*?version: (?<currentValue>v?\\d+\\.\\d+\\.\\d+)"
],
"depNameTemplate": "helm/helm",
"datasourceTemplate": "github-releases",
"versioningTemplate": "semver"
},
{
"description": "Update Kubeconform version in GitHub Actions env",
"customType": "regex",
"managerFilePatterns": [
"/^\\.github/workflows/.*\\.ya?ml$/"
],
"matchStrings": [
"KUBECONFORM_VERSION: \"(?<currentValue>v?\\d+\\.\\d+\\.\\d+)\""
],
"depNameTemplate": "yannh/kubeconform",
"datasourceTemplate": "github-releases",
"versioningTemplate": "semver"
}
],
"timezone": "US/Central",
@@ -65,7 +101,8 @@
{
"description": "Label images, helm",
"matchManagers": [
"custom.regex", "helm-values"
"custom.regex",
"helm-values"
],
"groupName": "{{#if packageName}}{{{replace 'ghcr.io/' '' (replace 'docker.io/' '' packageName)}}}{{else}}{{{replace 'ghcr.io/' '' (replace 'docker.io/' '' depName)}}}{{/if}}",
"groupSlug": "unified-{{{groupName}}}",
@@ -91,7 +128,8 @@
"digest"
],
"matchManagers": [
"custom.regex", "helm-values"
"custom.regex",
"helm-values"
],
"groupName": "{{#if packageName}}{{{replace 'ghcr.io/' '' (replace 'docker.io/' '' packageName)}}}{{else}}{{{replace 'ghcr.io/' '' (replace 'docker.io/' '' depName)}}}{{/if}}",
"groupSlug": "unified-{{{groupName}}}",