build: add deb and rpm release packages
This commit is contained in:
parent
0151076ca9
commit
b481bb9f3e
|
|
@ -28,6 +28,14 @@ jobs:
|
|||
go-version-file: go.mod
|
||||
cache: true
|
||||
|
||||
- name: install nfpm
|
||||
env:
|
||||
NFPM_VERSION: v2.47.0
|
||||
run: |
|
||||
mkdir -p "$RUNNER_TEMP/bin"
|
||||
GOBIN="$RUNNER_TEMP/bin" go install github.com/goreleaser/nfpm/v2/cmd/nfpm@"$NFPM_VERSION"
|
||||
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
|
||||
|
||||
# Cheaper than the full release-check, but still refuses to publish a
|
||||
# broken build.
|
||||
- name: test
|
||||
|
|
@ -81,6 +89,7 @@ jobs:
|
|||
Verify downloads against \`checksums.txt\`.
|
||||
EOF
|
||||
|
||||
PKG_VERSION="${VERSION#v}"
|
||||
gh release delete nightly --yes || echo "no previous nightly release"
|
||||
gh release create nightly \
|
||||
--prerelease \
|
||||
|
|
@ -91,4 +100,8 @@ jobs:
|
|||
"dist/sshkeeper_${VERSION}_darwin_amd64.tar.gz" \
|
||||
"dist/sshkeeper_${VERSION}_darwin_arm64.tar.gz" \
|
||||
"dist/sshkeeper_${VERSION}_windows_amd64.zip" \
|
||||
"dist/sshkeeper_${PKG_VERSION}-1_amd64.deb" \
|
||||
"dist/sshkeeper_${PKG_VERSION}-1_arm64.deb" \
|
||||
"dist/sshkeeper-${PKG_VERSION}-1.x86_64.rpm" \
|
||||
"dist/sshkeeper-${PKG_VERSION}-1.aarch64.rpm" \
|
||||
dist/checksums.txt
|
||||
|
|
|
|||
|
|
@ -23,6 +23,14 @@ jobs:
|
|||
go-version-file: go.mod
|
||||
cache: true
|
||||
|
||||
- name: install nfpm
|
||||
env:
|
||||
NFPM_VERSION: v2.47.0
|
||||
run: |
|
||||
mkdir -p "$RUNNER_TEMP/bin"
|
||||
GOBIN="$RUNNER_TEMP/bin" go install github.com/goreleaser/nfpm/v2/cmd/nfpm@"$NFPM_VERSION"
|
||||
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
|
||||
|
||||
# Gate the release on the same checks used locally. A red suite must not
|
||||
# be able to publish.
|
||||
- name: release checks
|
||||
|
|
@ -53,6 +61,7 @@ jobs:
|
|||
set -- --generate-notes
|
||||
fi
|
||||
|
||||
PKG_VERSION="${VERSION#v}"
|
||||
gh release create "$VERSION" \
|
||||
--title "sshkeeper $VERSION" \
|
||||
--verify-tag \
|
||||
|
|
@ -62,4 +71,8 @@ jobs:
|
|||
"dist/sshkeeper_${VERSION}_darwin_amd64.tar.gz" \
|
||||
"dist/sshkeeper_${VERSION}_darwin_arm64.tar.gz" \
|
||||
"dist/sshkeeper_${VERSION}_windows_amd64.zip" \
|
||||
"dist/sshkeeper_${PKG_VERSION}-1_amd64.deb" \
|
||||
"dist/sshkeeper_${PKG_VERSION}-1_arm64.deb" \
|
||||
"dist/sshkeeper-${PKG_VERSION}-1.x86_64.rpm" \
|
||||
"dist/sshkeeper-${PKG_VERSION}-1.aarch64.rpm" \
|
||||
dist/checksums.txt
|
||||
|
|
|
|||
17
README.md
17
README.md
|
|
@ -52,7 +52,7 @@ Platform status:
|
|||
|
||||
| Platform | Status | Notes |
|
||||
|----------|--------|-------|
|
||||
| Linux | Primary release target | `linux/amd64` and `linux/arm64` release tarballs are available. |
|
||||
| Linux | Primary release target | `amd64`/`arm64` tarballs plus native `.deb` and `.rpm` packages. |
|
||||
| macOS | Primary release target | `darwin/amd64` and `darwin/arm64` release tarballs are available. Requires system `ssh` client. Homebrew formula planned. |
|
||||
| Windows | Experimental | Requires OpenSSH Client available as `ssh.exe` in `PATH`. Password/key-passphrase PTY flows are not validated on Windows. |
|
||||
|
||||
|
|
@ -68,6 +68,21 @@ Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
|
|||
|
||||
### Install from release
|
||||
|
||||
Debian/Ubuntu (amd64):
|
||||
|
||||
```bash
|
||||
sudo apt install ./sshkeeper_0.4.0-1_amd64.deb
|
||||
```
|
||||
|
||||
Fedora/RHEL-family (x86_64):
|
||||
|
||||
```bash
|
||||
sudo dnf install ./sshkeeper-0.4.0-1.x86_64.rpm
|
||||
```
|
||||
|
||||
`arm64`/`aarch64` packages are published alongside the x86_64 builds. The
|
||||
traditional tar.gz archive remains available too:
|
||||
|
||||
```bash
|
||||
tar -xzf sshkeeper_v0.4.0_linux_amd64.tar.gz
|
||||
sudo install -m 0755 sshkeeper_v0.4.0_linux_amd64/sshkeeper /usr/local/bin/sshkeeper
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ go build -o ~/.local/bin/sshkeeper .
|
|||
|
||||
| Платформа | Статус | Примечание |
|
||||
|-----------|--------|------------|
|
||||
| Linux | Основная релизная платформа | Архивы `linux/amd64` и `linux/arm64`. |
|
||||
| Linux | Основная релизная платформа | Архивы `amd64`/`arm64`, а также `.deb` и `.rpm`. |
|
||||
| macOS | Основная релизная платформа | Архивы `darwin/amd64` и `darwin/arm64`, нужен системный `ssh`. Homebrew formula запланирована. |
|
||||
| Windows | Experimental | Нужен OpenSSH Client как `ssh.exe` в `PATH`; password/key-passphrase PTY-сценарии на Windows пока не подтверждены. |
|
||||
|
||||
|
|
@ -79,11 +79,26 @@ go build -o ~/.local/bin/sshkeeper .
|
|||
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
|
||||
```
|
||||
|
||||
### Из релиза (после публикации v0.2.0)
|
||||
### Из релиза
|
||||
|
||||
Для Debian/Ubuntu (amd64):
|
||||
|
||||
```bash
|
||||
tar -xzf sshkeeper_v0.2.0_linux_amd64.tar.gz
|
||||
sudo install -m 0755 sshkeeper_v0.2.0_linux_amd64/sshkeeper /usr/local/bin/sshkeeper
|
||||
sudo apt install ./sshkeeper_0.4.0-1_amd64.deb
|
||||
```
|
||||
|
||||
Для Fedora/RHEL-подобных систем (x86_64):
|
||||
|
||||
```bash
|
||||
sudo dnf install ./sshkeeper-0.4.0-1.x86_64.rpm
|
||||
```
|
||||
|
||||
Для ARM64 публикуются `sshkeeper_0.4.0-1_arm64.deb` и
|
||||
`sshkeeper-0.4.0-1.aarch64.rpm`. Архивный вариант остаётся доступен:
|
||||
|
||||
```bash
|
||||
tar -xzf sshkeeper_v0.4.0_linux_amd64.tar.gz
|
||||
sudo install -m 0755 sshkeeper_v0.4.0_linux_amd64/sshkeeper /usr/local/bin/sshkeeper
|
||||
```
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ runs, and how to reproduce it by hand when needed.
|
|||
| `nightly.yml` | push to `main` | rebuilds the tip of `main` and replaces the `nightly` prerelease |
|
||||
|
||||
`release.yml` builds through `release.sh` rather than reimplementing packaging,
|
||||
so CI and a local run stay in step. See [Reproducibility](#reproducibility) for
|
||||
what that guarantees.
|
||||
so CI and a local run stay in step. Linux `.deb` and `.rpm` packages are built
|
||||
with nFPM v2.47.0 from the exact Linux tarball binaries. See
|
||||
[Reproducibility](#reproducibility) for what that guarantees.
|
||||
|
||||
### Release notes
|
||||
|
||||
|
|
@ -90,7 +91,14 @@ This runs:
|
|||
|
||||
## Build Artifacts
|
||||
|
||||
Run:
|
||||
Linux package generation requires nFPM v2.47.0. GitHub Actions installs this
|
||||
exact version; for a local release build install the same tool first:
|
||||
|
||||
```bash
|
||||
go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.47.0
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
./release.sh v0.2.0
|
||||
|
|
@ -104,6 +112,10 @@ sshkeeper_v0.2.0_linux_arm64.tar.gz
|
|||
sshkeeper_v0.2.0_darwin_amd64.tar.gz
|
||||
sshkeeper_v0.2.0_darwin_arm64.tar.gz
|
||||
sshkeeper_v0.2.0_windows_amd64.zip
|
||||
sshkeeper_0.2.0-1_amd64.deb
|
||||
sshkeeper_0.2.0-1_arm64.deb
|
||||
sshkeeper-0.2.0-1.x86_64.rpm
|
||||
sshkeeper-0.2.0-1.aarch64.rpm
|
||||
checksums.txt
|
||||
```
|
||||
|
||||
|
|
@ -114,6 +126,11 @@ Each archive contains:
|
|||
- `LICENSE`
|
||||
- `docs/guide.md`
|
||||
|
||||
Linux packages install the same release binary as `/usr/bin/sshkeeper` and add
|
||||
README, LICENSE, and the user guide under `/usr/share/doc/sshkeeper/`. Debian
|
||||
packages depend on `openssh-client`; RPM packages depend on `openssh-clients`.
|
||||
The package revision starts at `1` and is reset when the upstream version changes.
|
||||
|
||||
## Verify Checksums
|
||||
|
||||
From the `dist/` directory:
|
||||
|
|
@ -138,7 +155,10 @@ byte for byte. `release.sh` pins everything that would otherwise vary:
|
|||
everything else, so the builder's umask cannot leak into the archive.
|
||||
|
||||
- the Windows zip is packaged under `LC_ALL=C` and `TZ=UTC`, because `sort`
|
||||
orders entries by locale and zip stores DOS local time with no zone.
|
||||
orders entries by locale and zip stores DOS local time with no zone;
|
||||
- nFPM receives the same `SOURCE_DATE_EPOCH` and packages files extracted from
|
||||
the already-built Linux tarballs, so `.deb`/`.rpm` contain the identical Linux
|
||||
binary rather than triggering a second compile.
|
||||
|
||||
With those in place the archives themselves reproduce across hosts: a build on
|
||||
`ubuntu-latest` (umask 022, C locale, UTC) and one on a workstation (umask 002,
|
||||
|
|
@ -172,11 +192,10 @@ Release notes should mention platform status:
|
|||
|
||||
## Packaging TODO
|
||||
|
||||
Prepare these package channels after the first archive-based release:
|
||||
Native `.deb` and `.rpm` packages are part of the release pipeline. Remaining
|
||||
package channels:
|
||||
|
||||
- deb package
|
||||
- Arch PKGBUILD / AUR
|
||||
- rpm later
|
||||
- Homebrew tap
|
||||
- Scoop manifest
|
||||
- Winget later
|
||||
|
|
|
|||
|
|
@ -185,11 +185,23 @@ the data matters to you.
|
|||
|
||||
## Install
|
||||
|
||||
Debian/Ubuntu (amd64):
|
||||
|
||||
```bash
|
||||
tar -xzf sshkeeper_v0.4.0_linux_amd64.tar.gz
|
||||
sudo install -m 0755 sshkeeper_v0.4.0_linux_amd64/sshkeeper /usr/local/bin/sshkeeper
|
||||
sudo apt install ./sshkeeper_0.4.0-1_amd64.deb
|
||||
```
|
||||
|
||||
Fedora/RHEL-family (x86_64):
|
||||
|
||||
```bash
|
||||
sudo dnf install ./sshkeeper-0.4.0-1.x86_64.rpm
|
||||
```
|
||||
|
||||
ARM64 packages (`arm64.deb` / `aarch64.rpm`) and the original tar.gz archives
|
||||
are published alongside them. Package dependencies pull in the distro OpenSSH
|
||||
client; user config, database and vault files are not owned or modified by the
|
||||
package.
|
||||
|
||||
Verify downloads against `checksums.txt`. Linux and macOS are the primary
|
||||
release targets. Windows remains experimental and requires OpenSSH Client
|
||||
(`ssh.exe`) in `PATH`.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
APP=sshkeeper
|
||||
VERSION=${1:-${VERSION:-}}
|
||||
NFPM_BIN=${NFPM_BIN:-nfpm}
|
||||
NFPM_RELEASE=${NFPM_RELEASE:-1}
|
||||
|
||||
if [[ -z "$VERSION" ]]; then
|
||||
echo "usage: $0 <version>" >&2
|
||||
exit 2
|
||||
fi
|
||||
if ! command -v "$NFPM_BIN" >/dev/null 2>&1; then
|
||||
echo "nfpm is required to build .deb/.rpm packages" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PKG_VERSION=${VERSION#v}
|
||||
if [[ -z "${SOURCE_DATE_EPOCH:-}" ]]; then
|
||||
if git rev-parse --verify -q "${VERSION}^{commit}" >/dev/null; then
|
||||
SOURCE_DATE_EPOCH=$(git log -1 --format=%ct "$VERSION")
|
||||
else
|
||||
SOURCE_DATE_EPOCH=$(git log -1 --format=%ct 2>/dev/null || date +%s)
|
||||
fi
|
||||
fi
|
||||
export SOURCE_DATE_EPOCH
|
||||
TMP_DIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
build_one() {
|
||||
local goarch="$1"
|
||||
local rpmarch
|
||||
local tarball="dist/${APP}_${VERSION}_linux_${goarch}.tar.gz"
|
||||
local package_root="${TMP_DIR}/${APP}_${VERSION}_linux_${goarch}"
|
||||
local extracted="${package_root}/${APP}"
|
||||
|
||||
case "$goarch" in
|
||||
amd64) rpmarch=x86_64 ;;
|
||||
arm64) rpmarch=aarch64 ;;
|
||||
*) echo "unsupported package arch: $goarch" >&2; return 1 ;;
|
||||
esac
|
||||
if [[ ! -f "$tarball" ]]; then
|
||||
echo "missing Linux release archive: $tarball" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
tar -xzf "$tarball" -C "$TMP_DIR"
|
||||
if [[ ! -x "$extracted" ]]; then
|
||||
echo "missing binary in $tarball" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
export NFPM_ARCH="$goarch"
|
||||
export NFPM_VERSION="$PKG_VERSION"
|
||||
export NFPM_RELEASE
|
||||
export NFPM_BINARY="$extracted"
|
||||
export NFPM_README="${package_root}/README.md"
|
||||
export NFPM_LICENSE="${package_root}/LICENSE"
|
||||
export NFPM_GUIDE="${package_root}/docs/guide.md"
|
||||
|
||||
"$NFPM_BIN" package --config packaging/nfpm.yaml --packager deb \
|
||||
--target "dist/${APP}_${PKG_VERSION}-${NFPM_RELEASE}_${goarch}.deb"
|
||||
"$NFPM_BIN" package --config packaging/nfpm.yaml --packager rpm \
|
||||
--target "dist/${APP}-${PKG_VERSION}-${NFPM_RELEASE}.${rpmarch}.rpm"
|
||||
}
|
||||
|
||||
build_one amd64
|
||||
build_one arm64
|
||||
|
||||
echo "==> Linux packages:"
|
||||
ls -lh dist/*.deb dist/*.rpm
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
name: sshkeeper
|
||||
arch: ${NFPM_ARCH}
|
||||
platform: linux
|
||||
version: ${NFPM_VERSION}
|
||||
release: ${NFPM_RELEASE}
|
||||
section: utils
|
||||
priority: optional
|
||||
maintainer: mirivlad <mirvtop@yandex.ru>
|
||||
description: |
|
||||
Console manager for SSH profiles, bastion routes, port forwards,
|
||||
background tunnels, and encrypted SSH secrets.
|
||||
vendor: sshkeeper
|
||||
homepage: https://github.com/mirivlad/sshkeeper
|
||||
license: MIT
|
||||
|
||||
contents:
|
||||
- src: ${NFPM_BINARY}
|
||||
dst: /usr/bin/sshkeeper
|
||||
expand: true
|
||||
file_info:
|
||||
mode: 0755
|
||||
- src: ${NFPM_README}
|
||||
dst: /usr/share/doc/sshkeeper/README.md
|
||||
expand: true
|
||||
file_info:
|
||||
mode: 0644
|
||||
- src: ${NFPM_GUIDE}
|
||||
dst: /usr/share/doc/sshkeeper/guide.md
|
||||
expand: true
|
||||
file_info:
|
||||
mode: 0644
|
||||
- src: ${NFPM_LICENSE}
|
||||
dst: /usr/share/doc/sshkeeper/LICENSE
|
||||
expand: true
|
||||
file_info:
|
||||
mode: 0644
|
||||
|
||||
overrides:
|
||||
deb:
|
||||
depends:
|
||||
- openssh-client
|
||||
rpm:
|
||||
depends:
|
||||
- openssh-clients
|
||||
|
||||
rpm:
|
||||
compression: gzip
|
||||
|
|
@ -9,6 +9,7 @@ VERSION=${VERSION:-${1:-$(git describe --tags --match 'v*' --always --dirty 2>/d
|
|||
LDFLAGS="-s -w -X main.version=${VERSION}"
|
||||
DIST_DIR="dist"
|
||||
SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH:-$(git log -1 --format=%ct 2>/dev/null || date +%s)}
|
||||
export SOURCE_DATE_EPOCH
|
||||
|
||||
echo "==> Building release ${APP} ${VERSION}..."
|
||||
echo "==> SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}"
|
||||
|
|
@ -88,7 +89,9 @@ build_tarball darwin amd64
|
|||
build_tarball darwin arm64
|
||||
build_zip windows amd64
|
||||
|
||||
(cd "${DIST_DIR}" && sha256sum *.tar.gz *.zip > checksums.txt)
|
||||
./packaging/build-linux-packages.sh "${VERSION}"
|
||||
|
||||
(cd "${DIST_DIR}" && sha256sum *.tar.gz *.zip *.deb *.rpm > checksums.txt)
|
||||
|
||||
echo "==> Done."
|
||||
ls -lh "${DIST_DIR}/"*.tar.gz "${DIST_DIR}/"*.zip "${DIST_DIR}/checksums.txt"
|
||||
ls -lh "${DIST_DIR}/"*.tar.gz "${DIST_DIR}/"*.zip "${DIST_DIR}/"*.deb "${DIST_DIR}/"*.rpm "${DIST_DIR}/checksums.txt"
|
||||
|
|
|
|||
Loading…
Reference in New Issue