k8s-portal: build off-infra GHA -> ghcr + Keel; remove Woodpecker build (no-local-builds)
Some checks failed
ci/woodpecker/push/default Pipeline was canceled
Some checks failed
ci/woodpecker/push/default Pipeline was canceled
The last in-cluster image build. GHA build-k8s-portal.yml builds ghcr.io/viktorbarzin/k8s-portal:latest+sha (path-filtered on the Dockerfile dir); Keel (force/poll/match-tag) rolls the deployment. Stack image repointed to ghcr (ignore_changed); .woodpecker/k8s-portal.yml deleted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
9501da81a0
commit
b906f61ac3
3 changed files with 50 additions and 53 deletions
36
.github/workflows/build-k8s-portal.yml
vendored
Normal file
36
.github/workflows/build-k8s-portal.yml
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
name: Build k8s-portal
|
||||
|
||||
# ADR-0002 / no-local-builds: k8s-portal (infra-owned Go portal) builds off-infra
|
||||
# on GHA → public ghcr; Keel polls ghcr:latest and rolls the deployment. Replaces
|
||||
# the in-cluster .woodpecker/k8s-portal.yml build.
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'stacks/platform/modules/k8s-portal/files/**'
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: stacks/platform/modules/k8s-portal/files
|
||||
platforms: linux/amd64
|
||||
provenance: false
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/viktorbarzin/k8s-portal:latest
|
||||
ghcr.io/viktorbarzin/k8s-portal:${{ github.sha }}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
when:
|
||||
event: push
|
||||
branch: master
|
||||
path:
|
||||
include:
|
||||
- "stacks/platform/modules/k8s-portal/files/**"
|
||||
|
||||
clone:
|
||||
git:
|
||||
image: woodpeckerci/plugin-git
|
||||
settings:
|
||||
attempts: 5
|
||||
backoff: 10s
|
||||
|
||||
steps:
|
||||
- name: build-and-push
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
username: "viktorbarzin"
|
||||
password:
|
||||
from_secret: dockerhub-pat
|
||||
repo: viktorbarzin/k8s-portal
|
||||
dockerfile: stacks/platform/modules/k8s-portal/files/Dockerfile
|
||||
context: stacks/platform/modules/k8s-portal/files
|
||||
platforms:
|
||||
- linux/amd64
|
||||
tag: ["${CI_PIPELINE_NUMBER}", "latest"]
|
||||
cache_from: "viktorbarzin/k8s-portal:latest"
|
||||
cache_to: "type=inline"
|
||||
|
||||
- name: deploy
|
||||
image: bitnami/kubectl:latest
|
||||
commands:
|
||||
- "kubectl set image deployment/k8s-portal portal=viktorbarzin/k8s-portal:${CI_PIPELINE_NUMBER} -n k8s-portal"
|
||||
- "kubectl rollout status deployment/k8s-portal -n k8s-portal --timeout=120s"
|
||||
- "echo 'k8s-portal deployed successfully (build ${CI_PIPELINE_NUMBER})'"
|
||||
|
||||
- name: slack
|
||||
image: curlimages/curl
|
||||
commands:
|
||||
- |
|
||||
curl -s -X POST -H 'Content-type: application/json' \
|
||||
--data "{\"text\":\"K8s Portal: build #${CI_PIPELINE_NUMBER} ${CI_PIPELINE_STATUS}\"}" \
|
||||
"$SLACK_WEBHOOK" || true
|
||||
environment:
|
||||
SLACK_WEBHOOK:
|
||||
from_secret: slack_webhook
|
||||
when:
|
||||
status: [success, failure]
|
||||
|
|
@ -9,7 +9,7 @@ resource "kubernetes_namespace" "k8s_portal" {
|
|||
metadata {
|
||||
name = "k8s-portal"
|
||||
labels = {
|
||||
tier = var.tier
|
||||
tier = var.tier
|
||||
"keel.sh/enrolled" = "true"
|
||||
}
|
||||
}
|
||||
|
|
@ -40,6 +40,15 @@ resource "kubernetes_deployment" "k8s_portal" {
|
|||
metadata {
|
||||
name = "k8s-portal"
|
||||
namespace = kubernetes_namespace.k8s_portal.metadata[0].name
|
||||
# ADR-0002 / no-local-builds: image now GHA-built -> ghcr:latest
|
||||
# (.github/workflows/build-k8s-portal.yml). Keel polls ghcr:latest and rolls
|
||||
# this deployment (replaces the removed Woodpecker in-cluster build+deploy).
|
||||
annotations = {
|
||||
"keel.sh/policy" = "force"
|
||||
"keel.sh/trigger" = "poll"
|
||||
"keel.sh/pollSchedule" = "@every 5m"
|
||||
"keel.sh/match-tag" = "true"
|
||||
}
|
||||
labels = {
|
||||
app = "k8s-portal"
|
||||
tier = var.tier
|
||||
|
|
@ -68,7 +77,7 @@ resource "kubernetes_deployment" "k8s_portal" {
|
|||
spec {
|
||||
container {
|
||||
name = "portal"
|
||||
image = "viktorbarzin/k8s-portal:latest"
|
||||
image = "ghcr.io/viktorbarzin/k8s-portal:latest"
|
||||
port {
|
||||
container_port = 3000
|
||||
}
|
||||
|
|
@ -121,7 +130,8 @@ resource "kubernetes_deployment" "k8s_portal" {
|
|||
# DRIFT_WORKAROUND: CI pipeline owns image tag (kubectl set image from Woodpecker/GHA); Kyverno mutates dns_config for ndots. Reviewed 2026-04-18.
|
||||
ignore_changes = [
|
||||
spec[0].template[0].spec[0].dns_config, # KYVERNO_LIFECYCLE_V1
|
||||
spec[0].template[0].spec[0].container[0].image, # CI updates image tag
|
||||
spec[0].template[0].spec[0].container[0].image, # Keel manages ghcr:latest digest
|
||||
metadata[0].annotations["keel.sh/update-time"], # KEEL_LIFECYCLE_V1 (Keel stamps on roll)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -172,5 +182,5 @@ module "ingress_setup_script" {
|
|||
ingress_path = ["/setup/script", "/agent"]
|
||||
tls_secret_name = var.tls_secret_name
|
||||
# auth = "none": Setup script + agent endpoint must be curl-able without auth (no cookies preserved in automation).
|
||||
auth = "none"
|
||||
auth = "none"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue