name: offline-release on: workflow_dispatch: permissions: contents: read jobs: package-and-deploy: runs-on: build-host steps: - name: Prepare local worktree env: MAIBOT_REPO_SHA: ${{ gitea.sha }} MAIBOT_REPO_REF: ${{ gitea.ref }} MAIBOT_REPOSITORY: ${{ gitea.repository }} MAIBOT_SERVER_URL: ${{ gitea.server_url }} MAIBOT_REPO_URL: ${{ vars.MAIBOT_REPO_URL }} GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} shell: bash run: | set -euo pipefail worktree_root=/tmp/maibot-actions worktree="${worktree_root}/${MAIBOT_REPO_SHA}" rm -rf "$worktree" mkdir -p "$worktree_root" printf 'MAIBOT_WORKTREE=%s\n' "$worktree" >> "$GITHUB_ENV" repo_url="${MAIBOT_REPO_URL:-${MAIBOT_SERVER_URL%/}/${MAIBOT_REPOSITORY}.git}" auth_header="Authorization: token ${GITEA_TOKEN}" echo "Resolving repository source: $repo_url" git -c http.lowSpeedLimit=1 \ -c http.lowSpeedTime=30 \ -c http.extraHeader="$auth_header" \ ls-remote "$repo_url" "$MAIBOT_REPO_REF" git init "$worktree" git -C "$worktree" remote add origin "$repo_url" git -C "$worktree" \ -c http.lowSpeedLimit=1 \ -c http.lowSpeedTime=30 \ -c http.extraHeader="$auth_header" \ fetch --depth=1 origin "$MAIBOT_REPO_SHA" git -C "$worktree" checkout --force FETCH_HEAD git -C "$worktree" clean -dffx app_tag="$(git -C "$worktree" rev-parse --short=12 HEAD)" printf 'APP_TAG=%s\n' "$app_tag" >> "$GITHUB_ENV" - name: Build dashboard assets shell: bash run: | set -euo pipefail toolchain_root="${MAIBOT_NODE_TOOLCHAIN_ROOT:-/srv/gitea-runner-maibot/toolchains/node}" dist_bundle_root="${MAIBOT_PREBUILT_DASHBOARD_ROOT:-/srv/gitea-runner-maibot/prebuilt-dashboard}" dist_bundle="${dist_bundle_root}/${MAIBOT_REPO_SHA}.tar.gz" if [ -d "$toolchain_root/bin" ]; then export PATH="$toolchain_root/bin:$PATH" fi cd "$MAIBOT_WORKTREE/dashboard" if command -v npm >/dev/null 2>&1; then npm_cache_dir="${MAIBOT_NPM_CACHE_DIR:-/srv/gitea-runner-maibot/npm-cache}" mkdir -p "$npm_cache_dir" npm ci --cache "$npm_cache_dir" npm run build fi if [ ! -f dist/index.html ] && [ -f "$dist_bundle" ]; then echo "Using prebuilt dashboard bundle: $dist_bundle" rm -rf dist mkdir -p dist tar -xzf "$dist_bundle" -C "$MAIBOT_WORKTREE/dashboard" fi if [ ! -f dist/index.html ]; then echo "dashboard build output not found: $MAIBOT_WORKTREE/dashboard/dist/index.html" >&2 echo "Provide a working offline npm toolchain or upload a prebuilt dashboard bundle to $dist_bundle." >&2 exit 127 fi test -f dist/index.html - name: Stage release directory shell: bash run: | set -euo pipefail release_root="${MAIBOT_RELEASE_ROOT:-/srv/maibot/releases}" case "$release_root" in /srv/maibot/releases|/srv/maibot/releases/*) ;; *) echo "release root must stay under /srv/maibot/releases" >&2 exit 1 ;; esac release_dir="${release_root}/${APP_TAG}" rm -rf "$release_dir" mkdir -p "$release_dir" git -C "$MAIBOT_WORKTREE" archive HEAD | tar -x -C "$release_dir" mkdir -p "$release_dir/dashboard" cp -a "$MAIBOT_WORKTREE/dashboard/dist" "$release_dir/dashboard/dist" printf 'RELEASE_DIR=%s\n' "$release_dir" >> "$GITHUB_ENV" - name: Deploy release shell: bash run: | set -euo pipefail runtime_root="${MAIBOT_RUNTIME_ROOT:-/root/maibot-offline}" chmod +x "$RELEASE_DIR/deploy/server-maibot/activate-release.sh" MAIBOT_RUNTIME_ROOT="$runtime_root" "$RELEASE_DIR/deploy/server-maibot/activate-release.sh" "$RELEASE_DIR" - name: Cleanup worktree if: ${{ always() }} shell: bash run: | set -euo pipefail worktree_root=/tmp/maibot-actions/ case "${MAIBOT_WORKTREE:-}" in ${worktree_root}*) rm -rf "$MAIBOT_WORKTREE" ;; esac