summaryrefslogtreecommitdiff
path: root/doc/jenkins-cpp-build.md
blob: 31d88e2d5731f6e7a5b3d4eef413ff4b5be1ec46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# Building a C++ App in Jenkins (Docker Agent)

Step-by-step guide to set up a Jenkins pipeline that builds a C++ project
using a Docker container as the build agent (DooD).


## 1. Push your C++ project to the git server

On the server, create a bare repo:

```bash
cd /var/git/repos
git init --bare my-cpp-app.git
chown -R 1000:1000 my-cpp-app.git
```

From your local machine, push your code:

```bash
cd /path/to/my-cpp-app
git init
git remote add origin ssh://git@<server-ip>/repos/my-cpp-app.git
git add .
git commit -m "Initial commit"
git push -u origin master
```


## 2. Add a Jenkinsfile to your project

Create a file called `Jenkinsfile` in the root of your C++ project.

### Simple build (g++ directly)

```groovy
pipeline {
    agent {
        docker { image 'gcc:latest' }
    }

    stages {
        stage('Build') {
            steps {
                sh 'g++ -o my_app main.cpp'
            }
        }

        stage('Test') {
            steps {
                sh './my_app'
            }
        }
    }
}
```

Adjust the `g++` command to match your source files.

### CMake build

```groovy
pipeline {
    agent {
        docker { image 'gcc:latest' }
    }

    stages {
        stage('Configure') {
            steps {
                sh 'cmake -B build -S .'
            }
        }

        stage('Build') {
            steps {
                sh 'cmake --build build'
            }
        }

        stage('Test') {
            steps {
                sh 'cd build && ctest --output-on-failure'
            }
        }
    }
}
```

> Note: The `gcc:latest` image includes `g++`, `gcc`, `make`, and `cmake`.
> If you need extra libraries (e.g., Boost), you can use a custom image or
> add `apt-get install` steps.

Commit and push the Jenkinsfile:

```bash
git add Jenkinsfile
git commit -m "Add Jenkinsfile for CI"
git push
```


## 3. Create the Jenkins pipeline job

1. Open Jenkins at `https://jenkins.swave.lol` (or `https://swave.lol/jenkins`)
2. Click **New Item** (top-left)
3. Enter a name, e.g. `my-cpp-app`
4. Select **Pipeline**, then click **OK**


## 4. Configure the pipeline source

On the job configuration page:

1. Scroll down to the **Pipeline** section
2. Change **Definition** from "Pipeline script" to **Pipeline script from SCM**
3. Set **SCM** to **Git**
4. In **Repository URL**, enter: `git://git-server/my-cpp-app.git`
   - This works because Jenkins and git-server are on the same `jenkins_network` (172.23.0.0/16)
   - `git-server` resolves to `172.23.0.3` via Docker DNS
   - The git daemon protocol (`git://`) on port 9418 requires no credentials
   - Alternative: `ssh://git@git-server/repos/my-cpp-app.git` (requires SSH key setup in Jenkins)
5. Set **Branch Specifier** to `*/master` (or `*/main`, whatever your default branch is)
6. **Script Path**: leave as `Jenkinsfile` (default)
7. Click **Save**


## 5. Run the build

1. On the job page, click **Build Now** (left sidebar)
2. A build number will appear under **Build History** — click it
3. Click **Console Output** to watch the build live

You will see Jenkins:
- Pull the `gcc:latest` Docker image (first time only)
- Spin up a temporary container on the host (DooD via `/var/run/docker.sock`)
- Clone your repo inside the container
- Run each stage (`Build`, `Test`)
- Destroy the container when done


## 6. Automatic builds (optional)

### Option A — Poll SCM

1. Go to job config (**Configure**)
2. Under **Build Triggers**, check **Poll SCM**
3. Set schedule, e.g. `H/5 * * * *` (check every 5 minutes)
4. Click **Save**

### Option B — Git post-receive hook

Create a hook that notifies Jenkins immediately on push:

```bash
cat > /var/git/repos/my-cpp-app.git/hooks/post-receive << 'HOOK'
#!/bin/bash
curl -s "http://jenkins:8080/jenkins/git/notifyCommit?url=git://git-server/my-cpp-app.git" > /dev/null 2>&1 &
HOOK
chmod +x /var/git/repos/my-cpp-app.git/hooks/post-receive
```

This requires the **Git plugin** and **Poll SCM** to be enabled in the job
config (the schedule can be empty, e.g. just `H * * * *`).


## How DooD works

Jenkins is configured with Docker-out-of-Docker: it mounts the host's
`/var/run/docker.sock` into the Jenkins container. When the pipeline runs
`docker { image 'gcc:latest' }`, Jenkins creates a **sibling container** on
the host (not nested), runs the build steps inside it, and removes it after.
The Jenkins container never needs compilers installed — everything runs in the
ephemeral `gcc` container.