Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ env-defaults: ## Regenerate files/env-defaults.yaml from Appwrite's variables.ph
images: ## Sync the artifacthub.io/images annotation with values.yaml
hack/chart-images.sh

.PHONY: update-images
update-images: ## Bump every pinned image tag in values.yaml to the newest in its registry (ARGS="--dry-run --all")
hack/update-images.sh $(ARGS)

.PHONY: generate
generate: schema images docs ## Regenerate all generated files

Expand Down
8 changes: 4 additions & 4 deletions charts/appwrite/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ annotations:
- name: browser
image: docker.io/appwrite/browser:0.3.4
- name: builds
image: ghcr.io/open-runtimes/orchestrator/job-sidecar:2.2.2
image: ghcr.io/open-runtimes/orchestrator/job-sidecar:2.2.3
- name: builtin
image: docker.io/appwrite/postgres:0.1.0
- name: builtin
image: docker.io/library/redis:7.4.7-alpine
image: docker.io/library/redis:7.4.11-alpine
- name: builtin
image: docker.io/clickhouse/clickhouse-server:26.4.3-alpine
image: docker.io/clickhouse/clickhouse-server:26.4.5-alpine
- name: builtin-exporter
image: quay.io/prometheuscommunity/postgres-exporter:v0.20.1
- name: builtin-exporter
Expand All @@ -91,5 +91,5 @@ annotations:
- name: geo
image: docker.io/appwrite/geo:0.3.1
- name: orchestrator
image: ghcr.io/open-runtimes/orchestrator/jobs-service:2.2.2
image: ghcr.io/open-runtimes/orchestrator/jobs-service:2.2.3
artifacthub.io/displayName: Appwrite
8 changes: 4 additions & 4 deletions charts/appwrite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ Built-in or your own.
| redis.builtin.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. |
| redis.builtin.image.registry | string | `"docker.io"` | Image registry. |
| redis.builtin.image.repository | string | `"library/redis"` | Image repository. `valkey/valkey` works as a drop-in replacement, with a Valkey tag (e.g. `8-alpine`). |
| redis.builtin.image.tag | string | `"7.4.7-alpine"` | Image tag. |
| redis.builtin.image.tag | string | `"7.4.11-alpine"` | Image tag. |
| redis.builtin.maxmemory | string | `"512mb"` | `maxmemory`. Keep it below the memory limit. |
| redis.builtin.maxmemoryPolicy | string | `"allkeys-lru"` | `maxmemory-policy`. Appwrite's Docker install uses `allkeys-lru`. |
| redis.builtin.metrics.enabled | bool | `false` | Run a redis_exporter sidecar and expose it on port 9121 of the Service. See docs/production.md#monitoring. |
Expand Down Expand Up @@ -428,7 +428,7 @@ Built-in or your own.
| clickhouse.builtin.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. |
| clickhouse.builtin.image.registry | string | `"docker.io"` | Image registry. |
| clickhouse.builtin.image.repository | string | `"clickhouse/clickhouse-server"` | Image repository. |
| clickhouse.builtin.image.tag | string | `"26.4.3-alpine"` | Image tag. |
| clickhouse.builtin.image.tag | string | `"26.4.5-alpine"` | Image tag. |
| clickhouse.builtin.metrics.enabled | bool | `false` | Serve ClickHouse's built-in Prometheus endpoint on port 9363 of the Service (`/metrics`). No sidecar. See docs/production.md#monitoring. |
| clickhouse.builtin.nodeSelector | object | `{}` | Node selector. Empty inherits `defaults.nodeSelector`. |
| clickhouse.builtin.persistence.accessModes | list | `["ReadWriteOnce"]` | Access modes. |
Expand Down Expand Up @@ -848,7 +848,7 @@ The build orchestrator and the executor.
| compute.builds.sidecarImage.digest | string | `""` | Image digest. |
| compute.builds.sidecarImage.registry | string | `"ghcr.io"` | Image registry. |
| compute.builds.sidecarImage.repository | string | `"open-runtimes/orchestrator/job-sidecar"` | Image repository of the sidecar that moves sources, outputs and caches for each build. |
| compute.builds.sidecarImage.tag | string | `"2.2.2"` | Image tag. |
| compute.builds.sidecarImage.tag | string | `"2.2.3"` | Image tag. |
| compute.builds.tolerations | list | `[]` | Tolerations for build pods. |
| compute.enabled | bool | `false` | Enable Functions and Sites. Needs `storage.device: s3` and `compute.executor.privileged` (see docs/executor.md). |
| compute.executor.affinity | object | `{}` | Affinity. Empty inherits `defaults.affinity`. |
Expand Down Expand Up @@ -891,7 +891,7 @@ The build orchestrator and the executor.
| compute.orchestrator.image.pullPolicy | string | `"IfNotPresent"` | Image pull policy. |
| compute.orchestrator.image.registry | string | `"ghcr.io"` | Image registry. |
| compute.orchestrator.image.repository | string | `"open-runtimes/orchestrator/jobs-service"` | Image repository: the orchestrator's jobs service, with the Kubernetes backend. |
| compute.orchestrator.image.tag | string | `"2.2.2"` | Image tag. |
| compute.orchestrator.image.tag | string | `"2.2.3"` | Image tag. |
| compute.orchestrator.nodeSelector | object | `{}` | Node selector. Empty inherits `defaults.nodeSelector`. |
| compute.orchestrator.podAnnotations | object | `{}` | Pod annotations, merged over `defaults.podAnnotations`. |
| compute.orchestrator.podLabels | object | `{}` | Pod labels, merged over `defaults.podLabels`. |
Expand Down
7 changes: 6 additions & 1 deletion charts/appwrite/tests/builds_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ tests:
asserts:
- equal:
path: spec.template.spec.containers[0].image
value: ghcr.io/open-runtimes/orchestrator/jobs-service:2.2.2
value: ghcr.io/open-runtimes/orchestrator/jobs-service:2.2.3
- contains:
path: spec.template.spec.containers[0].env
content:
name: JOB_SIDECAR_IMAGE
value: ghcr.io/open-runtimes/orchestrator/job-sidecar:2.2.3
- equal:
path: spec.strategy.type
value: Recreate
Expand Down
8 changes: 4 additions & 4 deletions charts/appwrite/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ redis:
# with a Valkey tag (e.g. `8-alpine`).
repository: library/redis
# -- Image tag.
tag: 7.4.7-alpine
tag: 7.4.11-alpine
# -- Image digest.
digest: ""
# -- Image pull policy.
Expand Down Expand Up @@ -577,7 +577,7 @@ clickhouse:
# -- Image repository.
repository: clickhouse/clickhouse-server
# -- Image tag.
tag: 26.4.3-alpine
tag: 26.4.5-alpine
# -- Image digest.
digest: ""
# -- Image pull policy.
Expand Down Expand Up @@ -855,7 +855,7 @@ compute:
# -- Image repository: the orchestrator's jobs service, with the Kubernetes backend.
repository: open-runtimes/orchestrator/jobs-service
# -- Image tag.
tag: 2.2.2
tag: 2.2.3
# -- Image digest.
digest: ""
# -- Image pull policy.
Expand Down Expand Up @@ -911,7 +911,7 @@ compute:
# -- Image repository of the sidecar that moves sources, outputs and caches for each build.
repository: open-runtimes/orchestrator/job-sidecar
# -- Image tag.
tag: 2.2.2
tag: 2.2.3
Comment thread
hansi-codes[bot] marked this conversation as resolved.
# -- Image digest.
digest: ""
# -- Divides each build's CPU limit to get its CPU request
Expand Down
4 changes: 2 additions & 2 deletions hack/fixtures/external-dbs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ spec:
spec:
containers:
- name: redis
image: redis:7.4.7-alpine
image: redis:7.4.11-alpine
args: [--requirepass, $(REDIS_PASSWORD)]
env:
- name: REDIS_PASSWORD
Expand Down Expand Up @@ -97,7 +97,7 @@ spec:
spec:
containers:
- name: clickhouse
image: clickhouse/clickhouse-server:26.4.3-alpine
image: clickhouse/clickhouse-server:26.4.5-alpine
env:
- {name: CLICKHOUSE_DB, value: usage}
- {name: CLICKHOUSE_USER, value: usage}
Expand Down
115 changes: 115 additions & 0 deletions hack/update-images.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/env bash
# Updates every pinned image tag in values.yaml to the newest tag in its
# registry, then syncs the artifacthub.io/images annotation.
#
# A candidate tag has the same shape as the current one: the same prefix and
# suffix (v0.20.1, 7.4.7-alpine, 29.9.0-dind, 1.1.159-self-hosted) and the
# same number of version components, so floating tags (7, 7.4, latest) and
# pre-releases (-rc.1) are never picked. The built-in datastores stay on their
# current major version, as in renovate.json, and ClickHouse on its current
# year.month release (26.4.x), since each of those is a feature release.
#
# The images Renovate groups with Appwrite in renovate.json (the console,
# executor, orchestrator and Appwrite's own services) are pinned to what
# Appwrite's docker-compose.yml uses for appVersion, not to the newest tag:
# they're skipped unless --all is given. The Appwrite image follows appVersion
# (its tag is empty) and isn't touched; see CONTRIBUTING.md.
#
# Usage: hack/update-images.sh [--dry-run] [--all]
# Requires: yq v4, jq, curl.
set -euo pipefail

CHART="${CHART:-charts/appwrite}"
VALUES="$CHART/values.yaml"
dry_run=false
all=false
for arg in "$@"; do
case "$arg" in
--dry-run) dry_run=true ;;
--all) all=true ;;
-h | --help)
sed -n '2,/^set -euo/p' "$0" | sed '$d; s/^# \{0,1\}//'
exit 0
;;
*)
echo "Unknown argument: $arg (see --help)" >&2
exit 2
;;
esac
done
appwrite_group=$(jq -r '.packageRules[] | select(.groupName == "appwrite") | .matchPackageNames[]' \
"$(dirname "$0")/../renovate.json")

# Prints every tag of registry/repository, using an anonymous pull token when
# the registry asks for one and following Link pagination.
list_tags() {
local registry=$1 repository=$2 host=$1 auth=() challenge realm service token url
[[ "$registry" == docker.io ]] && host="registry-1.docker.io"
url="https://${host}/v2/${repository}/tags/list?n=10000"
challenge=$(curl -sS -o /dev/null -D - "$url" | tr -d '\r' | grep -i '^www-authenticate: bearer' || true)
if [[ -n "$challenge" ]]; then
realm=$(sed -E 's/.*realm="([^"]+)".*/\1/' <<<"$challenge")
service=$(sed -E 's/.*service="([^"]+)".*/\1/' <<<"$challenge")
token=$(curl -fsS "${realm}?service=${service}&scope=repository:${repository}:pull" | jq -er '.token // .access_token')
auth=(-H "Authorization: Bearer ${token}")
fi
while [[ -n "$url" ]]; do
headers=$(mktemp)
curl -fsS "${auth[@]}" -D "$headers" "$url" | jq -r '.tags[]?'
url=$(tr -d '\r' < "$headers" | sed -nE 's/^[Ll]ink: <([^>]+)>.*/\1/p')
rm -f "$headers"
[[ -z "$url" || "$url" == http* ]] || url="https://${host}${url}"
done
}

# Prints the newest tag of the same shape as $1 among the tags on stdin,
# keeping its first $2 version components (0: any version, 1: same major).
newest() {
local current=$1 fixed=$2 prefix suffix pattern="" i=0 part
[[ "$current" =~ ^([^0-9]*)([0-9]+(\.[0-9]+)*)(.*)$ ]] || return 0
prefix=${BASH_REMATCH[1]} suffix=${BASH_REMATCH[4]}
for part in ${BASH_REMATCH[2]//./ }; do
[[ "$i" -lt "$fixed" ]] || part='[0-9]+'
pattern+="${pattern:+\\.}${part}"
i=$((i + 1))
done
{ grep -E "^$(escape "$prefix")${pattern}$(escape "$suffix")\$" || true; } \
| awk -v p="${#prefix}" -v s="${#suffix}" '{print substr($0, p + 1, length($0) - p - s) "\t" $0}' \
| sort -V | tail -1 | cut -f2
}

escape() { sed 's/[][\.*^$+?(){}|/]/\\&/g' <<<"$1"; }

changed=0
while IFS=$'\t' read -r path registry repository tag; do
if [[ "$all" == false ]] && grep -qx "${registry}/${repository}" <<<"$appwrite_group"; then
printf ' %-45s %s (follows Appwrite %s, --all to update)\n' "${registry}/${repository}" "$tag" \
"$(yq '.appVersion' "$CHART/Chart.yaml")"
continue
fi
fixed=0
[[ "$path" == *.builtin.image ]] && fixed=1
[[ "$repository" == clickhouse/clickhouse-server ]] && fixed=2
latest=$(list_tags "$registry" "$repository" | newest "$tag" "$fixed")
if [[ -z "$latest" || "$latest" == "$tag" ]]; then
printf ' %-45s %s\n' "${registry}/${repository}" "$tag"
continue
fi
printf '* %-45s %s -> %s\n' "${registry}/${repository}" "$tag" "$latest"
changed=$((changed + 1))
if [[ "$dry_run" == false ]]; then
# yq -i would drop the file's blank lines: edit only the tag's line, the
# first one after the image's repository.
awk -v repo="$repository" -v old="$tag" -v new="$latest" '
$1 == "repository:" && $2 == repo { found = 1 }
found && $1 == "tag:" && $2 == old { sub(/tag: .*/, "tag: " new); found = 0 }
{ print }
' "$VALUES" > "$VALUES.tmp" && mv "$VALUES.tmp" "$VALUES"
fi
done < <(yq -r '.. | select(tag == "!!map" and has("registry") and has("repository") and .tag != "")
| [(path | map(tostring) | join(".")), .registry, .repository, .tag] | @tsv' "$VALUES")
Comment on lines +109 to +110

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Propagate failures from the values query

The yq command runs in process substitution, so its exit status is not covered by set -e or the while loop's status. If yq is missing or values.yaml cannot be parsed, the helper can print an error and still exit successfully, making a failed update look like a successful no-op.

Prompt To Fix With AI
This is a comment left during a code review.
Path: hack/update-images.sh
Line: 109-110

Comment:
**Propagate failures from the values query**

The `yq` command runs in process substitution, so its exit status is not covered by `set -e` or the `while` loop's status. If `yq` is missing or `values.yaml` cannot be parsed, the helper can print an error and still exit successfully, making a failed update look like a successful no-op.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

🟡 Minor · error-handling · Reply if this doesn't apply.


if [[ "$changed" -gt 0 && "$dry_run" == false ]]; then
"$(dirname "$0")/chart-images.sh"
echo "Updated ${changed} image(s). Run 'make generate test', and add a CHANGELOG.md entry."
fi
Loading