Skip to content

test: mock importlib.metadata.version in LocaleSync version test #7

test: mock importlib.metadata.version in LocaleSync version test

test: mock importlib.metadata.version in LocaleSync version test #7

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
env:
PYTHON_VERSION: "3.13"
jobs:
lint:
name: Lint & Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install dependencies
run: pip install -e ".[dev]"
- name: Ruff lint
run: python -m ruff check src/ tests/
- name: Ruff format check
run: python -m ruff format --check src/ tests/
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: pip install -e ".[dev]"
- name: Run tests
run: python -m pytest tests/ -v --tb=short --junitxml=test-results.xml
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-py${{ matrix.python-version }}
path: test-results.xml
validate-config:
name: Validate Configs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install dependencies
run: pip install -e ".[dev]"
- name: Validate manifest YAML
run: |
python -c "
from opsportal.config.manifest import load_manifest
from pathlib import Path
m = load_manifest(Path('opsportal.yaml'), Path('.'), Path('work/tools'))
print(f'Manifest OK: {len(m.enabled_tools)} tool(s) registered')
for t in m.enabled_tools:
src = f' [source: {t.source.repository}@{t.source.ref}]' if t.source else ''
print(f' - {t.slug} ({t.integration_mode}){src}')
"
build:
name: Build Package
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install build tools
run: pip install build
- name: Build wheel
run: python -m build
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
verify-install:
name: Verify Installed Package
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Download built wheel
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Install from wheel (not editable)
run: pip install dist/*.whl
- name: Verify CLI entrypoint exists
run: |
which opsportal
opsportal version
- name: Verify package metadata
run: |
python -c "
from importlib.metadata import version, entry_points
v = version('opsportal')
print(f'Installed version: {v}')
eps = [ep for ep in entry_points() if ep.group == 'console_scripts' and ep.name == 'opsportal']
assert len(eps) == 1, f'Expected 1 opsportal entrypoint, got {len(eps)}'
print(f'Entrypoint: {eps[0]}')
"
- name: Verify static assets are packaged
run: |
python -c "
from pathlib import Path
import opsportal.ui
ui_dir = Path(opsportal.ui.__file__).parent
templates = ui_dir / 'templates'
static = ui_dir / 'static'
assert templates.is_dir(), f'Templates dir missing: {templates}'
assert static.is_dir(), f'Static dir missing: {static}'
assert (templates / 'home.html').is_file(), 'home.html missing'
assert (templates / 'base.html').is_file(), 'base.html missing'
assert (static / 'css' / 'portal-base.css').is_file(), 'portal-base.css missing'
assert (static / 'js' / 'portal.js').is_file(), 'portal.js missing'
print(f'Templates: {list(templates.glob(\"*.html\"))}')
print(f'Static CSS: {list((static / \"css\").glob(\"*\"))}')
print(f'Static JS: {list((static / \"js\").glob(\"*\"))}')
print('All static assets verified')
"
- name: Verify manifest bootstrap
run: |
python -c "
from pathlib import Path
from opsportal.config.manifest import DEFAULT_MANIFEST_YAML, load_manifest
p = Path('/tmp/test-manifest.yaml')
p.write_text(DEFAULT_MANIFEST_YAML)
m = load_manifest(p, Path('/tmp'), Path('/tmp/tools'))
assert len(m.enabled_tools) == 2, f'Expected 2 tools, got {len(m.enabled_tools)}'
slugs = {t.slug for t in m.enabled_tools}
assert 'releasepilot' in slugs, 'releasepilot not found'
assert 'releaseboard' in slugs, 'releaseboard not found'
for t in m.enabled_tools:
assert t.source is not None, f'{t.slug} missing source'
assert t.port is not None, f'{t.slug} missing port'
print('Manifest bootstrap verified')
"
- name: Verify opsportal init command
run: |
cd /tmp
opsportal init test-portal.yaml
test -f test-portal.yaml
echo "Init command verified ✔"
deploy-smoke:
name: Deploy Smoke Test
runs-on: ubuntu-latest
needs: [build]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install OpsPortal from source
run: pip install ".[dev]"
- name: Install managed tools from remote sources
run: |
pip install "git+https://github.com/POLPROG-TECH/ReleasePilot.git@v1.1.0[all]" || echo "ReleasePilot install skipped (may not be public)"
pip install "git+https://github.com/POLPROG-TECH/ReleaseBoard.git@v1.1.0" || echo "ReleaseBoard install skipped (may not be public)"
- name: Verify CLI entrypoints
run: |
opsportal version
releasepilot --version || echo "ReleasePilot CLI not available"
releaseboard --version || echo "ReleaseBoard CLI not available"
- name: Verify setup command
run: |
cd /tmp
opsportal setup --manifest /tmp/smoke-test.yaml
test -f /tmp/smoke-test.yaml
echo "Setup command verified ✔"