name: Release on: push: tags: - 'RELEASE.*' permissions: contents: write packages: write jobs: build: runs-on: ubuntu-latest strategy: matrix: include: - goos: linux goarch: amd64 - goos: linux goarch: arm64 - goos: windows goarch: amd64 ext: .exe - goos: darwin goarch: arm64 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-go@v5 with: go-version: 1.25.x - name: Build binary env: CGO_ENABLED: 0 BUCKIT_RELEASE: RELEASE run: | # Extract timestamp from tag (e.g., RELEASE.2026-05-10T21-48-00Z.rc1 -> 2026-05-10T21-48-00Z) VERSION=$(echo "${{ github.ref_name }}" | sed 's/^RELEASE\.//' | sed 's/\.rc[0-9]*$//') # Pass RC suffix via BUCKIT_HOTFIX so it's embedded in the binary's ReleaseTag if [[ "${{ github.ref_name }}" =~ \.(rc[0-9]+)$ ]]; then export BUCKIT_HOTFIX="${BASH_REMATCH[1]}" fi LDFLAGS=$(go run buildscripts/gen-ldflags.go "${VERSION}") GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} go build -tags kqueue -trimpath --ldflags "${LDFLAGS}" -o buckit-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}.${{ github.ref_name }} - name: Generate checksum run: | sha256sum buckit-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}.${{ github.ref_name }} > buckit-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}.${{ github.ref_name }}.sha256sum - name: Sign with minisign env: MINISIGN_PRIVATE_KEY: ${{ secrets.MINISIGN_PRIVATE_KEY }} MINISIGN_PASSWORD: ${{ secrets.MINISIGN_PASSWORD }} run: | go install aead.dev/minisign/cmd/minisign@v0.2.1 echo "$MINISIGN_PRIVATE_KEY" | base64 -d > /tmp/minisign.key echo "$MINISIGN_PASSWORD" | minisign -Sm buckit-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}.${{ github.ref_name }} -s /tmp/minisign.key shred -u /tmp/minisign.key - name: Build packages if: matrix.goos == 'linux' env: NFPM_VERSION: 2.46.3 PKG_ARCH: ${{ matrix.goarch }} run: | wget -q "https://github.com/goreleaser/nfpm/releases/download/v${NFPM_VERSION}/nfpm_${NFPM_VERSION}_amd64.deb" sudo apt install -y "./nfpm_${NFPM_VERSION}_amd64.deb" mkdir -p dist cp "buckit-linux-${PKG_ARCH}.${{ github.ref_name }}" dist/buckit # Convert RELEASE.2026-05-11T17-20-40Z[.rcN] -> 20260511172040.0.0 PKG_VERSION=$(echo "${{ github.ref_name }}" | sed 's/^RELEASE\.//' | sed 's/\.rc[0-9]*$//' | tr -d '\-:TZ').0.0 export PKG_VERSION for pkg in rpm deb apk; do nfpm package -f packaging/nfpm.yaml -p "$pkg" -t dist/ done - name: Generate package checksums if: matrix.goos == 'linux' run: | for pkg in dist/*.deb dist/*.rpm dist/*.apk; do sha256sum "$pkg" > "${pkg}.sha256sum" done - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: build-${{ matrix.goos }}-${{ matrix.goarch }} path: | buckit-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}.${{ github.ref_name }} buckit-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}.${{ github.ref_name }}.sha256sum buckit-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}.${{ github.ref_name }}.minisig dist/*.deb dist/*.rpm dist/*.apk dist/*.deb.sha256sum dist/*.rpm.sha256sum dist/*.apk.sha256sum docker: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: path: artifacts merge-multiple: true - name: Prepare binaries for Docker run: | cp artifacts/buckit-linux-amd64.${{ github.ref_name }} buckit-amd64.${{ github.ref_name }} cp artifacts/buckit-linux-arm64.${{ github.ref_name }} buckit-arm64.${{ github.ref_name }} cp artifacts/buckit-linux-amd64.${{ github.ref_name }}.minisig buckit-amd64.${{ github.ref_name }}.minisig cp artifacts/buckit-linux-arm64.${{ github.ref_name }}.minisig buckit-arm64.${{ github.ref_name }}.minisig chmod +x buckit-*.${{ github.ref_name }} - uses: docker/setup-qemu-action@v3 - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Determine tags id: tags run: | TAGS="ghcr.io/buckit-io/buckit:${{ github.ref_name }}" TAGS="${TAGS},docker.io/buckitio/buckit:${{ github.ref_name }}" if [[ "${{ github.ref_name }}" != *".rc"* ]]; then TAGS="${TAGS},ghcr.io/buckit-io/buckit:latest" TAGS="${TAGS},docker.io/buckitio/buckit:latest" fi echo "tags=${TAGS}" >> $GITHUB_OUTPUT - uses: docker/build-push-action@v5 with: context: . file: Dockerfile platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.tags.outputs.tags }} build-args: | RELEASE=${{ github.ref_name }} publish: needs: [build, docker] runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v4 with: path: artifacts merge-multiple: true - name: Prepare release assets run: | mkdir -p release-assets find artifacts -type f \ ! -name 'buckit.rpm' \ ! -name 'buckit.deb' \ ! -name 'buckit.apk' \ ! -name 'buckit.rpm.sha256sum' \ ! -name 'buckit.deb.sha256sum' \ ! -name 'buckit.apk.sha256sum' \ -exec cp {} release-assets/ \; - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: generate_release_notes: true prerelease: ${{ contains(github.ref_name, '.rc') }} files: release-assets/* update-gh-pages: if: "!contains(github.ref_name, '.rc')" needs: [build, publish] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: ref: gh-pages path: pages - uses: actions/checkout@v4 with: path: src - uses: actions/download-artifact@v4 with: path: artifacts merge-multiple: true - name: Publish install scripts run: | cp src/packaging/install-linux.sh pages/install-linux.sh cp src/packaging/install-mac.sh pages/install-mac.sh cp src/packaging/install-windows.ps1 pages/install-windows.ps1 chmod +x pages/install-linux.sh pages/install-mac.sh - name: Write self-update checksum files run: | tag="${{ github.ref_name }}" # Rebuild the release tree from scratch to remove any stale assets. rm -rf pages/server/buckit/release pages/server/buckit/archives mkdir -p \ pages/server/buckit/release/linux-amd64 \ pages/server/buckit/release/linux-arm64 \ pages/server/buckit/release/windows-amd64 \ pages/server/buckit/release/darwin-arm64 \ pages/server/buckit/archives sha=$(awk '{print $1}' "artifacts/buckit-linux-amd64.${tag}.sha256sum") echo "${sha} buckit.${tag}" > "pages/server/buckit/release/linux-amd64/buckit.sha256sum" sha=$(awk '{print $1}' "artifacts/buckit-linux-arm64.${tag}.sha256sum") echo "${sha} buckit.${tag}" > "pages/server/buckit/release/linux-arm64/buckit.sha256sum" sha=$(awk '{print $1}' "artifacts/buckit-windows-amd64.exe.${tag}.sha256sum") echo "${sha} buckit.exe.${tag}" > "pages/server/buckit/release/windows-amd64/buckit.sha256sum" sha=$(awk '{print $1}' "artifacts/buckit-darwin-arm64.${tag}.sha256sum") echo "${sha} buckit.${tag}" > "pages/server/buckit/release/darwin-arm64/buckit.sha256sum" - name: Generate release index page run: | tag="${{ github.ref_name }}" base="https://github.com/buckit-io/buckit/releases/download/${tag}" PKG_VERSION=$(echo "${tag}" | sed 's/^RELEASE\.//' | sed 's/\.rc[0-9]*$//' | tr -d '\-:TZ').0.0 cat > pages/server/buckit/release/index.html < Buckit ${tag}
Latest Stable Release

Buckit

Signed release binaries for the Buckit S3-compatible object storage server.

Release tag ${tag}
Repository buckit-io/buckit

Install

One-line installers that download the right artifact for your platform, verify its SHA-256 checksum, and print the command to finish. They do not install for you — the privileged step is yours to review and run.

PlatformCommand
Linuxrpm / deb / apk curl -fsSL https://buckit-io.github.io/buckit/install-linux.sh | sh
macOSApple Silicon curl -fsSL https://buckit-io.github.io/buckit/install-mac.sh | sh
Windowsx86_64 irm https://buckit-io.github.io/buckit/install-windows.ps1 | iex

Downloads

Choose the binary for your OS and architecture. Each platform card includes the signed artifact, checksum, and minisign signature.

PlatformBinaryChecksumSignature
Linux x86_64Standard Linux buckit-linux-amd64.${tag} .sha256sum .minisig
Linux arm64ARM64 Linux buckit-linux-arm64.${tag} .sha256sum .minisig
macOS arm64Apple Silicon buckit-darwin-arm64.${tag} .sha256sum .minisig
Windows x86_6464-bit Windows buckit-windows-amd64.exe.${tag} .sha256sum .minisig

Linux packages

Native packages for Debian/Ubuntu, RPM, and Alpine distributions.

HTML - name: Generate archives index page env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | gh api repos/buckit-io/buckit/releases --paginate \ --jq '.[] | select(.prerelease == false) | {tag: .tag_name, date: .published_at[:10], url: .html_url}' \ > /tmp/releases.jsonl python3 - /tmp/releases.jsonl pages/server/buckit/archives/index.html <<'PYEOF' import json, html, sys releases = [json.loads(line) for line in open(sys.argv[1]) if line.strip()] rows = '\n'.join( f'' f'{html.escape(r["date"])}' f'{html.escape(r["tag"])}' f'Assets →' f'' for r in releases ) page = f''' Buckit Releases
Release Archive

Buckit Releases

Stable Buckit releases published to GitHub. Open any release to inspect artifacts, checksums, and signed binaries, or jump back to the current release landing page.

{rows}
DateReleaseDownloads
''' with open(sys.argv[2], 'w') as f: f.write(page) PYEOF - name: Deploy to gh-pages uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./pages force_orphan: true