diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..9ae6a71 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: Bug Report +about: Report a bug in the Tekton task or Python script +title: '[BUG] ' +labels: bug +assignees: '' +--- + +## Description + + + +## Steps to Reproduce + +1. +2. +3. + +## Expected Behavior + + + +## Actual Behavior + + + +## Environment + +- OCP/Kubernetes version: +- Tekton version: +- OPM version: + +## Logs + + + +``` +paste logs here +``` diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..d42f16c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature Request +about: Suggest a new feature or enhancement +title: '[FEATURE] ' +labels: enhancement +assignees: '' +--- + +## Description + + + +## Use Case + + + +## Proposed Solution + + + +## Alternatives Considered + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..a7a80d3 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,17 @@ +## Summary + + + +## Related Issues + + + +## Testing + +- [ ] Tests added/updated +- [ ] All tests pass (`pytest`) + +## Checklist + +- [ ] Code follows project conventions +- [ ] Documentation updated if needed diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b0f5089 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: pip + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25bc25d --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtual environments +.venv/ +venv/ +ENV/ + +# Testing +.pytest_cache/ +.coverage +htmlcov/ +.tox/ +.nox/ + +# IDE +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# AgentReady reports +.agentready/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..e7cd9da --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,21 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.4.4 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format + + - repo: https://github.com/compilerla/conventional-pre-commit + rev: v3.2.0 + hooks: + - id: conventional-pre-commit + stages: [commit-msg] diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..219e38f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,81 @@ +# iib-tekton-utils + +Tekton task for building multi-architecture Operator Index Images (IIB) using Python orchestration with buildah. + +## What This Does + +Builds container images for OLM file-based catalogs across multiple architectures (amd64, arm64, ppc64le, s390x), generates OPM cache, and pushes multi-arch manifest lists. + +## Tech Stack + +- Python 3.9+ (orchestration) +- Tekton Tasks (Kubernetes CI/CD) +- Buildah (container builds) +- OPM (Operator Package Manager) +- pytest (testing) + +## Key Files + +- `task/iib-image-builder-oci-ta/iib-image-builder-oci-ta.yaml` - Tekton Task definition +- `task/iib-image-builder-oci-ta/multi-arch-builder.py` - Python build orchestrator +- `Containerfile.iib-build-task` - Container image for the build task +- `pyproject.toml` - Project config and test dependencies + +## Directory Structure + +``` +task/iib-image-builder-oci-ta/ # Tekton task + Python script +tests/ + conftest.py # Shared fixtures, module loader for hyphenated filename + unit/test_multi_arch_builder.py # Unit tests for Python script + tekton/test_iib_image_builder_task.py # YAML structure validation +.github/workflows/ # CI workflows +``` + +## Commands + +```bash +# Install test dependencies +pip install ".[test]" + +# Run all tests +pytest + +# Run unit tests only +pytest tests/unit/ + +# Run Tekton task validation tests only +pytest tests/tekton/ + +# Single-file lint (fast feedback) +ruff check task/iib-image-builder-oci-ta/multi-arch-builder.py + +# Single-file type check +mypy task/iib-image-builder-oci-ta/multi-arch-builder.py + +# Build container image +buildah build -f Containerfile.iib-build-task -t iib-build-task:latest . + +# Setup pre-commit hooks +pip install pre-commit && pre-commit install +``` + +## Pattern References + +- **Adding a new Tekton parameter**: Follow pattern in `task/iib-image-builder-oci-ta/iib-image-builder-oci-ta.yaml:17-58` +- **Adding retry logic**: See `_build_image()` at multi-arch-builder.py:271 for tenacity decorator pattern +- **Adding a new test class**: Follow `TestRunCmd` pattern in tests/unit/test_multi_arch_builder.py:66 + +## Architecture Notes + +- `MultiArchBuilder` class in multi-arch-builder.py:201 orchestrates the build +- `generate_cache_locally()` at :144 runs OPM to create FBC cache +- Retry logic via tenacity for buildah operations (:271, :365) +- Exception hierarchy: `IIBBaseException` > `IIBError`, `ExternalServiceError` +- Tests use `conftest.py` to load hyphenated `multi-arch-builder.py` via importlib + +## Test Coverage + +- Unit tests mock all subprocess/filesystem calls (no container runtime needed) +- Tekton tests validate YAML structure with pyyaml (no cluster needed) +- Key fixtures: `build_config`, `builder` (conftest.py:46, :62) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a2b9156 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +# Pinned dependencies for reproducible builds +# Generated from pyproject.toml + +# Runtime dependencies +tenacity==8.2.3 + +# Test dependencies +pytest==8.2.1 +pytest-mock==3.14.0 +PyYAML==6.0.1