import fcntl import os import subprocess import sys import zipfile from pathlib import Path def test_repo_upgrade_refuses_concurrent_run(tmp_path): script = Path(__file__).parents[1] / "deploy" / "repo-upgrade.sh" lock_path = tmp_path / "repo-upgrade.lock" bin_dir = tmp_path / "bin" bin_dir.mkdir() fake_id = bin_dir / "id" fake_id.write_text("#!/bin/sh\nprintf '0\\n'\n") fake_id.chmod(0o755) with lock_path.open("w") as lock: fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB) result = subprocess.run( ["sh", str(script)], env={ **os.environ, "PATH": f"{bin_dir}:{os.environ['PATH']}", "IMPORTARR_ENV_FILE": str(tmp_path / "missing.env"), "IMPORTARR_PREFIX": str(tmp_path), }, capture_output=True, text=True, check=False, ) assert result.returncode == 1 assert "another Importarr upgrade is already running" in result.stderr def test_wheel_contains_built_frontend_assets(tmp_path): root = Path(__file__).parents[1] subprocess.run( [sys.executable, "-m", "pip", "wheel", "--no-deps", "--wheel-dir", str(tmp_path), str(root)], check=True, capture_output=True, text=True, ) wheel = next(tmp_path.glob("importarr-*.whl")) with zipfile.ZipFile(wheel) as archive: packaged = set(archive.namelist()) assert "importarr/static/index.html" in packaged assert "importarr/static/assets/app.js" in packaged assert "importarr/static/assets/app.css" in packaged def test_repo_upgrade_forces_fresh_install_without_skipping_dependencies(): script = (Path(__file__).parents[1] / "deploy/repo-upgrade.sh").read_text() assert "pip\" install --upgrade --force-reinstall --no-cache-dir" in script assert "--no-deps" not in script assert '"${WHEEL:-$REPO_DIR}"' in script def test_deploy_workflow_pins_built_wheel_to_triggering_revision(): workflow = (Path(__file__).parents[1] / ".gitea/workflows/deploy.yml").read_text() assert "actions/upload-artifact@v4" in workflow assert "actions/download-artifact@v4" in workflow assert "scp -P" in workflow assert "DEPLOY_SHA: ${{ github.sha }}" in workflow assert "git checkout --detach $DEPLOY_SHA" in workflow assert "repo-upgrade.sh /tmp/importarr-deploy.whl $DEPLOY_SHA" in workflow def test_deploy_workflow_cleans_up_without_masking_deployment_failure(): workflow = (Path(__file__).parents[1] / ".gitea/workflows/deploy.yml").read_text() capture = "|| deploy_status=\\$?;" cleanup = "rm -f /tmp/importarr-deploy.whl;" propagate = "exit \\$deploy_status" assert "deploy_status=0; sudo" in workflow assert workflow.index(capture) < workflow.index(cleanup) < workflow.index(propagate) def test_repo_upgrade_uses_pinned_revision_for_build_metadata(): script = (Path(__file__).parents[1] / "deploy/repo-upgrade.sh").read_text() assert 'test "$(git rev-parse HEAD)" = "$(git rev-parse "$REVISION^{commit}")"' in script assert 'GIT_SHA="$(git rev-parse --short=12 HEAD' in script assert 'VERSION="$(git rev-parse --short=12 HEAD)"' in script def test_repo_upgrade_deploys_only_origin_main(): script = (Path(__file__).parents[1] / "deploy/repo-upgrade.sh").read_text() assert "git fetch --prune origin main" in script assert "git checkout -B main origin/main" in script assert "refs/tags" not in script def test_repo_upgrade_removes_obsolete_update_command(): script = (Path(__file__).parents[1] / "deploy/repo-upgrade.sh").read_text() assert "IMPORTARR_UPDATE_COMMAND=/d" in script