Skip to content

Commit a53affc

Browse files
authored
Merge pull request #14 from hotosm/build/helm-chart
Add helm chart for deployment in Kubernetes
2 parents a910186 + 96713ce commit a53affc

32 files changed

+670
-4626
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# API Configuration
2-
VITE_API_URL=http://localhost:3000
2+
VITE_API_URL=http://localhost:3001
33

44
# For local development with MinIO:
55
VITE_METADATA_URL=http://localhost:9000/xlsforms/metadata.json
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: 🚀 Release Chart
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
permissions:
8+
contents: read
9+
packages: write
10+
11+
jobs:
12+
publish:
13+
uses: hotosm/gh-workflows/.github/workflows/just.yml@3.3.2
14+
with:
15+
environment: "test"
16+
command: "chart publish"
17+
secrets: inherit

.github/workflows/release_image.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,17 @@ permissions:
1010
packages: write
1111

1212
jobs:
13-
container-img:
13+
backend:
1414
uses: hotosm/gh-workflows/.github/workflows/image_build.yml@2.0.5
1515
needs: prep
1616
with:
17+
image_name: ghcr.io/${{ github.repository }}/backend
18+
context: backend
19+
build_target: release
20+
21+
frontend:
22+
uses: hotosm/gh-workflows/.github/workflows/image_build.yml@2.0.5
23+
needs: prep
24+
with:
25+
image_name: ghcr.io/${{ github.repository }}/frontend
1726
build_target: release
18-
image_name: ghcr.io/${{ github.repository }}/server

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,8 @@ backend/.env
3030
*.sw?
3131

3232
# Backend
33-
backend/server
33+
backend/backend
3434
backend/tmp
35+
36+
# Helm chart
37+
xlsform-builder-*.tgz

.goreleaser.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: 2
22

33
builds:
4-
- binary: server
4+
- binary: backend
55
main: main.go
66
env:
77
- CGO_ENABLED=0
@@ -18,7 +18,7 @@ builds:
1818
- -s -w -X main.version={{.Tag}} -X main.buildTime={{.Date}}
1919

2020
archives:
21-
- name_template: "server_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
21+
- name_template: "backend_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
2222
wrap_in_directory: false
2323
format: tar.gz
2424
# use zip for windows archives

.prettierignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ coverage
88
*.min.js
99
*.yaml
1010
yarn.lock
11-
package-lock.json
11+
pnpm-lock.yaml

CNAME

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
xlsform-builder.fmtm.hotosm.org
1+
xlsforms.field.hotosm.org

Dockerfile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
FROM node:20-alpine AS build
2+
WORKDIR /app
3+
4+
COPY package.json pnpm-lock.yaml ./
5+
RUN npm install -g pnpm@10.13.1 && pnpm install --frozen-lockfile
6+
7+
COPY . .
8+
ARG VITE_API_URL
9+
ARG VITE_METADATA_URL
10+
ENV VITE_API_URL=$VITE_API_URL \
11+
VITE_METADATA_URL=$VITE_METADATA_URL
12+
RUN pnpm run build
13+
14+
15+
16+
FROM nginx:1.27-alpine AS release
17+
COPY --from=build /app/dist /usr/share/nginx/html
18+
COPY nginx.conf /etc/nginx/conf.d/default.conf
19+
EXPOSE 80
20+
CMD ["nginx", "-g", "daemon off;"]

Justfile

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
set dotenv-load
2+
3+
mod chart 'tasks/chart'
4+
5+
# List available commands
6+
[private]
7+
default:
8+
just help
9+
10+
# List available commands
11+
help:
12+
just --justfile {{justfile()}} --list
13+
14+
# Install curl if missing
15+
[private]
16+
_install-curl:
17+
#!/usr/bin/env bash
18+
set -e
19+
20+
if ! command -v curl &> /dev/null; then
21+
echo "📦 Installing curl..."
22+
if command -v apt-get &> /dev/null; then
23+
sudo apt-get update -qq && sudo apt-get install -y curl
24+
elif command -v yum &> /dev/null; then
25+
sudo yum install -y curl
26+
elif command -v apk &> /dev/null; then
27+
sudo apk add --no-cache curl
28+
else
29+
echo "❌ Error: curl is not installed and no package manager found"
30+
echo " Please install curl manually"
31+
exit 1
32+
fi
33+
echo "✓ curl installed"
34+
fi
35+
36+
# Install Helm if missing
37+
[private]
38+
_install-helm:
39+
#!/usr/bin/env bash
40+
set -e
41+
42+
if command -v helm &> /dev/null; then
43+
exit 0
44+
fi
45+
46+
echo "📦 Installing Helm..."
47+
48+
# Only Linux / amd64 automated install for now; otherwise instruct user
49+
UNAME_S="$(uname -s || echo unknown)"
50+
UNAME_M="$(uname -m || echo unknown)"
51+
52+
if [ "$UNAME_S" != "Linux" ] || { [ "$UNAME_M" != "x86_64" ] && [ "$UNAME_M" != "amd64" ]; }; then
53+
echo "❌ Automatic Helm install only supported on Linux amd64."
54+
echo " Please install Helm manually: https://helm.sh/docs/intro/install/"
55+
exit 1
56+
fi
57+
58+
TMP_DIR="$(mktemp -d)"
59+
trap 'rm -rf "$TMP_DIR"' EXIT
60+
61+
# Get latest Helm release tag
62+
HELM_TAG="$(curl -sSL https://api.github.com/repos/helm/helm/releases/latest | grep -oE '\"tag_name\":\s*\"v[0-9.]+\"' | head -1 | sed -E 's/\"tag_name\":\s*\"(v[0-9.]+)\"/\1/')"
63+
if [ -z "$HELM_TAG" ]; then
64+
echo "❌ Failed to determine latest Helm version."
65+
exit 1
66+
fi
67+
68+
ARCHIVE="helm-${HELM_TAG}-linux-amd64.tar.gz"
69+
URL="https://get.helm.sh/${ARCHIVE}"
70+
71+
echo "⬇️ Downloading ${URL}..."
72+
curl -sSL "$URL" -o "$TMP_DIR/helm.tar.gz"
73+
tar -xzf "$TMP_DIR/helm.tar.gz" -C "$TMP_DIR"
74+
75+
if sudo mv "$TMP_DIR/linux-amd64/helm" /usr/local/bin/helm 2>/dev/null; then
76+
chmod +x /usr/local/bin/helm
77+
echo "✓ Helm installed to /usr/local/bin/helm"
78+
else
79+
mkdir -p "$HOME/.local/bin"
80+
mv "$TMP_DIR/linux-amd64/helm" "$HOME/.local/bin/helm"
81+
chmod +x "$HOME/.local/bin/helm"
82+
export PATH="$HOME/.local/bin:$PATH"
83+
echo "✓ Helm installed to ~/.local/bin/helm"
84+
fi
85+
86+
if ! command -v helm &> /dev/null; then
87+
echo "❌ Error: Failed to install Helm"
88+
exit 1
89+
fi
90+
91+
# Start compose services (backend, frontend, minio s3)
92+
start:
93+
#!/usr/bin/env bash
94+
set -e
95+
docker compose up -d
96+
97+
# Stop compose services
98+
stop:
99+
docker compose down --remove-orphans
100+
101+
# Start all services for development
102+
dev:
103+
just start
104+
105+
# Echo to terminal with blue colour
106+
[no-cd]
107+
_echo-blue text:
108+
#!/usr/bin/env sh
109+
printf "\033[0;34m%s\033[0m\n" "{{ text }}"
110+
111+
# Echo to terminal with yellow colour
112+
[no-cd]
113+
_echo-yellow text:
114+
#!/usr/bin/env sh
115+
printf "\033[0;33m%s\033[0m\n" "{{ text }}"
116+
117+
# Echo to terminal with red colour
118+
[no-cd]
119+
_echo-red text:
120+
#!/usr/bin/env sh
121+
printf "\033[0;41m%s\033[0m\n" "{{ text }}"

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ A repo to house:
88

99
Next steps:
1010

11-
- [ ] Improve styling / use web-awesome components.
12-
- [ ] Generate IAM creds for bucket `xlsforms` and set relevant upload policy.
13-
- [ ] Attach small backend for creating pre-signed upload URLs (cross-project).
11+
- [x] Improve styling / use web-awesome components.
12+
- [x] Generate IAM creds for bucket `xlsforms` and set relevant upload policy.
13+
- [x] Attach small backend for creating pre-signed upload URLs (cross-project).
1414
- [ ] Allow users to upload their XLSForm examples, with attached metadata.
1515
- [ ] Start the XLSForm editor web component (build around getodk/webforms).

0 commit comments

Comments
 (0)