# devops-lib Jenkins Shared Library for this homelab's CI/CD pipeline. Adapted from a much larger, company-wide library — everything not needed for a single-node homelab (GKE/EKS, JFrog, S3, Sonar, org-specific BU/team validation, and ~65 other files covering languages/deploy-targets this setup never uses) has been removed rather than carried along unused; see git history if any of that is ever worth reviving. ## Using it in a service repo The entire Jenkinsfile is 2 lines: ```groovy @Library('devops-lib') _ homelabPipeline(repo_name: 'my-service') ``` `repo_name` is the only required key. Everything else has a sensible default — override any of them by passing extra keys to `homelabPipeline`, or by committing a `config.yaml` to the service repo's own root (merged in after checkout; repo-committed values win over the Jenkinsfile call). | Key | Default | Notes | |---|---|---| | `service_name` | `repo_name` | Second path segment under `devops-helm-charts/values/` | | `argo_app_name` | `repo_name` | Must match the ArgoCD Application's `metadata.name` | | `harbor_project` | `homelab` | Must be an existing, public Harbor project | | `helm_repo_url` | `devops-helm-charts` on this Gitea | — | | `image_tag_yq_path` | `.deployment.image.tag` | **Override this if the app's chart isn't `1.0.0`** — e.g. `sts-2.0.0` uses `.podtemplate.image.tag` instead. Getting this wrong doesn't fail loudly: `yq -i` creates the path if missing rather than erroring, silently leaving the real field un-bumped. | | `dockerBuildVersion` | none | Only read when the repo has **no Dockerfile of its own** — picks a fallback template (see below). No default; either ship a Dockerfile or set this. | ## Pipeline stages `checkOut → loadConfig → runHooks(pre_build) → buildDocker → runHooks(post_build) → updateHelmTag → syncArgoApp → notify`, all inside a `podTemplate` (`resources/org/homelab/dind-pod.yaml`) via `node(POD_LABEL) { ... }`. - **`loadConfig`** — if the repo has a `config.yaml` at its root, its keys are merged into the pipeline config (repo values win). - **`runHooks`** — reads `config.yaml`'s `hooks.pre_build`/`hooks.post_build` lists, each `{name, script, interpreter, requirements, blocking, timeout_seconds}`. Blocking by default; `blocking: false` demotes a failure to advisory (log + continue). Script paths must be repo-relative (no `..`, no absolute paths). - **`buildDocker`** — uses the repo's own `Dockerfile` if present; otherwise renders one from `resources/com/homelab/-Dockerfile` based on `dockerBuildVersion` (e.g. `go-1.22`, `node-20`, `python-3.12`, `java-21`, `php-8.3`). All fallback templates pull base images from Harbor's `base-images` project (mirrored via the separate `devops-base-images` repo), not Docker Hub directly. - **`updateHelmTag`** — clones `devops-helm-charts`, bumps the image tag via `yq` at `image_tag_yq_path`, commits, pushes to `main`. - **`syncArgoApp`** — calls the ArgoCD REST API to sync `argo_app_name`. ## Adding a new language's fallback template 1. Add the base image to `devops-base-images/images.txt`, re-mirror it into Harbor. 2. Add `resources/com/homelab/-Dockerfile`, parametrized by `${version}` (rendered via `constructTemplate.groovy`'s `SimpleTemplateEngine` wrapper). 3. Add a case for it in `buildDocker.groovy`'s `templates` map. ## Build-tools image `resources/org/homelab/build-tools.Dockerfile` bakes git/yq/bash/ python3+pip/venv/curl into the `docker-cli` container's image, so nothing gets installed on demand on every single build. Built and pushed manually (not through any Jenkins job) — see that file's own header comment.