From 2bd0f29ac65d4c0cb1f9fb137afcb9c32c3de8f4 Mon Sep 17 00:00:00 2001 From: Oleksandr Berezovskyi Date: Mon, 11 May 2026 23:58:06 +0300 Subject: [PATCH] feat(k8s/gitea): add renovate support --- kubernetes/app/gitea/release.yaml | 172 +++++++++++++++++++++++++++++ kubernetes/app/gitea/renovate.json | 33 ++++++ renovate.json | 3 +- 3 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 kubernetes/app/gitea/renovate.json diff --git a/kubernetes/app/gitea/release.yaml b/kubernetes/app/gitea/release.yaml index dddad70..539dd5a 100644 --- a/kubernetes/app/gitea/release.yaml +++ b/kubernetes/app/gitea/release.yaml @@ -21,6 +21,175 @@ spec: upgrade: remediation: retries: 3 + # Patch the init script: Gitea 1.26 removed environment-to-ini; use built-in subcommand instead. + # Remove once helm-gitea chart ships a release with the fix (commit 1baf2d0). + postRenderers: + - kustomize: + patches: + - target: + kind: Secret + name: gitea-gitea + patch: | + apiVersion: v1 + kind: Secret + metadata: + name: gitea-gitea + stringData: + config_environment.sh: | + #!/usr/bin/env bash + set -euo pipefail + + function env2ini::log() { + printf "$${1}\n" + } + + function env2ini::read_config_to_env() { + local section="$${1}" + local line="$${2}" + + if [[ -z "$${line}" ]]; then + # skip empty line + return + fi + + # 'xargs echo -n' trims all leading/trailing whitespaces and a trailing new line + local setting="$(awk -F '=' '{print $1}' <<< "$${line}" | xargs echo -n)" + + if [[ -z "$${setting}" ]]; then + env2ini::log ' ! invalid setting' + exit 1 + fi + + local value='' + local regex="^$${setting}(\s*)=(\s*)(.*)" + if [[ $line =~ $regex ]]; then + value="$${BASH_REMATCH[3]}" + else + env2ini::log ' ! invalid setting' + exit 1 + fi + + env2ini::log " + '$${setting}'" + + if [[ -z "$${section}" ]]; then + export "GITEA____$${setting^^}=$${value}" # '^^' makes the variable content uppercase + return + fi + + local masked_section="$${section//./_0X2E_}" # '//' instructs to replace all matches + masked_section="$${masked_section//-/_0X2D_}" + + export "GITEA__$${masked_section^^}__$${setting^^}=$${value}" # '^^' makes the variable content uppercase + } + + function env2ini::reload_preset_envs() { + env2ini::log "Reloading preset envs..." + + while read -r line; do + if [[ -z "$${line}" ]]; then + # skip empty line + return + fi + + # 'xargs echo -n' trims all leading/trailing whitespaces and a trailing new line + local setting="$(awk -F '=' '{print $1}' <<< "$${line}" | xargs echo -n)" + + if [[ -z "$${setting}" ]]; then + env2ini::log ' ! invalid setting' + exit 1 + fi + + local value='' + local regex="^$${setting}(\s*)=(\s*)(.*)" + if [[ $line =~ $regex ]]; then + value="$${BASH_REMATCH[3]}" + else + env2ini::log ' ! invalid setting' + exit 1 + fi + + env2ini::log " + '$${setting}'" + + export "$${setting^^}=$${value}" # '^^' makes the variable content uppercase + done < "$TMP_EXISTING_ENVS_FILE" + + rm $TMP_EXISTING_ENVS_FILE + } + + + function env2ini::process_config_file() { + local config_file="$${1}" + local section="$(basename "$${config_file}")" + + if [[ $section == '_generals_' ]]; then + env2ini::log " [ini root]" + section='' + else + env2ini::log " $${section}" + fi + + while read -r line; do + env2ini::read_config_to_env "$${section}" "$${line}" + done < <(awk 1 "$${config_file}") # Helm .toYaml trims the trailing new line which breaks line processing; awk 1 ... adds it back while reading + } + + function env2ini::load_config_sources() { + local path="$${1}" + + if [[ -d "$${path}" ]]; then + env2ini::log "Processing $(basename "$${path}")..." + + while read -d '' configFile; do + env2ini::process_config_file "$${configFile}" + done < <(find "$${path}" -type l -not -name '..data' -print0) + + env2ini::log "\n" + fi + } + + function env2ini::generate_initial_secrets() { + # These environment variables will either be + # - overwritten with user defined values, + # - initially used to set up Gitea + # Anyway, they won't harm existing app.ini files + + export GITEA__SECURITY__INTERNAL_TOKEN=$(gitea generate secret INTERNAL_TOKEN) + export GITEA__SECURITY__SECRET_KEY=$(gitea generate secret SECRET_KEY) + export GITEA__OAUTH2__JWT_SECRET=$(gitea generate secret JWT_SECRET) + export GITEA__SERVER__LFS_JWT_SECRET=$(gitea generate secret LFS_JWT_SECRET) + + env2ini::log "...Initial secrets generated\n" + } + + # save existing envs prior to script execution. Necessary to keep order of preexisting and custom envs + env | (grep -e '^GITEA__' || [[ $? == 1 ]]) > $TMP_EXISTING_ENVS_FILE + + # MUST BE CALLED BEFORE OTHER CONFIGURATION + env2ini::generate_initial_secrets + + env2ini::load_config_sources "$ENV_TO_INI_MOUNT_POINT/inlines/" + env2ini::load_config_sources "$ENV_TO_INI_MOUNT_POINT/additionals/" + + # load existing envs to override auto generated envs + env2ini::reload_preset_envs + + env2ini::log "=== All configuration sources loaded ===\n" + + # safety to prevent rewrite of secret keys if an app.ini already exists + if [ -f $${GITEA_APP_INI} ]; then + env2ini::log 'An app.ini file already exists. To prevent overwriting secret keys, these settings are dropped and remain unchanged:' + env2ini::log ' - security.INTERNAL_TOKEN' + env2ini::log ' - security.SECRET_KEY' + env2ini::log ' - oauth2.JWT_SECRET' + env2ini::log ' - server.LFS_JWT_SECRET' + + unset GITEA__SECURITY__INTERNAL_TOKEN + unset GITEA__SECURITY__SECRET_KEY + unset GITEA__OAUTH2__JWT_SECRET + unset GITEA__SERVER__LFS_JWT_SECRET + fi + + gitea config edit-ini --apply-env --config "$GITEA_APP_INI" --out "$GITEA_APP_INI" values: strategy: type: Recreate @@ -30,6 +199,9 @@ spec: type: RuntimeDefault image: + # renovate: currentValue=1.26.1-rootless currentDigest=sha256:4c4256497e2e237ddebdd30986c7ce52cb6f936b3e90c34bb9f4665714599f62 + tag: 1.26.1 + digest: sha256:4c4256497e2e237ddebdd30986c7ce52cb6f936b3e90c34bb9f4665714599f62 rootless: true pullPolicy: IfNotPresent diff --git a/kubernetes/app/gitea/renovate.json b/kubernetes/app/gitea/renovate.json new file mode 100644 index 0000000..8e1ce22 --- /dev/null +++ b/kubernetes/app/gitea/renovate.json @@ -0,0 +1,33 @@ +{ + "customManagers": [ + { + "customType": "regex", + "description": "Track gitea rootless image; chart appends -rootless to tag automatically", + "fileMatch": ["kubernetes/app/gitea/release\\.yaml$"], + "matchStrings": [ + "(?\\s+)# renovate: currentValue=(?[^\\s]+) currentDigest=(?sha256:[a-f0-9]+)\\n\\s+tag: [^\\s]+\\n\\s+digest: [^\\s]+" + ], + "depNameTemplate": "gitea/gitea", + "datasourceTemplate": "docker", + "autoReplaceStringTemplate": "{{indentation}}# renovate: currentValue={{newValue}} currentDigest={{#if newDigest}}{{{newDigest}}}{{else}}{{{currentDigest}}}{{/if}}\n{{indentation}}tag: {{newMajor}}.{{newMinor}}.{{newPatch}}\n{{indentation}}digest: {{#if newDigest}}{{{newDigest}}}{{else}}{{{currentDigest}}}{{/if}}" + } + ], + "packageRules": [ + { + "matchFileNames": ["kubernetes/app/gitea/**"], + "semanticCommitScope": "k8s/gitea" + }, + { + "matchFileNames": ["kubernetes/app/gitea/**"], + "matchPackageNames": ["gitea/gitea"], + "matchUpdateTypes": ["patch", "minor"], + "automerge": true + }, + { + "description": "Ignore infrastructure images", + "matchFileNames": ["kubernetes/app/gitea/**"], + "matchPackageNames": ["creativeprojects/resticprofile", "postgres"], + "enabled": false + } + ] +} diff --git a/renovate.json b/renovate.json index 868735c..a9bea1d 100644 --- a/renovate.json +++ b/renovate.json @@ -5,7 +5,8 @@ ":semanticCommits", "local>oleksandr/homelab//kubernetes/app/jellyfin/renovate.json", "local>oleksandr/homelab//kubernetes/app/media/renovate.json", - "local>oleksandr/homelab//kubernetes/app/immich/renovate.json" + "local>oleksandr/homelab//kubernetes/app/immich/renovate.json", + "local>oleksandr/homelab//kubernetes/app/gitea/renovate.json" ], "enabledManagers": ["kubernetes", "custom.regex"], "automergeType": "branch",