Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
448567a
docs: define enterprise e self-host no glossario
thnbi Sep 25, 2026
455a8a1
docs: registra o indexador como funcao pura na adr-0033
thnbi Sep 25, 2026
e59f18b
docs: poe as fases on-premise e nuvem na adr-0027
thnbi Sep 25, 2026
739fb3c
docs: troca a aws pelo componente pulumi do cluster na adr-0025
thnbi Sep 25, 2026
bc919f0
docs: aponta o embedding para a adr-0029
thnbi Sep 25, 2026
f2c7ed3
docs: tira o papel da lambda da credencial do bedrock
thnbi Sep 25, 2026
8b97cb5
docs: poe o cloudnativepg e o backup por snapshot no diagrama
thnbi Sep 25, 2026
d7f1132
docs: nomeia o job de migracao no diagrama
thnbi Sep 25, 2026
403de06
docs: troca o ses por smtp no enterprise
thnbi Sep 25, 2026
bf3c098
docs: tira o plano de controle do self-host no diagrama
thnbi Sep 25, 2026
9bc0f65
test: espera o componente pulumi com api, banco e entrada
thnbi Sep 28, 2026
7a4a2c0
feat: adiciona o componente pulumi com api, banco e entrada
thnbi Sep 28, 2026
7ebd0e5
feat: adiciona a stack pulumi do cluster de producao
thnbi Sep 28, 2026
189b037
docs: reescreve o deploy para kubernetes e compose com postgres
thnbi Sep 28, 2026
edf53d8
chore: roda os testes do componente pulumi no ci
thnbi Sep 28, 2026
903b9c4
test: espera o emissor autoassinado como opcao do componente
thnbi Sep 28, 2026
3525da4
feat: aceita emissor autoassinado no componente pulumi
thnbi Sep 28, 2026
9c93808
refact: generaliza a stack de producao num projeto com uma stack por …
thnbi Sep 28, 2026
01a863b
feat: adiciona as stacks dev e prod do pulumi
thnbi Sep 28, 2026
8c7873b
feat: adiciona o cluster kind da stack dev com os requisitos de producao
thnbi Sep 29, 2026
c1a70ea
feat: testa a implantacao da stack dev num kind a cada push em dev
thnbi Sep 29, 2026
15bcae4
docs: descreve as stacks dev e prod no deploy
thnbi Sep 29, 2026
192d9a9
feat: aponta a stack prod para markupp.negoci.online
thnbi Sep 29, 2026
3ae3f7e
chore: roda o teste da stack dev em cada pr
thnbi Oct 1, 2026
5d9c00b
test: espera o postgres no namespace no lugar do cloudnativepg
thnbi Oct 1, 2026
553b59c
feat: troca o cloudnativepg pelo postgres no namespace no componente
thnbi Oct 1, 2026
b01af17
refact: tira o numero de instancias do banco das stacks
thnbi Oct 1, 2026
5792e2d
feat: usa a storageclass que o cluster de producao ja tem na stack prod
thnbi Oct 1, 2026
524c7d2
docs: troca o cloudnativepg pelo postgres no namespace
thnbi Oct 1, 2026
9c8fbba
chore: tira o cloudnativepg do cluster kind da stack dev
thnbi Oct 1, 2026
37a23d4
feat: adiciona o smoke descartavel da stack dev num kind
thnbi Oct 1, 2026
8cb1c88
chore: expoe o smoke da stack dev no make smoke-kind
thnbi Oct 1, 2026
a6b039a
refact: faz o ci da stack dev rodar o mesmo script do smoke local
thnbi Oct 1, 2026
69d1e01
docs: troca os passos da stack dev local pelo make smoke-kind
thnbi Oct 1, 2026
5f1ee9f
refact: fixa a imagem local e o salt na stack dev
thnbi Oct 1, 2026
a1e2695
feat: adiciona o ambiente kind de pe com o painel headlamp
thnbi Oct 1, 2026
53d1b5d
docs: descreve o ambiente kind de pe com o painel
thnbi Oct 1, 2026
92da34d
docs: neutraliza o local do cluster de producao nos textos
thnbi Oct 1, 2026
77c9051
docs: adiciona o diagrama de implantacao no kubernetes
thnbi Oct 1, 2026
f72585c
test: espera gateway existente, replicas zero e postgres fixo no comp…
thnbi Oct 2, 2026
4fa879c
feat: pendura o httproute num gateway existente no componente
thnbi Oct 2, 2026
cdbebae
fix: aceita zero replicas da api no componente
thnbi Oct 2, 2026
3c41850
chore: fixa a versao do postgres no componente pulumi
thnbi Oct 2, 2026
99c20c9
fix: traz emissor e email acme na mensagem de campo vazio do componente
thnbi Oct 2, 2026
a043f00
refact: renomeia o workflow da stack dev para smoke
thnbi Oct 2, 2026
c99f2cf
chore: roda o smoke da stack dev so quando muda servidor ou deploy
thnbi Oct 2, 2026
f23d4f3
docs: descreve o gateway existente no deploy
thnbi Oct 2, 2026
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
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,30 @@ jobs:
- name: Vulnerabilidades conhecidas
run: go run golang.org/x/vuln/cmd/govulncheck@v1.8.0 ./...

pulumi-component-tests:
name: Componente Pulumi (Go) tests
runs-on: ubuntu-latest
defaults:
run:
working-directory: deploy/pulumi
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: deploy/pulumi/go.mod
cache-dependency-path: deploy/pulumi/go.sum

- name: Run vet
run: go vet ./...

- name: Run golangci-lint
run: go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 run -c ../../markupp/.golangci.yml

- name: Run tests
run: go test ./... -race -count=1

convencoes:
name: Convencoes de commit
runs-on: ubuntu-latest
Expand Down
49 changes: 49 additions & 0 deletions .github/workflows/smoke-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Smoke da stack dev

# Testa a implantação em cada PR e a cada push em dev com o mesmo smoke de
# make smoke-kind: kind com os requisitos do cluster de produção, stack dev do
# Pulumi e API testada por https pelo Gateway.

on:
pull_request:
paths:
- 'markupp/**'
- 'deploy/**'
- '.github/workflows/smoke-dev.yml'
push:
branches: [dev]
paths:
- 'markupp/**'
- 'deploy/**'
- '.github/workflows/smoke-dev.yml'
workflow_dispatch:

permissions:
contents: read

jobs:
smoke-kind:
name: Smoke da stack dev num kind
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: deploy/pulumi/go.mod
cache-dependency-path: deploy/pulumi/go.sum

- name: Instala kind
run: go install sigs.k8s.io/kind@v0.33.0

- name: Instala helm
uses: azure/setup-helm@v5
with:
version: v4.3.0

- name: Instala o Pulumi
uses: pulumi/actions@v7

- name: Smoke da stack dev num kind
run: ./deploy/kind/ambiente.sh smoke
19 changes: 18 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ DOCKER_COMPOSE=docker compose
META_COVERAGE=90
PERFIL_COVERAGE=markupp/cover.out

.PHONY: all test compose-config compose-env docker-up docker-down run hooks test-scripts coverage coverage-check
.PHONY: all test smoke-kind kind-up kind-painel kind-down compose-config compose-env docker-up docker-down run hooks test-scripts coverage coverage-check

all: compose-env compose-config test

Expand All @@ -12,6 +12,23 @@ all: compose-env compose-config test
test:
cd markupp && go test ./...

# Smoke descartável da stack dev num kind com os requisitos do cluster de produção.
# Precisa de Docker, kind, helm, kubectl e Pulumi, e apaga o cluster no fim
smoke-kind:
./deploy/kind/ambiente.sh smoke

# Sobe o mesmo ambiente com o painel Headlamp e deixa de pé para acompanhar
kind-up:
./deploy/kind/ambiente.sh up

# Abre o Headlamp do ambiente de pé em http://localhost:4466
kind-painel:
./deploy/kind/ambiente.sh painel

# Apaga o ambiente de pé
kind-down:
./deploy/kind/ambiente.sh down

# Valida o arquivo docker-compose e a interpolação de variáveis de ambiente
compose-config:
$(DOCKER_COMPOSE) -f $(COMPOSE_FILE) config
Expand Down
113 changes: 113 additions & 0 deletions deploy/kind/ambiente.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env bash
# Ambiente da stack dev num kind com os requisitos do cluster de produção.
#
# up sobe o cluster, o painel Headlamp e a stack dev, e deixa de pé
# painel abre o Headlamp em http://localhost:4466 e mostra o token de acesso
# down apaga o cluster e o estado do Pulumi do ambiente de pé
# smoke sobe, testa a API por https e apaga tudo, passe ou falhe; é o do CI
set -euo pipefail

REPO="$(cd "$(dirname "$0")/../.." && pwd)"
STACKS="$REPO/deploy/stacks"
IMAGE=markupp:dev
URL=https://markupp.local:8443
AMBIENTE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/markupp-kind"
PAINEL_PORTA=4466

export CLUSTER=markupp-dev
export PULUMI_CONFIG_PASSPHRASE=""

# usa_diretorio guarda kubeconfig e estado do Pulumi em $1, longe do
# ~/.kube/config de quem roda.
usa_diretorio() {
mkdir -p "$1/state"
export KUBECONFIG="$1/kubeconfig"
export PULUMI_BACKEND_URL="file://$1/state"
}

recusa_cluster_existente() {
if kind get clusters 2>/dev/null | grep -qx "$CLUSTER"; then
echo "o cluster $CLUSTER já existe; rode make kind-down antes" >&2
exit 1
fi
}

sobe_cluster() {
docker build -q -t "$IMAGE" "$REPO/markupp" >/dev/null
"$REPO/deploy/kind/prepara-cluster.sh"
kind load docker-image "$IMAGE" --name "$CLUSTER"
}

aplica_stack() {
cd "$STACKS"
pulumi stack select dev --create --non-interactive
pulumi up --yes --non-interactive
}

instala_painel() {
helm install headlamp headlamp --repo https://kubernetes-sigs.github.io/headlamp/ \
--namespace headlamp --create-namespace --wait --timeout 10m
}

curl_api() {
curl -sfk --resolve markupp.local:8443:127.0.0.1 "$@"
}

testa_api() {
for _ in $(seq 1 30); do
if curl_api "$URL/healthz"; then
echo
curl_api -X POST "$URL/notes" -H 'Content-Type: application/json' -d '{"path":"smoke.md","content":"oi"}'
echo
return 0
fi
sleep 5
done
kubectl -n markupp get all,certificate,gateway,httproute
return 1
}

cmd_up() {
recusa_cluster_existente
usa_diretorio "$AMBIENTE_DIR"
sobe_cluster
instala_painel
aplica_stack
echo "API de pé: curl -k --resolve markupp.local:8443:127.0.0.1 $URL/healthz"
echo "painel: make kind-painel"
}

cmd_painel() {
usa_diretorio "$AMBIENTE_DIR"
echo "token para entrar no Headlamp:"
kubectl create token headlamp --namespace headlamp --duration 24h
echo "painel em http://localhost:$PAINEL_PORTA, Ctrl+C para fechar"
kubectl port-forward --namespace headlamp service/headlamp "$PAINEL_PORTA:80"
}

cmd_down() {
kind delete cluster --name "$CLUSTER"
rm -rf "$AMBIENTE_DIR"
}

cmd_smoke() {
recusa_cluster_existente
SMOKE_DIR="$(mktemp -d)"
trap 'kind delete cluster --name "$CLUSTER" >/dev/null 2>&1 || true; rm -rf "$SMOKE_DIR"' EXIT
usa_diretorio "$SMOKE_DIR"
sobe_cluster
aplica_stack
testa_api
echo "smoke passou"
}

case "${1:-}" in
up) cmd_up ;;
painel) cmd_painel ;;
down) cmd_down ;;
smoke) cmd_smoke ;;
*)
echo "subcomando '${1:-}' desconhecido, esperado up, painel, down ou smoke" >&2
exit 2
;;
esac
22 changes: 22 additions & 0 deletions deploy/kind/cilium-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Espelha o Cilium do cluster de produção: Gateway API com o Envoy na rede
# do nó, sem kube-proxy. O k8sServiceHost é preenchido pelo script, e o
# operator tem uma réplica porque o kind tem um nó só.
kubeProxyReplacement: true
k8sServicePort: 6443
ipam:
mode: kubernetes
gatewayAPI:
enabled: true
enableAlpn: true
hostNetwork:
enabled: true
envoy:
enabled: true
securityContext:
privileged: true
capabilities:
keepCapNetBindService: true
envoy:
- NET_BIND_SERVICE
operator:
replicas: 1
12 changes: 12 additions & 0 deletions deploy/kind/cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Cluster da stack dev. Sem CNI nem kube-proxy padrão, porque o Cilium
# substitui os dois, como no cluster de produção.
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
disableDefaultCNI: true
kubeProxyMode: none
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 443
hostPort: 8443
42 changes: 42 additions & 0 deletions deploy/kind/prepara-cluster.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Sobe o cluster kind da stack dev com os pré-requisitos que o cluster de produção
# tem: Gateway API, Cilium e cert-manager.
set -euo pipefail

CLUSTER="${CLUSTER:-markupp-dev}"
NAMESPACE="${NAMESPACE:-markupp}"
DIR="$(cd "$(dirname "$0")" && pwd)"
GATEWAY_API_VERSION=v1.6.1
CILIUM_VERSION=1.20.2
CERT_MANAGER_VERSION=v1.21.2

cria_cluster() {
kind create cluster --name "$CLUSTER" --config "$DIR/cluster.yaml"
kubectl apply --server-side -f \
"https://github.com/kubernetes-sigs/gateway-api/releases/download/$GATEWAY_API_VERSION/standard-install.yaml"
}

instala_cilium() {
helm install cilium cilium --repo https://helm.cilium.io --version "$CILIUM_VERSION" \
--namespace kube-system --values "$DIR/cilium-values.yaml" \
--set k8sServiceHost="$CLUSTER-control-plane" --wait --timeout 10m
}

instala_cert_manager() {
kubectl apply -f \
"https://github.com/cert-manager/cert-manager/releases/download/$CERT_MANAGER_VERSION/cert-manager.yaml"
liga_gateway_no_cert_manager
kubectl wait --for=condition=Available --timeout=10m deployment --all -n cert-manager
}

# liga_gateway_no_cert_manager faz o cert-manager emitir certificado a partir
# da anotação do Gateway, como o controller de produção roda com --enable-gateway-api.
liga_gateway_no_cert_manager() {
kubectl -n cert-manager patch deployment cert-manager --type=json -p \
'[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--enable-gateway-api"}]'
}

cria_cluster
instala_cilium
instala_cert_manager
kubectl create namespace "$NAMESPACE"
1 change: 1 addition & 0 deletions deploy/pulumi/PulumiPlugin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
runtime: go
Loading
Loading