Skip to content

Latest commit

 

History

History
261 lines (203 loc) · 8.05 KB

File metadata and controls

261 lines (203 loc) · 8.05 KB

Hacking documentation

This document explains how to develop on this repository.

Requirements

  • A Bourne-Again-Shell compatible prompt (bash)

  • GNU make 3.80+

  • Docker with BuildX capability

    • Docker 20.10+ is recommended as it is usually packaged with Buildx

    • Docker 19.03+ is required

    • BuildX v0.5.1+ is needed (manual installation of the plugin can be done if you don’t have it: https://github.com/docker/buildx)

  • git 1.6+ (git 2+ is recommended)

  • jq 1.6+

  • curl 7+

We recommend GNU Parallel for parallel test execution, but it is not required.

Tests currently do not work on Mac M1 due to a known issue in 'Docker Desktop 3.4.0'.

Building

Linux

## build all linux platforms
make build

## only build a specific linux image
make build-debian_jdk17 # or build-alpine_jdk17 build-debian_slim_jdk17 build-debian_jdk17 ...

Testing

Linux

Tests for Linux images are written using bats under the tests/ directory.

Tests pre-requisites are automatically managed by the make prepare-test target (dependency of any make test* target) which:

  • Ensures that the bats command is installed in the bats/bin/ directory (along with all the bats project in ./bats/)

  • Ensures that the additional bats helper are installed as git sub-modules in ./tests/test_helper/

For efficiency, the tests are executed in parallel.

Important
Due to the parallel execution, each test should be self-contained and not depend on another test, even inside a given test harness.

Please note that:

  • You can disable the parallel execution by setting the environment variable DISABLE_PARALLEL_TESTS to the value true

  • Parallel execution is disabled if the commands docker or (GNU) parallel are not installed.

You can restrict the execution to only a subset of test harness files. By setting the environment variable TEST_SUITES to the path of the bats test harness file to execute alone.

## Run tests for all linux platforms
make test

## Run tests for a specific linux platform
make test-debian_jdk17 # or test-alpine_jdk17 test-debian_slim_jdk17 test-debian_jdk17 ...

## Run tests for Alpine Linux JDK17 platform in sequential mode
DISABLE_PARALLEL_TESTS=true make test-alpine_jdk17

## Only run the test suite `functions.bats` for the Debian JDK21 platform
TEST_SUITES=./tests/functions.bats make test-debian_jdk21

You can also pass extra parameters to bats by setting BATS_FLAGS.

Example:

## Run tests except those with a "test-type:golden-file" `bats` tag
make test BATS_FLAGS="--filter-tags '\!test-type:golden-file'"

## Add an extra parameter
make test BATS_FLAGS="--filter-tags '\!test-type:golden-file' --verbose-run"

See https://bats-core.readthedocs.io/en/stable/usage.html for the list of bats options.

Golden files

A golden file (sometimes called a snapshot) is a file that contains the expected output of a program or function. Tests compare the current output of the code against this "golden" reference to detect regressions or unintended changes. They are treated as contract artifacts, not test fixtures.

Golden files may be updated only when:

  • Output behavior is intentionally changed

  • A bug fix corrects previously incorrect output

  • A new test case is added

Golden updates must be reviewed like code.

If your work implies golden file changes, those changes must be committed: * In the same commit as the behavior change * With a commit message explaining why output changed

Golden updates must never be automatic.

How to update a golden file

  • Reproduce output manually

  • Inspect output

  • Update the golden file explicitly

  • Run tests

To update a golden file, you can use the dedicated ./tests/update-golden-file.sh helper script.

Example if there are new LTS tags:

./tests/update-golden-file.sh expected_tags_latest_lts make tags LATEST_LTS=true

Then ensure corresponding tests are passing with:

bats ./tests/tags.bats

Multiarch support

The buildx tool is used to build our multiarch images, this relies on either QEMU for emulating the architecture being built, or a remote builder configured for the required platform(s).

Planned supported architectures:

  • amd64

  • arm64

  • s390x

Debugging

In order to debug the controller, use the -e DEBUG=true -p 5005:5005 when starting the container. Jenkins will be suspended on the startup in such case, and then it will be possible to attach a debugger from IDE to it.

Test images publication

You can test the script used for publication in dry-run by setting an existing Jenkins Core version and by passing the -n option:

$ export JENKINS_VERSION=2.528.3
$ ./.ci/publish.sh -n
Dry run, will not publish images
Using the following settings:
* JENKINS_REPO: jenkins/jenkins
* JENKINS_VERSION: 2.528.3
* COMMIT_SHA: 1c72a9383191562eb3c44838aeeadad0839c2c92
* LATEST_WEEKLY: false
* LATEST_LTS: true
* BUILD_METADATA_PATH: target/build-result-metadata_linux_dry-run.json
[+] Building 104.6s (59/73)
<...snip...>

Note that if you can set BAKE_TARGET to test the publication of a single target instead the default "linux" multiarch (heavy) build:

$ export BAKE_TARGET=debiand_jdk25
$ ./.ci/publish.sh -n
Using the following settings:
* JENKINS_REPO: jenkins/jenkins
* JENKINS_VERSION: 2.528.3
* COMMIT_SHA: aaf4e7faf887b7ac4879c3bf540ede48220cca9f
* LATEST_WEEKLY: false
* LATEST_LTS: true
* BUILD_METADATA_PATH: target/build-result-metadata_debian_jdk25_dry-run.json
* BAKE TARGET: debian_jdk25
* BUILDX OPTIONS:
  --pull
  --set=*.output=type=cacheonly
  --metadata-file=target/build-result-metadata_debian_jdk25_dry-run.json

* RESOLVED BAKE CONFIG:
{
  "group": {
    "default": {
      "targets": [
        "debian_jdk25"
      ]
    }
  },
  "target": {
    "debian_jdk25": {
      "context": ".",
      "dockerfile": "debian/Dockerfile",
      "args": {
        "COMMIT_SHA": "aaf4e7faf887b7ac4879c3bf540ede48220cca9f",
        "DEBIAN_RELEASE_LINE": "trixie",
        "DEBIAN_VARIANT": "",
        "DEBIAN_VERSION": "20251117",
        "JAVA_VERSION": "25.0.1_8",
        "JENKINS_VERSION": "2.528.3",
        "PLUGIN_CLI_VERSION": "2.13.2",
        "WAR_URL": "https://get.jenkins.io/war-stable/2.528.3/jenkins.war"
      },
      "tags": [
        "docker.io/jenkins/jenkins:2.528.3-jdk25",
        "docker.io/jenkins/jenkins:lts-jdk25",
        "docker.io/jenkins/jenkins:2.528.3-lts-jdk25"
      ],
      "platforms": [
        "linux/amd64",
        "linux/arm64",
        "linux/s390x",
        "linux/ppc64le"
      ]
    }
  }
}
[+] Building 104.6s (59/73)
...

You can also pass the -d option (debug) to see traces from the script.

Using an overridden target repository on Docker Hub

Create a new dedicated target repository in your Docker Hub account, and use it like follows (note the absence of -d option):

$ export DOCKERHUB_ORGANISATION=jenkins4eval
$ export DOCKERHUB_REPO=test-jenkins
# The log below will help confirm this override was taken in account:
$ ./.ci/publish.sh
Using the following settings:
* JENKINS_REPO: jenkins4eval/test-jenkins
* JENKINS_VERSION: 2.528.3
* WAR_SHA: bfa31f1e3aacebb5bce3d5076c73df97bf0c0567eeb8d8738f54f6bac48abd74
* COMMIT_SHA: aaf4e7faf887b7ac4879c3bf540ede48220cca9f
* LATEST_WEEKLY: false
* LATEST_LTS: true
* BUILD_METADATA_PATH: target/build-result-metadata_linux_publish.json
* BAKE TARGET: linux
* BUILDX OPTIONS:
  --pull
  --push
  --metadata-file=target/build-result-metadata_linux_publish.json

* RESOLVED BAKE CONFIG:
{
...