{"id":29995511,"url":"https://github.com/seanson/octo-py","last_synced_at":"2025-08-05T01:42:20.100Z","repository":{"id":304083291,"uuid":"1017715583","full_name":"seanson/octo-py","owner":"seanson","description":"A small utility for managing Octopus Deploy release promotions at scale.","archived":false,"fork":false,"pushed_at":"2025-07-11T02:43:58.000Z","size":47,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-11T06:38:50.819Z","etag":null,"topics":["octopus-deploy","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seanson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-11T01:49:29.000Z","updated_at":"2025-07-11T02:44:01.000Z","dependencies_parsed_at":"2025-07-11T06:38:53.548Z","dependency_job_id":"7105bb3c-69f7-47fd-9175-2423b6c04701","html_url":"https://github.com/seanson/octo-py","commit_stats":null,"previous_names":["seanson/octo-py"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/seanson/octo-py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seanson%2Focto-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seanson%2Focto-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seanson%2Focto-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seanson%2Focto-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seanson","download_url":"https://codeload.github.com/seanson/octo-py/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seanson%2Focto-py/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268820439,"owners_count":24312380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-04T02:00:09.867Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["octopus-deploy","python3"],"created_at":"2025-08-05T01:42:14.039Z","updated_at":"2025-08-05T01:42:20.045Z","avatar_url":"https://github.com/seanson.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Octopus Deploy CLI\n\n[![Tests](https://github.com/seanson/octo-py/actions/workflows/test.yml/badge.svg)](https://github.com/seanson/octo-py/actions/workflows/test.yml)\n[![Python 3.13](https://img.shields.io/badge/python-3.13-blue.svg)](https://www.python.org/downloads/)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n\nA Python command-line interface for interacting with Octopus Deploy servers. This tool provides commands for managing spaces, projects, releases, and deployments.\n\n## Installation\n\n### Prerequisites\n\n- Python 3.13 or higher\n- Poetry (for dependency management)\n\n### Setup\n\n1. Clone the repository:\n\n```bash\ngit clone \u003crepository-url\u003e\ncd octo-py\n```\n\n2. Install dependencies:\n\n```bash\npoetry install\n```\n\n3. Create configuration file:\n\n```bash\nmkdir -p ~/.config/octopus\n```\n\nCreate `~/.config/octopus/cli_config.json` with your Octopus Deploy server details:\n\n```json\n{\n  \"url\": \"https://your-octopus-server.com\",\n  \"apikey\": \"API-YOUR-API-KEY-HERE\"\n}\n```\n\n## Usage\n\nRun the CLI using:\n\n```bash\npoetry run python src/main.py [COMMAND] [OPTIONS]\n```\n\n### Available Commands\n\n#### `spaces`\n\nList all spaces in your Octopus Deploy server.\n\n```bash\npoetry run python src/main.py spaces\n```\n\n**Output:**\n\n```\nSpaces-1: Default Space\nSpaces-2: Development Space\n```\n\n#### `projects`\n\nList all projects in a specific space.\n\n```bash\npoetry run python src/main.py projects \u003cspace_id\u003e\n```\n\n**Example:**\n\n```bash\npoetry run python src/main.py projects Spaces-1\n```\n\n#### `releases`\n\nList all releases for a specific project in a space.\n\n```bash\npoetry run python src/main.py releases \u003cspace_id\u003e \u003cproject_id\u003e\n```\n\n**Example:**\n\n```bash\npoetry run python src/main.py releases Spaces-1 Projects-1\n```\n\n#### `latest-release`\n\nGet the latest release deployed to a specific environment.\n\n```bash\npoetry run python src/main.py latest-release \u003cspace_id\u003e \u003cproject_id\u003e [--environment \u003cenv_name\u003e]\n```\n\n**Options:**\n\n- `--environment`: Environment name (default: \"staging\")\n\n**Example:**\n\n```bash\npoetry run python src/main.py latest-release Spaces-1 Projects-1 --environment production\n```\n\n#### `promote`\n\nPromote the latest staging release to QA environment.\n\n```bash\npoetry run python src/main.py promote \u003cspace_name\u003e \u003cproject_name\u003e\n```\n\n**Example:**\n\n```bash\npoetry run python src/main.py promote \"Default Space\" \"MyApp\"\n```\n\n#### `deploy-all`\n\nDeploy latest releases from one environment to another for all projects in a space.\n\n```bash\npoetry run python src/main.py deploy-all \u003csource_environment\u003e \u003ctarget_environment\u003e --space \u003cspace_name\u003e [OPTIONS]\n```\n\n**Required Arguments:**\n\n- `source_environment`: Source environment name (e.g., \"staging\", \"dev\")\n- `target_environment`: Target environment name (e.g., \"production\", \"qa\")\n\n**Required Options:**\n\n- `--space`: Space name (case-insensitive)\n\n**Optional Options:**\n\n- `--filter`: Filter projects by name (case-insensitive substring match)\n- `--exclude`: Exclude projects by name (case-insensitive substring match) - **can be used multiple times**\n- `--dry-run`: Show what would be deployed without actually deploying\n\n**Examples:**\n\nDeploy all projects from staging to production:\n\n```bash\npoetry run python src/main.py deploy-all staging production --space \"Default Space\"\n```\n\nDeploy with filtering:\n\n```bash\npoetry run python src/main.py deploy-all staging production --space \"Default Space\" --filter \"api\"\n```\n\nDeploy with multiple exclusions:\n\n```bash\npoetry run python src/main.py deploy-all staging production --space \"Default Space\" --exclude \"test\" --exclude \"legacy\" --exclude \"deprecated\"\n```\n\nDry run to see what would be deployed:\n\n```bash\npoetry run python src/main.py deploy-all staging production --space \"Default Space\" --dry-run\n```\n\n**Output:**\nThe command displays a progress bar while processing and then shows a summary table:\n\n```\nFound 5 projects in space 'Default Space'\nProcessing projects: 100%|████████████| 5/5 [00:30\u003c00:00,  6.12s/project]\n\n┌─────────────┬─────────────────┬────────────────────┬──────────────────┐\n│ Project     │ Staging Version │ Production Version │ Action           │\n├─────────────┼─────────────────┼────────────────────┼──────────────────┤\n│ API Service │ 2.1.0           │ 2.0.0              │ Deployed         │\n│ Web App     │ 1.5.2           │ 1.5.2              │ Already deployed │\n│ Worker      │ 3.0.1           │ N/A                │ Deployed         │\n└─────────────┴─────────────────┴────────────────────┴──────────────────┘\n\n📊 Summary: 2 deployed, 1 already deployed, 0 skipped, 0 failed\n```\n\n### Configuration\n\nThe CLI requires a configuration file at `~/.config/octopus/cli_config.json` with the following structure:\n\n```json\n{\n  \"url\": \"https://your-octopus-server.com\",\n  \"apikey\": \"API-YOUR-API-KEY-HERE\"\n}\n```\n\n**Configuration Details:**\n\n- `url`: Your Octopus Deploy server URL (without trailing slash)\n- `apikey`: Your Octopus Deploy API key\n\n### Getting an API Key\n\n1. Log in to your Octopus Deploy server\n2. Go to your user profile\n3. Navigate to \"API Keys\" tab\n4. Create a new API key\n5. Copy the key and add it to your configuration file\n\n### Features\n\n- **Case-insensitive matching**: Space names, project names, and environment names are matched case-insensitively\n- **Bulk operations**: Deploy multiple projects at once with filtering and exclusion options\n- **Progress tracking**: Visual progress bars for long-running operations\n- **Dry run mode**: Preview deployments without actually executing them\n- **Multiple exclusions**: Exclude multiple patterns by using `--exclude` multiple times\n- **Detailed reporting**: Comprehensive tables and summaries of deployment results\n\n### Error Handling\n\nThe CLI provides clear error messages for common issues:\n\n- Missing or invalid configuration file\n- Invalid API keys\n- Non-existent spaces, projects, or environments\n- Network connectivity issues\n- Deployment failures\n\n### Dependencies\n\n- `requests`: HTTP client for Octopus Deploy API\n- `click`: Command-line interface framework\n- `tqdm`: Progress bars\n- `tabulate`: Table formatting for output\n\n### Development\n\nTo set up for development:\n\n1. Install Poetry if you haven't already:\n\n```bash\ncurl -sSL https://install.python-poetry.org | python3 -\n```\n\n2. Install dependencies including development dependencies:\n\n```bash\npoetry install --with dev\n```\n\n3. Run the CLI:\n\n```bash\npoetry run python src/main.py --help\n```\n\n### Testing\n\nThe project includes comprehensive pytest tests for the OctopusClient API.\n\n#### Running Tests\n\nThe project includes a Makefile for convenient testing and development tasks.\n\n1. Install development dependencies:\n\n```bash\nmake install-dev\n```\n\n2. Run all tests:\n\n```bash\nmake test\n```\n\n3. Run tests with coverage:\n\n```bash\nmake test-cov\n```\n\n4. Run specific tests:\n\n```bash\n# Run a specific test class\nmake test-specific TEST=TestOctopusClientInitialization\n\n# Run a specific test method\nmake test-specific TEST=test_init_with_valid_config\n```\n\n5. Run linting checks with ruff:\n\n```bash\nmake lint\n```\n\n6. Format code with ruff:\n\n```bash\nmake format\n```\n\n7. Run all checks (format, lint, test):\n\n```bash\nmake check\n```\n\n8. View all available make targets:\n\n```bash\nmake help\n```\n\n#### Test Structure\n\n- `tests/test_octopus.py` - Tests for the OctopusClient API\n- `tests/conftest.py` - Shared pytest fixtures\n\n#### Test Coverage\n\nThe test suite includes:\n- Configuration and initialization tests\n- API request method tests (GET, POST, pagination)\n- Space-related operations\n- Project-related operations\n- Release and deployment operations\n- Error handling and edge cases\n\n#### Running Specific Tests\n\nRun a specific test class:\n\n```bash\npoetry run pytest tests/test_octopus.py::TestOctopusClientInitialization\n```\n\nRun a specific test:\n\n```bash\npoetry run pytest tests/test_octopus.py::TestOctopusClientInitialization::test_init_with_valid_config\n```\n\n### License\n\nThis project is licensed under the terms specified in the project configuration.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseanson%2Focto-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseanson%2Focto-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseanson%2Focto-py/lists"}