diff --git a/CHANGELOG.md b/CHANGELOG.md index f19c70b..ba7ab8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased [minor] + +> Development of this release was supported by [Reset Tech](https://www.reset.tech). + +### Added + +- Support deployment of Open Terms Archive Explorer + ## 3.0.0 - 2025-12-19 _Full changeset and discussions: [#58](https://github.com/OpenTermsArchive/deployment/pull/58)._ diff --git a/playbooks/deploy.yml b/playbooks/deploy.yml index f32b6fa..7efa282 100644 --- a/playbooks/deploy.yml +++ b/playbooks/deploy.yml @@ -13,6 +13,8 @@ contribution-tool {%- elif ota_federation_api_instance_repository is defined -%} federation-api + {%- elif ota_explorer_repository is defined -%} + explorer {%- else -%} unknown {%- endif -%} @@ -23,7 +25,7 @@ msg: >- Unable to detect app type. Please define one of: ota_collection_repository, ota_contribution_tool_repository, - or ota_federation_api_instance_repository in your inventory. + ota_federation_api_instance_repository, or ota_explorer_repository in your inventory. when: ota_app_type == 'unknown' - name: Display detected app type @@ -142,6 +144,38 @@ basePath: "{{ ota_federation_api_config['@opentermsarchive/federation-api'].basePath }}" port: "{{ ota_federation_api_config['@opentermsarchive/federation-api'].port }}" + # Explorer: configuration & setup + - name: Configure explorer + tags: [always] + when: ota_app_type == 'explorer' + block: + - name: Load explorer config + ansible.builtin.include_role: + name: ota/explorer + public: true + apply: + tags: [always] + vars: + ota_explorer_read_config_only: true + + - name: Set explorer variables + ansible.builtin.set_fact: + ota_chromium_required: false + ota_mongo_required: false + # Generic variables for pm2 and nginx + ota_app_directory: "{{ ota_explorer_directory }}" + ota_app_collection_id: "{{ ota_explorer_collection_id }}" + ota_app_pm2_home: "{{ ota_explorer_pm2_home }}" + # Port and basepath are read from config file by the explorer role + ota_app_endpoints: + - name: "explorer" + basePath: "{{ ota_explorer_base_path }}" + port: "{{ ota_explorer_port }}" + + - name: Setup GitHub bot SSH key + ansible.builtin.include_role: + name: github + # Infrastructure installation (common) - name: Install infrastructure become: true @@ -220,6 +254,15 @@ name: ota/federation_api public: true + # Explorer: application deployment + - name: Deploy explorer application + when: ota_app_type == 'explorer' + block: + - name: Setup explorer + ansible.builtin.include_role: + name: ota/explorer + public: true + # Process management & web server (common) - name: Manage application processes ansible.builtin.include_role: diff --git a/roles/ota/explorer/defaults/main.yml b/roles/ota/explorer/defaults/main.yml new file mode 100644 index 0000000..118c620 --- /dev/null +++ b/roles/ota/explorer/defaults/main.yml @@ -0,0 +1,9 @@ +--- +ota_explorer_read_config_only: false +ota_explorer_repository_branch: main +# Allow override of directory name for multi-instance deployment +# If not set, extract from repository URL +ota_explorer_directory: "{{ ota_explorer_directory_override | default(ota_explorer_repository | ansible.builtin.urlsplit('path') | ansible.builtin.basename | ansible.builtin.splitext | first) }}" +ota_explorer_collection_id: "{{ ota_explorer_directory }}" +ota_explorer_pm2_home: "/home/{{ ansible_user }}/.pm2-{{ ota_explorer_collection_id }}" +ota_github_bot_key_path: "/home/{{ ansible_user }}/.ssh/ota-github-bot-key-{{ ota_explorer_collection_id }}" diff --git a/roles/ota/explorer/tasks/main.yml b/roles/ota/explorer/tasks/main.yml new file mode 100644 index 0000000..ed01cef --- /dev/null +++ b/roles/ota/explorer/tasks/main.yml @@ -0,0 +1,71 @@ +--- +# Configuration is read from the config/production.json file in the inventory directory. + +- name: Check if config/production.json file exists + ansible.builtin.stat: + path: "{{ inventory_dir }}/config/production.json" + register: ota_explorer_config_file + delegate_to: localhost + +- name: Fail if config/production.json file is missing + ansible.builtin.fail: + msg: "A config/production.json file must be present in the inventory directory for explorer deployments" + when: not ota_explorer_config_file.stat.exists + +- name: Read config/production.json content + ansible.builtin.slurp: + src: "{{ inventory_dir }}/config/production.json" + register: ota_explorer_config_content_raw + delegate_to: localhost + +- name: Parse config/production.json + ansible.builtin.set_fact: + ota_explorer_config: "{{ ota_explorer_config_content_raw.content | b64decode | from_json }}" + +- name: Set explorer port from config + ansible.builtin.set_fact: + ota_explorer_port: "{{ ota_explorer_config.port }}" + +- name: Set explorer base path from config + ansible.builtin.set_fact: + ota_explorer_base_path: "{{ ota_explorer_config.basePath | default('/') }}" + +- name: Clone explorer repository + ansible.builtin.git: + repo: "{{ ota_explorer_repository }}" + dest: /home/{{ ansible_user }}/{{ ota_explorer_directory }} + version: "{{ ota_explorer_repository_branch }}" + force: true + depth: 1 + key_file: "{{ ota_github_bot_key_path | default(omit) }}" + accept_hostkey: true + when: not ota_explorer_read_config_only | bool + +- name: Set up configuration, install dependencies and build + when: not ota_explorer_read_config_only | bool + block: + - name: Copy config/production.json to server + ansible.builtin.copy: + src: "{{ inventory_dir }}/config/production.json" + dest: /home/{{ ansible_user }}/{{ ota_explorer_directory }}/config/production.json + force: true + mode: "0644" + + - name: Install dependencies + ansible.builtin.command: + cmd: npm ci + chdir: /home/{{ ansible_user }}/{{ ota_explorer_directory }} + + - name: Run type check + ansible.builtin.command: + cmd: npm run typecheck + chdir: /home/{{ ansible_user }}/{{ ota_explorer_directory }} + environment: + NODE_ENV: production + + - name: Build explorer + ansible.builtin.command: + cmd: npm run build + chdir: /home/{{ ansible_user }}/{{ ota_explorer_directory }} + environment: + NODE_ENV: production