Files
attune/packs/core/workflows/install_packs.yaml
2026-03-01 20:43:48 -06:00

331 lines
10 KiB
YAML

# 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 (StackStorm-style with inline required/secret)
parameters:
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
required: true
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
# 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: "{{ workflow.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: "{{ workflow.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: "{{ workflow.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: "{{ workflow.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: "{{ workflow.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: "{{ workflow.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: {{ workflow.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: {{ workflow.temp_dir }}"
publish:
- cleanup_status: "failed"
# Output schema
output_schema:
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