Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b05910eaa | ||
|
|
4fd694ec67 | ||
|
|
0fc1be3a8a |
@@ -23,28 +23,25 @@ jobs:
|
|||||||
REVIEW__INLINE_COMMENT_FALLBACK: "false"
|
REVIEW__INLINE_COMMENT_FALLBACK: "false"
|
||||||
# LLM configuration
|
# LLM configuration
|
||||||
LLM__PROVIDER: CLAUDE
|
LLM__PROVIDER: CLAUDE
|
||||||
LLM__META__MODEL: claude-3-opus
|
LLM__META__MODEL: claude-sonnet-4-20250514
|
||||||
LLM__META__MAX_TOKENS: "4096"
|
LLM__META__MAX_TOKENS: "4096"
|
||||||
LLM__HTTP_CLIENT__API_URL: https://api.anthropic.com
|
LLM__HTTP_CLIENT__API_URL: https://api.anthropic.com
|
||||||
LLM__HTTP_CLIENT__API_TOKEN: ${{ secrets.ANTHROPIC_API_KEY }}
|
LLM__HTTP_CLIENT__API_TOKEN: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v7
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
token: ${{ secrets.AI_REVIEW_TOKEN }}
|
token: ${{ secrets.AI_REVIEW_TOKEN }}
|
||||||
|
|
||||||
- name: Update submodules to remote
|
|
||||||
run: git submodule update --remote --merge
|
|
||||||
|
|
||||||
- name: Run inline review
|
- name: Run inline review
|
||||||
uses: docker://nikitafilonov/ai-review:v0.77.0
|
uses: docker://nikitafilonov/ai-review:v0.64.0
|
||||||
with:
|
with:
|
||||||
args: ai-review run-inline
|
args: ai-review run-inline
|
||||||
|
|
||||||
- name: Run summary review
|
- name: Run summary review
|
||||||
uses: docker://nikitafilonov/ai-review:v0.77.0
|
uses: docker://nikitafilonov/ai-review:v0.64.0
|
||||||
with:
|
with:
|
||||||
args: ai-review run-summary
|
args: ai-review run-summary
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v7
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Install TruffleHog
|
- name: Install TruffleHog
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
[submodule "shared-prompts"]
|
[submodule "shared-prompts"]
|
||||||
path = shared-prompts
|
path = shared-prompts
|
||||||
url = https://git.forteapps.net/Forte/ai-review-prompts.git
|
url = https://git.forteapps.net/Forte/ai-review-prompts.git
|
||||||
branch = main
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,64 +1,3 @@
|
|||||||
# =============================================================================
|
|
||||||
# UpCloud Workload Cluster
|
|
||||||
# =============================================================================
|
|
||||||
# A lean UCS cluster for running application workloads. No managed data
|
|
||||||
# services — those live on the platform cluster. ArgoCD (on the platform
|
|
||||||
# cluster) deploys apps to this cluster via the app-of-apps pattern.
|
|
||||||
#
|
|
||||||
# Platform components deployed by deploy-workload.sh:
|
|
||||||
# nginx-ingress, cert-manager, external-dns, external-secrets, alloy
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# tofu init && tofu plan && tofu apply
|
|
||||||
# ./sync-tofu-outputs.sh --env upcloud-workload
|
|
||||||
# ./deploy-workload.sh --env upcloud-workload
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
variable "prefix" {
|
|
||||||
description = "Prefix for resource names"
|
|
||||||
type = string
|
|
||||||
default = "clst-workload"
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "zone" {
|
|
||||||
description = "UpCloud zone"
|
|
||||||
type = string
|
|
||||||
default = "no-svg1"
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "node_plan" {
|
|
||||||
description = "UpCloud server plan for worker nodes"
|
|
||||||
type = string
|
|
||||||
default = "2xCPU-4GB"
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "node_count" {
|
|
||||||
description = "Number of worker nodes"
|
|
||||||
type = number
|
|
||||||
default = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "network_cidr" {
|
|
||||||
description = "CIDR block for the private network"
|
|
||||||
type = string
|
|
||||||
default = "10.110.0.0/24"
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "control_plane_ip_filter" {
|
|
||||||
description = "CIDRs allowed to access the K8s API"
|
|
||||||
type = list(string)
|
|
||||||
default = ["0.0.0.0/0"]
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "tags" {
|
|
||||||
description = "Labels to apply to resources"
|
|
||||||
type = map(string)
|
|
||||||
default = {
|
|
||||||
Environment = "workload"
|
|
||||||
ManagedBy = "tofu"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module "cluster" {
|
module "cluster" {
|
||||||
source = "../modules/cluster"
|
source = "../modules/cluster"
|
||||||
|
|
||||||
@@ -76,45 +15,3 @@ module "cluster" {
|
|||||||
ManagedBy = "tofu"
|
ManagedBy = "tofu"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ─── Networking ───────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
resource "upcloud_router" "kubernetes" {
|
|
||||||
name = "${var.prefix}-workload-router"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "upcloud_gateway" "kubernetes" {
|
|
||||||
name = "${var.prefix}-workload-gateway"
|
|
||||||
zone = var.zone
|
|
||||||
features = ["nat"]
|
|
||||||
router {
|
|
||||||
id = upcloud_router.kubernetes.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "upcloud_network" "kubernetes" {
|
|
||||||
name = "${var.prefix}-workload-network"
|
|
||||||
zone = var.zone
|
|
||||||
router = upcloud_router.kubernetes.id
|
|
||||||
|
|
||||||
ip_network {
|
|
||||||
address = var.network_cidr
|
|
||||||
dhcp = true
|
|
||||||
dhcp_default_route = true
|
|
||||||
family = "IPv4"
|
|
||||||
gateway = cidrhost(var.network_cidr, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
depends_on = [upcloud_gateway.kubernetes]
|
|
||||||
}
|
|
||||||
|
|
||||||
# ─── Kubernetes Cluster ───────────────────────────────────────────────
|
|
||||||
|
|
||||||
resource "upcloud_kubernetes_cluster" "main-prod" {
|
|
||||||
name = "${var.prefix}-workload"
|
|
||||||
zone = var.zone
|
|
||||||
network = upcloud_network.kubernetes.id
|
|
||||||
control_plane_ip_filter = var.control_plane_ip_filter
|
|
||||||
|
|
||||||
private_node_groups = true
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,9 +5,56 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||||||
TOFU_ROOT="$(dirname "$SCRIPT_DIR")"
|
TOFU_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
PROJECT_ROOT="$(dirname "$TOFU_ROOT")"
|
PROJECT_ROOT="$(dirname "$TOFU_ROOT")"
|
||||||
|
|
||||||
CLUSTER="${1:?Usage: $0 <cluster> (e.g., aks-dev, eks-prod)}"
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $0 <cluster> --envtype <dev|prod|workload>
|
||||||
|
|
||||||
|
Fetch (or reuse) a kubeconfig for the given cluster.
|
||||||
|
Platform is read from the cluster prefix (<platform>-...).
|
||||||
|
Env type must be supplied explicitly — it is no longer inferred
|
||||||
|
from the cluster name, so names like 'upc-forte-group' work.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
$0 aks-dev --envtype dev
|
||||||
|
$0 upc-forte-group --envtype prod
|
||||||
|
$0 eks-workload --envtype workload
|
||||||
|
EOF
|
||||||
|
exit "${1:-0}"
|
||||||
|
}
|
||||||
|
|
||||||
|
CLUSTER=""
|
||||||
|
ENVTYPE=""
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--envtype) ENVTYPE="${2:-}"; shift 2 ;;
|
||||||
|
--envtype=*) ENVTYPE="${1#*=}"; shift ;;
|
||||||
|
-h|--help) usage 0 ;;
|
||||||
|
-*) echo "Unknown option: $1"; usage 1 ;;
|
||||||
|
*)
|
||||||
|
if [[ -z "$CLUSTER" ]]; then
|
||||||
|
CLUSTER="$1"; shift
|
||||||
|
else
|
||||||
|
echo "Error: unexpected argument '$1'"; usage 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ -z "$CLUSTER" ]] && { echo "Error: <cluster> argument required"; usage 1; }
|
||||||
|
[[ -z "$ENVTYPE" ]] && { echo "Error: --envtype <dev|prod|workload> required"; usage 1; }
|
||||||
|
|
||||||
|
case "$ENVTYPE" in
|
||||||
|
dev|prod|workload) ;;
|
||||||
|
*) echo "Error: invalid --envtype '$ENVTYPE'. Expected: dev, prod, workload"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
PLATFORM="${CLUSTER%%-*}"
|
PLATFORM="${CLUSTER%%-*}"
|
||||||
ENV="${CLUSTER#*-}"
|
ENV="$ENVTYPE"
|
||||||
|
|
||||||
|
case "$PLATFORM" in
|
||||||
|
aks|eks|gke|upc) ;;
|
||||||
|
*) echo "Error: unknown platform '$PLATFORM'. Expected: aks, eks, gke, upc"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
KUBECONFIG_FILE="$PROJECT_ROOT/private/$CLUSTER/kubeconfig"
|
KUBECONFIG_FILE="$PROJECT_ROOT/private/$CLUSTER/kubeconfig"
|
||||||
|
|
||||||
@@ -53,10 +100,6 @@ else
|
|||||||
CLUSTER_ID=$(tofu output -raw cluster_id 2>/dev/null || echo "${UPCLOUD_CLUSTER_ID:-}")
|
CLUSTER_ID=$(tofu output -raw cluster_id 2>/dev/null || echo "${UPCLOUD_CLUSTER_ID:-}")
|
||||||
upctl kubernetes config "$CLUSTER_ID" > "$KUBECONFIG_FILE"
|
upctl kubernetes config "$CLUSTER_ID" > "$KUBECONFIG_FILE"
|
||||||
;;
|
;;
|
||||||
*)
|
|
||||||
echo "Error: unknown platform '$PLATFORM'"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
chmod 600 "$KUBECONFIG_FILE"
|
chmod 600 "$KUBECONFIG_FILE"
|
||||||
|
|||||||
@@ -8,25 +8,33 @@ PROJECT_ROOT="$(dirname "$TOFU_ROOT")"
|
|||||||
# ─── Usage ────────────────────────────────────────────────────────────
|
# ─── Usage ────────────────────────────────────────────────────────────
|
||||||
usage() {
|
usage() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: $0 <cluster> [options]
|
Usage: $0 <cluster> --envtype <dev|prod|workload> [options]
|
||||||
|
|
||||||
Provision a Kubernetes cluster using OpenTofu.
|
Provision a Kubernetes cluster using OpenTofu.
|
||||||
Mirrors bootstrap.sh convention: cluster = <platform>-<env>
|
Cluster name is opaque — platform is read from its prefix
|
||||||
|
(<platform>-...), env is taken from --envtype.
|
||||||
|
|
||||||
Clusters: aks-dev | aks-prod | eks-dev | eks-prod
|
Platforms (inferred from cluster prefix):
|
||||||
gke-dev | gke-prod | upc-dev | upc-prod
|
aks | eks | gke | upc
|
||||||
<platform>-workload (for workload clusters)
|
|
||||||
|
Env types (required via --envtype):
|
||||||
|
dev Platform cluster, development
|
||||||
|
prod Platform cluster, production
|
||||||
|
workload Lean cluster for application workloads (no managed data
|
||||||
|
services — those run on the platform cluster)
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--plan Plan only, don't apply
|
--envtype <type> dev | prod | workload (required)
|
||||||
--destroy Destroy the cluster (use teardown-cluster.sh instead)
|
--plan Plan only, don't apply
|
||||||
--auto Skip confirmation prompts
|
--destroy Destroy the cluster (use teardown-cluster.sh instead)
|
||||||
-h, --help Show this help
|
--auto Skip confirmation prompts
|
||||||
|
-h, --help Show this help
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
$0 aks-dev
|
$0 aks-dev --envtype dev
|
||||||
$0 eks-prod --plan
|
$0 eks-prod --envtype prod --plan
|
||||||
$0 upc-dev --auto
|
$0 upc-forte-group --envtype prod --auto
|
||||||
|
$0 upc-workload --envtype workload
|
||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
- tofu, kubectl, helm installed
|
- tofu, kubectl, helm installed
|
||||||
@@ -41,17 +49,20 @@ EOF
|
|||||||
|
|
||||||
# ─── Parse arguments ──────────────────────────────────────────────────
|
# ─── Parse arguments ──────────────────────────────────────────────────
|
||||||
CLUSTER=""
|
CLUSTER=""
|
||||||
|
ENVTYPE=""
|
||||||
PLAN_ONLY=false
|
PLAN_ONLY=false
|
||||||
DESTROY=false
|
DESTROY=false
|
||||||
AUTO_APPROVE=false
|
AUTO_APPROVE=false
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--plan) PLAN_ONLY=true; shift ;;
|
--plan) PLAN_ONLY=true; shift ;;
|
||||||
--destroy) DESTROY=true; shift ;;
|
--destroy) DESTROY=true; shift ;;
|
||||||
--auto) AUTO_APPROVE=true; shift ;;
|
--auto) AUTO_APPROVE=true; shift ;;
|
||||||
-h|--help) usage 0 ;;
|
--envtype) ENVTYPE="${2:-}"; shift 2 ;;
|
||||||
-*) echo "Unknown option: $1"; usage 1 ;;
|
--envtype=*) ENVTYPE="${1#*=}"; shift ;;
|
||||||
|
-h|--help) usage 0 ;;
|
||||||
|
-*) echo "Unknown option: $1"; usage 1 ;;
|
||||||
*)
|
*)
|
||||||
if [[ -z "$CLUSTER" ]]; then
|
if [[ -z "$CLUSTER" ]]; then
|
||||||
CLUSTER="$1"
|
CLUSTER="$1"
|
||||||
@@ -65,10 +76,16 @@ while [[ $# -gt 0 ]]; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
[[ -z "$CLUSTER" ]] && { echo "Error: <cluster> argument required"; usage 1; }
|
[[ -z "$CLUSTER" ]] && { echo "Error: <cluster> argument required"; usage 1; }
|
||||||
|
[[ -z "$ENVTYPE" ]] && { echo "Error: --envtype <dev|prod|workload> required"; usage 1; }
|
||||||
|
|
||||||
# ─── Map cluster → platform + env ────────────────────────────────────
|
case "$ENVTYPE" in
|
||||||
PLATFORM="${CLUSTER%%-*}" # aks-dev → aks
|
dev|prod|workload) ;;
|
||||||
ENV="${CLUSTER#*-}" # aks-dev → dev
|
*) echo "Error: invalid --envtype '$ENVTYPE'. Expected: dev, prod, workload"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# ─── Resolve platform + env ───────────────────────────────────────────
|
||||||
|
PLATFORM="${CLUSTER%%-*}" # cluster prefix → platform (e.g. upc-forte-group → upc)
|
||||||
|
ENV="$ENVTYPE" # env comes from --envtype, not the cluster name
|
||||||
|
|
||||||
case "$PLATFORM" in
|
case "$PLATFORM" in
|
||||||
aks|eks|gke|upc) ;;
|
aks|eks|gke|upc) ;;
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: monitoring
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: "-1"
|
||||||
|
---
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: infrastructure-apps
|
||||||
|
namespace: argocd
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: infrastructure-apps
|
||||||
|
app.kubernetes.io/part-of: platform
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
|
||||||
|
targetRevision: HEAD
|
||||||
|
path: infra/overlays/upc-forte-group
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: default
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
@@ -15,6 +15,9 @@ metadata:
|
|||||||
namespace: argocd
|
namespace: argocd
|
||||||
annotations:
|
annotations:
|
||||||
argocd.argoproj.io/sync-wave: "1"
|
argocd.argoproj.io/sync-wave: "1"
|
||||||
|
notifications.argoproj.io/subscribe.on-sync-succeeded.slack: ""
|
||||||
|
notifications.argoproj.io/subscribe.on-sync-failed.slack: ""
|
||||||
|
notifications.argoproj.io/subscribe.on-degraded.slack: ""
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: dot-ai-stack
|
app.kubernetes.io/name: dot-ai-stack
|
||||||
app.kubernetes.io/part-of: apps
|
app.kubernetes.io/part-of: apps
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ metadata:
|
|||||||
namespace: mcp10x
|
namespace: mcp10x
|
||||||
spec:
|
spec:
|
||||||
encryptedData:
|
encryptedData:
|
||||||
BENKEN_CLIENT_SECRET: AgBjps8BCn20C8upAaAdb1fG4Qh3eKBbTeFuuWhQb8WoIvHmk+v03mw8i39evkQwlUWvLBWV1mtGiKwpCNhmAAdicRFG6u0m30+21K6ZtYqtKEniPKo/kjPd9nDbtxvIwiaqKs+kvFpqbxKaeqF5THYNxHZBg8gGeSbAkSx+BNIY2iLm8NRBzgC5FME5jbX8pet+DN7tbmsQTtG5f1q+h24aKXjvN5SigPft1BetfleHGlus0hFXpJ7zS4rV7rpSKSiLVV/KtS5YqEDj9uunZKyGT8j93z5xQbj0bCPVF3TU5+RCL6eE/GSgJxM4ePZ2gWZRG4eHDlGK2qE+JaNIng8wWycqLVrbs1kWoP2cdRGq6b8GHwoplAM4h4ud2fac6+5V4alhy8uhRTAX7dUG3UkwOQV/hTRb97pctPwQfltkBpDBhhW3Lfy9whSdqBuD9OqhegTqxCuWXr/P4KVOORUr0V0Iex45oLMqivI3FB2rTq9Lkwpf5YKE14d7RbKWF1G28FCNAcV8vnOIslkztLuu3GgQbVIoIiZGnnYEPofjUxbDZ/Sd1LrGeHEPR+/JJnNhNxv2297UuIIEC8kfiKuwjtLOMVQg51UbESx/+d1XmgLPqkz+jAqEPxvu8u5wO0Dov6vliTbtewJf8+fet3xnFNvyuY5ymmiTla6Gm9XPJscLj5iCzT3VhA/QuhhWXinmE/UnpYP0U4YPl5B/dUA9qT95BA6GBpDXPrDJRWNfpAH1wfG70lEBuBQXgdixYlwvx2JO6OI5+ztBKO0qFkgK
|
FLOWCASE_TOKEN: AgAjQ0Jm779LiB2/EBKtIl18Iky/tgl7VvEvkJfr82mbe7JIp99+I8WPIMgmlXsxWBDfwJ/DZoDEAKG5o8mvwc7DtaE7LkpPSXKRIviLrm+7amNdEpwb1zKjCmZ3vNOPXLnCTD3W1od8u106MEvrZpt1N1Pzav/QUElAA4lqyf4AZPuio0H/7jF8QciVHIN4BdofodOmWWCTxP1aVMylat3txlkzuqwkXc1fKBPmOKC1qWepAG7dlQ3xJ2C5Cinz5IqOYnQPO6sm/Gp+c8yQSS+0NpKO3dp93yuwRsOLOMNpCeeYOyzn2ypFIdiBuLA5k85l5WyI9BCvRjP+kzRX+u69XL7p2eMEg+vRVfoOWNetysYCdK+96bWNVVleQEuPAFxsbJWK5eV8jTZk+QeFES8kkXQwUoTMqh+JULgONakxrzc1LmA+FtKNwHWCHalh8pLQ9KeI2i9E5CtotjHfEGLE6T0ibwwOg1ZrL3irQVII8VFm4Rk+dSicbeEMAtIaII023NWuZlonrwIIy+GSVzskhhcjV7t51hylqFA3yfb+RQCzdGYA5fySlJBWhli8IotvqnDmWduPBHGb/+yrdXHsaiDqWuUu6JBUg4JqM+AMa8FkaFh8SbctbGBoycpzLVFn9N2qWviojhC9s1NJ4MiCegvE6IsCLaHidY4UXeeGjUK6Mx6h4x3y/q7ZIrBIpUOJ+8I4Mgvi9sTCogeR+vWtpP9ZZ/31MXELuu/ho3Wn9Q==
|
||||||
FLOWCASE_TOKEN: AgBLN1BWnFs3R2K+Wvb37ABucQWvx8mVVDEhZiIOYYLE8SDdbshxluP4J4IISmHwLX7Q0gYWeypfTCfvMa9c5b9AEjTcpodv4CMhjp5Mq7zUCtTI6pH6QZgLhjGheKCY+RciIK1DBsNk7CZa9MuVUdd1w0/m2C7fwikPPvNDHcNLR7zBBPWVlprgRyMrsdykcm7cmWcyqTwa/55DVPPJsG9x1K2YnjzgWHlX7BoLB/Nx7qX4XVadKEXnV0jVO5isalARxvke32pwebaiFSg8EZMhe4lntOqMSP26y/9RbveeEZS8qxzoR2OmsVrHUpMeppzpVkvQ9sKi2B4Vx8XoiRY6hZR+TmZKTvFa6JKx9gwAOVs53LEUaF7+uOQOrIcFyOXm7Ibj/azf7opqfvGajygRzSUaffTIixj+M5eJnm/iua/BWarW2w4c+ZIKvQ9DhcYpnF9Gj0U7+EWfNZyzlMoLRHsOIyKNUhOeEaSLoVQGyqRY72ZGqs83EPfQYlEu74PGyXPjd11KMhAayluGLadeAH2QDyigpf7REdXAGULNDhkJrqeYMmmGCZCyrvNOoXjYC4jQQEYA4Sd4QJA05q/EW8aFE/++nY8RqhbHqDz6wshAW/WFsTsR4JC6fc5qR+YVSmjKOa7lnk7I9vD7uPEZzCc6ImvA/NxTCfDKCREvLA5G0lYsmiTuxYmBesUgCSVVMxflEl1GXvGpFniZKPyvxIdna9j7XEQjUZsGTiyN1w==
|
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
creationTimestamp: null
|
creationTimestamp: null
|
||||||
|
|||||||
@@ -77,12 +77,6 @@ spec:
|
|||||||
mc rm --recursive --force --older-than 30d "obj/${S3_BUCKET}/_pgbackups/" || true
|
mc rm --recursive --force --older-than 30d "obj/${S3_BUCKET}/_pgbackups/" || true
|
||||||
echo "backup retention pass complete"
|
echo "backup retention pass complete"
|
||||||
env:
|
env:
|
||||||
# mc writes its config under $MC_CONFIG_DIR; point it at the shared
|
|
||||||
# emptyDir (writable by uid 65532 via fsGroup). Without this it tries
|
|
||||||
# to mkdir /.mc on the read-only-to-nonroot root fs -> "mkdir /.mc:
|
|
||||||
# permission denied" and every run fails before uploading.
|
|
||||||
- name: MC_CONFIG_DIR
|
|
||||||
value: "/work/.mc"
|
|
||||||
- name: S3_ENDPOINT
|
- name: S3_ENDPOINT
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef: { name: forte-drop-secrets, key: S3_ENDPOINT }
|
secretKeyRef: { name: forte-drop-secrets, key: S3_ENDPOINT }
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- ../../base
|
- ../../base/musicman
|
||||||
|
- ../../base/dot-ai-stack
|
||||||
|
- ../../base/argo-mcp
|
||||||
- forte-drop-postgresql
|
- forte-drop-postgresql
|
||||||
- forte-drop
|
- forte-drop
|
||||||
- forte-drop-mcp
|
- forte-drop-mcp
|
||||||
|
|
||||||
# No patches needed — base apps already default to "upc-dev" value paths
|
patches:
|
||||||
# (upc-dev is the default/base cluster).
|
# dot-ai-stack: swap upc-dev → upc-forte-group
|
||||||
# forte-drop (postgres + web + mcp) and dbunk-demo are upc-dev-only apps — their
|
- target:
|
||||||
# values hardcode upc-dev hosts (drop.forteapps.net etc.) and must not sync to
|
kind: Application
|
||||||
# upc-prod, so they live here in the overlay rather than in apps/base/.
|
name: dot-ai-stack
|
||||||
|
patch: |
|
||||||
|
- op: replace
|
||||||
|
path: /spec/sources/0/helm/valueFiles/1
|
||||||
|
value: $values/infra/values/upc-dev/dot-ai-stack-values.yaml
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- dot-ai-stack
|
- ../../base/mcp10x
|
||||||
- mcp10x
|
- ../../base/ts-mcp
|
||||||
- musicman
|
|
||||||
- ts-mcp
|
|
||||||
- argo-mcp
|
|
||||||
@@ -2,13 +2,3 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
|||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- ../../base
|
- ../../base
|
||||||
|
|
||||||
patches:
|
|
||||||
# dot-ai-stack: swap upc-dev → upc-prod
|
|
||||||
- target:
|
|
||||||
kind: Application
|
|
||||||
name: dot-ai-stack
|
|
||||||
patch: |
|
|
||||||
- op: replace
|
|
||||||
path: /spec/sources/0/helm/valueFiles/1
|
|
||||||
value: $values/infra/values/upc-prod/dot-ai-stack-values.yaml
|
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
# in case of $'\r': command not found error, run command below first
|
# in case of $'\r': command not found error, run command below first
|
||||||
# sed -i 's/\r$//' ./bootstrap.sh
|
# sed -i 's/\r$//' ./bootstrap.sh
|
||||||
|
|
||||||
CLUSTER="${1:?Usage: ./bootstrap.sh <cluster> (upc-dev|upc-prod|aks-dev|aks-prod|eks-dev|eks-prod|gke-dev|gke-prod)}"
|
CLUSTER="${1:?Usage: ./bootstrap.sh <cluster> # e.g. upc-dev, upc-prod, upc-forte-group, aks-dev, eks-prod, gke-dev — must match clusters/<cluster>.yaml}"
|
||||||
|
|
||||||
echo "running $0 for cluster: ${CLUSTER}..."
|
echo "running $0 for cluster: ${CLUSTER}..."
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ spec:
|
|||||||
topologyKey: kubernetes.io/hostname
|
topologyKey: kubernetes.io/hostname
|
||||||
initContainers:
|
initContainers:
|
||||||
- name: gitea-dump
|
- name: gitea-dump
|
||||||
image: gitea/gitea:1.27.3
|
image: gitea/gitea:1.25.4
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
|
|||||||
@@ -24,15 +24,8 @@ spec:
|
|||||||
name: azuredns-config
|
name: azuredns-config
|
||||||
key: client-secret
|
key: client-secret
|
||||||
selector:
|
selector:
|
||||||
# NOTE: cert-manager solver selectors are NOT TLS-style wildcards. selector.dnsNames
|
dnsNames:
|
||||||
# matches by exact FQDN, so '*.forteapps.net' here would match only a cert literally
|
- '*.forteapps.net'
|
||||||
# named '*.forteapps.net' — it would NOT cover 'drop.forteapps.net'. selector.dnsZones
|
|
||||||
# instead suffix-matches the zone apex AND every subdomain at any depth, so this single
|
|
||||||
# entry routes all forteapps.net ACME challenges (forteapps.net, *.forteapps.net,
|
|
||||||
# drop.forteapps.net, *.drop.forteapps.net, mcp.drop.forteapps.net, ...) through this
|
|
||||||
# Azure dns01 solver. Wildcard names require dns01; non-wildcard names that ever fail
|
|
||||||
# to match fall through to the http01 solver below.
|
|
||||||
dnsZones:
|
|
||||||
- 'forteapps.net'
|
- 'forteapps.net'
|
||||||
# HTTP-01 fallback for non-wildcard certificates
|
# HTTP-01 fallback for non-wildcard certificates
|
||||||
- http01:
|
- http01:
|
||||||
@@ -65,15 +58,8 @@ spec:
|
|||||||
name: azuredns-config
|
name: azuredns-config
|
||||||
key: client-secret
|
key: client-secret
|
||||||
selector:
|
selector:
|
||||||
# NOTE: cert-manager solver selectors are NOT TLS-style wildcards. selector.dnsNames
|
dnsNames:
|
||||||
# matches by exact FQDN, so '*.forteapps.net' here would match only a cert literally
|
- '*.forteapps.net'
|
||||||
# named '*.forteapps.net' — it would NOT cover 'drop.forteapps.net'. selector.dnsZones
|
|
||||||
# instead suffix-matches the zone apex AND every subdomain at any depth, so this single
|
|
||||||
# entry routes all forteapps.net ACME challenges (forteapps.net, *.forteapps.net,
|
|
||||||
# drop.forteapps.net, *.drop.forteapps.net, mcp.drop.forteapps.net, ...) through this
|
|
||||||
# Azure dns01 solver. Wildcard names require dns01; non-wildcard names that ever fail
|
|
||||||
# to match fall through to the http01 solver below.
|
|
||||||
dnsZones:
|
|
||||||
- 'forteapps.net'
|
- 'forteapps.net'
|
||||||
# HTTP-01 fallback for non-wildcard certificates
|
# HTTP-01 fallback for non-wildcard certificates
|
||||||
- http01:
|
- http01:
|
||||||
|
|||||||
@@ -233,10 +233,6 @@ spec:
|
|||||||
value: "{{ regex_replace_all('https?://[^/]*', request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-callback-path\", '') }}"
|
value: "{{ regex_replace_all('https?://[^/]*', request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-callback-path\", '') }}"
|
||||||
- name: AUTH_OIDC_SCOPES
|
- name: AUTH_OIDC_SCOPES
|
||||||
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-scopes\" || 'openid,profile,email' }}"
|
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-scopes\" || 'openid,profile,email' }}"
|
||||||
- name: AUTH_OIDC_COOKIE_DOMAIN
|
|
||||||
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-cookie-domain\" || '' }}"
|
|
||||||
- name: AUTH_OIDC_ALLOWED_RETURN_HOSTS
|
|
||||||
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-allowed-return-hosts\" || '' }}"
|
|
||||||
- name: AUTH_PUBLIC_PATHS
|
- name: AUTH_PUBLIC_PATHS
|
||||||
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-public-paths\" || '/healthz' }}"
|
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-public-paths\" || '/healthz' }}"
|
||||||
- name: AUTH_OIDC_COOKIE_SECRET
|
- name: AUTH_OIDC_COOKIE_SECRET
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Cluster config reference — values must match the corresponding overlay files.
|
||||||
|
# Read by bootstrap.sh at install time; NOT auto-propagated to ArgoCD value files.
|
||||||
|
clusterName: prod-fd-no-svg1 # → infra/values/upc-forte-group/argocd-values.yaml (notifications.context.clusterName)
|
||||||
|
domain: fortedigital.com # → infra/values/base/gitea-values.yaml, renovate-values.yaml, keycloak-values.yaml (subdomains)
|
||||||
|
argocdDomain: argocd.127.0.0.1.nip.io # → infra/values/upc-forte-group/argocd-values.yaml (global.domain)
|
||||||
|
grafanaDomain: grafana.fortedigital.com # → infra/values/upc-forte-group/grafana-values.yaml (ingress.hosts)
|
||||||
|
keycloakDomain: id.fortedigital.com # → infra/values/upc-forte-group/keycloak-values.yaml (ingress.hostname)
|
||||||
|
dotaiDomain: kubemcp.fortedigital.com # → infra/values/upc-forte-group/dot-ai-stack-values.yaml (dot-ai.ingress.host)
|
||||||
|
dotaiUiDomain: kubemcpui.fortedigital.com # → infra/values/upc-forte-group/dot-ai-stack-values.yaml (dot-ai-ui.ingress.host)
|
||||||
|
letsencryptEmail: danijel.simeunovic@fortedigital.com # → cluster-resources/letsencrypt-issuer.yaml (spec.acme.email)
|
||||||
|
trustedIPs: "172.16.1.0/24" # → infra/values/upc-forte-group/traefik-values.yaml (ports.*.trustedIPs)
|
||||||
|
cloudProvider: upcloud # → determines overlay directory and cloud-specific LB/storage annotations
|
||||||
+20
-20
@@ -1,27 +1,27 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.16.0/.schema/devbox.schema.json",
|
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.16.0/.schema/devbox.schema.json",
|
||||||
"packages": [
|
"packages": [
|
||||||
"kubectl@1.36.3",
|
"kubectl@1.33.2",
|
||||||
"kubernetes-helm@4.2.4",
|
"kubernetes-helm@3.18.4",
|
||||||
"k9s@0.51.0",
|
"k9s@0.50.7",
|
||||||
"kubeseal@0.38.4",
|
"kubeseal@0.30.0",
|
||||||
"argocd@3.4.6",
|
"argocd@2.14.11",
|
||||||
"kubecm@0.35.1",
|
"kubecm@0.33.1",
|
||||||
"kubectl-tree@0.6.0",
|
"kubectl-tree@0.4.3",
|
||||||
"kind@0.32.0",
|
"kind@0.29.0",
|
||||||
"kustomize@5.8.1",
|
"kustomize@5.7.0",
|
||||||
"kyverno@1.19.0",
|
"kyverno@1.14.3",
|
||||||
"syft@1.51.0",
|
"syft@1.29.0",
|
||||||
"grype@0.118.0",
|
"grype@0.92.2",
|
||||||
"traefik@3.7.10",
|
"traefik@3.6.7",
|
||||||
"claude-code@2.1.245",
|
"claude-code@latest",
|
||||||
"go@latest",
|
"go@latest",
|
||||||
"dotnet-sdk@8.0.424",
|
"dotnet-sdk@latest",
|
||||||
"opentofu@1.12.5",
|
"opentofu@1.11.6",
|
||||||
"_1password@2.30.0",
|
"_1password@latest",
|
||||||
"github-cli@2.23.0",
|
"github-cli@latest",
|
||||||
"upcloud-cli@3.36.0",
|
"upcloud-cli@3.29.0",
|
||||||
"awscli2@2.35.11"
|
"awscli2@2.34.24"
|
||||||
],
|
],
|
||||||
"shell": {
|
"shell": {
|
||||||
"init_hook": [
|
"init_hook": [
|
||||||
|
|||||||
+2
-2
@@ -1326,7 +1326,7 @@ storage:
|
|||||||
- Shared configuration and prompts live in the `shared-prompts` Git submodule (→ `Forte/ai-review-prompts`)
|
- Shared configuration and prompts live in the `shared-prompts` Git submodule (→ `Forte/ai-review-prompts`)
|
||||||
- Review mode: `ONLY_ADDED_WITH_CONTEXT` — reviews only new/changed lines plus surrounding context (token-efficient)
|
- Review mode: `ONLY_ADDED_WITH_CONTEXT` — reviews only new/changed lines plus surrounding context (token-efficient)
|
||||||
- Agent mode: disabled (one-shot review, no multi-turn reasoning)
|
- Agent mode: disabled (one-shot review, no multi-turn reasoning)
|
||||||
- LLM: Claude Sonnet (`claude-3-opus`)
|
- LLM: Claude Sonnet (`claude-sonnet-4-20250514`)
|
||||||
|
|
||||||
**Shared Prompts Structure** (submodule: `Forte/ai-review-prompts`):
|
**Shared Prompts Structure** (submodule: `Forte/ai-review-prompts`):
|
||||||
```
|
```
|
||||||
@@ -1344,7 +1344,7 @@ shared-prompts/
|
|||||||
```yaml
|
```yaml
|
||||||
llm:
|
llm:
|
||||||
provider: CLAUDE
|
provider: CLAUDE
|
||||||
model: claude-3-opus
|
model: claude-sonnet-4-20250514
|
||||||
vcs:
|
vcs:
|
||||||
provider: GITEA
|
provider: GITEA
|
||||||
review:
|
review:
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
# Domain Docs
|
|
||||||
|
|
||||||
How the engineering skills should consume this repo's domain documentation when exploring the codebase.
|
|
||||||
|
|
||||||
## Before exploring, read these
|
|
||||||
|
|
||||||
- **`CONTEXT.md`** at the repo root, or
|
|
||||||
- **`CONTEXT-MAP.md`** at the repo root if it exists — it points at one `CONTEXT.md` per context. Read each one relevant to the topic.
|
|
||||||
- **`docs/adr/`** — read ADRs that touch the area you're about to work in. In multi-context repos, also check `src/<context>/docs/adr/` for context-scoped decisions.
|
|
||||||
|
|
||||||
If any of these files don't exist, **proceed silently**. Don't flag their absence; don't suggest creating them upfront. The `/domain-modeling` skill (reached via `/grill-with-docs` and `/improve-codebase-architecture`) creates them lazily when terms or decisions actually get resolved.
|
|
||||||
|
|
||||||
## File structure
|
|
||||||
|
|
||||||
Single-context repo (most repos):
|
|
||||||
|
|
||||||
```
|
|
||||||
/
|
|
||||||
├── CONTEXT.md
|
|
||||||
├── docs/adr/
|
|
||||||
│ ├── 0001-event-sourced-orders.md
|
|
||||||
│ └── 0002-postgres-for-write-model.md
|
|
||||||
└── src/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Use the glossary's vocabulary
|
|
||||||
|
|
||||||
When your output names a domain concept (in an issue title, a refactor proposal, a hypothesis, a test name), use the term as defined in `CONTEXT.md`. Don't drift to synonyms the glossary explicitly avoids.
|
|
||||||
|
|
||||||
If the concept you need isn't in the glossary yet, that's a signal — either you're inventing language the project doesn't use (reconsider) or there's a real gap (note it for `/domain-modeling`).
|
|
||||||
|
|
||||||
## Flag ADR conflicts
|
|
||||||
|
|
||||||
If your output contradicts an existing ADR, surface it explicitly rather than silently overriding:
|
|
||||||
|
|
||||||
> _Contradicts ADR-0007 (event-sourced orders) — but worth reopening because…_
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
# Issue tracker: Gitea
|
|
||||||
|
|
||||||
Issues for this repo live in Gitea at `git.forteapps.net/Forte/launchpad`. Use the Gitea API or `tea` CLI.
|
|
||||||
|
|
||||||
## Conventions
|
|
||||||
|
|
||||||
- **Create an issue**: `tea issue create --title "..." --description "..."`
|
|
||||||
or via API: `curl -X POST "https://git.forteapps.net/api/v1/repos/Forte/launchpad/issues" -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" -d '{"title":"...","body":"..."}'`
|
|
||||||
- **Read an issue**: `tea issue view <number>` or API `GET /api/v1/repos/Forte/launchpad/issues/<number>`
|
|
||||||
- **List issues**: `tea issue list` or API `GET /api/v1/repos/Forte/launchpad/issues?state=open`
|
|
||||||
- **Comment on an issue**: `tea issue comment <number> "..."` or API `POST /api/v1/repos/Forte/launchpad/issues/<number>/comments`
|
|
||||||
- **Apply labels**: API `POST /api/v1/repos/Forte/launchpad/issues/<number>/labels` with `{"labels": [<label_id>]}`
|
|
||||||
- **Close**: API `PATCH /api/v1/repos/Forte/launchpad/issues/<number>` with `{"state": "closed"}`
|
|
||||||
|
|
||||||
Infer the repo from `git remote -v`.
|
|
||||||
|
|
||||||
## Pull requests as a triage surface
|
|
||||||
|
|
||||||
**PRs as a request surface: no.**
|
|
||||||
|
|
||||||
## When a skill says "publish to the issue tracker"
|
|
||||||
|
|
||||||
Create a Gitea issue.
|
|
||||||
|
|
||||||
## When a skill says "fetch the relevant ticket"
|
|
||||||
|
|
||||||
Fetch the issue via API or `tea issue view <number>`.
|
|
||||||
|
|
||||||
## Wayfinding operations
|
|
||||||
|
|
||||||
Used by `/wayfinder`. The **map** is a single issue with **child** issues as tickets.
|
|
||||||
|
|
||||||
- **Map**: a single issue labelled `wayfinder:map`, holding the Destination / Notes / Decisions-so-far / Fog body.
|
|
||||||
- Create: `POST /api/v1/repos/Forte/launchpad/issues` with `{"title":"...","body":"...","labels":[<wayfinder:map label id>]}`
|
|
||||||
- **Child ticket**: an issue carrying `Part of #<map>` at the top of its body and a `wayfinder:<type>` label (`research`/`prototype`/`grilling`/`task`). Once claimed, the ticket is assigned to the driving dev.
|
|
||||||
- **Blocking**: Gitea does not have native issue dependencies. Fall back to a `Blocked by: #<n>, #<n>` line at the top of the child body. A ticket is unblocked when every issue it lists is closed.
|
|
||||||
- **Frontier query**: list the map's open children — `GET /api/v1/repos/Forte/launchpad/issues?state=open&labels=wayfinder:research,wayfinder:prototype,wayfinder:grilling,wayfinder:task` — then filter to those whose body starts with `Part of #<map>`. Drop any with an open issue in their `Blocked by` line, or with an assignee. First in map order wins.
|
|
||||||
- **Claim**: `PATCH /api/v1/repos/Forte/launchpad/issues/<n>` with `{"assignees":["<username>"]}` — the session's first write.
|
|
||||||
- **Resolve**: post the answer as a comment (`POST .../comments`), close the issue (`PATCH` with `{"state":"closed"}`), then append a context pointer (gist + link) to the map's Decisions-so-far by editing the map issue body.
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
# Triage Labels
|
|
||||||
|
|
||||||
The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker.
|
|
||||||
|
|
||||||
| Label in mattpocock/skills | Label in our tracker | Meaning |
|
|
||||||
| -------------------------- | -------------------- | ---------------------------------------- |
|
|
||||||
| `needs-triage` | `needs-triage` | Maintainer needs to evaluate this issue |
|
|
||||||
| `needs-info` | `needs-info` | Waiting on reporter for more information |
|
|
||||||
| `ready-for-agent` | `ready-for-agent` | Fully specified, ready for an AFK agent |
|
|
||||||
| `ready-for-human` | `ready-for-human` | Requires human implementation |
|
|
||||||
| `wontfix` | `wontfix` | Will not be actioned |
|
|
||||||
|
|
||||||
When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding label string from this table.
|
|
||||||
|
|
||||||
Edit the right-hand column to match whatever vocabulary you actually use.
|
|
||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
source:
|
source:
|
||||||
repoURL: https://charts.jetstack.io
|
repoURL: https://charts.jetstack.io
|
||||||
chart: cert-manager
|
chart: cert-manager
|
||||||
targetRevision: "v1.21.2"
|
targetRevision: "v1.14.0"
|
||||||
|
|
||||||
helm:
|
helm:
|
||||||
values: |
|
values: |
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: https://fluent.github.io/helm-charts
|
- repoURL: https://fluent.github.io/helm-charts
|
||||||
chart: fluent-bit
|
chart: fluent-bit
|
||||||
targetRevision: 0.58.2
|
targetRevision: 0.47.10
|
||||||
helm:
|
helm:
|
||||||
releaseName: fluent-bit
|
releaseName: fluent-bit
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: https://dl.gitea.com/charts
|
- repoURL: https://dl.gitea.com/charts
|
||||||
chart: actions
|
chart: actions
|
||||||
targetRevision: "0.1.2"
|
targetRevision: "0.0.5"
|
||||||
helm:
|
helm:
|
||||||
releaseName: gitea-actions
|
releaseName: gitea-actions
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: https://dl.gitea.com/charts
|
- repoURL: https://dl.gitea.com/charts
|
||||||
chart: gitea
|
chart: gitea
|
||||||
targetRevision: "12.7.0"
|
targetRevision: "12.6.0"
|
||||||
helm:
|
helm:
|
||||||
releaseName: gitea
|
releaseName: gitea
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: https://grafana.github.io/helm-charts
|
- repoURL: https://grafana.github.io/helm-charts
|
||||||
chart: grafana
|
chart: grafana
|
||||||
targetRevision: "10.5.15"
|
targetRevision: "8.0.0"
|
||||||
helm:
|
helm:
|
||||||
releaseName: grafana
|
releaseName: grafana
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ spec:
|
|||||||
source:
|
source:
|
||||||
chart: kyverno
|
chart: kyverno
|
||||||
repoURL: https://kyverno.github.io/kyverno/
|
repoURL: https://kyverno.github.io/kyverno/
|
||||||
targetRevision: 3.9.1
|
targetRevision: v3.7.0 # Update to latest stable version
|
||||||
helm:
|
helm:
|
||||||
releaseName: kyverno
|
releaseName: kyverno
|
||||||
valuesObject:
|
valuesObject:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: https://grafana.github.io/helm-charts
|
- repoURL: https://grafana.github.io/helm-charts
|
||||||
chart: loki
|
chart: loki
|
||||||
targetRevision: "7.3.0"
|
targetRevision: "6.0.0"
|
||||||
helm:
|
helm:
|
||||||
releaseName: loki
|
releaseName: loki
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: https://opencost.github.io/opencost-helm-chart
|
- repoURL: https://opencost.github.io/opencost-helm-chart
|
||||||
chart: opencost
|
chart: opencost
|
||||||
targetRevision: "1.43.2"
|
targetRevision: "1.42.0"
|
||||||
helm:
|
helm:
|
||||||
releaseName: opencost
|
releaseName: opencost
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: https://prometheus-community.github.io/helm-charts
|
- repoURL: https://prometheus-community.github.io/helm-charts
|
||||||
chart: prometheus
|
chart: prometheus
|
||||||
targetRevision: "28.16.0"
|
targetRevision: "28.9.0"
|
||||||
helm:
|
helm:
|
||||||
releaseName: prometheus
|
releaseName: prometheus
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: ghcr.io/renovatebot/charts
|
- repoURL: ghcr.io/renovatebot/charts
|
||||||
chart: renovate
|
chart: renovate
|
||||||
targetRevision: "46.318.0"
|
targetRevision: "46.109.0"
|
||||||
helm:
|
helm:
|
||||||
releaseName: renovate
|
releaseName: renovate
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ spec:
|
|||||||
|
|
||||||
source:
|
source:
|
||||||
chart: sealed-secrets
|
chart: sealed-secrets
|
||||||
repoURL: https://bitnami.github.io/sealed-secrets
|
repoURL: https://bitnami-labs.github.io/sealed-secrets
|
||||||
targetRevision: 2.20.0
|
targetRevision: 2.16.2 # Update to latest stable version
|
||||||
helm:
|
helm:
|
||||||
releaseName: sealed-secrets
|
releaseName: sealed-secrets
|
||||||
parameters:
|
parameters:
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: https://traefik.github.io/charts
|
- repoURL: https://traefik.github.io/charts
|
||||||
chart: traefik
|
chart: traefik
|
||||||
targetRevision: "28.3.0"
|
targetRevision: "28.0.0"
|
||||||
helm:
|
helm:
|
||||||
releaseName: traefik
|
releaseName: traefik
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: https://helm.releases.hashicorp.com
|
- repoURL: https://helm.releases.hashicorp.com
|
||||||
chart: vault
|
chart: vault
|
||||||
targetRevision: "0.34.1"
|
targetRevision: "0.32.0"
|
||||||
helm:
|
helm:
|
||||||
releaseName: vault
|
releaseName: vault
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -28,12 +28,3 @@ resources:
|
|||||||
|
|
||||||
# No patches needed — base already has "upc-dev" paths
|
# No patches needed — base already has "upc-dev" paths
|
||||||
# upc-dev is the default/base cluster
|
# upc-dev is the default/base cluster
|
||||||
|
|
||||||
patches:
|
|
||||||
- target:
|
|
||||||
kind: Application
|
|
||||||
name: databunker
|
|
||||||
patch: |
|
|
||||||
- op: add
|
|
||||||
path: /spec/sources/0/helm/valueFiles/-
|
|
||||||
value: $values/infra/values/upc-dev/databunker-values.yaml
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ spec:
|
|||||||
sources:
|
sources:
|
||||||
- repoURL: https://guerzon.github.io/vaultwarden
|
- repoURL: https://guerzon.github.io/vaultwarden
|
||||||
chart: vaultwarden
|
chart: vaultwarden
|
||||||
targetRevision: "0.46.2"
|
targetRevision: "0.36.4"
|
||||||
helm:
|
helm:
|
||||||
releaseName: vaultwarden
|
releaseName: vaultwarden
|
||||||
valueFiles:
|
valueFiles:
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- ../../base/cert-manager-application
|
||||||
|
- ../../base/cluster-resources-application
|
||||||
|
- ../../base/enterprise-apps
|
||||||
|
- ../../base/fluent-bit
|
||||||
|
- ../../base/gitea
|
||||||
|
- ../../base/gitea-actions
|
||||||
|
- ../../base/grafana
|
||||||
|
- ../../base/grafana-dashboards
|
||||||
|
- ../../base/homepage
|
||||||
|
- ../../base/karpor
|
||||||
|
- ../../base/keycloak
|
||||||
|
- ../../base/kyverno
|
||||||
|
- ../../base/kyverno-policies
|
||||||
|
- ../../base/loki
|
||||||
|
- ../../base/opencost
|
||||||
|
- ../../base/prometheus
|
||||||
|
- ../../base/renovate
|
||||||
|
- ../../base/sealedsecrets
|
||||||
|
- ../../base/tempo
|
||||||
|
- ../../base/traefik-application
|
||||||
|
- ../../base/vault
|
||||||
|
|
||||||
|
patches:
|
||||||
|
# Traefik: swap upc-dev → upc-forte-group
|
||||||
|
- target:
|
||||||
|
kind: Application
|
||||||
|
name: traefik
|
||||||
|
patch: |
|
||||||
|
- op: replace
|
||||||
|
path: /spec/sources/0/helm/valueFiles/1
|
||||||
|
value: $values/infra/values/upc-forte-group/traefik-values.yaml
|
||||||
|
|
||||||
|
# Grafana: swap upc-dev → upc-forte-group
|
||||||
|
- target:
|
||||||
|
kind: Application
|
||||||
|
name: grafana
|
||||||
|
patch: |
|
||||||
|
- op: replace
|
||||||
|
path: /spec/sources/0/helm/valueFiles/1
|
||||||
|
value: $values/infra/values/upc-forte-group/grafana-values.yaml
|
||||||
|
|
||||||
|
# OpenCost: swap upc-dev → upc-forte-group
|
||||||
|
- target:
|
||||||
|
kind: Application
|
||||||
|
name: opencost
|
||||||
|
patch: |
|
||||||
|
- op: replace
|
||||||
|
path: /spec/sources/0/helm/valueFiles/1
|
||||||
|
value: $values/infra/values/upc-forte-group/opencost-values.yaml
|
||||||
|
|
||||||
|
# Gitea: swap upc-dev → upc-forte-group
|
||||||
|
- target:
|
||||||
|
kind: Application
|
||||||
|
name: gitea
|
||||||
|
patch: |
|
||||||
|
- op: replace
|
||||||
|
path: /spec/sources/0/helm/valueFiles/1
|
||||||
|
value: $values/infra/values/upc-forte-group/gitea-values.yaml
|
||||||
@@ -31,7 +31,7 @@ gitea:
|
|||||||
ENABLE_PASSWORD_SIGNIN_FORM: false
|
ENABLE_PASSWORD_SIGNIN_FORM: false
|
||||||
AUTO_WATCH_ON_CHANGES: false
|
AUTO_WATCH_ON_CHANGES: false
|
||||||
AUTO_WATCH_NEW_REPOS: false
|
AUTO_WATCH_NEW_REPOS: false
|
||||||
ENABLE_NOTIFY_MAIL: true
|
ENABLE_NOTIFY_MAIL: false
|
||||||
ENABLE_TIMETRACKING: false
|
ENABLE_TIMETRACKING: false
|
||||||
|
|
||||||
openid:
|
openid:
|
||||||
|
|||||||
@@ -290,7 +290,6 @@ extraDeploy:
|
|||||||
namespace: keycloak
|
namespace: keycloak
|
||||||
spec:
|
spec:
|
||||||
schedule: "*/2 * * * *"
|
schedule: "*/2 * * * *"
|
||||||
timeZone: "Europe/Oslo"
|
|
||||||
concurrencyPolicy: Forbid
|
concurrencyPolicy: Forbid
|
||||||
successfulJobsHistoryLimit: 1
|
successfulJobsHistoryLimit: 1
|
||||||
failedJobsHistoryLimit: 3
|
failedJobsHistoryLimit: 3
|
||||||
@@ -303,7 +302,7 @@ extraDeploy:
|
|||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
containers:
|
containers:
|
||||||
- name: registrar
|
- name: registrar
|
||||||
image: alpine:3.24
|
image: alpine:3.20
|
||||||
command: [ "/bin/sh", "-c" ]
|
command: [ "/bin/sh", "-c" ]
|
||||||
args:
|
args:
|
||||||
- |
|
- |
|
||||||
@@ -618,9 +617,7 @@ extraDeploy:
|
|||||||
name: keycloak-client-cleanup
|
name: keycloak-client-cleanup
|
||||||
namespace: keycloak
|
namespace: keycloak
|
||||||
spec:
|
spec:
|
||||||
schedule: "0 3 1 * *"
|
schedule: "0 3 * * 0"
|
||||||
timeZone: "Europe/Oslo"
|
|
||||||
startingDeadlineSeconds: 3600
|
|
||||||
concurrencyPolicy: Forbid
|
concurrencyPolicy: Forbid
|
||||||
successfulJobsHistoryLimit: 1
|
successfulJobsHistoryLimit: 1
|
||||||
failedJobsHistoryLimit: 3
|
failedJobsHistoryLimit: 3
|
||||||
@@ -633,7 +630,7 @@ extraDeploy:
|
|||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
containers:
|
containers:
|
||||||
- name: cleanup
|
- name: cleanup
|
||||||
image: alpine:3.24
|
image: alpine:3.20
|
||||||
command: [ "/bin/sh", "-c" ]
|
command: [ "/bin/sh", "-c" ]
|
||||||
args:
|
args:
|
||||||
- |
|
- |
|
||||||
@@ -645,7 +642,7 @@ extraDeploy:
|
|||||||
ADMIN_USER="admin"
|
ADMIN_USER="admin"
|
||||||
ADMIN_PASS=$(cat /secrets/admin-password)
|
ADMIN_PASS=$(cat /secrets/admin-password)
|
||||||
DRY_RUN="${DRY_RUN:-true}"
|
DRY_RUN="${DRY_RUN:-true}"
|
||||||
MIN_AGE_DAYS="${MIN_AGE_DAYS:-14}"
|
MIN_AGE_DAYS="${MIN_AGE_DAYS:-7}"
|
||||||
if [ -z "$CLIENT_ID_PATTERN" ]; then
|
if [ -z "$CLIENT_ID_PATTERN" ]; then
|
||||||
CLIENT_ID_PATTERN='^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
|
CLIENT_ID_PATTERN='^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
|
||||||
fi
|
fi
|
||||||
@@ -677,15 +674,13 @@ extraDeploy:
|
|||||||
CLIENTS=$(curl -sf -H "Authorization: Bearer ${TOKEN}" \
|
CLIENTS=$(curl -sf -H "Authorization: Bearer ${TOKEN}" \
|
||||||
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients")
|
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients")
|
||||||
|
|
||||||
CANDIDATES=$(echo "$CLIENTS" | jq -c --argjson protected "$PROTECTED_JSON" \
|
CANDIDATES=$(echo "$CLIENTS" | jq -c --argjson protected "$PROTECTED_JSON" --argjson now "$NOW_SEC" --argjson min_age "$MIN_AGE_SEC" --arg pattern "$CLIENT_ID_PATTERN" '
|
||||||
--argjson now "$NOW_SEC" --argjson min_age "$MIN_AGE_SEC" --arg pattern "$CLIENT_ID_PATTERN" '
|
|
||||||
[
|
[
|
||||||
.[]
|
.[]
|
||||||
| select(.clientId as $cid | $protected | index($cid) | not)
|
| select(.clientId as $cid | $protected | index($cid) | not)
|
||||||
| select(.attributes["k8s.secret.sync"] != "true")
|
| select(.attributes["k8s.secret.sync"] != "true")
|
||||||
| select(.clientId | test($pattern; "i"))
|
| select(.clientId | test($pattern; "i"))
|
||||||
| select(.attributes["client.secret.creation.time"] != null)
|
| select((.createdTimestamp // 0) / 1000 < ($now - $min_age))
|
||||||
| select((.attributes["client.secret.creation.time"] | tonumber) < ($now - $min_age))
|
|
||||||
]
|
]
|
||||||
')
|
')
|
||||||
|
|
||||||
@@ -733,7 +728,7 @@ extraDeploy:
|
|||||||
- name: DRY_RUN
|
- name: DRY_RUN
|
||||||
value: "false"
|
value: "false"
|
||||||
- name: MIN_AGE_DAYS
|
- name: MIN_AGE_DAYS
|
||||||
value: "60"
|
value: "7"
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: keycloak-credentials
|
- name: keycloak-credentials
|
||||||
mountPath: /secrets
|
mountPath: /secrets
|
||||||
|
|||||||
@@ -17,14 +17,7 @@ loki:
|
|||||||
period: 24h
|
period: 24h
|
||||||
object_store: filesystem # we're storing on filesystem so there's no real persistence here.
|
object_store: filesystem # we're storing on filesystem so there's no real persistence here.
|
||||||
schema: v13
|
schema: v13
|
||||||
compactor:
|
|
||||||
working_directory: /var/loki/compactor
|
|
||||||
retention_enabled: true
|
|
||||||
delete_request_store: filesystem
|
|
||||||
compaction_interval: 10m
|
|
||||||
retention_delete_delay: 2h
|
|
||||||
limits_config:
|
limits_config:
|
||||||
retention_period: 168h # 7 days
|
|
||||||
reject_old_samples: true
|
reject_old_samples: true
|
||||||
reject_old_samples_max_age: 168h
|
reject_old_samples_max_age: 168h
|
||||||
ingestion_rate_mb: 15
|
ingestion_rate_mb: 15
|
||||||
@@ -35,8 +28,6 @@ chunksCache:
|
|||||||
resultsCache:
|
resultsCache:
|
||||||
enabled: false
|
enabled: false
|
||||||
singleBinary:
|
singleBinary:
|
||||||
persistence:
|
|
||||||
size: 20Gi
|
|
||||||
replicas: 1
|
replicas: 1
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
|
|||||||
@@ -21,11 +21,6 @@ renovate:
|
|||||||
"assignees": ["danijel.simeunovic"],
|
"assignees": ["danijel.simeunovic"],
|
||||||
"reviewers": ["danijel.simeunovic"]
|
"reviewers": ["danijel.simeunovic"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"matchRepositories": ["**/launchpad"],
|
|
||||||
"assignees": ["danijel.simeunovic"],
|
|
||||||
"reviewers": ["danijel.simeunovic"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"matchRepositories": ["**/forte-helm"],
|
"matchRepositories": ["**/forte-helm"],
|
||||||
"assignees": ["danijel.simeunovic"],
|
"assignees": ["danijel.simeunovic"],
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
global:
|
||||||
|
domain: argocd.fortedigital.com
|
||||||
|
notifications:
|
||||||
|
context:
|
||||||
|
clusterName: "prod-fd-no-svg1"
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# UpCloud storage class for Gitea and its embedded PostgreSQL
|
||||||
|
persistence:
|
||||||
|
storageClass: upcloud-block-storage-maxiops
|
||||||
|
postgresql:
|
||||||
|
primary:
|
||||||
|
persistence:
|
||||||
|
storageClass: upcloud-block-storage-maxiops
|
||||||
|
|
||||||
|
gitea:
|
||||||
|
# -- Gitea app.ini configuration
|
||||||
|
config:
|
||||||
|
APP_NAME: "Forte Git"
|
||||||
|
|
||||||
|
server:
|
||||||
|
DOMAIN: source.forteapps.net
|
||||||
|
ROOT_URL: https://source.forteapps.net
|
||||||
|
SSH_DOMAIN: source.forteapps.net
|
||||||
|
|
||||||
|
|
||||||
|
# -- Ingress via Traefik with Let's Encrypt TLS
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: traefik
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
gethomepage.dev/enabled: "true"
|
||||||
|
gethomepage.dev/name: "Gitea"
|
||||||
|
gethomepage.dev/description: "Git hosting & CI/CD"
|
||||||
|
gethomepage.dev/group: "DevOps"
|
||||||
|
gethomepage.dev/icon: "gitea"
|
||||||
|
gethomepage.dev/href: "https://source.forteapps.net"
|
||||||
|
gethomepage.dev/widget.type: "gitea"
|
||||||
|
gethomepage.dev/widget.url: "https://source.forteapps.net"
|
||||||
|
gethomepage.dev/widget.key: "{{HOMEPAGE_VAR_GITEA_TOKEN}}"
|
||||||
|
hosts:
|
||||||
|
- host: source.forteapps.net
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: gitea-tls
|
||||||
|
hosts:
|
||||||
|
- source.forteapps.net
|
||||||
|
|
||||||
|
# -- Git repository storage
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 20Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
ingress:
|
||||||
|
hosts:
|
||||||
|
- grafana.fortedigital.com
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
ingress:
|
||||||
|
hostname: id.forteapps.com
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# UpCloud custom pricing (no native OpenCost integration)
|
||||||
|
opencost:
|
||||||
|
exporter:
|
||||||
|
customPricing:
|
||||||
|
enabled: true
|
||||||
|
provider: custom
|
||||||
|
costModel:
|
||||||
|
description: "UpCloud 4-node cluster pricing"
|
||||||
|
CPU: "5.86"
|
||||||
|
RAM: "1.46"
|
||||||
|
GPU: "0"
|
||||||
|
storage: "0.34"
|
||||||
|
zoneNetworkEgress: "0"
|
||||||
|
regionNetworkEgress: "0"
|
||||||
|
internetNetworkEgress: "0"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
service:
|
||||||
|
annotations: {}
|
||||||
|
ports:
|
||||||
|
web:
|
||||||
|
proxyProtocol:
|
||||||
|
trustedIPs: "10.0.0.0/16"
|
||||||
|
forwardedHeaders:
|
||||||
|
trustedIPs: "10.0.0.0/16"
|
||||||
|
websecure:
|
||||||
|
proxyProtocol:
|
||||||
|
trustedIPs: "10.0.0.0/16"
|
||||||
|
forwardedHeaders:
|
||||||
|
trustedIPs: "10.0.0.0/16"
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
dot-ai:
|
|
||||||
ingress:
|
|
||||||
host: kubemcp.fortedigital.com
|
|
||||||
webUI:
|
|
||||||
baseUrl: http://kubemcpui.fortedigital.com
|
|
||||||
dot-ai-ui:
|
|
||||||
ingress:
|
|
||||||
host: kubemcpui.fortedigital.com
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
||||||
"extends": [
|
|
||||||
"config:recommended",
|
|
||||||
"group:allNonMajor",
|
|
||||||
":dependencyDashboard",
|
|
||||||
":semanticCommits"
|
|
||||||
],
|
|
||||||
"timezone": "Europe/Oslo",
|
|
||||||
"labels": ["renovate"],
|
|
||||||
"reviewers": ["danijel.simeunovic"],
|
|
||||||
|
|
||||||
"prConcurrentLimit": 10,
|
|
||||||
"prHourlyLimit": 4,
|
|
||||||
"minimumReleaseAge": "3 days",
|
|
||||||
|
|
||||||
"ignorePaths": [
|
|
||||||
"**/*-sealed.yaml",
|
|
||||||
"cluster-resources/policies/**",
|
|
||||||
"private/**",
|
|
||||||
".devbox/**"
|
|
||||||
],
|
|
||||||
|
|
||||||
"argocd": {
|
|
||||||
"description": "ArgoCD Applications live under infra/, apps/ and the root app-of-apps files. The manager skips any file without an argoproj.io apiVersion, so matching broadly is safe.",
|
|
||||||
"managerFilePatterns": [
|
|
||||||
"/^_app-of-apps-.+\\.yaml$/",
|
|
||||||
"/^apps/.+\\.yaml$/",
|
|
||||||
"/^infra/.+\\.yaml$/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
"helm-values": {
|
|
||||||
"description": "Values files are named <app>-values.yaml, not the default values.yaml.",
|
|
||||||
"managerFilePatterns": ["/^infra/values/.+\\.ya?ml$/"]
|
|
||||||
},
|
|
||||||
|
|
||||||
"kubernetes": {
|
|
||||||
"description": "Plain manifests with inline image references. Kyverno policies are excluded via ignorePaths - their images are Go templates, not tags.",
|
|
||||||
"managerFilePatterns": [
|
|
||||||
"/^cluster-resources/.+\\.yaml$/",
|
|
||||||
"/^apps/.+/resources/.+\\.yaml$/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
"packageRules": [
|
|
||||||
{
|
|
||||||
"description": "Every Application carries a second source pointing at this repo at HEAD for $values. HEAD is not a version.",
|
|
||||||
"matchDatasources": ["git-tags"],
|
|
||||||
"matchDepNames": ["/forteapps\\.net/"],
|
|
||||||
"enabled": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Platform chart majors usually carry values-schema or CRD breaks - flag them for a careful read.",
|
|
||||||
"matchFileNames": ["infra/**"],
|
|
||||||
"matchUpdateTypes": ["major"],
|
|
||||||
"labels": ["renovate", "breaking-change"],
|
|
||||||
"minimumReleaseAge": "7 days"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Patch-level platform bumps are routine - let them through faster.",
|
|
||||||
"matchFileNames": ["infra/**"],
|
|
||||||
"matchUpdateTypes": ["patch"],
|
|
||||||
"minimumReleaseAge": "1 day"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user