diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..fc87a14 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,75 @@ +name: Deploy Hub + +on: + push: + branches: [main] + workflow_dispatch: + +concurrency: + group: hub-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: 60 + 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 hub + id: build + run: | + nix build .#hub --impure --option sandbox false --print-build-logs + STORE_PATH=$(readlink result) + echo "store-path=$STORE_PATH" >> "$GITHUB_OUTPUT" + echo "✅ hub: $STORE_PATH" + + - name: Setup SSH key + if: github.ref == 'refs/heads/main' + 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 hub to VPS + if: github.ref == 'refs/heads/main' + run: | + STORE_PATH="${{ steps.build.outputs.store-path }}" + echo "=== Copying hub: $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/hub --set '$STORE_PATH'" + + echo "=== Restarting service ===" + ssh "$VPS_USER@$VPS_HOST" "sudo systemctl restart hub" || echo " ⚠️ restart failed (may not be enabled yet)" + + echo "✅ hub 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 e3e0635..0000000 --- a/.github/workflows/notify-parent.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Notify Parent Repo - -on: - push: - branches: - - main - 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": "hub", - "ref": "${{ github.ref }}", - "sha": "${{ github.sha }}", - "actor": "${{ github.actor }}" - } diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..8c58452 --- /dev/null +++ b/flake.nix @@ -0,0 +1,70 @@ +{ + description = "Asepharyana Hub — personal portfolio SPA (Next.js)"; + + 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; + }; + + hub = pkgs.stdenv.mkDerivation { + name = "hub-0.1.0"; + src = ./.; + + nativeBuildInputs = with pkgs; [ bun nodejs-slim_22 ]; + buildInputs = with pkgs; [ nodejs openssl stdenv.cc.cc.lib libffi ]; + + LIBCLANG_PATH = "${pkgs.libclang.lib}/lib"; + LD_LIBRARY_PATH = "${pkgs.libclang.lib}/lib:${pkgs.stdenv.cc.cc.lib}/lib:${pkgs.libffi}/lib"; + NIX_ENFORCE_PURITY = "0"; + + SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + NODE_EXTRA_CA_CERTS = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + NODE_ENV = "production"; + + phases = [ "unpackPhase" "buildPhase" "installPhase" ]; + buildPhase = '' + export HOME="$TMPDIR" + echo "=== Installing dependencies ===" + bun install 2>&1 + echo "=== Building Next.js ===" + bun run build 2>&1 + ''; + installPhase = '' + mkdir -p $out/share/hub $out/bin + cp -r .next $out/share/hub/ + cp -r public $out/share/hub/ 2>/dev/null || true + cp package.json $out/share/hub/ + cp next.config.{ts,mjs,js} $out/share/hub/ 2>/dev/null || true + cp -r node_modules $out/share/hub/ + cat > $out/bin/hub << WRAPPER +#!${pkgs.runtimeShell} +exec ${pkgs.bun}/bin/bun run --cwd $out/share/hub start +WRAPPER + chmod +x $out/bin/hub + ''; + }; + in + { + packages = { + inherit hub; + default = hub; + }; + + apps.hub = { + type = "app"; + program = "${hub}/bin/hub"; + }; + + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ nodejs-slim_22 bun ]; + }; + }); +} \ No newline at end of file