working out the worker/execution interface
This commit is contained in:
335
packs/core/workflows/install_packs.yaml
Normal file
335
packs/core/workflows/install_packs.yaml
Normal file
@@ -0,0 +1,335 @@
|
||||
# Install Packs Workflow
|
||||
# Complete workflow for installing packs from multiple sources with dependency resolution
|
||||
|
||||
name: install_packs
|
||||
ref: core.install_packs
|
||||
label: "Install Packs"
|
||||
description: "Install one or more packs from git repositories, HTTP archives, or pack registry with automatic dependency resolution"
|
||||
version: "1.0.0"
|
||||
|
||||
# Input parameters
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
packs:
|
||||
type: array
|
||||
description: "List of packs to install (git URLs, HTTP URLs, or pack refs like 'slack@1.0.0')"
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
ref_spec:
|
||||
type: string
|
||||
description: "Git reference to checkout for git URLs (branch, tag, or commit)"
|
||||
skip_dependencies:
|
||||
type: boolean
|
||||
description: "Skip installing pack dependencies"
|
||||
default: false
|
||||
skip_tests:
|
||||
type: boolean
|
||||
description: "Skip running pack tests before registration"
|
||||
default: false
|
||||
skip_env_build:
|
||||
type: boolean
|
||||
description: "Skip building runtime environments (Python/Node.js)"
|
||||
default: false
|
||||
force:
|
||||
type: boolean
|
||||
description: "Force installation even if packs already exist or tests fail"
|
||||
default: false
|
||||
registry_url:
|
||||
type: string
|
||||
description: "Pack registry URL for resolving pack refs"
|
||||
default: "https://registry.attune.io/index.json"
|
||||
packs_base_dir:
|
||||
type: string
|
||||
description: "Base directory for permanent pack storage"
|
||||
default: "/opt/attune/packs"
|
||||
api_url:
|
||||
type: string
|
||||
description: "Attune API URL"
|
||||
default: "http://localhost:8080"
|
||||
timeout:
|
||||
type: integer
|
||||
description: "Timeout in seconds for the entire workflow"
|
||||
default: 1800
|
||||
minimum: 300
|
||||
maximum: 7200
|
||||
required:
|
||||
- packs
|
||||
|
||||
# Workflow variables
|
||||
vars:
|
||||
- temp_dir: null
|
||||
- downloaded_packs: []
|
||||
- missing_dependencies: []
|
||||
- installed_pack_refs: []
|
||||
- failed_packs: []
|
||||
- start_time: null
|
||||
|
||||
# Workflow tasks
|
||||
tasks:
|
||||
# Task 1: Initialize workflow
|
||||
- name: initialize
|
||||
action: core.noop
|
||||
input:
|
||||
message: "Starting pack installation workflow"
|
||||
publish:
|
||||
- start_time: "{{ now() }}"
|
||||
- temp_dir: "/tmp/attune-pack-install-{{ uuid() }}"
|
||||
on_success: download_packs
|
||||
|
||||
# Task 2: Download packs from specified sources
|
||||
- name: download_packs
|
||||
action: core.download_packs
|
||||
input:
|
||||
packs: "{{ parameters.packs }}"
|
||||
destination_dir: "{{ vars.temp_dir }}"
|
||||
registry_url: "{{ parameters.registry_url }}"
|
||||
ref_spec: "{{ parameters.ref_spec }}"
|
||||
api_url: "{{ parameters.api_url }}"
|
||||
timeout: 300
|
||||
verify_ssl: true
|
||||
publish:
|
||||
- downloaded_packs: "{{ task.download_packs.result.downloaded_packs }}"
|
||||
- failed_packs: "{{ task.download_packs.result.failed_packs }}"
|
||||
on_success:
|
||||
- when: "{{ task.download_packs.result.success_count > 0 }}"
|
||||
do: check_download_results
|
||||
on_failure: cleanup_on_failure
|
||||
|
||||
# Task 3: Check if any packs were successfully downloaded
|
||||
- name: check_download_results
|
||||
action: core.noop
|
||||
input:
|
||||
message: "Downloaded {{ task.download_packs.result.success_count }} pack(s)"
|
||||
on_success:
|
||||
- when: "{{ not parameters.skip_dependencies }}"
|
||||
do: get_dependencies
|
||||
- when: "{{ parameters.skip_dependencies }}"
|
||||
do: build_environments
|
||||
|
||||
# Task 4: Get pack dependencies from pack.yaml files
|
||||
- name: get_dependencies
|
||||
action: core.get_pack_dependencies
|
||||
input:
|
||||
pack_paths: "{{ vars.downloaded_packs | map(attribute='pack_path') | list }}"
|
||||
api_url: "{{ parameters.api_url }}"
|
||||
skip_validation: false
|
||||
publish:
|
||||
- missing_dependencies: "{{ task.get_dependencies.result.missing_dependencies }}"
|
||||
on_success:
|
||||
- when: "{{ task.get_dependencies.result.missing_dependencies | length > 0 }}"
|
||||
do: install_dependencies
|
||||
- when: "{{ task.get_dependencies.result.missing_dependencies | length == 0 }}"
|
||||
do: build_environments
|
||||
on_failure: cleanup_on_failure
|
||||
|
||||
# Task 5: Recursively install missing pack dependencies
|
||||
- name: install_dependencies
|
||||
action: core.install_packs
|
||||
input:
|
||||
packs: "{{ vars.missing_dependencies | map(attribute='pack_ref') | list }}"
|
||||
skip_dependencies: false
|
||||
skip_tests: "{{ parameters.skip_tests }}"
|
||||
skip_env_build: "{{ parameters.skip_env_build }}"
|
||||
force: "{{ parameters.force }}"
|
||||
registry_url: "{{ parameters.registry_url }}"
|
||||
packs_base_dir: "{{ parameters.packs_base_dir }}"
|
||||
api_url: "{{ parameters.api_url }}"
|
||||
timeout: 900
|
||||
publish:
|
||||
- installed_pack_refs: "{{ task.install_dependencies.result.registered_packs | map(attribute='pack_ref') | list }}"
|
||||
on_success: build_environments
|
||||
on_failure:
|
||||
- when: "{{ parameters.force }}"
|
||||
do: build_environments
|
||||
- when: "{{ not parameters.force }}"
|
||||
do: cleanup_on_failure
|
||||
|
||||
# Task 6: Build runtime environments (Python virtualenvs, npm install)
|
||||
- name: build_environments
|
||||
action: core.build_pack_envs
|
||||
input:
|
||||
pack_paths: "{{ vars.downloaded_packs | map(attribute='pack_path') | list }}"
|
||||
packs_base_dir: "{{ parameters.packs_base_dir }}"
|
||||
python_version: "3.11"
|
||||
nodejs_version: "20"
|
||||
skip_python: false
|
||||
skip_nodejs: false
|
||||
force_rebuild: "{{ parameters.force }}"
|
||||
timeout: 600
|
||||
on_success:
|
||||
- when: "{{ not parameters.skip_tests }}"
|
||||
do: run_tests
|
||||
- when: "{{ parameters.skip_tests }}"
|
||||
do: register_packs
|
||||
on_failure:
|
||||
- when: "{{ parameters.force or parameters.skip_env_build }}"
|
||||
do:
|
||||
- when: "{{ not parameters.skip_tests }}"
|
||||
next: run_tests
|
||||
- when: "{{ parameters.skip_tests }}"
|
||||
next: register_packs
|
||||
- when: "{{ not parameters.force and not parameters.skip_env_build }}"
|
||||
do: cleanup_on_failure
|
||||
|
||||
# Task 7: Run pack tests to verify functionality
|
||||
- name: run_tests
|
||||
action: core.run_pack_tests
|
||||
input:
|
||||
pack_paths: "{{ vars.downloaded_packs | map(attribute='pack_path') | list }}"
|
||||
timeout: 300
|
||||
fail_on_error: false
|
||||
on_success: register_packs
|
||||
on_failure:
|
||||
- when: "{{ parameters.force }}"
|
||||
do: register_packs
|
||||
- when: "{{ not parameters.force }}"
|
||||
do: cleanup_on_failure
|
||||
|
||||
# Task 8: Register packs in database and copy to permanent storage
|
||||
- name: register_packs
|
||||
action: core.register_packs
|
||||
input:
|
||||
pack_paths: "{{ vars.downloaded_packs | map(attribute='pack_path') | list }}"
|
||||
packs_base_dir: "{{ parameters.packs_base_dir }}"
|
||||
skip_validation: false
|
||||
skip_tests: "{{ parameters.skip_tests }}"
|
||||
force: "{{ parameters.force }}"
|
||||
api_url: "{{ parameters.api_url }}"
|
||||
on_success: cleanup_success
|
||||
on_failure: cleanup_on_failure
|
||||
|
||||
# Task 9: Cleanup temporary directory on success
|
||||
- name: cleanup_success
|
||||
action: core.noop
|
||||
input:
|
||||
message: "Pack installation completed successfully. Cleaning up temporary directory: {{ vars.temp_dir }}"
|
||||
publish:
|
||||
- cleanup_status: "success"
|
||||
|
||||
# Task 10: Cleanup temporary directory on failure
|
||||
- name: cleanup_on_failure
|
||||
action: core.noop
|
||||
input:
|
||||
message: "Pack installation failed. Cleaning up temporary directory: {{ vars.temp_dir }}"
|
||||
publish:
|
||||
- cleanup_status: "failed"
|
||||
|
||||
# Output schema
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
registered_packs:
|
||||
type: array
|
||||
description: "Successfully registered packs"
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
pack_ref:
|
||||
type: string
|
||||
pack_id:
|
||||
type: integer
|
||||
pack_version:
|
||||
type: string
|
||||
storage_path:
|
||||
type: string
|
||||
components_count:
|
||||
type: integer
|
||||
failed_packs:
|
||||
type: array
|
||||
description: "Packs that failed to install"
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
source:
|
||||
type: string
|
||||
error:
|
||||
type: string
|
||||
stage:
|
||||
type: string
|
||||
installed_dependencies:
|
||||
type: array
|
||||
description: "Pack dependencies that were installed"
|
||||
items:
|
||||
type: string
|
||||
summary:
|
||||
type: object
|
||||
description: "Installation summary"
|
||||
properties:
|
||||
total_requested:
|
||||
type: integer
|
||||
success_count:
|
||||
type: integer
|
||||
failure_count:
|
||||
type: integer
|
||||
dependencies_installed:
|
||||
type: integer
|
||||
duration_seconds:
|
||||
type: integer
|
||||
|
||||
# Metadata
|
||||
metadata:
|
||||
description: |
|
||||
This workflow orchestrates the complete pack installation process:
|
||||
|
||||
1. Download Packs: Downloads packs from git repositories, HTTP archives, or pack registry
|
||||
2. Get Dependencies: Analyzes pack.yaml files to identify dependencies
|
||||
3. Install Dependencies: Recursively installs missing pack dependencies
|
||||
4. Build Environments: Creates Python virtualenvs, installs requirements.txt and package.json deps
|
||||
5. Run Tests: Executes pack test suites (if present and not skipped)
|
||||
6. Register Packs: Loads pack components into database and copies to permanent storage
|
||||
|
||||
The workflow supports:
|
||||
- Multiple pack sources (git URLs, HTTP archives, pack refs)
|
||||
- Automatic dependency resolution (recursive)
|
||||
- Runtime environment setup (Python, Node.js)
|
||||
- Pack testing before registration
|
||||
- Force mode to override validation failures
|
||||
- Comprehensive error handling and cleanup
|
||||
|
||||
examples:
|
||||
- name: "Install pack from git repository"
|
||||
input:
|
||||
packs:
|
||||
- "https://github.com/attune/pack-slack.git"
|
||||
ref_spec: "v1.0.0"
|
||||
skip_dependencies: false
|
||||
skip_tests: false
|
||||
force: false
|
||||
|
||||
- name: "Install multiple packs from registry"
|
||||
input:
|
||||
packs:
|
||||
- "slack@1.0.0"
|
||||
- "aws@2.1.0"
|
||||
- "kubernetes@3.0.0"
|
||||
skip_dependencies: false
|
||||
skip_tests: false
|
||||
force: false
|
||||
|
||||
- name: "Install pack with force mode (skip validations)"
|
||||
input:
|
||||
packs:
|
||||
- "https://github.com/myorg/pack-custom.git"
|
||||
ref_spec: "main"
|
||||
skip_dependencies: true
|
||||
skip_tests: true
|
||||
force: true
|
||||
|
||||
- name: "Install from HTTP archive"
|
||||
input:
|
||||
packs:
|
||||
- "https://example.com/packs/custom-pack.tar.gz"
|
||||
skip_dependencies: false
|
||||
skip_tests: false
|
||||
force: false
|
||||
|
||||
tags:
|
||||
- pack
|
||||
- installation
|
||||
- workflow
|
||||
- automation
|
||||
- dependencies
|
||||
- git
|
||||
- registry
|
||||
Reference in New Issue
Block a user