chore: upgrade project stack and deployment baseline
This commit is contained in:
parent
68faa4795c
commit
51da6d8881
21
Dockerfile
21
Dockerfile
|
|
@ -1,9 +1,9 @@
|
||||||
# This file is based on these images:
|
# This file is based on these images:
|
||||||
#
|
#
|
||||||
# - https://hub.docker.com/r/hexpm/elixir/tags - for the builder image
|
# - https://hub.docker.com/r/hexpm/elixir/tags - for the builder image
|
||||||
# E.g.: docker.io/hexpm/elixir:1.18.4-erlang-27.3.4.13-debian-trixie-20260623-slim
|
# E.g.: docker.io/hexpm/elixir:1.20.2-erlang-29.0.3-debian-trixie-20260713-slim
|
||||||
# - https://hub.docker.com/_/debian/tags?name=trixie-20260623-slim - for the runner image
|
# - https://hub.docker.com/_/debian/tags?name=trixie-20260713-slim - for the runner image
|
||||||
# E.g.: docker.io/debian:trixie-20260623-slim
|
# E.g.: docker.io/debian:trixie-20260713-slim
|
||||||
#
|
#
|
||||||
# Find builder and runner images on Docker Hub or on Hex's Build Server (Bob).
|
# Find builder and runner images on Docker Hub or on Hex's Build Server (Bob).
|
||||||
# We recommend using Bob's Web UI to find recent tags:
|
# We recommend using Bob's Web UI to find recent tags:
|
||||||
|
|
@ -17,18 +17,19 @@
|
||||||
#
|
#
|
||||||
# For finding packages in Debian, search on https://packages.debian.org/.
|
# For finding packages in Debian, search on https://packages.debian.org/.
|
||||||
|
|
||||||
ARG ELIXIR_VERSION=1.18.4
|
ARG ELIXIR_VERSION=1.20.2
|
||||||
ARG OTP_VERSION=27.3.4.13
|
ARG OTP_VERSION=29.0.3
|
||||||
ARG DEBIAN_VERSION=trixie-20260623-slim
|
ARG DEBIAN_VERSION=trixie-20260713-slim
|
||||||
|
|
||||||
ARG BUILDER_IMAGE="docker.io/hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
|
ARG BUILDER_IMAGE="docker.io/hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}@sha256:6fcd8ea864221b960c1ec418e3b10fa488298ff9e70c9e0f3db18070e610fb8a"
|
||||||
ARG RUNNER_IMAGE="docker.io/debian:${DEBIAN_VERSION}"
|
ARG RUNNER_IMAGE="docker.io/debian:${DEBIAN_VERSION}@sha256:020c0d20b9880058cbe785a9db107156c3c75c2ac944a6aa7ab59f2add76a7bd"
|
||||||
|
|
||||||
FROM docker.io/node:22.21.1-bookworm-slim AS node_deps
|
FROM docker.io/node:24.18.0-bookworm-slim@sha256:6f7b03f7c2c8e2e784dcf9295400527b9b1270fd37b7e9a7285cf83b6951452d AS node_deps
|
||||||
|
|
||||||
WORKDIR /assets
|
WORKDIR /assets
|
||||||
COPY assets/package.json assets/package-lock.json ./
|
COPY assets/package.json assets/package-lock.json ./
|
||||||
RUN npm ci
|
RUN npm install --global npm@12.0.1 \
|
||||||
|
&& npm ci
|
||||||
|
|
||||||
FROM ${BUILDER_IMAGE} AS builder
|
FROM ${BUILDER_IMAGE} AS builder
|
||||||
|
|
||||||
|
|
|
||||||
19
README.md
19
README.md
|
|
@ -151,12 +151,22 @@ Open:
|
||||||
- Mailpit: <http://localhost:8028>
|
- Mailpit: <http://localhost:8028>
|
||||||
|
|
||||||
The script refuses to modify a pre-existing cluster named `who-need-help`
|
The script refuses to modify a pre-existing cluster named `who-need-help`
|
||||||
unless the project ownership marker exists.
|
unless the project ownership marker exists. On first install it creates
|
||||||
|
independent random application and PostgreSQL credentials in the
|
||||||
|
`who-need-help-local` Kubernetes Secret without writing them to Git. The local
|
||||||
|
PostGIS data directory persists inside the kind node. When migrating an older
|
||||||
|
project-owned cluster from the former `emptyDir` deployment, the script creates
|
||||||
|
and validates a local dump before replacing the database workload, then restores
|
||||||
|
that dump. After a successful rollout it also removes the obsolete chart Secret
|
||||||
|
and only the local Helm history revisions that stored the former inline
|
||||||
|
credential fields.
|
||||||
|
|
||||||
For an external cluster, provide a real PostgreSQL/PostGIS service and a
|
For an external cluster, provide a real PostgreSQL/PostGIS service and a
|
||||||
pre-created Secret through `existingSecret`. The chart intentionally has no
|
pre-created Secret through required `existingSecret`; the chart never renders
|
||||||
invented CPU/RAM limits or HPA thresholds; measure this application in the
|
credentials from tracked values. The Secret must contain `DATABASE_URL`,
|
||||||
target environment before setting them.
|
`SECRET_KEY_BASE`, `HANDOVER_SECRET`, and `RELEASE_COOKIE`. The chart
|
||||||
|
intentionally has no invented CPU/RAM limits or HPA thresholds; measure this
|
||||||
|
application in the target environment before setting them.
|
||||||
|
|
||||||
## Local Codex category review
|
## Local Codex category review
|
||||||
|
|
||||||
|
|
@ -185,6 +195,7 @@ and no fallback provider. Recommendations require a human moderator action.
|
||||||
- [Architecture](docs/architecture.md)
|
- [Architecture](docs/architecture.md)
|
||||||
- [Trust and safety](docs/trust-safety.md)
|
- [Trust and safety](docs/trust-safety.md)
|
||||||
- [Implementation verification and known limits](docs/verification.md)
|
- [Implementation verification and known limits](docs/verification.md)
|
||||||
|
- [Verified dependency baseline](docs/dependency-baseline.md)
|
||||||
- [PostgreSQL/PostGIS ADR](docs/decisions/0001-postgresql-postgis-over-spacetimedb.md)
|
- [PostgreSQL/PostGIS ADR](docs/decisions/0001-postgresql-postgis-over-spacetimedb.md)
|
||||||
|
|
||||||
Exact dependency versions are locked in `mix.lock`,
|
Exact dependency versions are locked in `mix.lock`,
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ FROM gradle:9.6.1-jdk17@sha256:7364ce528f33bb6038672bcef990d524f1ad8fbc292935819
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
ARG ANDROID_COMMAND_LINE_TOOLS_VERSION=14742923
|
ARG ANDROID_COMMAND_LINE_TOOLS_VERSION=15859902
|
||||||
ARG ANDROID_COMMAND_LINE_TOOLS_SHA1=48833c34b761c10cb20bcd16582129395d121b27
|
ARG ANDROID_COMMAND_LINE_TOOLS_SHA1=040d3996a65543d22ec4bf73e4c37aa37a8d4af4
|
||||||
|
|
||||||
ENV ANDROID_HOME=/opt/android-sdk
|
ENV ANDROID_HOME=/opt/android-sdk
|
||||||
ENV ANDROID_SDK_ROOT=/opt/android-sdk
|
ENV ANDROID_SDK_ROOT=/opt/android-sdk
|
||||||
|
|
@ -21,12 +21,11 @@ RUN mkdir -p "${ANDROID_HOME}/cmdline-tools" \
|
||||||
| sha1sum -c - \
|
| sha1sum -c - \
|
||||||
&& unzip -q /tmp/android-command-line-tools.zip -d /tmp/android-command-line-tools \
|
&& unzip -q /tmp/android-command-line-tools.zip -d /tmp/android-command-line-tools \
|
||||||
&& mv /tmp/android-command-line-tools/cmdline-tools "${ANDROID_HOME}/cmdline-tools/latest" \
|
&& mv /tmp/android-command-line-tools/cmdline-tools "${ANDROID_HOME}/cmdline-tools/latest" \
|
||||||
&& rm -rf /tmp/android-command-line-tools /tmp/android-command-line-tools.zip \
|
&& rm -rf /tmp/android-command-line-tools /tmp/android-command-line-tools.zip
|
||||||
&& yes | sdkmanager --licenses >/dev/null
|
|
||||||
|
|
||||||
RUN sdkmanager \
|
RUN android --no-metrics --sdk="${ANDROID_HOME}" sdk install \
|
||||||
"build-tools;37.0.0" \
|
"build-tools/37.0.0" \
|
||||||
"platforms;android-37.0" \
|
"platforms/android-37.0" \
|
||||||
&& chown -R gradle:gradle "${ANDROID_HOME}"
|
&& chown -R gradle:gradle "${ANDROID_HOME}"
|
||||||
|
|
||||||
FROM android-base AS android-sdk
|
FROM android-base AS android-sdk
|
||||||
|
|
@ -52,6 +51,11 @@ FROM android-base AS emulator
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
|
RUN android --no-metrics --sdk="${ANDROID_HOME}" sdk install \
|
||||||
|
"emulator" \
|
||||||
|
"system-images/android-37.0/google_apis_ps16k/x86_64" \
|
||||||
|
&& chown -R gradle:gradle "${ANDROID_HOME}"
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
libdbus-1-3 \
|
libdbus-1-3 \
|
||||||
|
|
@ -63,20 +67,16 @@ RUN apt-get update \
|
||||||
libxcomposite1 \
|
libxcomposite1 \
|
||||||
libxcursor1 \
|
libxcursor1 \
|
||||||
libxi6 \
|
libxi6 \
|
||||||
|
libxkbfile1 \
|
||||||
libxrandr2 \
|
libxrandr2 \
|
||||||
libxrender1 \
|
libxrender1 \
|
||||||
libxtst6 \
|
libxtst6 \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN sdkmanager \
|
|
||||||
"emulator" \
|
|
||||||
"system-images;android-37.0;google_apis_ps16k;x86_64" \
|
|
||||||
&& chown -R gradle:gradle "${ANDROID_HOME}"
|
|
||||||
|
|
||||||
# The container is operated from the host through `docker exec ... adb`.
|
# The container is operated from the host through `docker exec ... adb`.
|
||||||
# Keep platform-tools in the emulator target without invalidating the large
|
# Keep platform-tools in the emulator target without invalidating the large
|
||||||
# system-image layer when application sources change.
|
# system-image layer when application sources change.
|
||||||
RUN sdkmanager "platform-tools" \
|
RUN android --no-metrics --sdk="${ANDROID_HOME}" sdk install "platform-tools" \
|
||||||
&& chown -R gradle:gradle "${ANDROID_HOME}"
|
&& chown -R gradle:gradle "${ANDROID_HOME}"
|
||||||
|
|
||||||
USER gradle
|
USER gradle
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ background-location permission.
|
||||||
|
|
||||||
- Android Gradle Plugin 9.3.0
|
- Android Gradle Plugin 9.3.0
|
||||||
- Gradle 9.6.1
|
- Gradle 9.6.1
|
||||||
|
- Android SDK Command-line Tools 22.0
|
||||||
|
- Android CLI 1.0.15857036 (embedded in the locked Command-line Tools archive)
|
||||||
- compileSdk / targetSdk 37
|
- compileSdk / targetSdk 37
|
||||||
- Build Tools 37.0.0
|
- Build Tools 37.0.0
|
||||||
- Java source and bytecode level 17
|
- Java source and bytecode level 17
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ x-app-environment: &app-environment
|
||||||
|
|
||||||
services:
|
services:
|
||||||
proxy:
|
proxy:
|
||||||
image: traefik:v3.7
|
image: traefik:v3.7.8@sha256:4299bbed850421258fc5448c2e0e6ad350981d4d335a68de11b92448aedbefe5
|
||||||
command:
|
command:
|
||||||
- --api.dashboard=false
|
- --api.dashboard=false
|
||||||
- --providers.docker=true
|
- --providers.docker=true
|
||||||
|
|
@ -41,7 +41,7 @@ services:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: postgis/postgis:18-3.6-alpine
|
image: postgis/postgis:18-3.6-alpine@sha256:05d68c7f0f19b9aa0bf7c4a2049b2e8b38b44a63116392b95726a4c913766cf6
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: ${POSTGRES_DB:?Set POSTGRES_DB in .env}
|
POSTGRES_DB: ${POSTGRES_DB:?Set POSTGRES_DB in .env}
|
||||||
POSTGRES_USER: ${POSTGRES_USER:?Set POSTGRES_USER in .env}
|
POSTGRES_USER: ${POSTGRES_USER:?Set POSTGRES_USER in .env}
|
||||||
|
|
@ -57,7 +57,7 @@ services:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
mailpit:
|
mailpit:
|
||||||
image: axllent/mailpit:v1.27
|
image: axllent/mailpit:v1.30.4@sha256:5a49a77c5bdbe7c5474450b4f46348d09949df3695257729c93a30369382d4f6
|
||||||
ports:
|
ports:
|
||||||
- "${MAILPIT_PORT:-8027}:8025"
|
- "${MAILPIT_PORT:-8027}:8025"
|
||||||
networks: [edge, internal]
|
networks: [edge, internal]
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ config :who_need_help, WhoNeedHelp.Mailer, adapter: Swoosh.Adapters.Local
|
||||||
|
|
||||||
# Configure esbuild (the version is required)
|
# Configure esbuild (the version is required)
|
||||||
config :esbuild,
|
config :esbuild,
|
||||||
version: "0.25.4",
|
version: "0.28.1",
|
||||||
who_need_help: [
|
who_need_help: [
|
||||||
args:
|
args:
|
||||||
~w(js/app.js --bundle --target=es2022 --outdir=../priv/static/assets/js --external:/fonts/* --external:/images/* --alias:@=.),
|
~w(js/app.js --bundle --target=es2022 --outdir=../priv/static/assets/js --external:/fonts/* --external:/images/* --alias:@=.),
|
||||||
|
|
@ -82,7 +82,7 @@ config :esbuild,
|
||||||
|
|
||||||
# Configure tailwind (the version is required)
|
# Configure tailwind (the version is required)
|
||||||
config :tailwind,
|
config :tailwind,
|
||||||
version: "4.3.0",
|
version: "4.3.3",
|
||||||
who_need_help: [
|
who_need_help: [
|
||||||
args: ~w(
|
args: ~w(
|
||||||
--input=assets/css/app.css
|
--input=assets/css/app.css
|
||||||
|
|
|
||||||
|
|
@ -22,5 +22,5 @@ app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- define "who-need-help.secretName" -}}
|
{{- define "who-need-help.secretName" -}}
|
||||||
{{- default (include "who-need-help.fullname" .) .Values.existingSecret }}
|
{{- required "existingSecret must name a pre-created Kubernetes Secret" .Values.existingSecret }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,8 @@ spec:
|
||||||
app.kubernetes.io/component: {{ $component }}
|
app.kubernetes.io/component: {{ $component }}
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
|
||||||
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") $root | sha256sum }}
|
|
||||||
{{- with $root.Values.podAnnotations }}
|
{{- with $root.Values.podAnnotations }}
|
||||||
|
annotations:
|
||||||
{{- toYaml . | nindent 8 }}
|
{{- toYaml . | nindent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
labels:
|
labels:
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
{{- if not .Values.existingSecret }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: {{ include "who-need-help.fullname" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "who-need-help.labels" . | nindent 4 }}
|
|
||||||
annotations:
|
|
||||||
helm.sh/hook: pre-install,pre-upgrade
|
|
||||||
helm.sh/hook-weight: "-10"
|
|
||||||
helm.sh/hook-delete-policy: before-hook-creation
|
|
||||||
type: Opaque
|
|
||||||
stringData:
|
|
||||||
DATABASE_URL: {{ .Values.app.databaseUrl | quote }}
|
|
||||||
SECRET_KEY_BASE: {{ .Values.app.secretKeyBase | quote }}
|
|
||||||
HANDOVER_SECRET: {{ .Values.app.handoverSecret | quote }}
|
|
||||||
RELEASE_COOKIE: {{ .Values.app.releaseCookie | quote }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
@ -8,11 +8,9 @@ service:
|
||||||
port: 80
|
port: 80
|
||||||
nodePort: 30080
|
nodePort: 30080
|
||||||
|
|
||||||
|
existingSecret: who-need-help-local
|
||||||
|
|
||||||
app:
|
app:
|
||||||
host: localhost
|
host: localhost
|
||||||
scheme: http
|
scheme: http
|
||||||
urlPort: "4011"
|
urlPort: "4011"
|
||||||
databaseUrl: ecto://postgres:postgres@postgis/who_need_help
|
|
||||||
secretKeyBase: y9XxDIDxcn8uHarbX1B4feQl0xXi413tdYO472d758DtvslbtlVdUs2HdxPEPXCQ
|
|
||||||
handoverSecret: L2a4yz6nLYkWvIBTlREj8uDByngsY39JfLIfdYNDH/7dnIQEVW4T8OCjCkHOGZ7H
|
|
||||||
releaseCookie: OwNDSCX7aQkkNXovILLiESVolaRuYm67xC+JbMC3j3ERTY6sHIM/F4gc0elm1l07
|
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,6 @@ app:
|
||||||
urlPort: "443"
|
urlPort: "443"
|
||||||
port: "4000"
|
port: "4000"
|
||||||
poolSize: "10"
|
poolSize: "10"
|
||||||
databaseUrl: ecto://postgres:postgres@postgis/who_need_help
|
|
||||||
secretKeyBase: replace-before-public-deployment
|
|
||||||
handoverSecret: replace-before-public-deployment
|
|
||||||
releaseCookie: replace-before-public-deployment
|
|
||||||
codexSessionId: not-configured
|
codexSessionId: not-configured
|
||||||
# Shared limits are opt-in; set only after product policy thresholds are approved.
|
# Shared limits are opt-in; set only after product policy thresholds are approved.
|
||||||
rateLimitPoliciesJson: "{}"
|
rateLimitPoliciesJson: "{}"
|
||||||
|
|
@ -31,6 +27,8 @@ app:
|
||||||
smtpRelay: mailpit
|
smtpRelay: mailpit
|
||||||
smtpPort: "1025"
|
smtpPort: "1025"
|
||||||
|
|
||||||
|
# Required. The Secret must contain DATABASE_URL, SECRET_KEY_BASE,
|
||||||
|
# HANDOVER_SECRET, and RELEASE_COOKIE.
|
||||||
existingSecret: ""
|
existingSecret: ""
|
||||||
|
|
||||||
ingress:
|
ingress:
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: StatefulSet
|
||||||
metadata:
|
metadata:
|
||||||
name: postgis
|
name: postgis
|
||||||
spec:
|
spec:
|
||||||
|
serviceName: postgis
|
||||||
replicas: 1
|
replicas: 1
|
||||||
selector:
|
selector:
|
||||||
matchLabels: {app: postgis}
|
matchLabels: {app: postgis}
|
||||||
|
|
@ -13,10 +14,23 @@ spec:
|
||||||
containers:
|
containers:
|
||||||
- name: postgis
|
- name: postgis
|
||||||
image: postgis/postgis:18-3.6-alpine
|
image: postgis/postgis:18-3.6-alpine
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
env:
|
env:
|
||||||
- {name: POSTGRES_DB, value: who_need_help}
|
- name: POSTGRES_DB
|
||||||
- {name: POSTGRES_USER, value: postgres}
|
valueFrom:
|
||||||
- {name: POSTGRES_PASSWORD, value: postgres}
|
secretKeyRef:
|
||||||
|
name: who-need-help-local
|
||||||
|
key: POSTGRES_DB
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: who-need-help-local
|
||||||
|
key: POSTGRES_USER
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: who-need-help-local
|
||||||
|
key: POSTGRES_PASSWORD
|
||||||
ports:
|
ports:
|
||||||
- {name: postgres, containerPort: 5432}
|
- {name: postgres, containerPort: 5432}
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
|
|
@ -27,7 +41,9 @@ spec:
|
||||||
- {name: data, mountPath: /var/lib/postgresql}
|
- {name: data, mountPath: /var/lib/postgresql}
|
||||||
volumes:
|
volumes:
|
||||||
- name: data
|
- name: data
|
||||||
emptyDir: {}
|
hostPath:
|
||||||
|
path: /var/local/who-need-help/postgres
|
||||||
|
type: DirectoryOrCreate
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
|
@ -52,7 +68,8 @@ spec:
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: mailpit
|
- name: mailpit
|
||||||
image: axllent/mailpit:v1.27
|
image: axllent/mailpit:v1.30.4
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
ports:
|
ports:
|
||||||
- {name: smtp, containerPort: 1025}
|
- {name: smtp, containerPort: 1025}
|
||||||
- {name: http, containerPort: 8025}
|
- {name: http, containerPort: 8025}
|
||||||
|
|
|
||||||
95
docs/dependency-baseline.md
Normal file
95
docs/dependency-baseline.md
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
# Dependency baseline
|
||||||
|
|
||||||
|
Verified on 2026-07-18. This is a point-in-time stable baseline, not a claim
|
||||||
|
that future security updates or major-version migrations can be avoided.
|
||||||
|
Application locks and OCI digests remain committed so the same revision can be
|
||||||
|
rebuilt deterministically.
|
||||||
|
|
||||||
|
## Runtime and application
|
||||||
|
|
||||||
|
| Component | Locked version |
|
||||||
|
| --- | --- |
|
||||||
|
| Elixir | 1.20.2 |
|
||||||
|
| Erlang/OTP | 29.0.3 |
|
||||||
|
| Phoenix | 1.8.9 |
|
||||||
|
| Phoenix LiveView | 1.2.7 |
|
||||||
|
| Ecto / Ecto SQL | 3.14.1 / 3.14.0 |
|
||||||
|
| Oban | 2.23.0 |
|
||||||
|
| Node.js LTS | 24.18.0 |
|
||||||
|
| npm build tool | 12.0.1 |
|
||||||
|
| Tailwind CSS binary | 4.3.3 |
|
||||||
|
| esbuild binary | 0.28.1 |
|
||||||
|
| daisyUI | 5.6.18 |
|
||||||
|
| Heroicons | 2.2.0 |
|
||||||
|
| MapLibre GL JS | 5.24.0 |
|
||||||
|
|
||||||
|
`mix hex.outdated` reported every direct Hex dependency as up-to-date.
|
||||||
|
`npm outdated --json` returned an empty object, and the production `npm ci`
|
||||||
|
audit reported zero known vulnerabilities. The full transitive versions and
|
||||||
|
package checksums are in `mix.lock` and `assets/package-lock.json`.
|
||||||
|
|
||||||
|
## Services and container build
|
||||||
|
|
||||||
|
| Component | Locked version |
|
||||||
|
| --- | --- |
|
||||||
|
| PostgreSQL | 18.4 |
|
||||||
|
| PostGIS | 3.6.4 |
|
||||||
|
| Traefik | 3.7.8 |
|
||||||
|
| Mailpit | 1.30.4 |
|
||||||
|
| Debian builder/runner snapshot | trixie-20260713-slim |
|
||||||
|
|
||||||
|
Every external Compose/kind service image and every Dockerfile base image is
|
||||||
|
locked to both an exact tag and an OCI digest. The observed local Docker tooling
|
||||||
|
was Docker Engine/CLI 29.6.2, Compose 5.3.1, and Buildx 0.35.0; their official
|
||||||
|
release feeds reported those same versions as current during verification.
|
||||||
|
|
||||||
|
## Android and local Kubernetes
|
||||||
|
|
||||||
|
| Component | Locked version |
|
||||||
|
| --- | --- |
|
||||||
|
| Android Gradle Plugin | 9.3.0 |
|
||||||
|
| Gradle | 9.6.1 |
|
||||||
|
| Android SDK Command-line Tools | 22.0 |
|
||||||
|
| Android CLI | 1.0.15857036 |
|
||||||
|
| Android Emulator | 36.6.11.0 |
|
||||||
|
| compileSdk / targetSdk | 37 / 37 |
|
||||||
|
| Android Build Tools | 37.0.0 |
|
||||||
|
| AndroidX Activity | 1.13.0 |
|
||||||
|
| kubectl | 1.36.2 |
|
||||||
|
| kind | 0.32.0 |
|
||||||
|
| Helm | 4.2.3 |
|
||||||
|
|
||||||
|
Android 17 API 37 is the stable target used here. API 37.1 was not selected
|
||||||
|
because the official SDK channel identifies it as a QPR beta.
|
||||||
|
|
||||||
|
## Primary version sources
|
||||||
|
|
||||||
|
- [Elixir releases](https://github.com/elixir-lang/elixir/releases)
|
||||||
|
- [Erlang/OTP releases](https://github.com/erlang/otp/releases)
|
||||||
|
- [Hex package registry](https://hex.pm/)
|
||||||
|
- [Node.js release schedule](https://nodejs.org/en/about/previous-releases)
|
||||||
|
- [npm registry](https://www.npmjs.com/package/npm)
|
||||||
|
- [PostgreSQL 18.4 release notes](https://www.postgresql.org/docs/release/18.4/)
|
||||||
|
- [PostGIS release notes](https://postgis.net/docs/en/release_notes.html)
|
||||||
|
- [Traefik releases](https://github.com/traefik/traefik/releases)
|
||||||
|
- [Mailpit releases](https://github.com/axllent/mailpit/releases)
|
||||||
|
- [Android Gradle Plugin 9.3.0 release notes](https://developer.android.com/build/releases/agp-9-3-0-release-notes)
|
||||||
|
- [Android 17 SDK setup](https://developer.android.com/about/versions/17/setup-sdk)
|
||||||
|
- [Gradle release notes](https://docs.gradle.org/current/release-notes.html)
|
||||||
|
- [kubectl releases](https://dl.k8s.io/release/stable.txt)
|
||||||
|
- [kind releases](https://github.com/kubernetes-sigs/kind/releases)
|
||||||
|
- [Helm releases](https://github.com/helm/helm/releases)
|
||||||
|
- [Docker Engine releases](https://github.com/moby/moby/releases)
|
||||||
|
- [Docker Compose releases](https://github.com/docker/compose/releases)
|
||||||
|
- [Docker Buildx releases](https://github.com/docker/buildx/releases)
|
||||||
|
|
||||||
|
## Repeatable checks
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm who-need-help:test mix hex.outdated
|
||||||
|
docker build --target node_deps --tag who-need-help:node-deps .
|
||||||
|
docker run --rm who-need-help:node-deps npm --version
|
||||||
|
docker run --rm who-need-help:node-deps npm outdated --json
|
||||||
|
./scripts/test.sh
|
||||||
|
./scripts/android-build.sh
|
||||||
|
```
|
||||||
|
|
@ -21,7 +21,8 @@ results from product limits and unknown production properties.
|
||||||
|
|
||||||
## Reproducible checks
|
## Reproducible checks
|
||||||
|
|
||||||
- `./scripts/test.sh`: 124 tests, 0 failures in the final pre-upgrade run.
|
- `./scripts/test.sh`: 124 tests, 0 failures in the final post-upgrade run on
|
||||||
|
Elixir 1.20.2 and Erlang/OTP 29.0.3.
|
||||||
- `mix format --check-formatted`: passed in the final run.
|
- `mix format --check-formatted`: passed in the final run.
|
||||||
- Android Docker build target: `testDebugUnitTest`, `lintDebug`, and
|
- Android Docker build target: `testDebugUnitTest`, `lintDebug`, and
|
||||||
`assembleDebug` passed; the final lint report contains no errors or warnings.
|
`assembleDebug` passed; the final lint report contains no errors or warnings.
|
||||||
|
|
@ -43,7 +44,7 @@ Local generated evidence (ignored by Git):
|
||||||
Android artifact:
|
Android artifact:
|
||||||
|
|
||||||
- `android/dist/who-need-help-debug.apk`
|
- `android/dist/who-need-help-debug.apk`
|
||||||
- SHA-256 before the dependency-upgrade pass:
|
- Final post-upgrade SHA-256:
|
||||||
`063f3d8d877009ee229a403692e4b16517244dd9e7dddab4c2b3c202c5def4b8`
|
`063f3d8d877009ee229a403692e4b16517244dd9e7dddab4c2b3c202c5def4b8`
|
||||||
- Observed manifest values: version `0.1.0-debug`, minimum SDK 24, target and
|
- Observed manifest values: version `0.1.0-debug`, minimum SDK 24, target and
|
||||||
compile SDK 37.
|
compile SDK 37.
|
||||||
|
|
@ -65,6 +66,37 @@ excluded from the root Docker build context.
|
||||||
The final local Compose observation found 2 users, 1 help request, and 7
|
The final local Compose observation found 2 users, 1 help request, and 7
|
||||||
messages. These are local scenario data; the database is not assumed empty.
|
messages. These are local scenario data; the database is not assumed empty.
|
||||||
|
|
||||||
|
The final kind observation found 0 users, 0 help requests, and 0 messages. That
|
||||||
|
state was queried before changing the database workload. The migration from the
|
||||||
|
old `emptyDir` Deployment created a custom-format dump, validated it with
|
||||||
|
`pg_restore --list`, changed PostGIS to a persistent StatefulSet, and restored
|
||||||
|
the dump before the Helm upgrade. The final kind database reported PostgreSQL
|
||||||
|
18.4 and PostGIS 3.6.4.
|
||||||
|
|
||||||
|
The local kind Secret contains independently generated values. Only their
|
||||||
|
decoded lengths were inspected: the PostgreSQL password is 64 characters and
|
||||||
|
each application secret is 128 characters. Secret values were not printed or
|
||||||
|
written to tracked files.
|
||||||
|
|
||||||
|
## Dependency-upgrade observations
|
||||||
|
|
||||||
|
- The running Compose and kind releases reported Elixir 1.20.2 and Erlang/OTP
|
||||||
|
29.
|
||||||
|
- Compose reported Traefik 3.7.8 and Mailpit 1.30.4; Compose and kind both
|
||||||
|
reported PostgreSQL 18.4 and PostGIS 3.6.4.
|
||||||
|
- The production asset build reported Tailwind CSS 4.3.3 and daisyUI 5.6.18;
|
||||||
|
esbuild is configured at 0.28.1.
|
||||||
|
- The isolated Node build stage reported Node.js 24.18.0, npm 12.0.1,
|
||||||
|
`npm outdated --json` returned `{}`, and `npm ci` reported zero known
|
||||||
|
vulnerabilities.
|
||||||
|
- The Android build used Android Gradle Plugin 9.3.0, Gradle 9.6.1, Command-line
|
||||||
|
Tools 22.0, and its embedded Android CLI 1.0.15857036. Unit tests, lint, and
|
||||||
|
debug assembly passed; the lint report says “No errors or warnings.” The
|
||||||
|
rebuilt emulator image contains the API 37 ps16k AVD and APK, and its emulator
|
||||||
|
36.6.11.0 binary returned its version successfully at runtime.
|
||||||
|
- The final complete `scripts/kind-up.sh` run was idempotent and finished with
|
||||||
|
both 2-replica Deployments Ready and a successful cross-replica PubSub probe.
|
||||||
|
|
||||||
The migration `20260718114233` and reverse block lookup index
|
The migration `20260718114233` and reverse block lookup index
|
||||||
`blocks_blocked_id_blocker_id_index` were present. An actual `EXPLAIN ANALYZE`
|
`blocks_blocked_id_blocker_id_index` were present. An actual `EXPLAIN ANALYZE`
|
||||||
for that reverse lookup selected the index. The table contained no block rows,
|
for that reverse lookup selected the index. The table contained no block rows,
|
||||||
|
|
|
||||||
4
mix.exs
4
mix.exs
|
|
@ -5,7 +5,7 @@ defmodule WhoNeedHelp.MixProject do
|
||||||
[
|
[
|
||||||
app: :who_need_help,
|
app: :who_need_help,
|
||||||
version: "0.1.0",
|
version: "0.1.0",
|
||||||
elixir: "~> 1.17",
|
elixir: "~> 1.20",
|
||||||
elixirc_paths: elixirc_paths(Mix.env()),
|
elixirc_paths: elixirc_paths(Mix.env()),
|
||||||
start_permanent: Mix.env() == :prod,
|
start_permanent: Mix.env() == :prod,
|
||||||
aliases: aliases(),
|
aliases: aliases(),
|
||||||
|
|
@ -63,7 +63,7 @@ defmodule WhoNeedHelp.MixProject do
|
||||||
depth: 1},
|
depth: 1},
|
||||||
{:daisyui,
|
{:daisyui,
|
||||||
github: "saadeghi/daisyui",
|
github: "saadeghi/daisyui",
|
||||||
tag: "v5.5.20",
|
tag: "v5.6.18",
|
||||||
sparse: "packages/bundle",
|
sparse: "packages/bundle",
|
||||||
app: false,
|
app: false,
|
||||||
compile: false,
|
compile: false,
|
||||||
|
|
|
||||||
2
mix.lock
2
mix.lock
|
|
@ -3,7 +3,7 @@
|
||||||
"bcrypt_elixir": {:hex, :bcrypt_elixir, "3.3.2", "d50091e3c9492d73e17fc1e1619a9b09d6a5ef99160eb4d736926fd475a16ca3", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "471be5151874ae7931911057d1467d908955f93554f7a6cd1b7d804cac8cef53"},
|
"bcrypt_elixir": {:hex, :bcrypt_elixir, "3.3.2", "d50091e3c9492d73e17fc1e1619a9b09d6a5ef99160eb4d736926fd475a16ca3", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "471be5151874ae7931911057d1467d908955f93554f7a6cd1b7d804cac8cef53"},
|
||||||
"cc_precompiler": {:hex, :cc_precompiler, "0.1.11", "8c844d0b9fb98a3edea067f94f616b3f6b29b959b6b3bf25fee94ffe34364768", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "3427232caf0835f94680e5bcf082408a70b48ad68a5f5c0b02a3bea9f3a075b9"},
|
"cc_precompiler": {:hex, :cc_precompiler, "0.1.11", "8c844d0b9fb98a3edea067f94f616b3f6b29b959b6b3bf25fee94ffe34364768", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "3427232caf0835f94680e5bcf082408a70b48ad68a5f5c0b02a3bea9f3a075b9"},
|
||||||
"comeonin": {:hex, :comeonin, "5.5.1", "5113e5f3800799787de08a6e0db307133850e635d34e9fab23c70b6501669510", [:mix], [], "hexpm", "65aac8f19938145377cee73973f192c5645873dcf550a8a6b18187d17c13ccdb"},
|
"comeonin": {:hex, :comeonin, "5.5.1", "5113e5f3800799787de08a6e0db307133850e635d34e9fab23c70b6501669510", [:mix], [], "hexpm", "65aac8f19938145377cee73973f192c5645873dcf550a8a6b18187d17c13ccdb"},
|
||||||
"daisyui": {:git, "https://github.com/saadeghi/daisyui.git", "22ecff57f2c391b80a75617325748cf4d13fdf47", [tag: "v5.5.20", sparse: "packages/bundle", depth: 1]},
|
"daisyui": {:git, "https://github.com/saadeghi/daisyui.git", "374d63758f997317e92e93e547569a5f9ad11250", [tag: "v5.6.18", sparse: "packages/bundle", depth: 1]},
|
||||||
"db_connection": {:hex, :db_connection, "2.10.2", "ae391e803a5adff104da913c2fc1c0c14a37f8b10001dcef568796e1fb7bf95c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "510b14482330f1af6490a2fa0efd8d4f1435d1529b165647df22ac0f2df0fa93"},
|
"db_connection": {:hex, :db_connection, "2.10.2", "ae391e803a5adff104da913c2fc1c0c14a37f8b10001dcef568796e1fb7bf95c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "510b14482330f1af6490a2fa0efd8d4f1435d1529b165647df22ac0f2df0fa93"},
|
||||||
"decimal": {:hex, :decimal, "3.1.1", "430d87b04011ce6cbd4fd205be758311a81f87d552d40904abd00f015935b1d0", [:mix], [], "hexpm", "c5f25f2ced74a0587d03e6023f595db8e924c9d3922c8c8ffd9edfc4498cf1f6"},
|
"decimal": {:hex, :decimal, "3.1.1", "430d87b04011ce6cbd4fd205be758311a81f87d552d40904abd00f015935b1d0", [:mix], [], "hexpm", "c5f25f2ced74a0587d03e6023f595db8e924c9d3922c8c8ffd9edfc4498cf1f6"},
|
||||||
"dns_cluster": {:hex, :dns_cluster, "0.2.0", "aa8eb46e3bd0326bd67b84790c561733b25c5ba2fe3c7e36f28e88f384ebcb33", [:mix], [], "hexpm", "ba6f1893411c69c01b9e8e8f772062535a4cf70f3f35bcc964a324078d8c8240"},
|
"dns_cluster": {:hex, :dns_cluster, "0.2.0", "aa8eb46e3bd0326bd67b84790c561733b25c5ba2fe3c7e36f28e88f384ebcb33", [:mix], [], "hexpm", "ba6f1893411c69c01b9e8e8f772062535a4cf70f3f35bcc964a324078d8c8240"},
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,61 @@ export PATH
|
||||||
|
|
||||||
CLUSTER=who-need-help
|
CLUSTER=who-need-help
|
||||||
MARKER="$ROOT/.tools/${CLUSTER}.owned"
|
MARKER="$ROOT/.tools/${CLUSTER}.owned"
|
||||||
|
NAMESPACE=who-need-help
|
||||||
|
SECRET_NAME=who-need-help-local
|
||||||
|
POSTGIS_IMAGE=postgis/postgis:18-3.6-alpine
|
||||||
|
POSTGIS_SOURCE="${POSTGIS_IMAGE}@sha256:05d68c7f0f19b9aa0bf7c4a2049b2e8b38b44a63116392b95726a4c913766cf6"
|
||||||
|
MAILPIT_IMAGE=axllent/mailpit:v1.30.4
|
||||||
|
MAILPIT_SOURCE="${MAILPIT_IMAGE}@sha256:5a49a77c5bdbe7c5474450b4f46348d09949df3695257729c93a30369382d4f6"
|
||||||
|
|
||||||
|
kube() {
|
||||||
|
kubectl --context "kind-${CLUSTER}" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$(uname -m)" in
|
||||||
|
x86_64) IMAGE_ARCH=amd64 ;;
|
||||||
|
aarch64|arm64) IMAGE_ARCH=arm64 ;;
|
||||||
|
*) echo "Unsupported container architecture: $(uname -m)" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
load_pinned_image() {
|
||||||
|
source=$1
|
||||||
|
local_tag=$2
|
||||||
|
archive=$3
|
||||||
|
|
||||||
|
docker pull --platform "linux/${IMAGE_ARCH}" "$source"
|
||||||
|
image_id=$(docker image inspect "$source" --format '{{.Id}}')
|
||||||
|
docker tag "$image_id" "$local_tag"
|
||||||
|
docker image save --platform "linux/${IMAGE_ARCH}" --output "$archive" "$local_tag"
|
||||||
|
kind load image-archive "$archive" --name "$CLUSTER"
|
||||||
|
rm -f "$archive"
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_legacy_inline_secrets() {
|
||||||
|
legacy_secret=who-need-help-who-need-help
|
||||||
|
|
||||||
|
# Older chart revisions rendered credentials from tracked Helm values. Once
|
||||||
|
# the new deployments are healthy, remove the obsolete Secret and only those
|
||||||
|
# release-history records that still contain the former inline secret keys.
|
||||||
|
kube --namespace "$NAMESPACE" delete secret "$legacy_secret" \
|
||||||
|
--ignore-not-found >/dev/null
|
||||||
|
|
||||||
|
for revision in $(
|
||||||
|
helm history who-need-help \
|
||||||
|
--kube-context "kind-${CLUSTER}" \
|
||||||
|
--namespace "$NAMESPACE" |
|
||||||
|
awk 'NR > 1 {print $1}'
|
||||||
|
); do
|
||||||
|
if helm get values who-need-help \
|
||||||
|
--revision "$revision" \
|
||||||
|
--kube-context "kind-${CLUSTER}" \
|
||||||
|
--namespace "$NAMESPACE" |
|
||||||
|
grep -Eq '^[[:space:]]*(databaseUrl|secretKeyBase|handoverSecret|releaseCookie):'; then
|
||||||
|
kube --namespace "$NAMESPACE" delete secret \
|
||||||
|
--selector="owner=helm,name=who-need-help,version=${revision}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
if kind get clusters | grep -Fxq "$CLUSTER"; then
|
if kind get clusters | grep -Fxq "$CLUSTER"; then
|
||||||
if [ ! -f "$MARKER" ]; then
|
if [ ! -f "$MARKER" ]; then
|
||||||
|
|
@ -20,25 +75,80 @@ else
|
||||||
touch "$MARKER"
|
touch "$MARKER"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
load_pinned_image "$POSTGIS_SOURCE" "$POSTGIS_IMAGE" "$ROOT/.tools/postgis-kind.tar"
|
||||||
|
load_pinned_image "$MAILPIT_SOURCE" "$MAILPIT_IMAGE" "$ROOT/.tools/mailpit-kind.tar"
|
||||||
|
|
||||||
docker build --tag who-need-help:local "$ROOT"
|
docker build --tag who-need-help:local "$ROOT"
|
||||||
kind load docker-image who-need-help:local --name "$CLUSTER"
|
kind load docker-image who-need-help:local --name "$CLUSTER"
|
||||||
|
|
||||||
kubectl create namespace who-need-help --dry-run=client --output=yaml | kubectl apply -f -
|
kube create namespace "$NAMESPACE" --dry-run=client --output=yaml | kube apply -f -
|
||||||
kubectl --namespace who-need-help apply -f "$ROOT/deploy/kind/dependencies.yaml"
|
|
||||||
kubectl --namespace who-need-help rollout status deployment/postgis
|
legacy_backup=
|
||||||
kubectl --namespace who-need-help rollout status deployment/mailpit
|
if kube --namespace "$NAMESPACE" get deployment postgis >/dev/null 2>&1; then
|
||||||
|
backup_dir="$ROOT/output/backups"
|
||||||
|
mkdir -p "$backup_dir"
|
||||||
|
umask 077
|
||||||
|
legacy_backup="$backup_dir/kind-who-need-help-$(date +%Y%m%d-%H%M%S).dump"
|
||||||
|
kube --namespace "$NAMESPACE" exec deployment/postgis -- \
|
||||||
|
pg_dump --username postgres --dbname who_need_help --format custom >"$legacy_backup"
|
||||||
|
test -s "$legacy_backup"
|
||||||
|
kube --namespace "$NAMESPACE" exec --stdin deployment/postgis -- \
|
||||||
|
pg_restore --list <"$legacy_backup" >/dev/null
|
||||||
|
echo "Validated legacy kind database backup: $legacy_backup"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! kube --namespace "$NAMESPACE" get secret "$SECRET_NAME" >/dev/null 2>&1; then
|
||||||
|
if kube --namespace "$NAMESPACE" get statefulset postgis >/dev/null 2>&1; then
|
||||||
|
echo "Secret '$SECRET_NAME' is missing while the persistent PostGIS StatefulSet exists." >&2
|
||||||
|
echo "Refusing to generate credentials that would not match the existing database." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
postgres_password=$(openssl rand -hex 32)
|
||||||
|
secret_key_base=$(openssl rand -hex 64)
|
||||||
|
handover_secret=$(openssl rand -hex 64)
|
||||||
|
release_cookie=$(openssl rand -hex 64)
|
||||||
|
|
||||||
|
kube --namespace "$NAMESPACE" create secret generic "$SECRET_NAME" \
|
||||||
|
--from-literal=POSTGRES_DB=who_need_help \
|
||||||
|
--from-literal=POSTGRES_USER=postgres \
|
||||||
|
--from-literal="POSTGRES_PASSWORD=$postgres_password" \
|
||||||
|
--from-literal="DATABASE_URL=ecto://postgres:${postgres_password}@postgis/who_need_help" \
|
||||||
|
--from-literal="SECRET_KEY_BASE=$secret_key_base" \
|
||||||
|
--from-literal="HANDOVER_SECRET=$handover_secret" \
|
||||||
|
--from-literal="RELEASE_COOKIE=$release_cookie"
|
||||||
|
|
||||||
|
unset postgres_password secret_key_base handover_secret release_cookie
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$legacy_backup" ]; then
|
||||||
|
kube --namespace "$NAMESPACE" delete deployment postgis --wait=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
kube --namespace "$NAMESPACE" apply -f "$ROOT/deploy/kind/dependencies.yaml"
|
||||||
|
kube --namespace "$NAMESPACE" rollout status statefulset/postgis
|
||||||
|
kube --namespace "$NAMESPACE" rollout status deployment/mailpit
|
||||||
|
|
||||||
|
if [ -n "$legacy_backup" ]; then
|
||||||
|
kube --namespace "$NAMESPACE" exec --stdin statefulset/postgis -- \
|
||||||
|
pg_restore --username postgres --dbname who_need_help \
|
||||||
|
--clean --if-exists --no-owner <"$legacy_backup"
|
||||||
|
echo "Restored legacy kind database backup."
|
||||||
|
fi
|
||||||
|
|
||||||
helm upgrade --install who-need-help "$ROOT/deploy/helm/who-need-help" \
|
helm upgrade --install who-need-help "$ROOT/deploy/helm/who-need-help" \
|
||||||
--namespace who-need-help \
|
--kube-context "kind-${CLUSTER}" \
|
||||||
|
--namespace "$NAMESPACE" \
|
||||||
--values "$ROOT/deploy/helm/who-need-help/values-kind.yaml" \
|
--values "$ROOT/deploy/helm/who-need-help/values-kind.yaml" \
|
||||||
--set-string app.codexSessionId="${CODEX_SESSION_ID:-${CODEX_THREAD_ID:-not-configured}}" \
|
--set-string app.codexSessionId="${CODEX_SESSION_ID:-${CODEX_THREAD_ID:-not-configured}}" \
|
||||||
--wait
|
--wait
|
||||||
|
|
||||||
kubectl --namespace who-need-help rollout restart \
|
kube --namespace "$NAMESPACE" rollout restart \
|
||||||
deployment/who-need-help-who-need-help-web \
|
deployment/who-need-help-who-need-help-web \
|
||||||
deployment/who-need-help-who-need-help-worker
|
deployment/who-need-help-who-need-help-worker
|
||||||
kubectl --namespace who-need-help rollout status deployment/who-need-help-who-need-help-web
|
kube --namespace "$NAMESPACE" rollout status deployment/who-need-help-who-need-help-web
|
||||||
kubectl --namespace who-need-help rollout status deployment/who-need-help-who-need-help-worker
|
kube --namespace "$NAMESPACE" rollout status deployment/who-need-help-who-need-help-worker
|
||||||
|
remove_legacy_inline_secrets
|
||||||
"$ROOT/scripts/verify-realtime-cluster.sh" kind
|
"$ROOT/scripts/verify-realtime-cluster.sh" kind
|
||||||
|
|
||||||
echo "Who Need Help: http://localhost:4011"
|
echo "Who Need Help: http://localhost:4011"
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@ case "$MODE" in
|
||||||
TARGET=$(
|
TARGET=$(
|
||||||
kubectl --context kind-who-need-help --namespace who-need-help get pods \
|
kubectl --context kind-who-need-help --namespace who-need-help get pods \
|
||||||
-l app.kubernetes.io/component=web \
|
-l app.kubernetes.io/component=web \
|
||||||
-o jsonpath='{.items[0].metadata.name}'
|
--field-selector=status.phase=Running \
|
||||||
|
--no-headers \
|
||||||
|
-o custom-columns='NAME:.metadata.name,READY:.status.containerStatuses[0].ready,DELETING:.metadata.deletionTimestamp' |
|
||||||
|
awk '$2 == "true" && $3 == "<none>" {print $1; exit}'
|
||||||
)
|
)
|
||||||
if [ -z "$TARGET" ]; then
|
if [ -z "$TARGET" ]; then
|
||||||
echo "No running kind web replica was found." >&2
|
echo "No running kind web replica was found." >&2
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user