6.5 KiB
AGENTS.md
What this repo is
Shell scripts to backport and build OpenSSH RPMs for CentOS/RHEL-like distros (EL5 through EL9, also Rocky, AlmaLinux, Anolis, UOS, openEuler, Amazon Linux).
Essential commands
# Download source tarballs into downloads/
./pullsrc.sh
# Build RPMs (auto-detects the EL version from the running system)
./compile.sh
# Force a specific EL target (useful on non-RPM build hosts like Docker/Ubuntu)
./compile.sh el7
# Docker-based build (see docker/README.md for per-version commands)
docker build -t elssh:el8 -f ./docker/Dockerfile.centos-stream --build-arg VERSION_NUM=8 .
docker run --rm -v .:/data elssh:el8
Configuration
version.env— source versions (OpenSSH, OpenSSL, Perl). Committed.version-local.env— user overrides likePKGREL,WITH_OPENSSL. Gitignored (*-local*).compile.shsourcesversion.envthenversion-local.env(if present), soversion-local.envwins.
Key variables
WITH_OPENSSL:0= no OpenSSL (no ssh-rsa keys),1= system OpenSSL,2= static OpenSSL. Only theel7spec dir (covering EL7/8/9) auto-detects incompile.shTOPDIR_SELECT: system OpenSSL >= 3 ->1, else2. EL5/EL6 leave it unset and rpmbuild falls back to2via${WITH_OPENSSL:-2}. Notedocker/docker_compile.shhas its own overlapping auto-detect (checks openssl-devel presence + version), so behavior inside Docker may differ from a direct./compile.shrun.PKGREL: package release number (defaults to1)M32=1: build 32-bit RPMs (EL5 only)DOCKERBUILD=1: when set,pullsrc.shskips the openssh/openssl/askpass downloads but still fetches PERLSRCUOS20=1: build the UOS 20 variant — enables the kernel-panic patch (openssh-uos20-kernel-panic-fix.patch) and prefixesPKGRELwithuos20.so resulting RPMs are distinguishable.
Architecture notes
- EL8 and EL9 both use
el7/as the spec directory, since they share systemd.compile.shGUESS_DIST returnsel7for all versions >= EL7. - EL6 uses
el6/(SysVinit). - EL5 uses
el5/(SysVinit, requires Perl bootstrap for building OpenSSL). - Supported architectures:
x86_64for all EL versions;aarch64for EL7/8/9 and UOS20 via per-arch tags (aarch64_el7,aarch64_el8,aarch64_el9). Docker tags are per-arch (e.g.ghcr.io/boypt/openssh-rpms:aarch64_el7), not multi-arch manifests. WITH_OPENSSLauto-detection: forel7(which covers EL7/8/9), if system OpenSSL >= 3, defaults to1(system), otherwise2(static).compile.shhas subcommands:GETEL(print detected distro),GETRPM(list RPM paths),RPMDIR(print RPM output dir).el7/SPECS/has two spec files:openssh.spec(default, systemd) andopenssh.initv.spec(SysVinit). The default spec is selected viaSPECFILEenv var. The UOS 20 build uses the default spec withUOS20=1.docker/docker_compile.shis the entrypoint inside Docker images — it copies the appropriateel*dir to/BUILDand runscompile.shagainst it.docker/modify_vault_source.shhandles vault mirrors; foraarch64it appends/altarch(CentOS AltArch vault, e.g..../centos-vault/altarch/7.9.2009/). For EL5EPELalways useshttp://mirrors.aliyun.com/epel-archive(avoids Python 2.4 TLS 1.0 → 302 → https failure onarchives.fedoraproject.org).
CI
.github/workflows/build-images.yml— manually triggered (workflow_dispatch), builds Docker images and pushes toghcr.io. Matrix:build-amd64(5 images:el5,el6,el7,el8,el9onubuntu-latest) +build-arm64(3 images:aarch64_el7,aarch64_el8,aarch64_el9onubuntu-latestwithsetup-qemu-action+platforms: linux/arm64). Cache:type=gha..github/workflows/build-rpm.yml— runs onv*tags, builds RPMs inside Docker containers and creates a GitHub release. Jobs:build-arm64(ubuntu-24.04-arm, natively runsaarch64_*images),build-amd64(ubuntu-latest),build-el5(ubuntu-latest, handlesm32for i686). Finalreleaseneeds all three and zips artifacts asopenssh_<tag>_<artifact>.zip.
Linting & formatting
All shell scripts (*.sh) must pass shellcheck and shfmt before committing:
# Lint (warnings are errors)
shellcheck -S warning compile.sh pullsrc.sh
# Format check (must produce no diff)
shfmt -d -i 0 -bn -ci compile.sh pullsrc.sh
# Auto-fix formatting in-place
shfmt -w -i 0 -bn -ci compile.sh pullsrc.sh
- shellcheck
-S warning: treat warnings as failures; informational/style notes may be suppressed inline with# shellcheck disable=SCxxxx. - shfmt
-i 0 -bn -ci: tabs for indentation (no extra indent), binary operators (&&,||,|) at start of next line, case body indented. - Both tools must exit 0 before any commit touching
*.shfiles.
Gitignore
*-local* is gitignored — version-local.env, editor swap files, etc. *.tar.gz is gitignored everywhere, including downloads/. Generated RPMs go to output/ (also gitignored).
Version bump workflow
When the user says "update to <version>" (e.g. "update to 10.5", "update to 10.6p1"), perform the following steps autonomously. Only update README.md and version.env — do not touch other files unless explicitly asked.
-
Normalize the version: append
p1if not already present (all portable releases usep1). E.g.10.5→10.5p1. -
Update
version.env: change theOPENSSHSRCline toopenssh-<version>.tar.gz.OPENSSHVERis derived automatically fromOPENSSHSRC. Do NOT changeOPENSSLSRC/OPENSSLVERor any other line unless the user explicitly asks. -
Update
README.md: in the "Current Version" section, update only the OpenSSH version line. Leave the OpenSSL line unchanged. -
Determine the next build number:
TAG_PREFIX="v${NEW_VERSION}_b" BUILD_NUM=$(git tag | grep "^${TAG_PREFIX}" | sed "s/^${TAG_PREFIX}//" | sort -n | tail -1) BUILD_NUM=$(( ${BUILD_NUM:-0} + 1 )) -
Commit and tag (do not push yet):
git add version.env README.md git commit -m "bump: OpenSSH ${NEW_VERSION}_b${BUILD_NUM}" git tag "v${NEW_VERSION}_b${BUILD_NUM}" -
Ask the user for confirmation to push to remote. This is the only confirmation needed — do not ask about file changes, commit message, tag name, or anything else.
-
After pushing, the tag triggers
.github/workflows/build-rpm.ymlwhich builds RPMs for all EL versions and creates a GitHub release. Monitor CI usingghcommands and report the status:gh run list --limit 5 gh run watch # watch the latest run to completion