Adding a Project¶
Once Jenkins is running, onboarding a new repo is minimal. Jenkins auto-discovers any repo
containing a Jenkinsfile — no Jenkins UI configuration required for each new project.
Steps¶
1. Add a Jenkinsfile to the repo¶
With shared library (recommended):
detectAgent() picks the right build environment automatically based on files in the repo.
No agent declaration needed:
Or with explicit stages:
@Library('shared') _
pipeline {
agent { script { detectAgent() } }
stages {
stage('Test') { steps { runTests() } }
stage('Update Changelog') { when { branch 'main' }
steps { generateChangelog() } }
stage('Deploy Docs') { when { branch 'main' }
steps { deployMkdocs() } }
}
}
Without shared library (manual):
Single language — use a pre-defined label:
Multi-language in different stages — agent none with per-stage labels:
pipeline {
agent none
stages {
stage('Backend') { agent { label 'python-3.14' } steps { sh 'pytest' } }
stage('Frontend') { agent { label 'node-20' } steps { sh 'npm test' } }
}
}
Multi-language in the same stage — add a Dockerfile.ci to the repo root (see below).
Before the shared library is ready, use the full Jenkinsfile from pipeline.md
and update the repo name in the git remote URL lines.
1a. Add a Dockerfile.ci (multi-language projects only)¶
If the project needs more than one runtime available simultaneously within a single build stage,
add a Dockerfile.ci to the repo root. Jenkins builds this image on first run and caches it —
no changes to casc.yml or magi required.
# Python + Node
FROM python:3.14
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs
# Java + Python
FROM maven:3.9-eclipse-temurin-21
RUN apt-get update && apt-get install -y python3 python3-pip
# Go + Node
FROM golang:1.22
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs
detectAgent() automatically uses Dockerfile.ci when it exists, taking priority over
all label detection.
2. Add a cliff.toml (for changelog generation)¶
[changelog]
header = "# Changelog\n"
body = """
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits %}
- {{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}](https://github.com/<your-github-username>/{{ package }}/commit/{{ commit.id }}))
{% endfor %}
{% endfor %}
"""
trim = true
[git]
conventional_commits = true
filter_unconventional = true
commit_parsers = [
{ message = "^feat", group = "Features" },
{ message = "^fix", group = "Bug Fixes" },
{ message = "^docs", group = "Documentation" },
{ message = "^refactor", group = "Refactoring" },
{ message = "^chore", group = "Chores" },
{ message = "^ci", skip = true },
]
filter_commits = true
tag_pattern = "v[0-9].*"
ignore_tags = ""
topo_order = false
sort_commits = "newest"
3. Push to GitHub¶
Push the Jenkinsfile (and cliff.toml) to any branch. The GitHub Organization Folder job
scans for new repos on a schedule and also responds to webhooks — a job for the new repo
appears in Jenkins within minutes.
4. Verify¶
Open Jenkins → <your-github-username> → your new repo. You should see a branch job for
the branch you just pushed to. Click it to see the build.
Per-project credentials (optional)¶
If a project needs its own secrets beyond the global jenkins-ci-app credential:
- In Jenkins, navigate to the project's folder:
<your-github-username>→<repo-name> - Credentials → Add Credentials (folder-scoped, not global)
- Reference the credential ID in that project's
JenkinsfileviawithCredentials
Folder-scoped credentials are only accessible to jobs within that folder, preventing cross-project credential leakage.
Conventional Commits¶
All commits to repos on this platform should follow Conventional Commits format for automated changelog generation:
feat: add user authentication
fix: resolve login timeout issue
docs: update API reference
refactor: simplify archive logic
chore: update dependencies
ci: adjust test timeout
The ci: prefix is filtered out of changelogs by cliff.toml. [skip ci] in a commit
message prevents Jenkins from triggering a build on that commit.