--- # Development mode installation - Clone repo, build from source, link globally - name: Create code directory ansible.builtin.file: path: "{{ openclaw_code_dir }}" state: directory owner: "{{ openclaw_user }}" group: "{{ openclaw_user }}" mode: '0755' - name: Check if openclaw repository already exists ansible.builtin.stat: path: "{{ openclaw_repo_dir }}/.git" register: openclaw_repo_exists - name: Clone openclaw repository ansible.builtin.git: repo: "{{ openclaw_repo_url }}" dest: "{{ openclaw_repo_dir }}" version: "{{ openclaw_repo_branch }}" update: true become: true become_user: "{{ openclaw_user }}" when: not openclaw_repo_exists.stat.exists - name: Pull latest changes if repo exists ansible.builtin.git: repo: "{{ openclaw_repo_url }}" dest: "{{ openclaw_repo_dir }}" version: "{{ openclaw_repo_branch }}" update: true become: true become_user: "{{ openclaw_user }}" when: openclaw_repo_exists.stat.exists register: git_pull_result - name: Display git pull status ansible.builtin.debug: msg: "Git repository updated: {{ git_pull_result.changed | default(false) }}" when: openclaw_repo_exists.stat.exists - name: Install dependencies with pnpm ansible.builtin.shell: cmd: pnpm install chdir: "{{ openclaw_repo_dir }}" executable: /bin/bash become: true become_user: "{{ openclaw_user }}" environment: PNPM_HOME: "{{ openclaw_home }}/.local/share/pnpm" PATH: "{{ openclaw_home }}/.local/bin:{{ openclaw_home }}/.local/share/pnpm:/usr/local/bin:/usr/bin:/bin" HOME: "{{ openclaw_home }}" register: pnpm_install_result changed_when: "'Already up to date' not in pnpm_install_result.stdout" - name: Build openclaw from source ansible.builtin.shell: cmd: pnpm build chdir: "{{ openclaw_repo_dir }}" executable: /bin/bash become: true become_user: "{{ openclaw_user }}" environment: PNPM_HOME: "{{ openclaw_home }}/.local/share/pnpm" PATH: "{{ openclaw_home }}/.local/bin:{{ openclaw_home }}/.local/share/pnpm:/usr/local/bin:/usr/bin:/bin" HOME: "{{ openclaw_home }}" register: pnpm_build_result changed_when: true # Build always changes dist/ directory - name: Display build output ansible.builtin.debug: msg: "Build completed successfully" when: pnpm_build_result.rc == 0 - name: Check if dist directory exists ansible.builtin.stat: path: "{{ openclaw_repo_dir }}/dist" register: dist_dir - name: Fail if build didn't create dist directory ansible.builtin.fail: msg: "Build failed - dist directory not found" when: not dist_dir.stat.exists - name: Check for package metadata ansible.builtin.stat: path: "{{ openclaw_repo_dir }}/package.json" register: openclaw_package_json_stat - name: Read package metadata ansible.builtin.slurp: src: "{{ openclaw_repo_dir }}/package.json" register: openclaw_package_json_raw when: openclaw_package_json_stat.stat.exists - name: Parse package metadata ansible.builtin.set_fact: openclaw_package_json: "{{ openclaw_package_json_raw.content | b64decode | from_json }}" when: openclaw_package_json_stat.stat.exists - name: Resolve metadata-defined CLI entrypoint ansible.builtin.set_fact: openclaw_package_bin_entry: >- {{ openclaw_package_json.bin if openclaw_package_json.bin is string else ( openclaw_package_json.bin.openclaw if openclaw_package_json.bin is mapping and 'openclaw' in openclaw_package_json.bin else ( (openclaw_package_json.bin | dict2items | map(attribute='value') | list | first) if openclaw_package_json.bin is mapping else '' ) ) }} when: openclaw_package_json_stat.stat.exists - name: Build CLI entrypoint candidate list ansible.builtin.set_fact: openclaw_cli_candidate_paths: >- {{ [ openclaw_package_bin_entry | default(''), 'openclaw.mjs', 'bin/openclaw.js', 'dist/index.js' ] | reject('equalto', '') | unique | list }} - name: Check possible OpenClaw CLI entrypoints ansible.builtin.stat: path: "{{ openclaw_repo_dir }}/{{ item }}" loop: "{{ openclaw_cli_candidate_paths }}" register: openclaw_cli_candidates - name: Resolve OpenClaw CLI entrypoint path ansible.builtin.set_fact: openclaw_cli_entry: >- {{ ( openclaw_cli_candidates.results | selectattr('stat.exists') | map(attribute='stat.path') | list | first ) | default('') }} changed_when: false - name: Fail if openclaw CLI entrypoint is missing ansible.builtin.fail: msg: >- Unable to locate OpenClaw CLI entrypoint in {{ openclaw_repo_dir }}. Expected one of: {{ openclaw_cli_candidate_paths | join(', ') }} when: openclaw_cli_entry == "" - name: Remove existing global openclaw symlink (if any) ansible.builtin.file: path: "{{ openclaw_home }}/.local/bin/openclaw" state: absent - name: Create symlink to openclaw binary ansible.builtin.file: src: "{{ openclaw_cli_entry }}" dest: "{{ openclaw_home }}/.local/bin/openclaw" state: link owner: "{{ openclaw_user }}" group: "{{ openclaw_user }}" force: true - name: Make openclaw binary executable ansible.builtin.file: path: "{{ openclaw_cli_entry }}" mode: '0755' owner: "{{ openclaw_user }}" group: "{{ openclaw_user }}" - name: Verify openclaw installation from development build ansible.builtin.shell: cmd: openclaw --version executable: /bin/bash become: true become_user: "{{ openclaw_user }}" environment: PNPM_HOME: "{{ openclaw_home }}/.local/share/pnpm" PATH: "{{ openclaw_home }}/.local/bin:{{ openclaw_home }}/.local/share/pnpm:/usr/local/bin:/usr/bin:/bin" HOME: "{{ openclaw_home }}" register: openclaw_dev_version changed_when: false - name: Display installed OpenClaw version (development build) ansible.builtin.debug: msg: | OpenClaw installed from source: {{ openclaw_dev_version.stdout }} Repository: {{ openclaw_repo_dir }} Binary: {{ openclaw_home }}/.local/bin/openclaw -> {{ openclaw_cli_entry }} - name: Add development mode info to .bashrc ansible.builtin.blockinfile: path: "{{ openclaw_home }}/.bashrc" marker: "# {mark} ANSIBLE MANAGED BLOCK - OpenClaw development" block: | # OpenClaw development mode export OPENCLAW_DEV_DIR="{{ openclaw_repo_dir }}" # Aliases for development alias openclaw-rebuild='cd {{ openclaw_repo_dir }} && pnpm build' alias openclaw-dev='cd {{ openclaw_repo_dir }}' alias openclaw-pull='cd {{ openclaw_repo_dir }} && git pull && pnpm install && pnpm build' create: true owner: "{{ openclaw_user }}" group: "{{ openclaw_user }}" mode: '0644'