diff --git a/src/mobu/constants.py b/src/mobu/constants.py index 8c3e8360..61e0f712 100644 --- a/src/mobu/constants.py +++ b/src/mobu/constants.py @@ -6,7 +6,6 @@ from pathlib import Path __all__ = [ - "GITHUB_CI_SCOPES", "GITHUB_REPO_CONFIG_PATH", "GITHUB_WEBHOOK_WAIT_SECONDS", "NOTEBOOK_REPO_BRANCH", @@ -17,14 +16,6 @@ ] -GITHUB_CI_SCOPES = [ - "exec:notebook", - "exec:portal", - "read:image", - "read:tap", -] -"""All NotebookRunner business run via GitHub CI get these scopes.""" - GITHUB_REPO_CONFIG_PATH = Path("mobu.yaml") """The path to a config file with repo-specific configuration.""" diff --git a/src/mobu/dependencies/github.py b/src/mobu/dependencies/github.py index 35a520c2..a4df2d16 100644 --- a/src/mobu/dependencies/github.py +++ b/src/mobu/dependencies/github.py @@ -4,7 +4,11 @@ import yaml -from ..github_config import GitHubCiAppConfig, GitHubRefreshAppConfig +from ..github_config import ( + GafaelfawrScope, + GitHubCiAppConfig, + GitHubRefreshAppConfig, +) from ..models.user import User from ..services.github_ci.ci_manager import CiManager from .context import ContextDependency @@ -68,11 +72,13 @@ def initialize( users: list[User], github_app_id: int, github_private_key: str, + scopes: list[GafaelfawrScope], ) -> None: self._ci_manager = CiManager( users=users, github_app_id=github_app_id, github_private_key=github_private_key, + scopes=scopes, http_client=base_context.process_context.http_client, gafaelfawr_storage=base_context.process_context.gafaelfawr, logger=base_context.process_context.logger, diff --git a/src/mobu/services/github_ci/ci_manager.py b/src/mobu/services/github_ci/ci_manager.py index 09c97ed5..4e098a36 100644 --- a/src/mobu/services/github_ci/ci_manager.py +++ b/src/mobu/services/github_ci/ci_manager.py @@ -12,6 +12,8 @@ from safir.github import GitHubAppClientFactory from structlog.stdlib import BoundLogger +from mobu.github_config import GafaelfawrScope + from ...config import config from ...models.ci_manager import CiManagerSummary, CiWorkerSummary from ...models.user import User @@ -72,11 +74,13 @@ def __init__( self, github_app_id: int, github_private_key: str, + scopes: list[GafaelfawrScope], users: list[User], http_client: AsyncClient, gafaelfawr_storage: GafaelfawrStorage, logger: BoundLogger, ) -> None: + self._scopes = scopes self._users = users self._gafaelfawr = gafaelfawr_storage self._http_client = http_client @@ -102,6 +106,7 @@ async def start(self) -> None: self.workers = [ Worker( user=user, + scopes=self._scopes, queue=self._queue, logger=self._logger, ) @@ -268,6 +273,8 @@ class Worker: Parameters ---------- + scopes + A list of Gafaelfawr scopes granted to the job's user user The user to do the work as. queue @@ -278,10 +285,12 @@ class Worker: def __init__( self, + scopes: list[GafaelfawrScope], user: User, queue: Queue[QueueItem], logger: BoundLogger, ) -> None: + self._scopes = scopes self._user = user self._queue = queue self._logger = logger.bind(ci_worker=user.username) @@ -308,7 +317,7 @@ async def run(self) -> None: f"Processing job: {job}, with user: {self._user}" ) - await job.run(user=self._user) + await job.run(user=self._user, scopes=self._scopes) lifecycle.processed.set() self.current_job = None diff --git a/src/mobu/services/github_ci/ci_notebook_job.py b/src/mobu/services/github_ci/ci_notebook_job.py index 52157975..212b73c6 100644 --- a/src/mobu/services/github_ci/ci_notebook_job.py +++ b/src/mobu/services/github_ci/ci_notebook_job.py @@ -7,8 +7,9 @@ from httpx import AsyncClient from structlog.stdlib import BoundLogger -from mobu.constants import GITHUB_CI_SCOPES, GITHUB_REPO_CONFIG_PATH +from mobu.constants import GITHUB_REPO_CONFIG_PATH from mobu.exceptions import GitHubFileNotFoundError +from mobu.github_config import GafaelfawrScope from mobu.models.business.notebookrunner import ( NotebookRunnerConfig, NotebookRunnerOptions, @@ -56,7 +57,7 @@ def __init__( self._logger = logger.bind(ci_job_type="NotebookJob") self._notebooks: list[Path] = [] - async def run(self, user: User) -> None: + async def run(self, user: User, scopes: list[GafaelfawrScope]) -> None: """Run all relevant changed notebooks and report back to GitHub. Run only changed notebooks that aren't excluded in the mobu config @@ -107,7 +108,7 @@ async def run(self, user: User) -> None: await self.check_run.start(summary=summary) solitary_config = SolitaryConfig( user=user, - scopes=GITHUB_CI_SCOPES, + scopes=[str(scope) for scope in scopes], business=NotebookRunnerConfig( type="NotebookRunner", options=NotebookRunnerOptions( diff --git a/tests/services/ci_manager_test.py b/tests/services/ci_manager_test.py index 76acb7a7..109a340f 100644 --- a/tests/services/ci_manager_test.py +++ b/tests/services/ci_manager_test.py @@ -9,6 +9,7 @@ from pydantic import HttpUrl from pytest_mock import MockerFixture +from mobu.github_config import GafaelfawrScope from mobu.models.ci_manager import ( CiJobSummary, CiManagerSummary, @@ -26,14 +27,16 @@ def create_ci_manager(respx_mock: respx.Router) -> CiManager: """Create a CiManger with appropriately mocked dependencies.""" + scopes = [ + GafaelfawrScope.exec_notebook, + GafaelfawrScope.exec_portal, + GafaelfawrScope.read_image, + GafaelfawrScope.read_tap, + ] + mock_gafaelfawr( respx_mock, - scopes=[ - "exec:notebook", - "exec:portal", - "read:image", - "read:tap", - ], + scopes=[str(scope) for scope in scopes], ) http_client = AsyncClient() logger = structlog.get_logger() @@ -43,6 +46,7 @@ def create_ci_manager(respx_mock: respx.Router) -> CiManager: http_client=http_client, gafaelfawr_storage=gafaelfawr, logger=logger, + scopes=scopes, github_app_id=123, github_private_key=TEST_GITHUB_CI_APP_PRIVATE_KEY, users=[User(username="user1"), User(username="user2")],