Files
devops-lib-gcp/vars/homelabPipeline.groovy
Mukul SharmaandClaude Opus 5 a9119d7b8e Push to apps-registry, the project that exists on this Harbor
The homelab pushes to a project called "homelab"; this cluster's is
apps-registry. Harbor rejects a push to a missing project with
"unauthorized: project homelab not found" — the word unauthorized sends
you looking at the robot account, when the credentials were never the
problem.

Only the harbor_project default changes. The com/homelab and org/homelab
paths in this repo are the library's own package and resource paths and
have nothing to do with the registry; renaming those would break the
library.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-13 08:02:13 +05:30

80 lines
4.2 KiB
Groovy

// New entry point — the homelab equivalent of the real devops-lib's
// buildPipeline.groovy. Same shape: a scripted pipeline global, so a
// service Jenkinsfile needs nothing but `@Library('devops-lib') _` plus
// one call to this — no pipeline{}/agent{}/stages{} block in the
// consuming repo at all, matching gkeCICD.groovy's Podcall precedent
// (podTemplate { node(POD_LABEL) { ... } }) rather than the declarative
// style the earlier version of this Jenkinsfile template used.
//
// Only repo_name is required — everything else defaults sensibly for a
// single-service repo on this one homelab cluster. Override any key by
// passing it explicitly, same as the real buildPipeline's param map, or
// by committing a config.yaml to the repo root (loadConfig merges it in
// after checkout — repo-committed values win over these defaults, same
// as the real system's config.yaml).
//
// dockerBuildVersion (e.g. 'go-1.22', 'node-20', 'python-3.12', 'java-21',
// 'php-8.3') is read by buildDocker.groovy only when the repo has no
// Dockerfile of its own — it picks which resources/com/homelab/<lang>-
// Dockerfile template to render and which base-image version to bake in.
// Repos that already ship a Dockerfile (like demo-go-app) never touch
// this key at all; it has no default because there's no sensible one to
// fall back to.
def call(Map config) {
config.service_name = config.service_name ?: config.repo_name
config.argo_app_name = config.argo_app_name ?: config.repo_name
// The Harbor project images are pushed to. Named apps-registry on this
// cluster, not the homelab's "homelab" — the project has to already
// exist, and Harbor rejects a push to a missing one with
// "unauthorized: project <name> not found", which reads like a
// credentials problem rather than a missing project.
config.harbor_project = config.harbor_project ?: 'apps-registry'
// Cluster DNS, not the ingress hostname: this clone happens from a build
// pod, so it is pod-to-pod traffic and has no business leaving the
// cluster and coming back in through Contour.
config.helm_repo_url = config.helm_repo_url ?: 'http://gitea-http.gitea.svc.cluster.local:3000/gitadmin/devops-helm-charts-gcp.git'
config.image_tag_yq_path = config.image_tag_yq_path ?: '.deployment.image.tag'
// Every stage file (both the ones adapted for this homelab and the
// untouched legacy ones carried over from the real devops-lib) reads
// `env.FAILURE` when setting currentBuild.result on error — the real
// system must define this as a global Jenkins environment variable
// somewhere upstream of buildPipeline.groovy, since it's referenced
// everywhere but never set anywhere in this repo. Left undefined,
// `env.FAILURE` is null, and `currentBuild.result = null` throws
// `NoSuchMethodError`/`NullPointerException` deep inside Jenkins'
// own result-normalization code — masking whatever the real error
// was. Defining it once here, before any stage runs, is the minimal
// fix rather than touching every individual stage file.
env.FAILURE = 'FAILURE'
podTemplate(yaml: libraryResource('org/homelab/dind-pod.yaml')) {
node(POD_LABEL) {
def checkOutObj = new com.homelab.stages.checkOut()
def loadConfigObj = new com.homelab.stages.loadConfig()
def runHooksObj = new com.homelab.stages.runHooks()
def buildDockerObj = new com.homelab.stages.buildDocker()
def updateHelmTagObj = new com.homelab.stages.updateHelmTag()
def syncArgoAppObj = new com.homelab.stages.syncArgoApp()
def notifyObj = new com.homelab.stages.notify()
try {
checkOutObj.run(config)
loadConfigObj.run(config)
runHooksObj.run(config, 'pre_build')
buildDockerObj.run(config)
runHooksObj.run(config, 'post_build')
updateHelmTagObj.run(config)
syncArgoAppObj.run(config)
}
catch (Exception e) {
currentBuild.result = 'FAILURE'
log.error(e.toString())
}
finally {
notifyObj.run(config)
}
}
}
}