From 3be27c667eb6130696e8ce3240cbf1603bedd405 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Thu, 27 Aug 2026 19:48:19 +0700 Subject: [PATCH] ci: add standalone Nix build + deploy workflow; remove parent notify Repo is now self-contained: flake.nix (cargo + llama.cpp build) + deploy.yml (nix build -> nix copy -> nix-env profile -> systemctl restart llm-api). No longer dispatches submodule-updated to asepharyana-hub. --- .github/workflows/deploy.yml | 75 +++++++++++++++++++++++++++++ .github/workflows/notify-parent.yml | 25 ---------- flake.nix | 60 +++++++++++++++++++++++ 3 files changed, 135 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/deploy.yml delete mode 100644 .github/workflows/notify-parent.yml create mode 100644 flake.nix diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..8d19a52 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,75 @@ +name: Deploy LLM API + +on: + push: + branches: [master] + workflow_dispatch: + +concurrency: + group: llm-api-deploy + cancel-in-progress: false + +permissions: + contents: read + id-token: write + +env: + VPS_HOST: ${{ secrets.VPS_HOST }} + VPS_USER: ${{ secrets.VPS_USER }} + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + timeout-minutes: 120 + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@v22 + with: + determinate: false + extra-conf: | + sandbox = false + accept-flake-config = true + + - name: Cache Nix + uses: DeterminateSystems/magic-nix-cache-action@v14 + with: + use-flakehub: false + + - name: Build llm-api + id: build + run: | + nix build .#llm-api --impure --option sandbox false --print-build-logs + STORE_PATH=$(readlink result) + echo "store-path=$STORE_PATH" >> "$GITHUB_OUTPUT" + echo "✅ llm-api: $STORE_PATH" + + - name: Setup SSH key + if: github.ref == 'refs/heads/master' + env: + SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + run: | + mkdir -p ~/.ssh + echo "$SSH_KEY" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + sed -i 's/\r$//' ~/.ssh/id_ed25519 + ssh-keygen -y -f ~/.ssh/id_ed25519 >/dev/null 2>&1 || { echo "SSH key invalid"; exit 1; } + ssh-keyscan -H "$VPS_HOST" >> ~/.ssh/known_hosts 2>/dev/null + + - name: Deploy llm-api to VPS + if: github.ref == 'refs/heads/master' + run: | + STORE_PATH="${{ steps.build.outputs.store-path }}" + echo "=== Copying llm-api: $STORE_PATH ===" + nix copy --to "ssh://${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }}" "$STORE_PATH" + + echo "=== Updating profile ===" + ssh "$VPS_USER@$VPS_HOST" "sudo /nix/var/nix/profiles/default/bin/nix-env --profile /nix/var/nix/profiles/llm-api --set '$STORE_PATH'" + + echo "=== Restarting service ===" + ssh "$VPS_USER@$VPS_HOST" "sudo systemctl restart llm-api" || echo " ⚠️ restart failed (may not be enabled yet)" + + echo "✅ llm-api deployed" \ No newline at end of file diff --git a/.github/workflows/notify-parent.yml b/.github/workflows/notify-parent.yml deleted file mode 100644 index 232763c..0000000 --- a/.github/workflows/notify-parent.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Notify Parent Repo - -on: - push: - branches: - - master - workflow_dispatch: - -jobs: - dispatch: - runs-on: ubuntu-latest - steps: - - name: Trigger root monorepo build - uses: peter-evans/repository-dispatch@v3 - with: - token: ${{ secrets.DISPATCH_TOKEN }} - repository: asepharyana/asepharyana-hub - event-type: submodule-updated - client-payload: | - { - "service": "llm-api", - "ref": "${{ github.ref }}", - "sha": "${{ github.sha }}", - "actor": "${{ github.actor }}" - } \ No newline at end of file diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..f441967 --- /dev/null +++ b/flake.nix @@ -0,0 +1,60 @@ +{ + description = "Asepharyana LLM API — Rust llama.cpp model serving (OpenAI-compatible)"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachSystem [ "x86_64-linux" ] (system: + let + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + }; + + llm-api = pkgs.stdenv.mkDerivation { + name = "llm-api-0.1.0"; + src = ./.; + + nativeBuildInputs = with pkgs; [ + cacert curl gcc gnumake openssl pkg-config python3 libclang + rustc cargo clang cmake zlib + ]; + buildInputs = with pkgs; [ openssl stdenv.cc.cc.lib ]; + + LIBCLANG_PATH = "${pkgs.libclang.lib}/lib"; + LD_LIBRARY_PATH = "${pkgs.libclang.lib}/lib:${pkgs.stdenv.cc.cc.lib}/lib"; + NIX_ENFORCE_PURITY = "0"; + + SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + + phases = [ "unpackPhase" "buildPhase" "installPhase" ]; + buildPhase = '' + export HOME="$TMPDIR" CARGO_HOME="$TMPDIR/.cargo-llm-api" + echo "=== Building llm-api ===" + cargo build --release 2>&1 + ''; + installPhase = '' + mkdir -p $out/bin + cp target/release/llm-api $out/bin/llm-api + ''; + }; + in + { + packages = { + inherit llm-api; + default = llm-api; + }; + + apps.llm-api = { + type = "app"; + program = "${llm-api}/bin/llm-api"; + }; + + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ rustc cargo clang cmake openssl pkg-config ]; + }; + }); +} \ No newline at end of file