Add Gitea Alpine registry workflow
This commit is contained in:
48
.gitea/workflows/build.yml
Normal file
48
.gitea/workflows/build.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Build Alpine Packages
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
tags:
|
||||
- "*"
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-and-publish:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: alpine:3.23
|
||||
env:
|
||||
ALPINE_VERSION: "3.23"
|
||||
ALPINE_ARCHES: "x86_64 aarch64"
|
||||
ALPINE_REGISTRY_BRANCH: "v3.23"
|
||||
ALPINE_REGISTRY_REPOSITORY: "${{ vars.PACKAGE_NAME }}"
|
||||
INSTANCE_URL: "${{ vars.INSTANCE_URL }}"
|
||||
PACKAGE_OWNER: "${{ vars.PACKAGE_OWNER }}"
|
||||
PACKAGE_USER: "${{ secrets.PACKAGE_USER }}"
|
||||
PACKAGE_TOKEN: "${{ secrets.PACKAGE_TOKEN }}"
|
||||
PACKAGER: "Joachim Schlöffel <me@joachim-schloeffel.com>"
|
||||
steps:
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
apk add --no-cache --update abuild-rootbld alpine-sdk atools-apkbuild-lint bash ca-certificates curl doas git nodejs sudo tar
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Build packages
|
||||
run: |
|
||||
scripts/apk/clean.sh
|
||||
apkbuild-lint packaging/alpine/local/seaweedfs/APKBUILD
|
||||
scripts/apk/ci-build.sh
|
||||
scripts/apk/list-packages.sh
|
||||
|
||||
- name: Smoke test
|
||||
run: scripts/apk/ci-smoke.sh
|
||||
|
||||
- name: Publish Alpine packages
|
||||
if: github.event_name != 'pull_request'
|
||||
run: scripts/apk/publish-gitea.sh
|
||||
36
README.md
36
README.md
@@ -1,6 +1,6 @@
|
||||
# SeaweedFS Alpine Package
|
||||
|
||||
Local Alpine packaging for SeaweedFS `4.31`. The workflow runs Alpine tooling
|
||||
Local Alpine 3.23 packaging for SeaweedFS `4.31`. The workflow runs Alpine tooling
|
||||
inside Docker and writes signed packages under `packages/local/<arch>/`.
|
||||
|
||||
## Commands
|
||||
@@ -17,6 +17,8 @@ mise run apk:packages
|
||||
mise run apk:smoke
|
||||
mise run apk:test-shell
|
||||
mise run apk:publish-check
|
||||
mise run apk:publish-gitea
|
||||
mise run gitea-workflow-build
|
||||
mise run apk:shell
|
||||
mise run apk:clean
|
||||
```
|
||||
@@ -50,6 +52,12 @@ The package repackages upstream release tarballs, so builds use
|
||||
`ALPINE_BUILD_PLATFORM=linux/amd64` by default. Signing keys and distfiles are
|
||||
cached in `.cache/abuild/` and `.cache/apk-distfiles/`.
|
||||
|
||||
The Gitea workflow publishes to the Alpine package registry branch `v3.23`.
|
||||
Override `ALPINE_VERSION` and `ALPINE_REGISTRY_BRANCH` if you intentionally
|
||||
build for another Alpine branch, including `edge`.
|
||||
Use `mise run gitea-workflow-build` for a local `pull_request` workflow check
|
||||
through `act`; the publish step is skipped for that event.
|
||||
|
||||
## Test And Publish
|
||||
|
||||
```sh
|
||||
@@ -116,6 +124,32 @@ rc-service seaweedfs.master start
|
||||
If the repo key is missing on a target system, copy `.cache/abuild/*.rsa.pub`
|
||||
into `/etc/apk/keys/` before `apk update`.
|
||||
|
||||
## Gitea Registry
|
||||
|
||||
The Gitea workflow reads these repository variables and secrets:
|
||||
|
||||
```text
|
||||
Variables: INSTANCE_URL, PACKAGE_OWNER, PACKAGE_NAME
|
||||
Secrets: PACKAGE_USER, PACKAGE_TOKEN
|
||||
```
|
||||
|
||||
It uploads each built `*.apk` with HTTP `PUT` to:
|
||||
|
||||
```text
|
||||
${INSTANCE_URL}/api/packages/${PACKAGE_OWNER}/alpine/v3.23/${PACKAGE_NAME}
|
||||
```
|
||||
|
||||
For local publishing, run:
|
||||
|
||||
```sh
|
||||
INSTANCE_URL=https://code.factoring.digital \
|
||||
PACKAGE_OWNER=fspdigital \
|
||||
PACKAGE_NAME=seaweedfs-alpine \
|
||||
PACKAGE_USER=... \
|
||||
PACKAGE_TOKEN=... \
|
||||
mise run apk:publish-gitea
|
||||
```
|
||||
|
||||
## Alpine Package Dos And Don'ts
|
||||
|
||||
Do:
|
||||
|
||||
17
mise.toml
17
mise.toml
@@ -1,4 +1,5 @@
|
||||
[tools]
|
||||
act = "latest"
|
||||
codex = "latest"
|
||||
docker-cli = "latest"
|
||||
shellcheck = "latest"
|
||||
@@ -11,6 +12,10 @@ run = "scripts/apk/build.sh build"
|
||||
description = "Build the Alpine package in Docker for all configured architectures"
|
||||
run = "scripts/apk/build.sh build-all"
|
||||
|
||||
[tasks."apk:ci-build"]
|
||||
description = "Build all configured Alpine packages directly in the current Alpine environment"
|
||||
run = "scripts/apk/ci-build.sh"
|
||||
|
||||
[tasks."apk:build-x86_64"]
|
||||
description = "Build the Alpine package in Docker for x86_64"
|
||||
run = "scripts/apk/build.sh build x86_64"
|
||||
@@ -35,6 +40,10 @@ run = "scripts/apk/build.sh lint"
|
||||
description = "Install-test built packages from the local repository in Docker"
|
||||
run = "scripts/apk/smoke.sh"
|
||||
|
||||
[tasks."apk:ci-smoke"]
|
||||
description = "Install-test built packages directly in the current Alpine environment"
|
||||
run = "scripts/apk/ci-smoke.sh"
|
||||
|
||||
[tasks."apk:test-shell"]
|
||||
description = "Open an Alpine shell with the current local package build installed"
|
||||
run = "scripts/apk/test-shell.sh"
|
||||
@@ -47,6 +56,14 @@ run = "scripts/apk/list-packages.sh"
|
||||
description = "Run lint, multi-arch build, package listing, and smoke test"
|
||||
run = "scripts/apk/publish-check.sh"
|
||||
|
||||
[tasks."apk:publish-gitea"]
|
||||
description = "Publish built packages to the Gitea Alpine package registry"
|
||||
run = "scripts/apk/publish-gitea.sh"
|
||||
|
||||
[tasks."gitea-workflow-build"]
|
||||
description = "Run the Gitea build workflow locally through act as a pull_request event"
|
||||
run = "act pull_request -W .gitea/workflows/build.yml -j build-and-publish"
|
||||
|
||||
[tasks."apk:shell"]
|
||||
description = "Open an Alpine package build shell in Docker"
|
||||
run = "scripts/apk/build.sh shell"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# Maintainer: Local Builder <local@example.invalid>
|
||||
# Maintainer: Joachim Schlöffel <me@joachim-schloeffel.com>
|
||||
pkgname=seaweedfs
|
||||
pkgver=4.31
|
||||
pkgrel=2
|
||||
pkgrel=3
|
||||
pkgdesc="Distributed storage system for object storage, file systems, and Iceberg tables"
|
||||
url="https://github.com/seaweedfs/seaweedfs"
|
||||
arch="x86_64 aarch64"
|
||||
license="Apache-2.0"
|
||||
depends="ca-certificates"
|
||||
provides="!$pkgname-openrc"
|
||||
depends="ca-certificates /bin/sh"
|
||||
provides="!$pkgname-openrc cmd:weed=$pkgver-r$pkgrel"
|
||||
install="$pkgname.pre-install"
|
||||
subpackages="
|
||||
$pkgname-admin-openrc:_openrc_admin:noarch
|
||||
@@ -21,7 +21,7 @@ subpackages="
|
||||
$pkgname-webdav-openrc:_openrc_webdav:noarch
|
||||
$pkgname-worker-openrc:_openrc_worker:noarch
|
||||
"
|
||||
options="!check !strip"
|
||||
options="!check !strip !tracedeps"
|
||||
|
||||
case "$CARCH" in
|
||||
x86_64)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG ALPINE_VERSION=3.22
|
||||
ARG ALPINE_VERSION=3.23
|
||||
FROM alpine:${ALPINE_VERSION}
|
||||
|
||||
ARG BUILDER_UID=1000
|
||||
|
||||
@@ -4,9 +4,18 @@ set -euo pipefail
|
||||
command_name="${1:-build}"
|
||||
requested_arch="${2:-${ALPINE_ARCH:-x86_64}}"
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
alpine_version="${ALPINE_VERSION:-3.22}"
|
||||
alpine_version="${ALPINE_VERSION:-3.23}"
|
||||
repo_name="${ALPINE_REPO_NAME:-local}"
|
||||
build_platform="${ALPINE_BUILD_PLATFORM:-linux/amd64}"
|
||||
builder_uid="$(id -u)"
|
||||
builder_gid="$(id -g)"
|
||||
|
||||
if [[ "${builder_uid}" == "0" ]]; then
|
||||
builder_uid=1000
|
||||
fi
|
||||
if [[ "${builder_gid}" == "0" ]]; then
|
||||
builder_gid=1000
|
||||
fi
|
||||
|
||||
validate_arch() {
|
||||
case "$1" in
|
||||
@@ -26,8 +35,8 @@ run_for_arch() {
|
||||
docker build \
|
||||
--platform "${build_platform}" \
|
||||
--build-arg "ALPINE_VERSION=${alpine_version}" \
|
||||
--build-arg "BUILDER_UID=$(id -u)" \
|
||||
--build-arg "BUILDER_GID=$(id -g)" \
|
||||
--build-arg "BUILDER_UID=${builder_uid}" \
|
||||
--build-arg "BUILDER_GID=${builder_gid}" \
|
||||
-f "${repo_root}/scripts/apk/Dockerfile" \
|
||||
-t "${image_name}" \
|
||||
"${repo_root}"
|
||||
@@ -41,7 +50,7 @@ run_for_arch() {
|
||||
-e "ALPINE_ARCH=${arch}" \
|
||||
-e "CARCH=${arch}" \
|
||||
-e "ALPINE_REPO_NAME=${repo_name}" \
|
||||
-e "PACKAGER=${PACKAGER:-Local Builder <local@example.invalid>}" \
|
||||
-e "PACKAGER=${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}" \
|
||||
-v "${repo_root}:/work" \
|
||||
-v "${repo_root}/.cache/abuild:/home/builder/.abuild" \
|
||||
-v "${repo_root}/.cache/apk-distfiles:/var/cache/distfiles" \
|
||||
|
||||
55
scripts/apk/ci-build.sh
Executable file
55
scripts/apk/ci-build.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
package_dir="${APKBUILD_DIR:-${repo_root}/packaging/alpine/local/seaweedfs}"
|
||||
repo_name="${ALPINE_REPO_NAME:-local}"
|
||||
arches="${ALPINE_ARCHES:-x86_64 aarch64}"
|
||||
packager="${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}"
|
||||
|
||||
if [[ "${1:-}" != "--as-builder" && "$(id -u)" == "0" ]]; then
|
||||
addgroup -g 1000 builder 2>/dev/null || addgroup builder
|
||||
adduser -D -u 1000 -G builder builder 2>/dev/null || true
|
||||
addgroup builder abuild
|
||||
addgroup builder wheel
|
||||
printf 'permit nopass :wheel\n' > /etc/doas.d/wheel.conf
|
||||
printf '%%wheel ALL=(ALL) NOPASSWD: ALL\n' > /etc/sudoers.d/wheel
|
||||
chown -R builder:builder "${repo_root}"
|
||||
exec su builder -c "ALPINE_ARCHES='${arches}' ALPINE_REPO_NAME='${repo_name}' PACKAGER='${packager}' '${BASH_SOURCE[0]}' --as-builder"
|
||||
fi
|
||||
|
||||
export PACKAGER="${packager}"
|
||||
export REPODEST="${repo_root}/packages"
|
||||
export SRCDEST="${repo_root}/.cache/apk-distfiles"
|
||||
|
||||
git config --global --add safe.directory "${repo_root}"
|
||||
mkdir -p "${repo_root}/.cache/abuild" "${SRCDEST}" "${REPODEST}" "${HOME}/.abuild"
|
||||
|
||||
if [[ ! -e "${HOME}/.abuild/abuild.conf" && -d "${repo_root}/.cache/abuild" ]]; then
|
||||
rmdir "${HOME}/.abuild" 2>/dev/null || true
|
||||
ln -s "${repo_root}/.cache/abuild" "${HOME}/.abuild"
|
||||
fi
|
||||
|
||||
if ! compgen -G "${HOME}/.abuild/*.rsa" > /dev/null; then
|
||||
abuild-keygen -a -n
|
||||
fi
|
||||
|
||||
doas cp "${HOME}"/.abuild/*.rsa.pub /etc/apk/keys/
|
||||
|
||||
for arch in ${arches}; do
|
||||
case "${arch}" in
|
||||
x86_64|aarch64) ;;
|
||||
*) printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2; exit 2 ;;
|
||||
esac
|
||||
|
||||
printf 'Building %s for %s\n' "$(basename "${package_dir}")" "${arch}"
|
||||
(
|
||||
export ALPINE_ARCH="${arch}"
|
||||
export CARCH="${arch}"
|
||||
cd "${package_dir}"
|
||||
abuild -r
|
||||
)
|
||||
|
||||
mkdir -p "${REPODEST}/${repo_name}/${arch}"
|
||||
cp "${HOME}"/.abuild/*.rsa.pub "${REPODEST}/${repo_name}/${arch}/"
|
||||
done
|
||||
24
scripts/apk/ci-smoke.sh
Executable file
24
scripts/apk/ci-smoke.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
repo_name="${ALPINE_REPO_NAME:-local}"
|
||||
arch="${ALPINE_ARCH:-$(apk --print-arch)}"
|
||||
packages="${SMOKE_PACKAGES:-seaweedfs seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc}"
|
||||
repo_dir="${repo_root}/packages/${repo_name}/${arch}"
|
||||
read -r -a package_list <<< "${packages}"
|
||||
|
||||
if [[ ! -d "${repo_dir}" ]]; then
|
||||
printf 'missing local repository: packages/%s/%s\n' "${repo_name}" "${arch}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp "${repo_dir}"/*.rsa.pub /etc/apk/keys/
|
||||
echo "${repo_root}/packages/${repo_name}" >> /etc/apk/repositories
|
||||
apk update
|
||||
apk add "${package_list[@]}"
|
||||
weed version
|
||||
ls -1 /etc/seaweedfs
|
||||
if ls /etc/init.d/seaweedfs.* >/dev/null 2>&1; then
|
||||
find /etc/init.d -maxdepth 1 -name 'seaweedfs.*' -print | sort
|
||||
fi
|
||||
@@ -7,7 +7,7 @@ repo_name="${ALPINE_REPO_NAME:-local}"
|
||||
arch="${ALPINE_ARCH:-x86_64}"
|
||||
|
||||
export CARCH="${CARCH:-$arch}"
|
||||
export PACKAGER="${PACKAGER:-Local Builder <local@example.invalid>}"
|
||||
export PACKAGER="${PACKAGER:-Joachim Schlöffel <me@joachim-schloeffel.com>}"
|
||||
if [[ -n "${PACKAGER_PRIVKEY:-}" ]]; then
|
||||
export PACKAGER_PRIVKEY
|
||||
fi
|
||||
|
||||
81
scripts/apk/publish-gitea.sh
Executable file
81
scripts/apk/publish-gitea.sh
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
repo_name="${ALPINE_REPO_NAME:-local}"
|
||||
alpine_version="${ALPINE_VERSION:-3.23}"
|
||||
branch="${ALPINE_REGISTRY_BRANCH:-v${alpine_version}}"
|
||||
repository="${ALPINE_REGISTRY_REPOSITORY:-${PACKAGE_NAME:-main}}"
|
||||
instance_url="${INSTANCE_URL:-}"
|
||||
owner="${PACKAGE_OWNER:-}"
|
||||
user="${PACKAGE_USER:-}"
|
||||
token="${PACKAGE_TOKEN:-}"
|
||||
allow_conflicts="${GITEA_APK_ALLOW_CONFLICTS:-1}"
|
||||
|
||||
require_env() {
|
||||
local name="$1"
|
||||
local value="$2"
|
||||
|
||||
if [[ -z "${value}" ]]; then
|
||||
printf 'missing required environment variable: %s\n' "${name}" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
require_env INSTANCE_URL "${instance_url}"
|
||||
require_env PACKAGE_OWNER "${owner}"
|
||||
require_env PACKAGE_USER "${user}"
|
||||
require_env PACKAGE_TOKEN "${token}"
|
||||
|
||||
instance_url="${instance_url%/}"
|
||||
upload_url="${instance_url}/api/packages/${owner}/alpine/${branch}/${repository}"
|
||||
package_root="${repo_root}/packages/${repo_name}"
|
||||
|
||||
if [[ ! -d "${package_root}" ]]; then
|
||||
printf 'missing local package repository: %s\n' "${package_root}" >&2
|
||||
printf 'run: mise run apk:build-all\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shopt -s nullglob
|
||||
apks=("${package_root}"/*/*.apk)
|
||||
shopt -u nullglob
|
||||
|
||||
if [[ "${#apks[@]}" -eq 0 ]]; then
|
||||
printf 'no APK files found under %s\n' "${package_root}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf 'Publishing %d APK files to %s\n' "${#apks[@]}" "${upload_url}"
|
||||
|
||||
for apk in "${apks[@]}"; do
|
||||
filename="$(basename "${apk}")"
|
||||
status="$(
|
||||
curl --silent --show-error --location \
|
||||
--user "${user}:${token}" \
|
||||
--upload-file "${apk}" \
|
||||
--write-out '%{http_code}' \
|
||||
--output /tmp/gitea-apk-publish-response \
|
||||
"${upload_url}"
|
||||
)"
|
||||
|
||||
case "${status}" in
|
||||
201)
|
||||
printf 'published: %s\n' "${filename}"
|
||||
;;
|
||||
409)
|
||||
if [[ "${allow_conflicts}" == "1" ]]; then
|
||||
printf 'already exists: %s\n' "${filename}"
|
||||
else
|
||||
printf 'conflict: %s already exists\n' "${filename}" >&2
|
||||
cat /tmp/gitea-apk-publish-response >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
printf 'publish failed for %s: HTTP %s\n' "${filename}" "${status}" >&2
|
||||
cat /tmp/gitea-apk-publish-response >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -2,7 +2,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
alpine_version="${ALPINE_VERSION:-3.22}"
|
||||
alpine_version="${ALPINE_VERSION:-3.23}"
|
||||
platform="${ALPINE_BUILD_PLATFORM:-linux/amd64}"
|
||||
arch="${ALPINE_ARCH:-x86_64}"
|
||||
packages="${SMOKE_PACKAGES:-seaweedfs seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc}"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
alpine_version="${ALPINE_VERSION:-3.22}"
|
||||
alpine_version="${ALPINE_VERSION:-3.23}"
|
||||
platform="${ALPINE_BUILD_PLATFORM:-linux/amd64}"
|
||||
arch="${ALPINE_ARCH:-x86_64}"
|
||||
packages="${TEST_SHELL_PACKAGES:-seaweedfs seaweedfs-doc bash-completion seaweedfs-master-openrc seaweedfs-filer-openrc seaweedfs-worker-openrc}"
|
||||
|
||||
Reference in New Issue
Block a user