name: Build & Publish on: push: tags: ["v*"] workflow_dispatch: {} jobs: build_publish: runs-on: ubuntu-latest steps: - name: Install deps (Ubuntu) run: | sudo apt-get update sudo apt-get install -y \ build-essential git ca-certificates curl tar gzip python3 - name: Checkout uses: actions/checkout@v4 - name: Cache Rust toolchain uses: actions/cache@v4 with: path: | ~/.cargo/bin ~/.rustup ~/.cargo/registry ~/.cargo/git key: ${{ runner.os }}-rustup-${{ hashFiles('rust-toolchain.toml') }} restore-keys: | ${{ runner.os }}-rustup- - name: Cache Cargo build uses: actions/cache@v4 with: path: | target key: ${{ runner.os }}-cargo-target-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo-target- - name: Install Rust (stable) shell: bash run: | set -e if [ ! -x "$HOME/.cargo/bin/cargo" ]; then curl -fsSL https://sh.rustup.rs | sh -s -- -y --default-toolchain stable fi echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - name: Debug workspace shell: bash run: | set -e pwd ls -la - name: Read package name id: pkg_meta shell: bash run: | set -e if [ -f Cargo.toml ]; then PKG_NAME="$(cargo metadata --no-deps --format-version=1 2>/dev/null | python3 -c 'import json,sys; data=json.load(sys.stdin); names=[t.get("name","") for p in data.get("packages", []) for t in p.get("targets", []) if "bin" in t.get("kind", [])]; print(names[0] if names else "")')" if [ -z "${PKG_NAME:-}" ]; then PKG_NAME="$(sed -n 's/^name = \"\\(.*\\)\"/\\1/p' Cargo.toml | head -n 1)" fi fi if [ -z "${PKG_NAME:-}" ]; then FULL="${GITHUB_REPOSITORY:-}" if [ -z "$FULL" ]; then echo "Could not read Cargo.toml and GITHUB_REPOSITORY is empty" exit 1 fi PKG_NAME="${FULL##*/}" echo "Cargo.toml missing or unreadable. Falling back to repo name: $PKG_NAME" fi echo "pkg_name=$PKG_NAME" >> "$GITHUB_OUTPUT" - name: Compute versions id: version_meta shell: bash run: | set -euo pipefail CARGO_VER="$(python3 - << 'PY' import re txt = open("Cargo.toml", "r", encoding="utf-8").read() m = re.search(r'(?m)^\s*version\s*=\s*"([^"]+)"\s*$', txt) print(m.group(1) if m else "") PY )" if [ -z "$CARGO_VER" ]; then echo "Could not read version from Cargo.toml" exit 1 fi REF="${GITHUB_REF_NAME:-}" SHA="${GITHUB_SHA:-}" SHORT_SHA="${SHA:0:8}" if [[ "$REF" == v* ]]; then PKG_VERSION="${REF#v}" else PKG_VERSION="${CARGO_VER}+g${SHORT_SHA}" fi echo "cargo_version=$CARGO_VER" >> "$GITHUB_OUTPUT" echo "pkg_version=$PKG_VERSION" >> "$GITHUB_OUTPUT" - name: Create source tarball (code) shell: bash run: | set -e FULL="${GITHUB_REPOSITORY:-}" if [ -z "$FULL" ]; then echo "GITHUB_REPOSITORY is empty. Set it in runner env or switch to explicit OWNER/REPO vars." exit 1 fi OWNER="${FULL%%/*}" REPO="${FULL##*/}" PKG_VERSION="${{ steps.version_meta.outputs.pkg_version }}" BIN_NAME="${{ steps.pkg_meta.outputs.pkg_name }}" mkdir -p dist # Clean source snapshot of the repository at current commit git archive --format=tar.gz \ --prefix="${BIN_NAME}-${PKG_VERSION}/" \ -o "dist/${BIN_NAME}-${PKG_VERSION}-source.tar.gz" \ HEAD ls -lh dist # OPTIONAL: build binary and package it too - name: Build (release) shell: bash run: | set -e cargo build --release - name: Collect binary shell: bash run: | set -e FULL="${GITHUB_REPOSITORY:-}" if [ -z "$FULL" ]; then echo "GITHUB_REPOSITORY is empty. Set it in runner env or switch to explicit OWNER/REPO vars." exit 1 fi REPO="${FULL##*/}" PKG_VERSION="${{ steps.version_meta.outputs.pkg_version }}" BIN_NAME="${{ steps.pkg_meta.outputs.pkg_name }}" mkdir -p dist cp "target/release/${BIN_NAME}" "dist/${BIN_NAME}-${PKG_VERSION}-linux-x86_64" chmod +x "dist/${BIN_NAME}-${PKG_VERSION}-linux-x86_64" ls -lh dist - name: Upload to Gitea Generic Packages shell: bash env: BASE_URL: ${{ vars.BASE_URL }} GITEA: ${{ secrets.GITEA }} run: | set -e FULL="${GITHUB_REPOSITORY:-}" if [ -z "$FULL" ]; then echo "GITHUB_REPOSITORY is empty. Set it in runner env or switch to explicit OWNER/REPO vars." exit 1 fi OWNER="${FULL%%/*}" REPO="${FULL##*/}" PKG_VERSION="${{ steps.version_meta.outputs.pkg_version }}" BIN_NAME="${{ steps.pkg_meta.outputs.pkg_name }}" if [ -z "${BASE_URL:-}" ]; then echo "Missing vars.BASE_URL (example: https://gitea.example.com)" exit 1 fi if [ -z "${GITEA:-}" ]; then echo "Missing secrets.GITEA" exit 1 fi # Choose a package name (keep stable). Here: cargo package name. PACKAGE_NAME="$BIN_NAME" for FILE in dist/*; do FILENAME="$(basename "$FILE")" URL="${BASE_URL}/api/packages/${OWNER}/generic/${PACKAGE_NAME}/${PKG_VERSION}/${FILENAME}" echo "Uploading $FILENAME -> $URL" curl -fsS -X PUT \ -H "Authorization: token ${GITEA}" \ --upload-file "$FILE" \ "$URL" done