AkurAI Build
Menu

AkurAI-Build

public

Latest change c473d59271bebbbbbfd9250d2bc9ed003ba1d51a - ci: run verify on all branches, keep package/deploy main-only by Ólafur Búi Ólafsson

#!/usr/bin/env python3
"""Validates .akurai.yml branch policy: PR/feature branches must run verify
but can never reach package or deploy-production.

Loads the real pipeline file (not a fixture/regex) and re-implements the same
branch-gate predicate as src/runner.rs::execute_job so the check exercises
actual config semantics, not merely the YAML's shape:

    if !spec.branches.is_empty() && !spec.branches.iter().any(|allowed| allowed == branch) {
        // job skipped
    }

Run: python3 tests/test_pr_pipeline.py
"""
import unittest
from pathlib import Path

import yaml

PIPELINE_PATH = Path(__file__).resolve().parent.parent / ".akurai.yml"


def job_runs_on_branch(job: dict, branch: str) -> bool:
    """Mirror runner.rs execute_job's allow-list check bit for bit."""
    branches = job.get("branches") or []
    if branches and branch not in branches:
        return False
    return True


def load_jobs() -> dict:
    pipeline = yaml.safe_load(PIPELINE_PATH.read_text())
    return {job["name"]: job for job in pipeline["jobs"]}


class PipelineBranchPolicy(unittest.TestCase):
    def setUp(self):
        self.jobs = load_jobs()

    def test_pipeline_version_and_job_set(self):
        self.assertEqual(
            {"verify", "package", "deploy-production"}, set(self.jobs)
        )

    def test_pr_branch_executes_verify(self):
        for branch in ("feature/pr-ci-safety", "feature/anything", "fix/1"):
            self.assertTrue(
                job_runs_on_branch(self.jobs["verify"], branch),
                f"verify must run on PR branch {branch}",
            )

    def test_pr_branch_never_packages_or_deploys(self):
        for job_name in ("package", "deploy-production"):
            job = self.jobs[job_name]
            for branch in ("feature/pr-ci-safety", "feature/anything", "fix/1"):
                self.assertFalse(
                    job_runs_on_branch(job, branch),
                    f"{job_name} must not run on PR branch {branch}",
                )

    def test_main_still_runs_everything(self):
        for job_name in ("verify", "package", "deploy-production"):
            self.assertTrue(
                job_runs_on_branch(self.jobs[job_name], "main"),
                f"{job_name} must still run on main",
            )

    def test_package_requires_verify(self):
        self.assertIn("verify", self.jobs["package"].get("needs", []))

    def test_deploy_requires_package(self):
        self.assertIn("package", self.jobs["deploy-production"].get("needs", []))

    def test_deploy_never_targets_non_main_branch_list(self):
        # deploy-production's own branch allow-list must stay main-only; a PR
        # branch reaching it is impossible regardless of `needs` chaining.
        self.assertEqual(["main"], self.jobs["deploy-production"].get("branches"))
        self.assertEqual(["main"], self.jobs["package"].get("branches"))


if __name__ == "__main__":
    unittest.main()