{"id":51462915,"url":"https://github.com/nubenetes/jenkins-2026-gitops-config","last_synced_at":"2026-07-06T07:30:38.028Z","repository":{"id":365225079,"uuid":"1270662281","full_name":"nubenetes/jenkins-2026-gitops-config","owner":"nubenetes","description":"GitOps target-state for the GKE Golden-Path IDP, synced by ArgoCD: Helm chart for the JHipster microservices + parameterized CNPG Postgres — stable HA (3 + PgBouncer + backups) or optional lean develop tier — zero-trust NetworkPolicies, OTel auto-instrumentation, ArgoCD App/AppSet manifests. Any of the 4 CI engines write the image tags.","archived":false,"fork":false,"pushed_at":"2026-07-03T02:13:24.000Z","size":96,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-03T02:22:26.115Z","etag":null,"topics":["argocd","cloudnative-pg","cnpg","devsecops","gitops","gke","helm","jhipster","kubernetes","network-policy","pgbouncer","security","zero-trust"],"latest_commit_sha":null,"homepage":null,"language":"Go Template","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nubenetes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-15T23:51:04.000Z","updated_at":"2026-07-03T02:13:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nubenetes/jenkins-2026-gitops-config","commit_stats":null,"previous_names":["nubenetes/jenkins-2026-gitops-config"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/nubenetes/jenkins-2026-gitops-config","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nubenetes%2Fjenkins-2026-gitops-config","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nubenetes%2Fjenkins-2026-gitops-config/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nubenetes%2Fjenkins-2026-gitops-config/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nubenetes%2Fjenkins-2026-gitops-config/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nubenetes","download_url":"https://codeload.github.com/nubenetes/jenkins-2026-gitops-config/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nubenetes%2Fjenkins-2026-gitops-config/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35182322,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-06T02:00:07.184Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argocd","cloudnative-pg","cnpg","devsecops","gitops","gke","helm","jhipster","kubernetes","network-policy","pgbouncer","security","zero-trust"],"created_at":"2026-07-06T07:30:34.440Z","updated_at":"2026-07-06T07:30:38.018Z","avatar_url":"https://github.com/nubenetes.png","language":"Go Template","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jenkins-2026-gitops-config\n\n[![GitOps source of truth](https://img.shields.io/badge/GitOps-source%20of%20truth-EF7B4D?style=flat-square\u0026logo=argo\u0026logoColor=white)](#golden-path-idp-infrastructure)\n[![Infra repo](https://img.shields.io/badge/infra%20repo-nubenetes%2Fjenkins--2026-181717?style=flat-square\u0026logo=github\u0026logoColor=white)](https://github.com/nubenetes/jenkins-2026)\n[![main: CI-writable](https://img.shields.io/badge/main-CI--writable%20(direct%20push)-D24939?style=flat-square\u0026logo=git\u0026logoColor=white)](#main-branch-protection--ci-writable-do-not-require-pull-requests)\n[![Machine-managed](https://img.shields.io/badge/image%20tags-machine--managed-64748B?style=flat-square)](#do-not-edit-manually)\n\n[![Last commit](https://img.shields.io/github/last-commit/nubenetes/jenkins-2026-gitops-config?logo=git\u0026logoColor=white)](https://github.com/nubenetes/jenkins-2026-gitops-config/commits/main)\n[![Commit activity](https://img.shields.io/github/commit-activity/m/nubenetes/jenkins-2026-gitops-config?logo=github)](https://github.com/nubenetes/jenkins-2026-gitops-config/pulse)\n![Top language](https://img.shields.io/github/languages/top/nubenetes/jenkins-2026-gitops-config?logo=helm\u0026logoColor=white)\n![Repo size](https://img.shields.io/github/repo-size/nubenetes/jenkins-2026-gitops-config)\n\n\u003c!-- STACK-BADGES:START --\u003e\n**Stack** — what this repo declares for ArgoCD to reconcile:\n\n**GitOps \u0026 delivery**  \n![Argo CD](https://img.shields.io/badge/Argo%20CD-EF7B4D?style=flat-square\u0026logo=argo\u0026logoColor=white) ![Helm](https://img.shields.io/badge/Helm-0F1689?style=flat-square\u0026logo=helm\u0026logoColor=white) ![ApplicationSet](https://img.shields.io/badge/ApplicationSet-EF7B4D?style=flat-square\u0026logo=argo\u0026logoColor=white)\n\n**Target platform**  \n![GKE Kubernetes](https://img.shields.io/badge/GKE%20Kubernetes-326CE5?style=flat-square\u0026logo=kubernetes\u0026logoColor=white) ![Gateway API](https://img.shields.io/badge/Gateway%20API-326CE5?style=flat-square\u0026logo=kubernetes\u0026logoColor=white) ![NetworkPolicies](https://img.shields.io/badge/NetworkPolicies%20(zero--trust)-326CE5?style=flat-square\u0026logo=kubernetes\u0026logoColor=white)\n\n**Data**  \n![CloudNativePG](https://img.shields.io/badge/CloudNativePG-336791?style=flat-square\u0026logo=postgresql\u0026logoColor=white) ![PostgreSQL](https://img.shields.io/badge/PostgreSQL-4169E1?style=flat-square\u0026logo=postgresql\u0026logoColor=white) ![pgAdmin](https://img.shields.io/badge/pgAdmin-326690?style=flat-square\u0026logo=postgresql\u0026logoColor=white)\n\n**Observability**  \n![OpenTelemetry](https://img.shields.io/badge/OpenTelemetry%20auto--instrumentation-425CC7?style=flat-square\u0026logo=opentelemetry\u0026logoColor=white)\n\n**Deployed app** — image tags written by the active CI engine  \n![JHipster](https://img.shields.io/badge/JHipster-3E8ACC?style=flat-square\u0026logo=jhipster\u0026logoColor=white) ![Spring Boot](https://img.shields.io/badge/Spring%20Boot-6DB33F?style=flat-square\u0026logo=springboot\u0026logoColor=white) ![Angular](https://img.shields.io/badge/Angular-DD0031?style=flat-square\u0026logo=angular\u0026logoColor=white) ![GitHub Container Registry](https://img.shields.io/badge/GitHub%20Container%20Registry-181717?style=flat-square\u0026logo=github\u0026logoColor=white)\n\n\u003c!-- STACK-BADGES:END --\u003e\n\n\u003e **GitOps configuration repository** for the [`jenkins-2026`](https://github.com/nubenetes/jenkins-2026) proof-of-concept.\n\u003e\n\u003e This repo is the **Git source of truth for ArgoCD**. The active CI engine writes image tags here; ArgoCD reads them and reconciles the cluster state. You do not deploy anything manually from this repo.\n\n\u003e ## ⚠️ `main` is CI-writable — do NOT require pull requests on it\n\u003e\n\u003e The active CI engine's **GitOps Update** step pushes image-tag bumps **directly** to `main` (`git push origin main`). Therefore:\n\u003e - `main` is protected only against **force-pushes/deletions** — **not** with *require-a-pull-request*.\n\u003e - Enabling \"Require a pull request before merging\" **wedges every deploy**: the CI's PAT-authenticated push is rejected (an admin PAT does **not** bypass branch protection) and the image tags freeze.\n\u003e - This is deliberate — and the **opposite** of the [`jenkins-2026`](https://github.com/nubenetes/jenkins-2026) infra repo, whose `main` is strict-GitFlow-protected (PR-from-`develop`-only) because it is human-reviewed.\n\u003e - Image-tag bumps here are machine-managed, not human-reviewed, so `main` must accept the CI's direct push.\n\n## Table of Contents\n- [Golden Path IDP Infrastructure](#golden-path-idp-infrastructure)\n- [Relationship to `jenkins-2026`](#relationship-to-jenkins-2026)\n- [Repository Layout](#repository-layout)\n- [How Image Tags Are Updated](#how-image-tags-are-updated)\n- [ArgoCD Applications](#argocd-applications)\n  - [`microservices` ApplicationSet](#microservices-applicationset)\n  - [Standalone Applications](#standalone-applications)\n- [Helm Chart: `helm/microservices`](#helm-chart-helmmicroservices)\n  - [Key values schema](#key-values-schema)\n  - [Environments](#environments)\n- [Postgres (CNPG)](#postgres-cnpg)\n- [NetworkPolicies (zero-trust)](#networkpolicies-zero-trust)\n- [Branch Strategy](#branch-strategy)\n  - [Why only the `main` branch?](#why-only-the-main-branch)\n  - [The `develop` branch — used by the optional develop tier](#the-develop-branch--used-by-the-optional-develop-tier)\n  - [`main` branch protection — CI-writable](#main-branch-protection--ci-writable-do-not-require-pull-requests)\n- [OTel Auto-Instrumentation](#otel-auto-instrumentation)\n- [Related Repositories](#related-repositories)\n- [Setup \u0026 Forking Guide](#setup--forking-guide)\n- [Release \u0026 Versioning Strategy](#release--versioning-strategy)\n- [Git History and Privacy](#git-history-and-privacy)\n- [Do Not Edit Manually](#do-not-edit-manually)\n\n## Golden Path IDP Infrastructure\n\nThis repository defines the GitOps state for the modernized **Internal Developer Platform (IDP)** architecture on GKE.\n\n### Decoupled Core Components\nIn alignment with 2026 Cloud-Native best practices, all platform infrastructure manifests are decoupled from CI build execution and versioned under the infra repo's `infrastructure/` directory. Some are GitOps-managed via ArgoCD; the ordering-sensitive ones (the `ComputeClass`, NetworkPolicies, the live per-app Gateway `HTTPRoute`s) are applied by the infra repo's idempotent scripts (`01-namespaces.sh`, `09-gateway.sh`) — see the infra repo's `docs/201-ARCHITECTURE.md` for the imperative-vs-GitOps split:\n* **Elastic Node Auto-Provisioning (NAP)**: GKE-native (GA) node auto-provisioning driven by a Custom `ComputeClass` under `infrastructure/compute-classes/` in the main repo, auto-creating **Spot, scale-to-zero** node pools for ephemeral build agents (the Google-supported equivalent of Karpenter — there is no production-ready Karpenter provider for GCP).\n* **GKE Gateway API Routing**: Secure HTTPS traffic routing for Jenkins and Headlamp is mapped under `infrastructure/gateway/` using native `Gateway`, `HTTPRoute`, and `BackendTLSPolicy` (zero-trust TLS to pods).\n* **Workload-Aware scheduling \u0026 Security**: `PodGroup` gang scheduling via the scheduler-plugins CRD (`scheduling.x-k8s.io/v1alpha1`, `infrastructure/scheduling/PodGroup.yaml`) plus a constrained-impersonation RBAC `ClusterRole` (resourceNames-scoped `impersonate` verbs, `infrastructure/headlamp/ImpersonationPolicy.yaml`) for Headlamp UI users.\n\n---\n\n## Relationship to `jenkins-2026`\n\n```\n+--------------------------------------------------------------------+\n|                nubenetes/jenkins-2026 (infra repo)                 |\n|                                                                    |\n|  scripts/        --- bootstrap cluster, install Jenkins/ArgoCD     |\n|  jenkins/        --- JCasC, Job DSL, shared pipeline library       |\n|  helm/           --- Helm charts for supporting services           |\n|  argocd/         --- ApplicationSet/Application manifests          |\n|  observability/  --- OTel collector, Grafana dashboards            |\n+------------------------+-------------------------------------------+\n                         | scripts/08.5-argocd.sh registers\n                         | THIS repo as ArgoCD source\n                         v\n+--------------------------------------------------------------------+\n|          nubenetes/jenkins-2026-gitops-config (this repo)          |\n|                                                                    |\n|  argocd/            --- Application / AppSet manifests (deployed   |\n|                         FROM infra repo, stored here for clarity)  |\n|  helm/microservices/--- Helm chart + env values files              |\n|    values-stable.yaml\u003c- active CI engine writes tags               |\n+--------------------------------------------------------------------+\n```\n\n| Action | Who does it | Where |\n|--------|------------|-------|\n| Bootstrap cluster \u0026 install ArgoCD | `scripts/08.5-argocd.sh` | `jenkins-2026` |\n| Register this repo in ArgoCD | `scripts/08.5-argocd.sh` | `jenkins-2026` |\n| Build \u0026 push container images | Active CI engine — one of four, selected by `ci.engine`: Jenkins (`MicroservicesPipeline`), Tekton, GitHub Actions/ARC, or Argo Workflows | `jenkins-2026/vars/`, `jenkins-2026/tekton/`, `jenkins-2026/jenkins/pipelines/seed/microservices-ci.yml.tmpl`, or `jenkins-2026/argoworkflows/` |\n| **Write image tag to values file** | Active CI engine — Jenkins (`vars/microservicesDeploy.groovy`), Tekton (`gitops-deploy` Task), GitHub Actions (rendered `microservices-ci` workflow's GitOps-bump step), or Argo Workflows (`gitops-deploy` step) | **this repo** |\n| Detect tag change \u0026 deploy to cluster | ArgoCD (automated sync) | cluster |\n| Grafana dashboard push | `scripts/07-grafana-dashboards.sh` | `jenkins-2026` |\n\n---\n\n## Repository Layout\n\n```\njenkins-2026-gitops-config/\n├── argocd/\n│   ├── microservices-appset.yaml   # ApplicationSet: generates microservices-stable Application\n│   ├── microservices-project.yaml  # AppProject: scope for the microservices Application\n│   ├── headlamp-app.yaml           # Application: Headlamp Kubernetes UI\n│   ├── pgadmin-app.yaml            # Application: pgAdmin 4 Postgres UI\n│   └── cnpg-app.yaml               # Application: CloudNative-PG Operator (CNPG)\n└── helm/\n    └── microservices/\n        ├── Chart.yaml                 # Helm chart metadata\n        ├── values.yaml                # Base defaults / schema documentation\n        ├── values-stable.yaml         # Stable env (namespace: microservices, branch: main)\n        ├── values-develop.yaml        # Dormant develop-tier values (only used if a develop track is re-enabled)\n        └── templates/\n            ├── deployment.yaml        # Deployment per service in .Values.services\n            ├── service.yaml           # ClusterIP Service\n            ├── ingress.yaml           # Ingress (enabled per platform)\n            ├── route.yaml             # Gateway API HTTPRoute / OpenShift Route (per platform)\n            ├── instrumentation.yaml   # OTel Instrumentation CR (auto-instruments JVM services)\n            ├── postgres.yaml          # CNPG Cluster \u0026 Pooler CR per service\n            ├── networkpolicies.yaml   # Zero-trust: default-deny + gateway / microservice / postgres policies\n            ├── logback-configmap.yaml # ECS-JSON structured-logging config\n            ├── gateway-cache-patch.yaml # gateway Hazelcast cache config\n            ├── limitrange.yaml        # Default container resource limits\n            ├── resourcequota.yaml     # Namespace resource cap\n            └── _helpers.tpl           # Shared template helpers\n```\n\n\u003e **Note**: the `argocd/` manifests here are **reference mirrors** and can lag the deployed reality — `scripts/08.5-argocd.sh` applies the copies in the **infra repo's** `argocd/` directory (where, e.g., `cnpg-operator` + `pgadmin` are now rendered by the `platform-postgres` app-of-apps and chart versions are pinned). The infra repo is authoritative for Application manifests; this repo is authoritative for `helm/microservices/`.\n\n---\n\n## How Image Tags Are Updated\n\nThe **active CI engine** — one of **four**, selected by `ci.engine` in the infra repo: **Jenkins** (default), **Tekton**, **GitHub Actions / ARC**, or **Argo Workflows** — updates the image tag here on every successful build. With Jenkins it is the `microservicesDeploy.groovy` shared-library step; with Tekton the `gitops-deploy` Task; with GitHub Actions the GitOps-bump step of the rendered `microservices-ci` workflow; with Argo Workflows the `gitops-deploy` step of the microservices WorkflowTemplate. All four clone this repo, bump the tag in the values file with `yq`, and push:\n\n```mermaid\nsequenceDiagram\n    autonumber\n    actor Jenkins as Active CI Pipeline (any of the 4 engines)\n    participant GitOps as jenkins-2026-gitops-config (Git)\n    participant ArgoCD as ArgoCD Server\n    participant Cluster as Kubernetes Cluster\n\n    Jenkins-\u003e\u003eGitOps: 1. Clone GitOps repo\n    Jenkins-\u003e\u003eGitOps: 2. Update tag in values-stable.yaml\n    Jenkins-\u003e\u003eGitOps: 3. git commit \u0026 push tag\n    Jenkins-\u003e\u003eArgoCD: 4. Sync microservices-stable application\n    ArgoCD-\u003e\u003eCluster: Reconcile manifests to new image tag\n    Cluster--\u003e\u003eArgoCD: Pods running \u0026 Healthy\n    ArgoCD--\u003e\u003eJenkins: Sync finished \u0026 Healthy\n```\n\nThe updated [`values-stable.yaml`](helm/microservices/values-stable.yaml) (or [`values-develop.yaml`](helm/microservices/values-develop.yaml)) is the **only file the CI engine ever modifies** in this repo — identically whichever of the four engines is active. Everything else is managed by humans or by `scripts/08.5-argocd.sh` in the infra repo. (Tekton itself is GitOps-managed by ArgoCD from the **infra** repo's `tekton/` + `argocd/tekton/`, not from here — this repo holds only the deployment target, which is CI-engine-agnostic. See [`docs/403-TEKTON.md`](https://github.com/nubenetes/jenkins-2026/blob/main/docs/403-TEKTON.md).)\n\n---\n\n## ArgoCD Applications\n\nAll Applications are **installed by `scripts/08.5-argocd.sh`** in the infra repo, from the **infra repo's own `argocd/` manifests**. The copies under [`argocd/`](argocd/) here are **non-authoritative reference copies** — nothing (ArgoCD or any script) consumes them, and they may lag the deployed versions; each file carries a header saying so. (The standalone CNPG/pgAdmin Applications below have since been superseded by the infra repo's `argocd/platform-postgres/` app-of-apps.)\n\n### `microservices` ApplicationSet\nGenerates the stable application:\n\n| Generated App | Namespace | Values file | Branch |\n|---------------|-----------|-------------|--------|\n| `microservices-stable` | `microservices` | [`values-stable.yaml`](helm/microservices/values-stable.yaml) | `main` |\n\n\u003e The stable app's `targetRevision` is templated (`{{branchStable}}`) with the infra **deploy branch** (`J2026_SELF_REPO_BRANCH`): `main` in production, but a `Day1` dispatched from the infra repo's `develop` branch points the stable app at this repo's `develop` branch to validate the whole platform before promotion.\n\nIt uses `prune: true` + `selfHeal: true`. Only the **stable** application is generated; the develop tier is **disabled by default** (the AppSet emits a `develop` element only when `microservices.developTrackEnabled` is set in the infra repo). The dormant [`values-develop.yaml`](helm/microservices/values-develop.yaml) stays in the chart for when that track is re-enabled — see [Branch Strategy](#branch-strategy).\n\n### Standalone Applications\n\n| Application | Source | Target Namespace | Notes |\n|-------------|--------|-----------------|-------|\n| `headlamp` | upstream `headlamp` chart + `helm/headlamp/values.yaml` (infra repo, multi-source) | `headlamp` | Kubernetes UI, Google OIDC |\n| `platform-postgres` (app-of-apps) | `argocd/platform-postgres/` (infra repo) | `argocd` | parent of the two rows below |\n| ├ `cnpg-operator` | `cloudnative-pg/cloudnative-pg` chart (version pinned in the infra repo's `argocd/platform-postgres/values.yaml`) | `cnpg-system` | ServerSideApply + Replace (huge CRDs) |\n| └ `pgadmin` | `helm/pgadmin/` (infra repo) | `pgadmin` | Postgres admin UI |\n\n---\n\n## Helm Chart: `helm/microservices`\n\nA single chart renders all services defined in `values.services.*`. Each service entry specifies its image tag and per-service config; the chart generates a `Deployment`, `Service`, `Instrumentation` CR, and `PostgresCluster` CR for each.\n\n### Key values schema\n\n```yaml\nglobal:\n  platform: gke          # gke | eks | aks | openshift\n\nnamespace: microservices  # overridden per-env by values-stable.yaml\nenv: stable               # \"stable\" → deployment.environment OTel attribute\nregistry: ghcr.io/nubenetes/jenkins-2026-microservices\nimagePullSecret: ghcr-credentials\n\notel:\n  collectorEndpoint: http://otel-collector-gateway.observability.svc.cluster.local:4317\n\nservices:\n  gateway:\n    type: java\n    image:\n      repository: gateway\n      tag: main-16        # ← the active CI engine bumps this via yq on every build (immutable `\u003cbranch\u003e-\u003cbuild#\u003e[-\u003csha8\u003e]` tag, not a bare SHA)\n    port: 8080\n    healthPath: /management/health\n    resources:\n      requests: { cpu: 100m, memory: 256Mi }\n      limits:   { cpu: 500m, memory: 512Mi }\n    env:\n      - name: SPRING_PROFILES_ACTIVE\n        value: prod,api-docs\n```\n\n### Environments\n\n| File | `env` | `namespace` | ArgoCD App |\n|------|-------|-------------|-----------|\n| [`values-stable.yaml`](helm/microservices/values-stable.yaml) | `stable` | `microservices` | `microservices-stable` |\n\nThe `env` value becomes the `deployment.environment` OTel resource attribute on every trace/metric/log emitted by deployed services, enabling environment filtering in Grafana dashboards.\n\n---\n\n## Postgres (CNPG)\n\nEach service in `.Values.services` gets CNPG `Cluster` and `Pooler` CRs templated by [`templates/postgres.yaml`](helm/microservices/templates/postgres.yaml) (the template ranges over **every** service unconditionally; per-service `postgres.storageSize` / `walStorageSize` are the only optional knobs). The CloudNative-PG Operator (installed via the `cnpg-operator` Application) reconciles these CRs into:\n\n- A highly-available **PostgreSQL 18.3** database tier — **3 instances**, zonal anti-affinity, dynamic primary promotion. The image is **pinned** explicitly (`spec.imageName`, default `ghcr.io/cloudnative-pg/postgresql:18.3-system-trixie`, overridable via `global.postgresImage`) so the DB version is reproducible; bump it deliberately\n- Connection pooling managed via native PgBouncer pooler deployments\n- Automated Barman Object Store backups targeting Google Cloud Storage (GCS)\n- Credentials from the auto-generated secret `postgres-\u003cservice\u003e-app` injected into the service pod via `SPRING_DATASOURCE_USERNAME`/`_PASSWORD` and `SPRING_R2DBC_USERNAME`/`_PASSWORD` secretKeyRefs; the corresponding `SPRING_DATASOURCE_URL`/`SPRING_R2DBC_URL` point at the `postgres-\u003cservice\u003e-pooler` Service (all traffic goes through PgBouncer)\n\nTwo clusters are provisioned in total — one per service in the stable environment:\n\n| Cluster | Namespace |\n|---------|-----------|\n| `postgres-gateway` | `microservices` |\n| `postgres-jhipstersamplemicroservice` | `microservices` |\n\n---\n\n## NetworkPolicies (zero-trust)\n\n[`templates/networkpolicies.yaml`](helm/microservices/templates/networkpolicies.yaml) ships a default-deny posture for the `microservices`\nnamespace (enforced by GKE **Dataplane V2 / Cilium-eBPF** in the infra repo). Four\npolicies:\n\n| Policy | Applies to | Key ingress | Key egress |\n|---|---|---|---|\n| `default-deny` | all pods | none | CoreDNS (`kube-system:53`) only |\n| `gateway-policy` | `gateway` pod | **8080** (from the Gateway/LB) | jhipster **8081**, its Postgres **5432**, OTLP `observability` **4317/4318** |\n| `microservice-policy` | `jhipstersamplemicroservice` pod | **8081** from the `gateway` pod **and** the four CI run namespaces — **`jenkins`, `tekton-ci`, `arc-runners`, `argo-ci`** (a selector for an absent namespace matches nothing, so listing inactive engines is harmless) — so CI smoke tests can hit `/management/health` | its Postgres **5432**, OTLP **4317/4318** |\n| `postgres-policy` | `cnpg.io/cluster` pods | **5432** from the app pods, `pgadmin` ns, intra-cluster | CNPG replication + **443** |\n\nThe CI-namespace ingress on 8081 is what lets the active engine's smoke/k6 stage reach the\nmicroservice under enforcement (see [`jenkins-2026` docs/501](https://github.com/nubenetes/jenkins-2026/blob/main/docs/501-PLATFORM_OPERATIONS.md#networkpolicy-matrix)).\n\n---\n\n## Branch Strategy\n\nThe GitOps repository uses the `main` branch to target `microservices-stable` deployments. The active CI engine (any of the four — Jenkins, Tekton, GitHub Actions/ARC, Argo Workflows) updates [`helm/microservices/values-stable.yaml`](helm/microservices/values-stable.yaml) on `main` to promote new image versions. The `develop` tier is **off by default** (only `microservices-stable` is generated); its [`values-develop.yaml`](helm/microservices/values-develop.yaml) is activated only when `microservices.developTrackEnabled` is set in the infra repo — see [The `develop` branch](#the-develop-branch--used-by-the-optional-develop-tier) below.\n\n### Why only the `main` branch?\n\n1. **Single Environment Target**: In this unified model the develop tier is disabled by default, leaving a single active target namespace (`microservices`); the develop track can be re-enabled (see below).\n2. **Simplified Promotion**: The active CI engine writes image tags directly inside [values-stable.yaml](helm/microservices/values-stable.yaml) on the `main` branch of the GitOps repository.\n\n### The `develop` branch — used by the optional develop tier\n\nA `develop` branch **exists and is wired in**: enabling `microservices.developTrackEnabled` in the infra repo (or the `develop_track` workflow input / `JENKINS2026_DEVELOP_TRACK_ENABLED`) makes the ApplicationSet generate a second `microservices-develop` Application that syncs [`values-develop.yaml`](helm/microservices/values-develop.yaml) from this repo's `develop` branch into the `microservices-develop` namespace, and the active CI engine pushes develop-tier tag bumps to `develop` instead of `main` (stable bumps always go to `main`). With the flag off (the default) only `main` is deployed from.\n\n---\n\n### `main` branch protection — CI-writable (do NOT require pull requests)\n\n`main` is **direct-push** so the CI's *GitOps Update* step can push image-tag bumps unattended. Actual `main` protection (GitHub -\u003e Settings -\u003e Branches):\n\n| Setting | Value | Why |\n|---|---|---|\n| Require a pull request before merging | **off** | The CI pushes tags straight to `main` (`git push origin main`). Require-PR rejects the PAT push (an admin PAT does **not** bypass protection) and **wedges every deploy**. |\n| Required status checks | **none** | Image-tag bumps are machine-generated — nothing to gate them on. |\n| Include administrators | **off** | — |\n| Allow force pushes | **off** | History on `main` is protected. |\n| Allow deletions | **off** | `main` cannot be deleted. |\n\n- **Allowed -\u003e `main`:** direct push (the CI's PAT, or a human pushing a chart/values edit).\n- **Forbidden -\u003e `main`:** force-push, branch deletion.\n\n\u003e WARNING: This is the **opposite** of the infra repo [`nubenetes/jenkins-2026`](https://github.com/nubenetes/jenkins-2026), whose `main` is **strict GitFlow** (require-PR from `develop` only, `gitflow-guard` required check, `enforce_admins=on`). The asymmetry is deliberate: the infra repo is human-reviewed, this repo is machine-managed. Full allowed/forbidden matrix: infra repo [`docs/101` -\u003e Branch protection \u0026 GitFlow promotion](https://github.com/nubenetes/jenkins-2026/blob/main/docs/101-GITHUB_ACTIONS_WORKFLOWS.md).\n\n## OTel Auto-Instrumentation\n\nThe [`templates/instrumentation.yaml`](helm/microservices/templates/instrumentation.yaml) template creates an `Instrumentation` CR (managed by the OTel Operator, installed by `scripts/02-otel-operator.sh`; the collector it exports to is installed by `scripts/03-observability.sh`). This automatically attaches the OTel Java agent to every Spring Boot service pod via a mutating webhook — no changes to application code or Docker images are required.\n\nThe agent is configured with:\n- `OTEL_EXPORTER_OTLP_ENDPOINT` → the in-cluster OTel Collector gateway\n- `OTEL_RESOURCE_ATTRIBUTES` → `deployment.environment`, `service.namespace` (`service.name` is set per service via `OTEL_SERVICE_NAME` in the Deployment template)\n- `OTEL_INSTRUMENTATION_LOGBACK_APPENDER_ENABLED=true` → injects `trace_id` into log lines for Loki correlation\n\n---\n\n## Related Repositories\n\n| Repository | Role |\n|-----------|------|\n| [`nubenetes/jenkins-2026`](https://github.com/nubenetes/jenkins-2026) | **Infra repo** — cluster bootstrap, Jenkins, ArgoCD, Observability, shared pipeline library |\n| [`nubenetes/jenkins-2026-gitops-config`](https://github.com/nubenetes/jenkins-2026-gitops-config) | **This repo** — GitOps state: Helm chart, env values, ArgoCD manifests |\n| [`nubenetes/jhipster-sample-app-gateway`](https://github.com/nubenetes/jhipster-sample-app-gateway) | **App source** — the JHipster **gateway** (Java / Spring Boot; it *serves* the Angular SPA, it is not itself an Angular app), built as the `gateway` service. Fork of upstream [`jhipster/jhipster-sample-app-gateway`](https://github.com/jhipster/jhipster-sample-app-gateway) (the fork carries a real `develop` branch for branch-based promotion). |\n| [`nubenetes/jhipster-sample-app-microservice`](https://github.com/nubenetes/jhipster-sample-app-microservice) | **App source** — the JHipster backend **microservice**, built as `jhipstersamplemicroservice`. Fork of upstream [`jhipster/jhipster-sample-app-microservice`](https://github.com/jhipster/jhipster-sample-app-microservice). |\n\n---\n\n## Setup \u0026 Forking Guide\n\nIf you are setting up this PoC for yourself or your organization, you must fork this configuration repository along with the main [infrastructure repository](https://github.com/nubenetes/jenkins-2026).\n\n1. **Fork the Repository**: Fork this repository (`jenkins-2026-gitops-config`) to your GitHub account/organization.\n2. **Update Main Infra Configuration**: In your fork of the infra repository (`jenkins-2026`), update `config/config.yaml`:\n   - `gitops.repoUrl` → your fork of **this** repository (e.g. `https://github.com/\u003cyou\u003e/jenkins-2026-gitops-config.git`). This single knob repoints the ArgoCD ApplicationSet **and** all four CI engines' image-tag-bump stages — no script/manifest edits needed. Per-run override: the `JENKINS2026_GITOPS_REPO_URL` env var. See the infra repo's `docs/502-MICROSERVICES_GITOPS.md` § *Repointing the GitOps repo*.\n   - `jenkins.selfRepoUrl` and `microservices.git.org` → your own infra/app forks.\n3. **Configure Git Credentials**: Ensure you set `GIT_USERNAME` and `GIT_TOKEN` secrets in the infra repository Actions settings, as the active CI engine's pipeline dynamically clones and commits updated image tags to this GitOps repository — the token must have push access to your `gitops.repoUrl` fork.\n\n---\n\n## Release \u0026 Versioning Strategy\n\nThis repository is versioned **independently** of the infra repo — it keeps its own `v0.9.x` line while `jenkins-2026` is on `v1.x`. There is deliberately **no lockstep**: ArgoCD tracks this repo by **branch**, not tag, and ~90% of commits are machine-written image-tag bumps, so infra release milestones do not map onto this repo.\n\n* **Git Tags**: a `v0.9.N` tag + GitHub Release is cut only when a meaningful chart/manifest milestone lands here.\n* **Release Flow**: human chart/config changes are tested on `develop` and merged to `main` via PR (CI tag bumps bypass this and push straight to `main`); the tag is then pushed and a Release drafted.\n\n---\n\n## Git History and Privacy\n\n\u003e [!NOTE]\n\u003e This repository's Git history has been fully rewritten and sanitized to remove any private Google identity email addresses and account IDs.\n\u003e When collaborating or contributing to this repository, please configure your local Git author settings to use GitHub's private email alias (e.g., `username@users.noreply.github.com`) to avoid accidentally leaking private email addresses in future commits.\n\n---\n\n## Do Not Edit Manually\n\n\u003e [!CAUTION]\n\u003e [`helm/microservices/values-stable.yaml`](helm/microservices/values-stable.yaml) is **continuously overwritten by the active CI engine** on every successful build. Manual edits to `services.\u003cname\u003e.image.tag` will be overwritten by the next pipeline run. All other fields (resources, env vars, healthPath) are safe to edit.\n\nFor all other infrastructure changes — Jenkins config, observability stack, ArgoCD setup, Helm charts for Headlamp/pgAdmin — make changes in [`nubenetes/jenkins-2026`](https://github.com/nubenetes/jenkins-2026) and re-run the relevant script or GitHub Actions workflow.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnubenetes%2Fjenkins-2026-gitops-config","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnubenetes%2Fjenkins-2026-gitops-config","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnubenetes%2Fjenkins-2026-gitops-config/lists"}