Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 92f2c636be | |||
| 3c305ac5b4 | |||
| 37968e48fc | |||
| 8cbc66227f |
@@ -0,0 +1,68 @@
|
|||||||
|
name: busybox static musl build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- .gitea/workflows/busybox.yml
|
||||||
|
- scripts/build_busybox.sh
|
||||||
|
- scripts/publish_release.py
|
||||||
|
- versions/busybox.version
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-release:
|
||||||
|
runs-on: alpine-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Bootstrap workspace
|
||||||
|
shell: sh
|
||||||
|
env:
|
||||||
|
REPO_URL: ${{ gitea.server_url }}
|
||||||
|
REPO_NAME: ${{ gitea.repository }}
|
||||||
|
GIT_SHA: ${{ gitea.sha }}
|
||||||
|
run: |
|
||||||
|
apk add --no-cache git
|
||||||
|
workdir="$(pwd)"
|
||||||
|
tmpdir="$(mktemp -d)"
|
||||||
|
git clone --depth 1 "$REPO_URL/$REPO_NAME.git" "$tmpdir/repo"
|
||||||
|
git -C "$tmpdir/repo" fetch --depth 1 origin "$GIT_SHA"
|
||||||
|
git -C "$tmpdir/repo" checkout "$GIT_SHA"
|
||||||
|
find "$workdir" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
|
||||||
|
cp -a "$tmpdir/repo"/. "$workdir"/
|
||||||
|
|
||||||
|
- name: Read version
|
||||||
|
id: meta
|
||||||
|
shell: sh
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
version="$(tr -d ' \n\r' < versions/busybox.version)"
|
||||||
|
artifact="busybox-${version}-linux-amd64-musl-static"
|
||||||
|
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "artifact=${artifact}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Build static busybox
|
||||||
|
shell: sh
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
chmod +x scripts/build_busybox.sh
|
||||||
|
./scripts/build_busybox.sh "${{ steps.meta.outputs.version }}" "$PWD/dist"
|
||||||
|
|
||||||
|
- name: Publish release assets
|
||||||
|
shell: sh
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ gitea.token }}
|
||||||
|
GITEA_API_URL: ${{ gitea.api_url }}
|
||||||
|
REPO_OWNER: ${{ gitea.repository_owner }}
|
||||||
|
REPO_NAME: static-musl-builds
|
||||||
|
TOOL: busybox
|
||||||
|
VERSION: ${{ steps.meta.outputs.version }}
|
||||||
|
TARGET_SHA: ${{ gitea.sha }}
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
apk add --no-cache python3
|
||||||
|
python3 scripts/publish_release.py "dist/${{ steps.meta.outputs.artifact }}" "dist/${{ steps.meta.outputs.artifact }}.tar.gz" "dist/${{ steps.meta.outputs.artifact }}.sha256"
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
name: doggo static musl build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- .gitea/workflows/doggo.yml
|
||||||
|
- scripts/build_doggo.sh
|
||||||
|
- scripts/publish_release.py
|
||||||
|
- versions/doggo.version
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-release:
|
||||||
|
runs-on: alpine-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Bootstrap workspace
|
||||||
|
shell: sh
|
||||||
|
env:
|
||||||
|
REPO_URL: ${{ gitea.server_url }}
|
||||||
|
REPO_NAME: ${{ gitea.repository }}
|
||||||
|
GIT_SHA: ${{ gitea.sha }}
|
||||||
|
run: |
|
||||||
|
apk add --no-cache git
|
||||||
|
workdir="$(pwd)"
|
||||||
|
tmpdir="$(mktemp -d)"
|
||||||
|
git clone --depth 1 "$REPO_URL/$REPO_NAME.git" "$tmpdir/repo"
|
||||||
|
git -C "$tmpdir/repo" fetch --depth 1 origin "$GIT_SHA"
|
||||||
|
git -C "$tmpdir/repo" checkout "$GIT_SHA"
|
||||||
|
find "$workdir" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
|
||||||
|
cp -a "$tmpdir/repo"/. "$workdir"/
|
||||||
|
|
||||||
|
- name: Read version
|
||||||
|
id: meta
|
||||||
|
shell: sh
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
version="$(tr -d ' \n\r' < versions/doggo.version)"
|
||||||
|
artifact="doggo-${version}-linux-amd64-musl-static"
|
||||||
|
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "artifact=${artifact}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Build static doggo
|
||||||
|
shell: sh
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
chmod +x scripts/build_doggo.sh
|
||||||
|
./scripts/build_doggo.sh "${{ steps.meta.outputs.version }}" "$PWD/dist"
|
||||||
|
|
||||||
|
- name: Publish release assets
|
||||||
|
shell: sh
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ gitea.token }}
|
||||||
|
GITEA_API_URL: ${{ gitea.api_url }}
|
||||||
|
REPO_OWNER: ${{ gitea.repository_owner }}
|
||||||
|
REPO_NAME: static-musl-builds
|
||||||
|
TOOL: doggo
|
||||||
|
VERSION: ${{ steps.meta.outputs.version }}
|
||||||
|
TARGET_SHA: ${{ gitea.sha }}
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
apk add --no-cache python3
|
||||||
|
python3 scripts/publish_release.py "dist/${{ steps.meta.outputs.artifact }}" "dist/${{ steps.meta.outputs.artifact }}.tar.gz" "dist/${{ steps.meta.outputs.artifact }}.sha256"
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
name: gdu static musl build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- .gitea/workflows/gdu.yml
|
||||||
|
- scripts/build_gdu.sh
|
||||||
|
- scripts/publish_release.py
|
||||||
|
- versions/gdu.version
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-release:
|
||||||
|
runs-on: alpine-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Bootstrap workspace
|
||||||
|
shell: sh
|
||||||
|
env:
|
||||||
|
REPO_URL: ${{ gitea.server_url }}
|
||||||
|
REPO_NAME: ${{ gitea.repository }}
|
||||||
|
GIT_SHA: ${{ gitea.sha }}
|
||||||
|
run: |
|
||||||
|
apk add --no-cache git
|
||||||
|
workdir="$(pwd)"
|
||||||
|
tmpdir="$(mktemp -d)"
|
||||||
|
git clone --depth 1 "$REPO_URL/$REPO_NAME.git" "$tmpdir/repo"
|
||||||
|
git -C "$tmpdir/repo" fetch --depth 1 origin "$GIT_SHA"
|
||||||
|
git -C "$tmpdir/repo" checkout "$GIT_SHA"
|
||||||
|
find "$workdir" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
|
||||||
|
cp -a "$tmpdir/repo"/. "$workdir"/
|
||||||
|
|
||||||
|
- name: Read version
|
||||||
|
id: meta
|
||||||
|
shell: sh
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
version="$(tr -d ' \n\r' < versions/gdu.version)"
|
||||||
|
artifact="gdu-${version}-linux-amd64-musl-static"
|
||||||
|
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "artifact=${artifact}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Build static gdu
|
||||||
|
shell: sh
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
chmod +x scripts/build_gdu.sh
|
||||||
|
./scripts/build_gdu.sh "${{ steps.meta.outputs.version }}" "$PWD/dist"
|
||||||
|
|
||||||
|
- name: Publish release assets
|
||||||
|
shell: sh
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ gitea.token }}
|
||||||
|
GITEA_API_URL: ${{ gitea.api_url }}
|
||||||
|
REPO_OWNER: ${{ gitea.repository_owner }}
|
||||||
|
REPO_NAME: static-musl-builds
|
||||||
|
TOOL: gdu
|
||||||
|
VERSION: ${{ steps.meta.outputs.version }}
|
||||||
|
TARGET_SHA: ${{ gitea.sha }}
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
apk add --no-cache python3
|
||||||
|
python3 scripts/publish_release.py \
|
||||||
|
"dist/${{ steps.meta.outputs.artifact }}" \
|
||||||
|
"dist/${{ steps.meta.outputs.artifact }}.tar.gz" \
|
||||||
|
"dist/${{ steps.meta.outputs.artifact }}.sha256"
|
||||||
@@ -59,6 +59,7 @@ jobs:
|
|||||||
GITEA_API_URL: ${{ gitea.api_url }}
|
GITEA_API_URL: ${{ gitea.api_url }}
|
||||||
REPO_OWNER: ${{ gitea.repository_owner }}
|
REPO_OWNER: ${{ gitea.repository_owner }}
|
||||||
REPO_NAME: static-musl-builds
|
REPO_NAME: static-musl-builds
|
||||||
|
TOOL: iperf3
|
||||||
VERSION: ${{ steps.meta.outputs.version }}
|
VERSION: ${{ steps.meta.outputs.version }}
|
||||||
TARGET_SHA: ${{ gitea.sha }}
|
TARGET_SHA: ${{ gitea.sha }}
|
||||||
working-directory: ${{ gitea.workspace }}
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
name: speedtest-go static musl build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- .gitea/workflows/speedtest-go.yml
|
||||||
|
- scripts/build_speedtest-go.sh
|
||||||
|
- scripts/publish_release.py
|
||||||
|
- versions/speedtest-go.version
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-release:
|
||||||
|
runs-on: alpine-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Bootstrap workspace
|
||||||
|
shell: sh
|
||||||
|
env:
|
||||||
|
REPO_URL: ${{ gitea.server_url }}
|
||||||
|
REPO_NAME: ${{ gitea.repository }}
|
||||||
|
GIT_SHA: ${{ gitea.sha }}
|
||||||
|
run: |
|
||||||
|
apk add --no-cache git
|
||||||
|
workdir="$(pwd)"
|
||||||
|
tmpdir="$(mktemp -d)"
|
||||||
|
git clone --depth 1 "$REPO_URL/$REPO_NAME.git" "$tmpdir/repo"
|
||||||
|
git -C "$tmpdir/repo" fetch --depth 1 origin "$GIT_SHA"
|
||||||
|
git -C "$tmpdir/repo" checkout "$GIT_SHA"
|
||||||
|
find "$workdir" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
|
||||||
|
cp -a "$tmpdir/repo"/. "$workdir"/
|
||||||
|
|
||||||
|
- name: Read version
|
||||||
|
id: meta
|
||||||
|
shell: sh
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
version="$(tr -d ' \n\r' < versions/speedtest-go.version)"
|
||||||
|
artifact="speedtest-go-${version}-linux-amd64-musl-static"
|
||||||
|
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "artifact=${artifact}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Build static speedtest-go
|
||||||
|
shell: sh
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
chmod +x scripts/build_speedtest-go.sh
|
||||||
|
./scripts/build_speedtest-go.sh "${{ steps.meta.outputs.version }}" "$PWD/dist"
|
||||||
|
|
||||||
|
- name: Publish release assets
|
||||||
|
shell: sh
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ gitea.token }}
|
||||||
|
GITEA_API_URL: ${{ gitea.api_url }}
|
||||||
|
REPO_OWNER: ${{ gitea.repository_owner }}
|
||||||
|
REPO_NAME: static-musl-builds
|
||||||
|
TOOL: speedtest-go
|
||||||
|
VERSION: ${{ steps.meta.outputs.version }}
|
||||||
|
TARGET_SHA: ${{ gitea.sha }}
|
||||||
|
working-directory: ${{ gitea.workspace }}
|
||||||
|
run: |
|
||||||
|
apk add --no-cache python3
|
||||||
|
python3 scripts/publish_release.py "dist/${{ steps.meta.outputs.artifact }}" "dist/${{ steps.meta.outputs.artifact }}.tar.gz" "dist/${{ steps.meta.outputs.artifact }}.sha256"
|
||||||
@@ -2,50 +2,16 @@
|
|||||||
|
|
||||||
Automated static `musl` builds for portable Linux binaries.
|
Automated static `musl` builds for portable Linux binaries.
|
||||||
|
|
||||||
Current target:
|
## Tools
|
||||||
- `iperf3` (x86_64 / amd64)
|
- `iperf3`
|
||||||
|
- `gdu`
|
||||||
|
- `speedtest-go`
|
||||||
|
- `doggo`
|
||||||
|
- `busybox`
|
||||||
|
|
||||||
## What this repo does
|
Each release publishes:
|
||||||
|
- the raw binary
|
||||||
|
- a `.tar.gz`
|
||||||
|
- a `.sha256`
|
||||||
|
|
||||||
- Tracks a pinned upstream version in `versions/`
|
Versions are pinned in `versions/*.version` and refreshed by cron. Matching Gitea Actions workflows build and publish updated releases automatically.
|
||||||
- Builds a fully static `musl` binary with Gitea Actions
|
|
||||||
- Publishes versioned release assets to Gitea Releases
|
|
||||||
- Is designed to grow with more binaries later
|
|
||||||
|
|
||||||
## Current output
|
|
||||||
|
|
||||||
For each `iperf3` release build, the workflow publishes:
|
|
||||||
- `iperf3-<version>-linux-amd64-musl-static`
|
|
||||||
- `iperf3-<version>-linux-amd64-musl-static.tar.gz`
|
|
||||||
- `iperf3-<version>-linux-amd64-musl-static.sha256`
|
|
||||||
|
|
||||||
## Repo layout
|
|
||||||
|
|
||||||
- `versions/iperf3.version` — tracked upstream version
|
|
||||||
- `scripts/build_iperf3.sh` — static build script
|
|
||||||
- `scripts/sync_iperf3_version.py` — checks upstream and updates pinned version
|
|
||||||
- `scripts/publish_release.py` — idempotent release asset publisher for Gitea
|
|
||||||
- `.gitea/workflows/iperf3.yml` — CI pipeline
|
|
||||||
|
|
||||||
## How updates happen
|
|
||||||
|
|
||||||
1. `scripts/sync_iperf3_version.py` checks the latest upstream iperf3 release.
|
|
||||||
2. If a newer version exists, it updates `versions/iperf3.version`.
|
|
||||||
3. A commit is pushed.
|
|
||||||
4. Gitea Actions builds the static binary and uploads release assets.
|
|
||||||
|
|
||||||
## Manual local update example
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python3 scripts/sync_iperf3_version.py --update-file
|
|
||||||
if ! git diff --quiet -- versions/iperf3.version; then
|
|
||||||
git add versions/iperf3.version
|
|
||||||
git commit -m "chore(iperf3): bump to $(cat versions/iperf3.version)"
|
|
||||||
git push
|
|
||||||
fi
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
- The current workflow targets `amd64` first because that is the most broadly useful Linux target.
|
|
||||||
- The structure is intentionally generic so more binaries can be added later without reworking the repo.
|
|
||||||
|
|||||||
+11
-1
@@ -72,7 +72,6 @@ services:
|
|||||||
GITEA_INSTANCE_URL: "https://g.o4kosebezablokiruyte.ru"
|
GITEA_INSTANCE_URL: "https://g.o4kosebezablokiruyte.ru"
|
||||||
GITEA_RUNNER_REGISTRATION_TOKEN: "PUT_TOKEN_HERE"
|
GITEA_RUNNER_REGISTRATION_TOKEN: "PUT_TOKEN_HERE"
|
||||||
GITEA_RUNNER_NAME: "nl-dedicated-static-builder"
|
GITEA_RUNNER_NAME: "nl-dedicated-static-builder"
|
||||||
GITEA_RUNNER_LABELS: "alpine-latest:docker://node:20-alpine,ubuntu-latest:docker://node:20-bookworm"
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./config.yaml:/config.yaml
|
- ./config.yaml:/config.yaml
|
||||||
- ./data:/data
|
- ./data:/data
|
||||||
@@ -87,6 +86,17 @@ docker run --rm --entrypoint="" docker.io/gitea/act_runner:0.2.11 \
|
|||||||
mkdir -p data
|
mkdir -p data
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Then edit `config.yaml` and replace the default `runner.labels` block with:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
runner:
|
||||||
|
labels:
|
||||||
|
- "alpine-latest:docker://node:20-alpine"
|
||||||
|
- "ubuntu-latest:docker://node:20-bookworm"
|
||||||
|
```
|
||||||
|
|
||||||
|
This matters because when `config.yaml` already contains `runner.labels`, the container startup env `GITEA_RUNNER_LABELS` is ignored.
|
||||||
|
|
||||||
Then start it:
|
Then start it:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
Executable
+60
@@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
VERSION="${1:?usage: build_busybox.sh <version> [output_dir]}"
|
||||||
|
OUTPUT_DIR="${2:-$PWD/dist}"
|
||||||
|
PREFIX_NAME="busybox-${VERSION}-linux-amd64-musl-static"
|
||||||
|
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
|
apk add --no-cache build-base bzip2 curl file tar xz
|
||||||
|
|
||||||
|
SRCDIR="${TMPDIR:-/tmp}/busybox-src-${VERSION}"
|
||||||
|
rm -rf "$SRCDIR"
|
||||||
|
mkdir -p "$SRCDIR"
|
||||||
|
|
||||||
|
curl -fsSL "https://busybox.net/downloads/busybox-${VERSION}.tar.bz2" | tar -xj -C "$SRCDIR" --strip-components=1
|
||||||
|
|
||||||
|
cd "$SRCDIR"
|
||||||
|
make defconfig >/dev/null
|
||||||
|
|
||||||
|
set_kconfig() {
|
||||||
|
key="$1"
|
||||||
|
value="$2"
|
||||||
|
if grep -q "^${key}=" .config; then
|
||||||
|
sed -i "s#^${key}=.*#${key}=${value}#" .config
|
||||||
|
elif grep -q "^# ${key} is not set$" .config; then
|
||||||
|
sed -i "s|^# ${key} is not set$|${key}=${value}|" .config
|
||||||
|
else
|
||||||
|
echo "${key}=${value}" >> .config
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_kconfig CONFIG_STATIC y
|
||||||
|
set_kconfig CONFIG_FEATURE_SEAMLESS_XZ y
|
||||||
|
set_kconfig CONFIG_FEATURE_SEAMLESS_BZ2 y
|
||||||
|
set_kconfig CONFIG_UNXZ y
|
||||||
|
set_kconfig CONFIG_XZ y
|
||||||
|
set_kconfig CONFIG_BZIP2 y
|
||||||
|
set_kconfig CONFIG_UNZIP y
|
||||||
|
|
||||||
|
yes '' | make oldconfig >/dev/null
|
||||||
|
make -j"$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 2)" busybox
|
||||||
|
cp busybox "$OUTPUT_DIR/$PREFIX_NAME"
|
||||||
|
strip "$OUTPUT_DIR/$PREFIX_NAME" 2>/dev/null || true
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$OUTPUT_DIR"
|
||||||
|
tar -czf "${PREFIX_NAME}.tar.gz" "$PREFIX_NAME"
|
||||||
|
sha256sum "$PREFIX_NAME" "${PREFIX_NAME}.tar.gz" > "${PREFIX_NAME}.sha256"
|
||||||
|
)
|
||||||
|
|
||||||
|
file "$OUTPUT_DIR/$PREFIX_NAME"
|
||||||
|
ldd "$OUTPUT_DIR/$PREFIX_NAME" || true
|
||||||
|
|
||||||
|
if file "$OUTPUT_DIR/$PREFIX_NAME" | grep -qi 'dynamically linked'; then
|
||||||
|
echo "error: output binary is still dynamically linked" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "build OK: $OUTPUT_DIR/$PREFIX_NAME"
|
||||||
Executable
+38
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
VERSION="${1:?usage: build_doggo.sh <version> [output_dir]}"
|
||||||
|
OUTPUT_DIR="${2:-$PWD/dist}"
|
||||||
|
VERSION="${VERSION#v}"
|
||||||
|
PREFIX_NAME="doggo-${VERSION}-linux-amd64-musl-static"
|
||||||
|
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
|
apk add --no-cache curl file go git tar xz
|
||||||
|
|
||||||
|
SRCDIR="${TMPDIR:-/tmp}/doggo-src-${VERSION}"
|
||||||
|
rm -rf "$SRCDIR"
|
||||||
|
mkdir -p "$SRCDIR"
|
||||||
|
|
||||||
|
curl -fsSL "https://github.com/mr-karan/doggo/archive/refs/tags/v${VERSION}.tar.gz" | tar -xz -C "$SRCDIR" --strip-components=1
|
||||||
|
|
||||||
|
cd "$SRCDIR"
|
||||||
|
CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -trimpath -ldflags="-s -w -extldflags=-static" -o "$OUTPUT_DIR/$PREFIX_NAME" ./cmd/doggo
|
||||||
|
|
||||||
|
strip "$OUTPUT_DIR/$PREFIX_NAME" 2>/dev/null || true
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$OUTPUT_DIR"
|
||||||
|
tar -czf "${PREFIX_NAME}.tar.gz" "$PREFIX_NAME"
|
||||||
|
sha256sum "$PREFIX_NAME" "${PREFIX_NAME}.tar.gz" > "${PREFIX_NAME}.sha256"
|
||||||
|
)
|
||||||
|
|
||||||
|
file "$OUTPUT_DIR/$PREFIX_NAME"
|
||||||
|
ldd "$OUTPUT_DIR/$PREFIX_NAME" || true
|
||||||
|
|
||||||
|
if file "$OUTPUT_DIR/$PREFIX_NAME" | grep -qi 'dynamically linked'; then
|
||||||
|
echo "error: output binary is still dynamically linked" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "build OK: $OUTPUT_DIR/$PREFIX_NAME"
|
||||||
Executable
+57
@@ -0,0 +1,57 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
VERSION="${1:?usage: build_gdu.sh <version> [output_dir]}"
|
||||||
|
OUTPUT_DIR="${2:-$PWD/dist}"
|
||||||
|
PREFIX_NAME="gdu-${VERSION}-linux-amd64-musl-static"
|
||||||
|
|
||||||
|
# strip leading 'v' if passed
|
||||||
|
VERSION="${VERSION#v}"
|
||||||
|
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
|
apk add --no-cache \
|
||||||
|
curl \
|
||||||
|
file \
|
||||||
|
go \
|
||||||
|
git \
|
||||||
|
tar \
|
||||||
|
xz
|
||||||
|
|
||||||
|
# gdu uses Go modules, pull source from GitHub
|
||||||
|
SRCDIR="${TMPDIR:-/tmp}/gdu-src-${VERSION}"
|
||||||
|
rm -rf "$SRCDIR"
|
||||||
|
mkdir -p "$SRCDIR"
|
||||||
|
|
||||||
|
curl -fsSL "https://github.com/dundee/gdu/archive/refs/tags/v${VERSION}.tar.gz" \
|
||||||
|
| tar -xz -C "$SRCDIR" --strip-components=1
|
||||||
|
|
||||||
|
cd "$SRCDIR"
|
||||||
|
|
||||||
|
# Build fully static with musl toolchain
|
||||||
|
# CGO_ENABLED=0 forces pure-Go, which means no C deps at all
|
||||||
|
# ldflags: strip debug + disable dynamic linking
|
||||||
|
CGO_ENABLED=0 GOARCH=amd64 GOOS=linux \
|
||||||
|
go build \
|
||||||
|
-trimpath \
|
||||||
|
-ldflags="-s -w -extldflags=-static" \
|
||||||
|
-o "$OUTPUT_DIR/$PREFIX_NAME" \
|
||||||
|
./cmd/gdu
|
||||||
|
|
||||||
|
strip "$OUTPUT_DIR/$PREFIX_NAME" 2>/dev/null || true
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$OUTPUT_DIR"
|
||||||
|
tar -czf "${PREFIX_NAME}.tar.gz" "$PREFIX_NAME"
|
||||||
|
sha256sum "$PREFIX_NAME" "${PREFIX_NAME}.tar.gz" > "${PREFIX_NAME}.sha256"
|
||||||
|
)
|
||||||
|
|
||||||
|
file "$OUTPUT_DIR/$PREFIX_NAME"
|
||||||
|
ldd "$OUTPUT_DIR/$PREFIX_NAME" || true
|
||||||
|
|
||||||
|
if file "$OUTPUT_DIR/$PREFIX_NAME" | grep -qi 'dynamically linked'; then
|
||||||
|
echo "error: output binary is still dynamically linked" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "build OK: $OUTPUT_DIR/$PREFIX_NAME"
|
||||||
Executable
+38
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
VERSION="${1:?usage: build_speedtest-go.sh <version> [output_dir]}"
|
||||||
|
OUTPUT_DIR="${2:-$PWD/dist}"
|
||||||
|
VERSION="${VERSION#v}"
|
||||||
|
PREFIX_NAME="speedtest-go-${VERSION}-linux-amd64-musl-static"
|
||||||
|
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
|
apk add --no-cache curl file go git tar xz
|
||||||
|
|
||||||
|
SRCDIR="${TMPDIR:-/tmp}/speedtest-go-src-${VERSION}"
|
||||||
|
rm -rf "$SRCDIR"
|
||||||
|
mkdir -p "$SRCDIR"
|
||||||
|
|
||||||
|
curl -fsSL "https://github.com/showwin/speedtest-go/archive/refs/tags/v${VERSION}.tar.gz" | tar -xz -C "$SRCDIR" --strip-components=1
|
||||||
|
|
||||||
|
cd "$SRCDIR"
|
||||||
|
CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -trimpath -ldflags="-s -w -extldflags=-static" -o "$OUTPUT_DIR/$PREFIX_NAME" .
|
||||||
|
|
||||||
|
strip "$OUTPUT_DIR/$PREFIX_NAME" 2>/dev/null || true
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$OUTPUT_DIR"
|
||||||
|
tar -czf "${PREFIX_NAME}.tar.gz" "$PREFIX_NAME"
|
||||||
|
sha256sum "$PREFIX_NAME" "${PREFIX_NAME}.tar.gz" > "${PREFIX_NAME}.sha256"
|
||||||
|
)
|
||||||
|
|
||||||
|
file "$OUTPUT_DIR/$PREFIX_NAME"
|
||||||
|
ldd "$OUTPUT_DIR/$PREFIX_NAME" || true
|
||||||
|
|
||||||
|
if file "$OUTPUT_DIR/$PREFIX_NAME" | grep -qi 'dynamically linked'; then
|
||||||
|
echo "error: output binary is still dynamically linked" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "build OK: $OUTPUT_DIR/$PREFIX_NAME"
|
||||||
@@ -93,10 +93,11 @@ def main() -> int:
|
|||||||
if missing:
|
if missing:
|
||||||
raise SystemExit(f"missing files: {', '.join(missing)}")
|
raise SystemExit(f"missing files: {', '.join(missing)}")
|
||||||
|
|
||||||
tag = f"iperf3-v{version}"
|
tool = os.environ.get("TOOL", "iperf3")
|
||||||
title = f"iperf3 {version}"
|
tag = f"{tool}-v{version}"
|
||||||
|
title = f"{tool} {version}"
|
||||||
body = (
|
body = (
|
||||||
f"Static musl build for iperf3 {version}.\\n\\n"
|
f"Static musl build for {tool} {version}.\\n\\n"
|
||||||
f"Repository: {owner}/{repo}\\n"
|
f"Repository: {owner}/{repo}\\n"
|
||||||
f"Commit: {target}"
|
f"Commit: {target}"
|
||||||
)
|
)
|
||||||
|
|||||||
Executable
+54
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import urllib.request
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
DOWNLOADS_URL = "https://busybox.net/downloads/"
|
||||||
|
VERSION_RE = re.compile(r"busybox-([0-9]+(?:\.[0-9]+)+)\.tar\.bz2")
|
||||||
|
|
||||||
|
|
||||||
|
def version_key(version: str):
|
||||||
|
return tuple(int(part) for part in version.split("."))
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_latest_version() -> str:
|
||||||
|
req = urllib.request.Request(
|
||||||
|
DOWNLOADS_URL,
|
||||||
|
headers={"User-Agent": "static-musl-builds-updater"},
|
||||||
|
)
|
||||||
|
with urllib.request.urlopen(req, timeout=30) as resp:
|
||||||
|
html = resp.read().decode("utf-8", "replace")
|
||||||
|
versions = sorted(set(VERSION_RE.findall(html)), key=version_key)
|
||||||
|
if not versions:
|
||||||
|
raise RuntimeError("No BusyBox versions found on downloads page")
|
||||||
|
return versions[-1]
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--version-file", required=True, type=Path)
|
||||||
|
parser.add_argument("--update-file", action="store_true")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
latest = fetch_latest_version()
|
||||||
|
current = args.version_file.read_text(encoding="utf-8").strip() if args.version_file.exists() else ""
|
||||||
|
|
||||||
|
print(f"current={current or '<missing>'}")
|
||||||
|
print(f"latest={latest}")
|
||||||
|
|
||||||
|
if current == latest:
|
||||||
|
print("status=up-to-date")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
print("status=update-available")
|
||||||
|
if args.update_file:
|
||||||
|
args.version_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
args.version_file.write_text(latest + "\n", encoding="utf-8")
|
||||||
|
print(f"updated_file={args.version_file}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
Executable
+65
@@ -0,0 +1,65 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import urllib.request
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
VERSION_RE = re.compile(r"[0-9]+(?:\.[0-9]+)*")
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_latest_tag(repo: str) -> str:
|
||||||
|
url = f"https://api.github.com/repos/{repo}/releases/latest"
|
||||||
|
req = urllib.request.Request(
|
||||||
|
url,
|
||||||
|
headers={
|
||||||
|
"Accept": "application/vnd.github+json",
|
||||||
|
"User-Agent": "static-musl-builds-updater",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
with urllib.request.urlopen(req, timeout=30) as resp:
|
||||||
|
data = json.load(resp)
|
||||||
|
return data["tag_name"].strip()
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_version(tag: str, strip_prefix: str) -> str:
|
||||||
|
version = tag
|
||||||
|
if strip_prefix and version.startswith(strip_prefix):
|
||||||
|
version = version[len(strip_prefix):]
|
||||||
|
version = version.strip()
|
||||||
|
if not VERSION_RE.fullmatch(version):
|
||||||
|
raise ValueError(f"Unexpected version format: {tag!r} -> {version!r}")
|
||||||
|
return version
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--repo", required=True, help="owner/repo on GitHub")
|
||||||
|
parser.add_argument("--version-file", required=True, type=Path)
|
||||||
|
parser.add_argument("--strip-prefix", default="v")
|
||||||
|
parser.add_argument("--update-file", action="store_true")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
latest_tag = fetch_latest_tag(args.repo)
|
||||||
|
latest = normalize_version(latest_tag, args.strip_prefix)
|
||||||
|
current = args.version_file.read_text(encoding="utf-8").strip() if args.version_file.exists() else ""
|
||||||
|
|
||||||
|
print(f"repo={args.repo}")
|
||||||
|
print(f"current={current or '<missing>'}")
|
||||||
|
print(f"latest={latest}")
|
||||||
|
|
||||||
|
if current == latest:
|
||||||
|
print("status=up-to-date")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
print("status=update-available")
|
||||||
|
if args.update_file:
|
||||||
|
args.version_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
args.version_file.write_text(latest + "\n", encoding="utf-8")
|
||||||
|
print(f"updated_file={args.version_file}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.37.0
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.1.5
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
5.36.1
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.7.10
|
||||||
Reference in New Issue
Block a user