adoptium / adoptium/installer

linux_new: Template de-duplication — Alpine (APK) and RHEL/SUSE (RPM) shared templates

Open
#1,447 0 comments 0 reactions 1 assignee Claimed by @steelhead31 View on GitHub
enhancement Linux
Dominant language
Jinja
Stars
168
Forks
77
Avg merge
2d 14h
Merged PRs (30d)
12

Description

Part of #1445

## Parent Epic

Part of: `[EPIC] linux_new: Packaging pipeline refactor — de-duplication, build-only mode,
security scanning & regression tests`

---

## Background

### Alpine (APK)

Each supported version has its own APKBUILD template under:

jdk/alpine/src/main/packaging/temurin/{version}/alpine.jdk{N}.template.j2

8 template files exist. Between JDK 11 and JDK 17+, only 3 lines differ meaningfully:

| Field | JDK 11 | JDK 17+ |
|---|---|---|
| `arch` | `"noarch"` (hardcoded) | `"{{ hardware_architecture }}"` |
| `ldpath` | `$_java_home/lib:$_java_home/lib/jli:$_java_home/lib/server` | `$_java_home/lib:$_java_home/lib/server` |
| `subpackages` | `$pkgname-jdk:_jdk:x86_64` | `$pkgname-jdk:_jdk` (no arch constraint) |

JDK 8 has a genuinely different version-string expansion format and must remain as a
per-version override.

Additionally, `HelloWorld.java`, `TestCryptoLevel.java`, and `TestECDSA.java` are duplicated
into every version directory (24 identical copies across 8 versions).

### RHEL / SUSE (RPM)

Each version has its own spec template under:

jdk/rhel/src/main/packaging/temurin/{version}/temurin-{N}-jdk.template.j2
jdk/suse/src/main/packaging/temurin/{version}/temurin-{N}-jdk.template.j2
jre/rhel/src/main/packaging/temurin/{version}/temurin-{N}-jre.template.j2
jre/suse/src/main/packaging/temurin/{version}/temurin-{N}-jre.template.j2

32 template files total. The ~240-line spec body (`%prep`, `%build`, `%install`, `%post`,
`%preun`, `%files`, `%changelog`) is structurally identical across all versions. What
differs per version:

| Field | How it varies |
|---|---|
| Package name / altname | `temurin-11-jdk` → `temurin-21-jdk` etc. |
| `source_url_base` repo | `temurin11-binaries` → `temurin21-binaries` |
| `priority` | `1111` for v11, `1711` for v17, `2111` for v21 etc. |
| `Provides:` list | Grows with each new version |
| `Obsoletes:` cutoff | Tracks previous package series (e.g. `< 11.0.28.0.0.6-1`) — cannot be derived algorithmically |
| `%post update-alternatives` tool list | Same version-threshold logic as Debian (deprecated tools removed at JDK 17, new tools added at JDK 16/18) |

RHEL and SUSE templates are structurally equivalent — the distro-specific download URL is
already a template variable, so a single shared spec template covers both.

---

## Goal

- Replace the 7 non-JDK8 Alpine templates with one shared template; consolidate the 24
duplicate Java test files into a single `shared/` directory.
- Replace the 32 RPM spec templates with 2 shared templates (`temurin-jdk.template.j2` and
`temurin-jre.template.j2`); store version-specific scalar metadata in a `version.yaml`
sidecar per version directory.
- Update `generate_spec.py` to optionally load `version.yaml` and pass its values as
additional Jinja2 variables (backward-compatible — no error when file is absent).

---

## Prerequisite

> ⚠️ The **golden file baseline** (child issue #4 — regression tests) must be committed
> **before** any templates in this issue are changed.

---

## Scope

### Alpine changes

**New shared template:**

jdk/alpine/src/main/packaging/temurin/shared/alpine.jdk.template.j2

Uses Jinja2 conditionals for the 3 version-varying lines:
```jinja2
{%- if version|int == 11 %}
arch="noarch"
ldpath="$_java_home/lib:$_java_home/lib/jli:$_java_home/lib/server"
subpackages="$pkgname-src:_src:noarch\n\t$pkgname-jdk:_jdk:x86_64"
{%- else %}
arch="{{ hardware_architecture }}"
ldpath="$_java_home/lib:$_java_home/lib/server"
subpackages="$pkgname-src:_src:noarch\n\t$pkgname-jdk:_jdk"
{%- endif %}

JDK 8 override retained — version-string expansion format is genuinely different:

jdk/alpine/src/main/packaging/temurin/8/alpine.jdk8.template.j2 ← keep as-is

Shared Java test files:

jdk/alpine/src/main/packaging/temurin/shared/HelloWorld.java
jdk/alpine/src/main/packaging/temurin/shared/TestCryptoLevel.java
jdk/alpine/src/main/packaging/temurin/shared/TestECDSA.java

Update build.sh to copy test files from shared/ first, falling back to a version-specific
directory if present (allows per-version overrides in future without breaking the shared case).

Jenkinsfile fallback (line ~591): same pattern as child issue #1 — check for version-specific
file first, fall back to shared/alpine.jdk.template.j2.

RPM changes
New shared templates:

jdk/rhel/src/main/packaging/temurin/shared/temurin-jdk.template.j2
jdk/suse/src/main/packaging/temurin/shared/temurin-jdk.template.j2
jre/rhel/src/main/packaging/temurin/shared/temurin-jre.template.j2
jre/suse/src/main/packaging/temurin/shared/temurin-jre.template.j2

(RHEL and SUSE share the same logical template; they are separate copies only to preserve
the existing directory convention — no cross-directory symlinks.)

Per-version version.yaml sidecars:

jdk/rhel/src/main/packaging/temurin/{version}/version.yaml

Example (temurin/11/version.yaml):

priority: 1111
obsoletes_version: "11.0.28.0.0.6-1"

The Provides: list and tool conditionals are derived from the version number directly in
the template (as with Debian). The version.yaml is only needed for values that cannot be
computed algorithmically.

generate_spec.py update:
Add optional version.yaml loading in render_template(). If a version.yaml exists in
the same directory as the template being rendered, load it and merge its keys into the
Jinja2 render context. No error if the file is absent.

import yaml, pathlib

yaml_path = pathlib.Path(template_dir) / "version.yaml"
extra_vars = yaml.safe_load(yaml_path.read_text()) if yaml_path.exists() else {}
rendered_content = template.render(
..., # existing variables
**extra_vars # priority, obsoletes_version etc.
)

Jenkinsfile fallback (line ~689): same pattern — check version-specific file first,
fall back to shared/temurin-jdk.template.j2.

Acceptance Criteria
jdk/alpine/.../temurin/shared/alpine.jdk.template.j2 exists and covers all non-JDK8 versions
jdk/alpine/.../temurin/8/alpine.jdk8.template.j2 is retained unchanged
HelloWorld.java, TestCryptoLevel.java, TestECDSA.java exist only in shared/; per-version copies deleted
Alpine build.sh sources test files from shared/ with per-version fallback
Shared RHEL/SUSE JDK + JRE spec templates exist in shared/ for both rhel and suse
version.yaml sidecars exist for all 8 versions under both jdk/rhel/ and jre/rhel/ (and suse/)
generate_spec.py loads version.yaml when present, silently skips when absent
Per-version .template.j2 files deleted from all non-JDK8 version directories (APK + RPM)
Jenkinsfile templatebase uses shared fallback for both alpine and rhel/suse
Running the regression test suite (run_tests.sh) passes for all versions and distro families
Both jdk and jre are covered for RPM

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.